Fix the code choosing between goto and break/continue.

The old code could choose goto even if the target language (Java)
did not support it.
This commit is contained in:
Zoltan Somogyi
2017-10-20 03:59:18 +11:00
parent 93fd027f99
commit b35452d85f

View File

@@ -793,8 +793,30 @@ init_ml_gen_tscc_info(ModuleInfo, InSccMap, TsccKind, TsccInfo) :-
counter.init(0, ConvVarCounter), counter.init(0, ConvVarCounter),
module_info_get_globals(ModuleInfo, Globals), module_info_get_globals(ModuleInfo, Globals),
SupportsBreakContinue = globals.get_target(Globals, Target),
globals_target_supports_break_and_continue(Globals), % Can we implement tail calls by adding a label at the start of
% the function, translating tail calls into a goto to that label?
SupportsGoto = target_supports_goto(Target),
% Can we implement tail calls by wrapping the function body inside
% `while (true) { ... break; }', translating tail calls into `continue'?
% Yes: all the current MLDS target languages support break and continue.
% SupportsBreakContinue = target_supports_break_and_continue(Target),
SupportsBreakContinue = yes,
(
% SupportsBreakContinue = no,
% SupportsGoto = no,
% unexpected($pred, "SupportsGoto = SupportsBreakContinue = no")
% ;
% SupportsBreakContinue = no,
% SupportsGoto = yes,
% LoopKind = tail_rec_loop_label_goto
% ;
SupportsBreakContinue = yes,
SupportsGoto = no,
LoopKind = tail_rec_loop_while_continue
;
SupportsBreakContinue = yes,
SupportsGoto = yes,
( (
TsccKind = tscc_self_rec_only, TsccKind = tscc_self_rec_only,
PreferBreakContinueOption = prefer_while_loop_over_jump_self PreferBreakContinueOption = prefer_while_loop_over_jump_self
@@ -804,20 +826,13 @@ init_ml_gen_tscc_info(ModuleInfo, InSccMap, TsccKind, TsccInfo) :-
), ),
globals.lookup_bool_option(Globals, PreferBreakContinueOption, globals.lookup_bool_option(Globals, PreferBreakContinueOption,
PreferBreakContinue), PreferBreakContinue),
( if (
SupportsBreakContinue = yes, PreferBreakContinue = no,
PreferBreakContinue = yes
then
% If we find a tail call, we will wrap the function body inside
% `while (true) { ... break; }', and so the tail call can just
% do a `continue', which will continue the next iteration
% of the loop.
LoopKind = tail_rec_loop_while_continue
else
% If we find a tail call, we will insert a label at the start
% of the function, and so the tail call can just goto
% to that label.
LoopKind = tail_rec_loop_label_goto LoopKind = tail_rec_loop_label_goto
;
PreferBreakContinue = yes,
LoopKind = tail_rec_loop_while_continue
)
), ),
TailRecInfo = tail_rec_info(InSccMap, LoopKind, TsccKind), TailRecInfo = tail_rec_info(InSccMap, LoopKind, TsccKind),
TsccInfo = ml_gen_tscc_info(FuncLabelCounter, LabelCounter, TsccInfo = ml_gen_tscc_info(FuncLabelCounter, LabelCounter,