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