[m-rev.] for review: structure reuse for LLDS
Peter Wang
novalazy at gmail.com
Fri Jan 18 17:03:53 AEDT 2008
Branches: main
compiler/var_locn.m:
Make the LLDS code generator to generate code which performs structure
reuse.
Index: compiler/var_locn.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/var_locn.m,v
retrieving revision 1.53
diff -u -r1.53 var_locn.m
--- compiler/var_locn.m 15 Jan 2008 05:45:46 -0000 1.53
+++ compiler/var_locn.m 18 Jan 2008 06:03:00 -0000
@@ -365,6 +365,7 @@
:- implementation.
+:- import_module backend_libs.builtin_ops.
:- import_module check_hlds.type_util.
:- import_module libs.compiler_util.
:- import_module libs.options.
@@ -896,24 +897,63 @@
var_locn_produce_var(ModuleInfo, RegionVar, RegionRval,
RegionVarCode, !VLI),
MaybeRegionRval = yes(RegionRval),
- LldsComment = "Allocating region for "
+ LldsComment = "Allocating region for ",
+ CellCode = node([
+ llds_instr(
+ incr_hp(Lval, yes(Ptag), TotalOffset,
+ const(llconst_int(TotalSize)), TypeMsg, MayUseAtomic,
+ MaybeRegionRval), LldsComment ++ VarName)
+ ]),
+ SetupReuseCode = empty,
+ TempRegs = []
;
- % XXX We should probably throw an exception if we find either
- % construct_statically or reuse_cell here.
+ % XXX We should probably throw an exception if we find
+ % construct_statically here.
( HowToConstruct = construct_statically(_)
; HowToConstruct = construct_dynamically
- ; HowToConstruct = reuse_cell(_)
),
+ SetupReuseCode = empty,
RegionVarCode = empty,
MaybeRegionRval = no,
- LldsComment = "Allocating heap for "
+ LldsComment = "Allocating heap for ",
+ CellCode = node([
+ llds_instr(
+ incr_hp(Lval, yes(Ptag), TotalOffset,
+ const(llconst_int(TotalSize)), TypeMsg, MayUseAtomic,
+ MaybeRegionRval), LldsComment ++ VarName)
+ ]),
+ TempRegs = []
+ ;
+ HowToConstruct = reuse_cell(CellToReuse),
+ CellToReuse = cell_to_reuse(ReuseVar, _ReuseConsId, _),
+ var_locn_produce_var(ModuleInfo, ReuseVar, ReuseRval, ReuseVarCode,
+ !VLI),
+ ( ReuseRval = lval(ReuseLval0) ->
+ ReuseLval = ReuseLval0
+ ;
+ unexpected(this_file,
+ "var_locn_produce_var: reused cell not an lval")
+ ),
+
+ % Save any variables which are available only in the reused cell into
+ % temporary registers.
+ save_reused_cell_fields(ModuleInfo, ReuseVar, ReuseLval, SaveArgsCode,
+ TempRegs, !VLI),
+ SetupReuseCode = tree(ReuseVarCode, SaveArgsCode),
+
+ % XXX optimise the stripping of the tag when the tags are the same or
+ % the old tag is known, as we do in the high level backend
+ LldsComment = "Reusing cell on heap for ",
+ CellCode = node([
+ llds_instr(
+ assign(Lval,
+ mkword(Ptag,
+ unop(strip_tag, lval(ReuseLval)))),
+ LldsComment ++ VarName)
+ ]),
+
+ RegionVarCode = empty
),
- CellCode = node([
- llds_instr(
- incr_hp(Lval, yes(Ptag), TotalOffset,
- const(llconst_int(TotalSize)), TypeMsg, MayUseAtomic,
- MaybeRegionRval), LldsComment ++ VarName)
- ]),
var_locn_set_magic_var_location(Var, Lval, !VLI),
(
MaybeOffset = yes(Offset),
@@ -922,9 +962,11 @@
MaybeOffset = no,
StartOffset = 0
),
+ % XXX with structure reuse we don't necessarily have to assign all fields
assign_cell_args(ModuleInfo, Vector, yes(Ptag), lval(Lval), StartOffset,
ArgsCode, !VLI),
- Code = tree_list([CellCode, RegionVarCode, ArgsCode]).
+ list.foldl(var_locn_release_reg, TempRegs, !VLI),
+ Code = tree_list([SetupReuseCode, CellCode, RegionVarCode, ArgsCode]).
:- pred assign_cell_args(module_info::in, list(maybe(rval))::in,
maybe(tag)::in, rval::in, int::in, code_tree::out,
@@ -980,6 +1022,60 @@
!VLI),
Code = tree(ThisCode, RestCode).
+ % Save any variables which depend on the ReuseLval into temporary
+ % registers so that they are available after ReuseLval is clobbered.
+ %
+:- pred save_reused_cell_fields(module_info::in, prog_var::in, lval::in,
+ code_tree::out, list(lval)::out, var_locn_info::in, var_locn_info::out)
+ is det.
+
+save_reused_cell_fields(ModuleInfo, ReuseVar, ReuseLval, Code, Regs, !VLI) :-
+ var_locn_get_var_state_map(!.VLI, VarStateMap),
+ map.lookup(VarStateMap, ReuseVar, ReuseVarState0),
+ DepVarsSet = ReuseVarState0 ^ using_vars,
+ DepVars = set.to_sorted_list(DepVarsSet),
+ list.map_foldl2(save_reused_cell_fields_2(ModuleInfo, ReuseLval),
+ DepVars, SaveArgsCode, [], Regs, !VLI),
+ Code = tree_list(SaveArgsCode).
+
+:- pred save_reused_cell_fields_2(module_info::in, lval::in, prog_var::in,
+ code_tree::out, list(lval)::in, list(lval)::out,
+ var_locn_info::in, var_locn_info::out) is det.
+
+save_reused_cell_fields_2(ModuleInfo, ReuseLval, DepVar, SaveDepVarCode,
+ !Regs, !VLI) :-
+ find_var_availability(!.VLI, DepVar, no, Avail),
+ (
+ Avail = available(DepVarRval),
+ EvalCode = empty
+ ;
+ Avail = needs_materialization,
+ materialize_var(ModuleInfo, DepVar, no, no, [], DepVarRval, EvalCode,
+ !VLI)
+ ),
+ var_locn_get_vartypes(!.VLI, VarTypes),
+ map.lookup(VarTypes, DepVar, DepVarType),
+ (
+ is_dummy_argument_type(ModuleInfo, DepVarType)
+ ->
+ AssignCode = empty
+ ;
+ rval_depends_on_search_lval(DepVarRval,
+ specific_reg_or_stack(ReuseLval))
+ ->
+ var_locn_acquire_reg(Target, !VLI),
+ add_additional_lval_for_var(DepVar, Target, !VLI),
+ get_var_name(!.VLI, DepVar, DepVarName),
+ AssignCode = node([
+ llds_instr(assign(Target, DepVarRval),
+ "saving " ++ DepVarName)
+ ]),
+ !:Regs = [Target | !.Regs]
+ ;
+ AssignCode = empty
+ ),
+ SaveDepVarCode = tree(EvalCode, AssignCode).
+
%----------------------------------------------------------------------------%
% Record that Var is now available in Lval, as well as in the locations
@@ -1296,8 +1392,8 @@
Code = empty
).
- % If we must copy the value in Lval somewhere else to prevent it from
- % being lost when Lval overwritten, then we try to put it into a location
+ % If we must copy the value in Lval somewhere else to prevent it from being
+ % lost when Lval is overwritten, then we try to put it into a location
% where it will be needed next. First we find a variable that is stored
% in Lval directly, and not just in some location whose path includes Lval
% (the set of all variables affected by the update of Lval is
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to: mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions: mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------
More information about the reviews
mailing list