Fix a long-known undocumented bug in which preds for which

code_gen.{nl,pp}:
	Fix a long-known undocumented bug in which preds for which
	the main conj has inst 'unreachable' aborted.

	Before generating a negated goal, save live variables onto
	the stack so we can find them again later.

ite_gen.nl:
	Before generating the condition of an if-then-else, save the
	live variables onto the stack so that we can find them in the
	else clause.

live_vars.nl:
	Add interference for the cases where live vars are saved before
	negations and ite conditions.
This commit is contained in:
Thomas Conway
1995-02-12 00:56:42 +00:00
parent fc52ecb56a
commit c48b5f6fcf
3 changed files with 51 additions and 14 deletions

View File

@@ -528,11 +528,18 @@ code_gen__generate_det_prolog(EntryCode, SUsed) -->
:- mode code_gen__generate_det_epilog(out, in, out) is det.
code_gen__generate_det_epilog(ExitCode) -->
code_info__get_instmap(Instmap),
code_info__get_arginfo(ArgModes),
code_info__get_headvars(HeadVars),
{ assoc_list__from_corresponding_lists(HeadVars, ArgModes, Args)},
(
{ Instmap = unreachable }
->
{ CodeA = empty }
;
code_info__setup_call(Args, HeadVars, callee, CodeA)
),
code_info__get_succip_used(Used),
{ assoc_list__from_corresponding_lists(HeadVars, ArgModes, Args) },
code_info__setup_call(Args, HeadVars, callee, CodeA),
code_info__get_total_stackslot_count(NS0),
(
{ Used = yes }
@@ -620,11 +627,18 @@ code_gen__generate_semi_prolog(EntryCode, SUsed) -->
:- mode code_gen__generate_semi_epilog(out, in, out) is det.
code_gen__generate_semi_epilog(Instr) -->
code_info__get_instmap(Instmap),
code_info__get_arginfo(ArgModes),
code_info__get_headvars(HeadVars),
{assoc_list__from_corresponding_lists(HeadVars,ArgModes,Args) },
(
{ Instmap = unreachable }
->
{ CodeA = empty }
;
code_info__setup_call(Args, HeadVars, callee, CodeA)
),
code_info__get_succip_used(Used),
{ assoc_list__from_corresponding_lists(HeadVars, ArgModes, Args) },
code_info__setup_call(Args, HeadVars, callee, CodeA),
code_info__get_total_stackslot_count(NS0),
code_info__failure_cont(FailCont),
{ code_gen__output_args(Args, LiveArgs0) },
@@ -731,10 +745,17 @@ code_gen__generate_non_prolog(EntryCode, no) -->
:- mode code_gen__generate_non_epilog(out, in, out) is det.
code_gen__generate_non_epilog(Instr) -->
code_info__get_instmap(Instmap),
code_info__get_arginfo(ArgModes),
code_info__get_headvars(HeadVars),
{ assoc_list__from_corresponding_lists(HeadVars, ArgModes, Args) },
code_info__setup_call(Args, HeadVars, callee, CodeA),
{assoc_list__from_corresponding_lists(HeadVars,ArgModes,Args) },
(
{ Instmap = unreachable }
->
{ CodeA = empty }
;
code_info__setup_call(Args, HeadVars, callee, CodeA)
),
{ code_gen__output_args(Args, LiveArgs) },
{ LiveValCode = node([
livevals(LiveArgs) - ""
@@ -918,17 +939,19 @@ code_gen__generate_negation(Goal, Code) -->
code_info__get_next_label(SuccLab),
code_info__push_failure_cont(known(SuccLab)),
code_info__maybe_save_hp(Reclaim, SaveHeapCode),
code_info__generate_nondet_saves(SaveCode),
% The contained goal cannot be nondet, because if it's
% mode-correct, it won't have any output vars, and so
% it will be semi-det.
code_gen__generate_semi_goal(Goal, GoalCode),
code_info__remake_with_call_info,
code_info__maybe_restore_hp(Reclaim, RestoreHeapCode),
code_info__pop_failure_cont,
code_info__generate_failure(FailCode),
{ SuccessCode = node([
label(SuccLab) - "negated goal failed, so proceed"
]) },
{ Code = tree(tree(SaveHeapCode, GoalCode),
{ Code = tree(tree(tree(SaveHeapCode, SaveCode), GoalCode),
tree(FailCode, tree(SuccessCode, RestoreHeapCode))) }.
%---------------------------------------------------------------------------%

View File

@@ -41,17 +41,19 @@ ite_gen__generate_det_ite(CondGoal, ThenGoal, ElseGoal, Instr) -->
code_info__maybe_save_hp(ReclaimHeap, HPSaveCode),
code_info__get_next_label(ElseLab),
code_info__push_failure_cont(known(ElseLab)),
code_info__generate_nondet_saves(SaveCode),
% Grab the instmap
code_info__get_instmap(InstMap),
% generate the semi-deterministic test goal
code_info__get_instmap(InstMap),
code_info__grab_code_info(CodeInfo),
code_gen__generate_semi_goal(CondGoal, TestCode),
code_info__pop_failure_cont,
code_info__grab_code_info(CodeInfo),
code_info__maybe_pop_stack(ReclaimHeap, HPPopCode),
code_gen__generate_forced_det_goal(ThenGoal, ThenGoalCode),
% generate code that executes the then condition
% and branches to the end of the if-then-else
code_info__slap_code_info(CodeInfo),
code_info__remake_with_call_info,
% restore the instmap
code_info__set_instmap(InstMap),
code_info__maybe_restore_hp(ReclaimHeap, HPRestoreCode),
@@ -74,7 +76,7 @@ ite_gen__generate_det_ite(CondGoal, ThenGoal, ElseGoal, Instr) -->
) },
% generate the then condition
{ Instr = tree(
tree(HPSaveCode, TestCode),
tree(tree(HPSaveCode, SaveCode), TestCode),
tree(ThenCode, ElseCode)
) },
code_info__remake_with_store_map.
@@ -95,18 +97,23 @@ ite_gen__generate_semidet_ite(CondGoal, ThenGoal, ElseGoal, Instr) -->
code_info__maybe_save_hp(ReclaimHeap, HPSaveCode),
code_info__get_next_label(ElseLab),
code_info__push_failure_cont(known(ElseLab)),
code_info__generate_nondet_saves(SaveCode),
% generate the semi-deterministic test goal
code_gen__generate_semi_goal(CondGoal, CondCode),
code_info__pop_failure_cont,
code_info__get_instmap(InstMap),
code_info__grab_code_info(CodeInfo),
code_info__maybe_pop_stack(ReclaimHeap, HPPopCode),
code_gen__generate_forced_semi_goal(ThenGoal, ThenGoalCode),
code_info__slap_code_info(CodeInfo),
code_info__remake_with_call_info,
% restore the instmap
code_info__set_instmap(InstMap),
code_info__maybe_restore_hp(ReclaimHeap, HPRestoreCode),
code_gen__generate_forced_semi_goal(ElseGoal, ElseGoalCode),
code_info__get_next_label(EndLab),
{ TestCode = tree(
HPSaveCode,
tree(HPSaveCode, SaveCode),
CondCode
) },
{ ThenCode = tree(
@@ -147,6 +154,7 @@ ite_gen__generate_nondet_ite(CondGoal, ThenGoal, ElseGoal, Instr) -->
code_info__maybe_save_hp(ReclaimHeap, HPSaveCode),
code_info__get_next_label(ElseLab),
code_info__push_failure_cont(known(ElseLab)),
code_info__generate_nondet_saves(SaveCode),
{ CondGoal = _ - GoalInfo },
{ goal_info_determinism(GoalInfo, CondDeterminism) },
{ CondDeterminism = nondeterministic ->
@@ -164,16 +172,20 @@ ite_gen__generate_nondet_ite(CondGoal, ThenGoal, ElseGoal, Instr) -->
;
{ RestoreRedoipCode = empty }
),
code_info__get_instmap(InstMap),
code_info__grab_code_info(CodeInfo),
code_info__maybe_pop_stack(ReclaimHeap, HPPopCode),
code_gen__generate_forced_non_goal(ThenGoal, ThenGoalCode),
code_info__slap_code_info(CodeInfo),
code_info__remake_with_call_info,
% restore the instmap
code_info__set_instmap(InstMap),
code_info__maybe_restore_hp(ReclaimHeap, HPRestoreCode),
code_gen__generate_forced_non_goal(ElseGoal, ElseGoalCode),
code_info__get_next_label(EndLab),
{ TestCode = tree(
tree(
HPSaveCode,
tree(HPSaveCode, SaveCode),
ModRedoipCode
),
CondCode

View File

@@ -167,7 +167,8 @@ detect_live_vars_in_goal_2(switch(_Var, _Det, Cases0), ExtraLives0, Liveness0,
detect_live_vars_in_goal_2(if_then_else(_Vars, Cond0, Then0, Else0),
ExtraLives0, Liveness0, LiveSets0, Category,
ModuleInfo, ExtraLives, Liveness, LiveSets) :-
detect_live_vars_in_goal(Cond0, ExtraLives0, Liveness0, LiveSets0,
set__insert(LiveSets0, Liveness0, LiveSets0A),
detect_live_vars_in_goal(Cond0, ExtraLives0, Liveness0, LiveSets0A,
Category,ModuleInfo, ExtraLives1, Liveness1, LiveSets1),
detect_live_vars_in_goal(Then0, ExtraLives1, Liveness1, LiveSets1,
Category,ModuleInfo,ExtraLives2, _Liveness2, LiveSets2),
@@ -176,7 +177,8 @@ detect_live_vars_in_goal_2(if_then_else(_Vars, Cond0, Then0, Else0),
detect_live_vars_in_goal_2(not(Goal0), ExtraLives0, Liveness0, LiveSets0,
Category, ModuleInfo, ExtraLives, Liveness, LiveSets) :-
detect_live_vars_in_goal(Goal0, ExtraLives0, Liveness0, LiveSets0,
set__insert(LiveSets0, Liveness0, LiveSets1),
detect_live_vars_in_goal(Goal0, ExtraLives0, Liveness0, LiveSets1,
Category, ModuleInfo, ExtraLives, Liveness, LiveSets).
detect_live_vars_in_goal_2(some(_Vs, Goal0), ExtraLives0, Liveness0, LiveSets0,