for review: cleanup of liveness info around calls
Zoltan Somogyi
zs at cs.mu.OZ.AU
Wed Nov 11 15:30:11 AEDT 1998
This is for Tyson.
I do not intend to commit this change before the release
(unless Tyson insists).
compiler/call_gen.m:
compiler/code_info.m:
General cleanup of the code dealing with (a) the livevals annotation
before calls, which says what lvals are live before a call; and (b)
what lvals are live containing what values after a call. This involves
a rewrite of the appropriate submodule in code_info, including much
more meaningful predicate names, and related changes in call_gen.
It also involves adding a new, non-exported predicate in another
submodule of code_info, and removing some code duplication; some
of the work of the code_info submodule was duplicated in call_gen.
There is no change in functionality.
Zoltan.
I include a unified diff for call_gen and a context diff for code_info,
since these are significantly easier to read.
Index: compiler/call_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/call_gen.m,v
retrieving revision 1.126
diff -u -u -r1.126 call_gen.m
--- 1.126 1998/11/05 03:52:03
+++ call_gen.m 1998/11/10 10:03:50
@@ -19,7 +19,7 @@
:- interface.
:- import_module prog_data, hlds_pred, hlds_data, hlds_goal, llds, code_info.
-:- import_module term, list, set, assoc_list, std_util.
+:- import_module term, list, set, assoc_list.
:- pred call_gen__generate_higher_order_call(code_model, var, list(var),
list(type), list(mode), determinism, hlds_goal_info,
@@ -45,12 +45,12 @@
list(var), list(var)).
:- mode call_gen__partition_args(in, out, out) is det.
-:- pred call_gen__input_arg_locs(list(pair(var, arg_info)),
- list(pair(var, arg_loc))).
+:- pred call_gen__input_arg_locs(assoc_list(var, arg_info),
+ assoc_list(var, arg_loc)).
:- mode call_gen__input_arg_locs(in, out) is det.
-:- pred call_gen__output_arg_locs(list(pair(var, arg_info)),
- list(pair(var, arg_loc))).
+:- pred call_gen__output_arg_locs(assoc_list(var, arg_info),
+ assoc_list(var, arg_loc)).
:- mode call_gen__output_arg_locs(in, out) is det.
:- pred call_gen__save_variables(set(var), code_tree,
@@ -64,7 +64,7 @@
:- import_module hlds_module, code_util.
:- import_module arg_info, type_util, mode_util, unify_proc, instmap.
:- import_module trace, globals, options.
-:- import_module bool, int, tree, map.
+:- import_module std_util, bool, int, tree, map.
:- import_module varset, require.
%---------------------------------------------------------------------------%
@@ -94,23 +94,23 @@
% Figure out what locations are live at the call point,
% for use by the value numbering optimization.
{ call_gen__input_args(ArgInfo, InputArguments) },
- call_gen__generate_call_livevals(OutArgs, InputArguments, LiveCode),
+ call_gen__generate_call_vn_livevals(InputArguments, OutArgs,
+ LiveCode),
% Figure out what variables will be live at the return point,
% and where, for use in the accurate garbage collector, and
% in the debugger.
code_info__get_instmap(InstMap),
{ goal_info_get_instmap_delta(GoalInfo, InstMapDelta) },
- { instmap__apply_instmap_delta(InstMap, InstMapDelta,
- AfterCallInstMap) },
- { call_gen__output_arg_locs(ArgsInfos, OutputArguments) },
+ { instmap__apply_instmap_delta(InstMap, InstMapDelta, ReturnInstMap) },
+ { call_gen__output_arg_locs(ArgsInfos, OutputArgLocs) },
% We must update the code generator state to reflect
% the situation after the call before building
% the return liveness info. No later code in this
% predicate depends on the old state.
call_gen__rebuild_registers(ArgsInfos),
- call_gen__generate_return_livevals(OutArgs, OutputArguments,
- AfterCallInstMap, OutLiveVals),
+ code_info__generate_return_live_lvalues(OutputArgLocs, ReturnInstMap,
+ ReturnLiveLvalues),
% Make the call.
code_info__get_module_info(ModuleInfo),
@@ -118,7 +118,7 @@
code_info__get_next_label(ReturnLabel),
{ call_gen__call_comment(CodeModel, CallComment) },
{ CallCode = node([
- call(Address, label(ReturnLabel), OutLiveVals, CallModel)
+ call(Address, label(ReturnLabel), ReturnLiveLvalues, CallModel)
- CallComment,
label(ReturnLabel)
- "continuation label"
@@ -171,7 +171,7 @@
% place the immediate input arguments in registers
% starting at r4.
call_gen__generate_immediate_args(InVars, 4, InLocs, ImmediateCode),
- code_info__generate_stack_livevals(OutArgs, LiveVals0),
+ code_info__generate_call_stack_vn_livevals(OutArgs, LiveVals0),
{ set__insert_list(LiveVals0,
[reg(r, 1), reg(r, 2), reg(r, 3) | InLocs], LiveVals) },
(
@@ -183,11 +183,10 @@
),
{ call_gen__outvars_to_outargs(OutVars, FirstArg, OutArguments) },
- { call_gen__output_arg_locs(OutArguments, OutLocs) },
+ { call_gen__output_arg_locs(OutArguments, OutputArgLocs) },
code_info__get_instmap(InstMap),
{ goal_info_get_instmap_delta(GoalInfo, InstMapDelta) },
- { instmap__apply_instmap_delta(InstMap, InstMapDelta,
- AfterCallInstMap) },
+ { instmap__apply_instmap_delta(InstMap, InstMapDelta, ReturnInstMap) },
code_info__produce_variable(PredVar, PredVarCode, PredRVal),
(
@@ -216,14 +215,15 @@
% the return liveness info. No later code in this
% predicate depends on the old state.
call_gen__rebuild_registers(OutArguments),
- call_gen__generate_return_livevals(OutArgs, OutLocs, AfterCallInstMap,
- OutLiveVals),
+ code_info__generate_return_live_lvalues(OutputArgLocs, ReturnInstMap,
+ ReturnLiveLvalues),
code_info__get_next_label(ReturnLabel),
{ CallCode = node([
livevals(LiveVals)
- "",
- call(DoHigherCall, label(ReturnLabel), OutLiveVals, CallModel)
+ call(DoHigherCall, label(ReturnLabel), ReturnLiveLvalues,
+ CallModel)
- "Setup and call higher order pred",
label(ReturnLabel)
- "Continuation label"
@@ -278,7 +278,7 @@
% place the immediate input arguments in registers
% starting at r5.
call_gen__generate_immediate_args(InVars, 5, InLocs, ImmediateCode),
- code_info__generate_stack_livevals(OutArgs, LiveVals0),
+ code_info__generate_call_stack_vn_livevals(OutArgs, LiveVals0),
{ set__insert_list(LiveVals0,
[reg(r, 1), reg(r, 2), reg(r, 3), reg(r, 4) | InLocs],
LiveVals) },
@@ -290,11 +290,10 @@
{ FirstArg = 1 }
),
{ call_gen__outvars_to_outargs(OutVars, FirstArg, OutArguments) },
- { call_gen__output_arg_locs(OutArguments, OutLocs) },
+ { call_gen__output_arg_locs(OutArguments, OutputArgLocs) },
code_info__get_instmap(InstMap),
{ goal_info_get_instmap_delta(GoalInfo, InstMapDelta) },
- { instmap__apply_instmap_delta(InstMap, InstMapDelta,
- AfterCallInstMap) },
+ { instmap__apply_instmap_delta(InstMap, InstMapDelta, ReturnInstMap) },
code_info__produce_variable(TCVar, TCVarCode, TCVarRVal),
(
@@ -325,14 +324,15 @@
% the return liveness info. No later code in this
% predicate depends on the old state.
call_gen__rebuild_registers(OutArguments),
- call_gen__generate_return_livevals(OutArgs, OutLocs, AfterCallInstMap,
- OutLiveVals),
+ code_info__generate_return_live_lvalues(OutputArgLocs, ReturnInstMap,
+ ReturnLiveLvalues),
code_info__get_next_label(ReturnLabel),
{ CallCode = node([
livevals(LiveVals)
- "",
- call(DoMethodCall, label(ReturnLabel), OutLiveVals, CallModel)
+ call(DoMethodCall, label(ReturnLabel), ReturnLiveLvalues,
+ CallModel)
- "Setup and call class method",
label(ReturnLabel)
- "Continuation label"
@@ -615,74 +615,15 @@
%---------------------------------------------------------------------------%
-:- pred call_gen__generate_call_livevals(set(var), list(arg_loc), code_tree,
- code_info, code_info).
-:- mode call_gen__generate_call_livevals(in, in, out, in, out) is det.
+:- pred call_gen__generate_call_vn_livevals(list(arg_loc)::in, set(var)::in,
+ code_tree::out, code_info::in, code_info::out) is det.
-call_gen__generate_call_livevals(OutArgs, InputArgs, Code) -->
- code_info__generate_stack_livevals(OutArgs, LiveVals0),
- { call_gen__insert_arg_livevals(InputArgs, LiveVals0, LiveVals) },
+call_gen__generate_call_vn_livevals(InputArgLocs, OutputArgs, Code) -->
+ code_info__generate_call_vn_livevals(InputArgLocs, OutputArgs,
+ LiveVals),
{ Code = node([
livevals(LiveVals) - ""
]) }.
-
-%---------------------------------------------------------------------------%
-
-:- pred call_gen__insert_arg_livevals(list(arg_loc),
- set(lval), set(lval)).
-:- mode call_gen__insert_arg_livevals(in, in, out) is det.
-
-call_gen__insert_arg_livevals([], LiveVals, LiveVals).
-call_gen__insert_arg_livevals([L | As], LiveVals0, LiveVals) :-
- code_util__arg_loc_to_register(L, R),
- set__insert(LiveVals0, R, LiveVals1),
- call_gen__insert_arg_livevals(As, LiveVals1, LiveVals).
-
-%---------------------------------------------------------------------------%
-
-:- pred call_gen__generate_return_livevals(set(var), list(pair(var, arg_loc)),
- instmap, list(liveinfo), code_info, code_info).
-:- mode call_gen__generate_return_livevals(in, in, in, out, in, out) is det.
-
-call_gen__generate_return_livevals(OutArgs, OutputArgs, AfterCallInstMap,
- LiveVals) -->
- code_info__generate_stack_livelvals(OutArgs, AfterCallInstMap,
- LiveVals0),
- code_info__get_globals(Globals),
- { globals__want_return_var_layouts(Globals, WantReturnVarLayout) },
- call_gen__insert_arg_livelvals(OutputArgs, WantReturnVarLayout,
- AfterCallInstMap, LiveVals0, LiveVals).
-
-% Maybe a varlist to type_id list would be a better way to do this...
-
-%---------------------------------------------------------------------------%
-
-:- pred call_gen__insert_arg_livelvals(list(pair(var, arg_loc)), bool,
- instmap, list(liveinfo), list(liveinfo), code_info, code_info).
-:- mode call_gen__insert_arg_livelvals(in, in, in, in, out, in, out) is det.
-
-call_gen__insert_arg_livelvals([], _, _, LiveVals, LiveVals) --> [].
-call_gen__insert_arg_livelvals([Var - L | As], WantReturnVarLayout,
- AfterCallInstMap, LiveVals0, LiveVals) -->
- code_info__get_varset(VarSet),
- { varset__lookup_name(VarSet, Var, Name) },
- { code_util__arg_loc_to_register(L, R) },
- (
- { WantReturnVarLayout = yes }
- ->
- { instmap__lookup_var(AfterCallInstMap, Var, Inst) },
-
- code_info__variable_type(Var, Type),
- { type_util__vars(Type, TypeVars) },
- code_info__find_typeinfos_for_tvars(TypeVars, TypeParams),
- { VarInfo = var(Var, Name, Type, Inst) },
- { LiveVal = live_lvalue(direct(R), VarInfo, TypeParams) }
- ;
- { map__init(Empty) },
- { LiveVal = live_lvalue(direct(R), unwanted, Empty) }
- ),
- call_gen__insert_arg_livelvals(As, WantReturnVarLayout,
- AfterCallInstMap, [LiveVal | LiveVals0], LiveVals).
%---------------------------------------------------------------------------%
Index: compiler/code_info.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/code_info.m,v
retrieving revision 1.232
diff -u -u -c -r1.232 code_info.m
/usr/local/bin/diff: conflicting specifications of output style
*** 1.232 1998/11/05 03:52:08
--- code_info.m 1998/11/11 00:48:52
***************
*** 648,653 ****
--- 648,657 ----
code_exprn__set_follow_vars(FollowVars, ExprnInfo0, ExprnInfo),
code_info__set_exprn_info(ExprnInfo, CI0, CI).
+ :- pred code_info__get_active_temps_data(assoc_list(lval, slot_contents),
+ code_info, code_info).
+ :- mode code_info__get_active_temps_data(out, in, out) is det.
+
%-----------------------------------------------------------------------------%
% Update the code info structure to be consistent
***************
*** 847,852 ****
--- 851,862 ----
},
code_info__set_layout_info(Internals).
+ code_info__get_active_temps_data(Temps) -->
+ code_info__get_temps_in_use(TempsInUse),
+ code_info__get_temp_content_map(TempContentMap),
+ { map__select(TempContentMap, TempsInUse, TempsInUseContentMap) },
+ { map__to_assoc_list(TempsInUseContentMap, Temps) }.
+
%---------------------------------------------------------------------------%
%---------------------------------------------------------------------------%
***************
*** 3066,3190 ****
%---------------------------------------------------------------------------%
%---------------------------------------------------------------------------%
! % Submodule for dealing with information for garbage collection
! % and value numbering.
:- interface.
! :- pred code_info__generate_stack_livevals(set(var), set(lval),
! code_info, code_info).
! :- mode code_info__generate_stack_livevals(in, out, in, out) is det.
! :- pred code_info__generate_stack_livelvals(set(var), instmap,
! list(liveinfo), code_info, code_info).
! :- mode code_info__generate_stack_livelvals(in, in, out, in, out) is det.
%---------------------------------------------------------------------------%
:- implementation.
! code_info__generate_stack_livevals(Args, LiveVals) -->
! code_info__get_known_variables(LiveVars),
! { set__list_to_set(LiveVars, Vars0) },
! { set__difference(Vars0, Args, Vars) },
! { set__to_sorted_list(Vars, VarList) },
{ set__init(LiveVals0) },
! code_info__generate_var_livevals(VarList, LiveVals0, LiveVals1),
! code_info__get_temps_in_use(TempsInUse),
! code_info__get_temp_content_map(TempContentMap),
! { map__select(TempContentMap, TempsInUse, TempsInUseContentMap) },
! { map__to_assoc_list(TempsInUseContentMap, Temps) },
! { code_info__generate_temp_livevals(Temps, LiveVals1, LiveVals) }.
! :- pred code_info__generate_var_livevals(list(var), set(lval), set(lval),
! code_info, code_info).
! :- mode code_info__generate_var_livevals(in, in, out, in, out) is det.
! code_info__generate_var_livevals([], Vals, Vals) --> [].
! code_info__generate_var_livevals([V | Vs], Vals0, Vals) -->
! code_info__get_variable_slot(V, Slot),
! { set__insert(Vals0, Slot, Vals1) },
! code_info__generate_var_livevals(Vs, Vals1, Vals).
! :- pred code_info__generate_temp_livevals(assoc_list(lval, slot_contents),
! set(lval), set(lval)).
! :- mode code_info__generate_temp_livevals(in, in, out) is det.
! code_info__generate_temp_livevals([], Vals, Vals).
! code_info__generate_temp_livevals([Slot - _ | Slots], Vals0, Vals) :-
! set__insert(Vals0, Slot, Vals1),
! code_info__generate_temp_livevals(Slots, Vals1, Vals).
%---------------------------------------------------------------------------%
! code_info__generate_stack_livelvals(Args, AfterCallInstMap, LiveVals) -->
! code_info__get_known_variables(LiveVars),
! { set__list_to_set(LiveVars, Vars0) },
! { set__difference(Vars0, Args, Vars) },
! { set__to_sorted_list(Vars, VarList) },
! { set__init(LiveVals0) },
! code_info__generate_var_livelvals(VarList, LiveVals0, LiveVals1),
! { set__to_sorted_list(LiveVals1, LiveVals2) },
code_info__get_globals(Globals),
{ globals__want_return_var_layouts(Globals, WantReturnVarLayout) },
! code_info__livevals_to_livelvals(LiveVals2, WantReturnVarLayout,
! AfterCallInstMap, LiveVals3),
! code_info__get_temps_in_use(TempsInUse),
! code_info__get_temp_content_map(TempContentMap),
! { map__select(TempContentMap, TempsInUse, TempsInUseContentMap) },
! { map__to_assoc_list(TempsInUseContentMap, Temps) },
! { code_info__generate_temp_livelvals(Temps, LiveVals3, LiveVals) }.
! :- pred code_info__generate_var_livelvals(list(var),
! set(pair(lval, var)), set(pair(lval, var)), code_info, code_info).
! :- mode code_info__generate_var_livelvals(in, in, out, in, out) is det.
!
! code_info__generate_var_livelvals([], Vals, Vals) --> [].
! code_info__generate_var_livelvals([V | Vs], Vals0, Vals) -->
! code_info__get_variable_slot(V, Slot),
! { set__insert(Vals0, Slot - V, Vals1) },
! code_info__generate_var_livelvals(Vs, Vals1, Vals).
!
! :- pred code_info__generate_temp_livelvals(assoc_list(lval, slot_contents),
! list(liveinfo), list(liveinfo)).
! :- mode code_info__generate_temp_livelvals(in, in, out) is det.
!
! code_info__generate_temp_livelvals([], LiveInfo, LiveInfo).
! code_info__generate_temp_livelvals([Slot - StoredLval | Slots], LiveInfo0,
! [live_lvalue(direct(Slot), LiveValueType, Empty) | LiveInfo1])
! :-
map__init(Empty),
! code_info__get_live_value_type(StoredLval, LiveValueType),
! code_info__generate_temp_livelvals(Slots, LiveInfo0, LiveInfo1).
! :- pred code_info__livevals_to_livelvals(assoc_list(lval, var), bool,
! instmap, list(liveinfo), code_info, code_info).
! :- mode code_info__livevals_to_livelvals(in, in, in, out, in, out) is det.
!
! code_info__livevals_to_livelvals([], _, _, []) --> [].
! code_info__livevals_to_livelvals([Lval - Var | Ls], WantReturnVarLayout,
! AfterCallInstMap, [LiveLval | Lives]) -->
! code_info__get_varset(VarSet),
(
{ WantReturnVarLayout = yes }
->
! { instmap__lookup_var(AfterCallInstMap, Var, Inst) },
{ varset__lookup_name(VarSet, Var, Name) },
-
code_info__variable_type(Var, Type),
{ type_util__vars(Type, TypeVars) },
code_info__find_typeinfos_for_tvars(TypeVars, TypeParams),
! { LiveLval = live_lvalue(direct(Lval),
! var(Var, Name, Type, Inst), TypeParams) }
;
{ map__init(Empty) },
! { LiveLval = live_lvalue(direct(Lval), unwanted, Empty) }
),
! code_info__livevals_to_livelvals(Ls, WantReturnVarLayout,
! AfterCallInstMap, Lives).
! :- pred code_info__get_live_value_type(slot_contents, live_value_type).
! :- mode code_info__get_live_value_type(in, out) is det.
code_info__get_live_value_type(lval(succip), succip).
code_info__get_live_value_type(lval(hp), hp).
--- 3076,3216 ----
%---------------------------------------------------------------------------%
%---------------------------------------------------------------------------%
! % Submodule for dealing with the recording of variable liveness
! % information around calls.
! %
! % Value numbering needs to know what locations are live before calls;
! % the garbage collector and the debugger need to know what locations
! % are live containing what types of values after calls.
:- interface.
! :- pred code_info__generate_call_stack_vn_livevals(set(var)::in,
! set(lval)::out, code_info::in, code_info::out) is det.
! :- pred code_info__generate_call_vn_livevals(list(arg_loc)::in, set(var)::in,
! set(lval)::out, code_info::in, code_info::out) is det.
!
! :- pred code_info__generate_return_live_lvalues(assoc_list(var, arg_loc)::in,
! instmap::in, list(liveinfo)::out, code_info::in, code_info::out)
! is det.
%---------------------------------------------------------------------------%
:- implementation.
! code_info__generate_call_stack_vn_livevals(OutputArgs, LiveVals) -->
! code_info__get_known_variables(KnownVarList),
! { set__list_to_set(KnownVarList, KnownVars) },
! { set__difference(KnownVars, OutputArgs, LiveVars) },
! { set__to_sorted_list(LiveVars, LiveVarList) },
{ set__init(LiveVals0) },
! code_info__generate_stack_var_vn(LiveVarList, LiveVals0, LiveVals1),
! code_info__get_active_temps_data(Temps),
! { code_info__generate_call_temp_vn(Temps, LiveVals1, LiveVals) }.
!
! code_info__generate_call_vn_livevals(InputArgLocs, OutputArgs, LiveVals) -->
! code_info__generate_call_stack_vn_livevals(OutputArgs, StackLiveVals),
! { code_info__generate_input_var_vn(InputArgLocs, StackLiveVals,
! LiveVals) }.
!
! :- pred code_info__generate_stack_var_vn(list(var)::in, set(lval)::in,
! set(lval)::out, code_info::in, code_info::out) is det.
!
! code_info__generate_stack_var_vn([], Vals, Vals) --> [].
! code_info__generate_stack_var_vn([V | Vs], Vals0, Vals) -->
! code_info__get_variable_slot(V, Lval),
! { set__insert(Vals0, Lval, Vals1) },
! code_info__generate_stack_var_vn(Vs, Vals1, Vals).
!
! :- pred code_info__generate_call_temp_vn(assoc_list(lval, slot_contents)::in,
! set(lval)::in, set(lval)::out) is det.
! code_info__generate_call_temp_vn([], Vals, Vals).
! code_info__generate_call_temp_vn([Lval - _ | Temps], Vals0, Vals) :-
! set__insert(Vals0, Lval, Vals1),
! code_info__generate_call_temp_vn(Temps, Vals1, Vals).
! :- pred code_info__generate_input_var_vn(list(arg_loc)::in,
! set(lval)::in, set(lval)::out) is det.
! code_info__generate_input_var_vn([], Vals, Vals).
! code_info__generate_input_var_vn([InputArgLoc | InputArgLocs], Vals0, Vals) :-
! code_util__arg_loc_to_register(InputArgLoc, Lval),
! set__insert(Vals0, Lval, Vals1),
! code_info__generate_input_var_vn(InputArgLocs, Vals1, Vals).
%---------------------------------------------------------------------------%
! code_info__generate_return_live_lvalues(OutputArgLocs, ReturnInstMap,
! LiveLvalues) -->
! code_info__get_known_variables(Vars),
code_info__get_globals(Globals),
{ globals__want_return_var_layouts(Globals, WantReturnVarLayout) },
! code_info__find_return_var_lvals(Vars, OutputArgLocs, VarLvals),
! code_info__generate_var_live_lvalues(VarLvals,
! ReturnInstMap, WantReturnVarLayout, VarLiveLvalues),
!
! code_info__get_active_temps_data(Temps),
! { code_info__generate_temp_live_lvalues(Temps, TempLiveLvalues) },
!
! { list__append(VarLiveLvalues, TempLiveLvalues, LiveLvalues) }.
!
! :- pred code_info__find_return_var_lvals(list(var)::in,
! assoc_list(var, arg_loc)::in, assoc_list(var, lval)::out,
! code_info::in, code_info::out) is det.
! code_info__find_return_var_lvals([], _, []) --> [].
! code_info__find_return_var_lvals([Var | Vars], OutputArgLocs,
! [Var - Lval | VarLvals]) -->
! ( { assoc_list__search(OutputArgLocs, Var, ArgLoc) } ->
! % On return, output arguments are in their registers.
! { code_util__arg_loc_to_register(ArgLoc, Lval) }
! ;
! % On return, other live variables are in their stack slots.
! code_info__get_variable_slot(Var, Lval)
! ),
! code_info__find_return_var_lvals(Vars, OutputArgLocs, VarLvals).
!
! :- pred code_info__generate_temp_live_lvalues(
! assoc_list(lval, slot_contents)::in, list(liveinfo)::out) is det.
!
! code_info__generate_temp_live_lvalues([], []).
! code_info__generate_temp_live_lvalues([Temp | Temps], [Live | Lives]) :-
! Temp = Slot - Contents,
! code_info__get_live_value_type(Contents, LiveLvalueType),
map__init(Empty),
! Live = live_lvalue(direct(Slot), LiveLvalueType, Empty),
! code_info__generate_temp_live_lvalues(Temps, Lives).
! :- pred code_info__generate_var_live_lvalues(assoc_list(var, lval)::in,
! instmap::in, bool::in, list(liveinfo)::out,
! code_info::in, code_info::out) is det.
!
! code_info__generate_var_live_lvalues([], _, _, []) --> [].
! code_info__generate_var_live_lvalues([Var - Lval | VarLvals], InstMap,
! WantReturnVarLayout, [Live | Lives]) -->
(
{ WantReturnVarLayout = yes }
->
! code_info__get_varset(VarSet),
{ varset__lookup_name(VarSet, Var, Name) },
code_info__variable_type(Var, Type),
+ { instmap__lookup_var(InstMap, Var, Inst) },
{ type_util__vars(Type, TypeVars) },
code_info__find_typeinfos_for_tvars(TypeVars, TypeParams),
! { VarInfo = var(Var, Name, Type, Inst) },
! { Live = live_lvalue(direct(Lval), VarInfo, TypeParams) }
;
{ map__init(Empty) },
! { Live = live_lvalue(direct(Lval), unwanted, Empty) }
),
! code_info__generate_var_live_lvalues(VarLvals, InstMap,
! WantReturnVarLayout, Lives).
! :- pred code_info__get_live_value_type(slot_contents::in, live_value_type::out)
! is det.
code_info__get_live_value_type(lval(succip), succip).
code_info__get_live_value_type(lval(hp), hp).
More information about the developers
mailing list