[m-rev.] for post-commit review: special LLDS code generation for ground terms
Zoltan Somogyi
zs at csse.unimelb.edu.au
Mon Jan 5 12:28:03 AEDT 2009
Speed up the LLDS code generator's handling of code that constructs large
ground terms by specializing it.
This diff reduces the compilation time for training_cars_full.m by a further
38% or so, for an overall reduction by about a factor of five since I started.
The time on tools/speedtest stays pretty much the same.
compiler/unify_gen.m:
Add a mechanism to construct code for from_ground_term_construct
scopes directly.
compiler/code_gen.m:
Invoke the new mechanism in unify_gen.m for from_ground_term_construct
scopes.
Reorganize some trace goal by duplicating some common support code
inside them. The compiler wasn't optimizing it away as it should have.
compiler/code_info.m:
Export a predicate for use by the new code in unify_gen.m.
Add some debugging predicates.
compiler/opt_debug.m:
Rename a predicate to better reflect its function.
Zoltan.
Index: unify_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/unify_gen.m,v
retrieving revision 1.189
diff -u -b -r1.189 unify_gen.m
--- unify_gen.m 8 Sep 2008 03:39:06 -0000 1.189
+++ unify_gen.m 2 Jan 2009 16:23:53 -0000
@@ -48,6 +48,9 @@
test_sense::in, label::out, code_tree::out, code_info::in, code_info::out)
is det.
+:- pred generate_ground_term(prog_var::in, hlds_goal::in,
+ code_info::in, code_info::out) is det.
+
%---------------------------------------------------------------------------%
%---------------------------------------------------------------------------%
@@ -59,6 +62,7 @@
:- import_module backend_libs.type_class_info.
:- import_module check_hlds.mode_util.
:- import_module check_hlds.type_util.
+:- import_module hlds.hlds_code_util.
:- import_module hlds.hlds_module.
:- import_module hlds.hlds_out.
:- import_module hlds.hlds_pred.
@@ -69,6 +73,7 @@
:- import_module libs.tree.
:- import_module ll_backend.code_util.
:- import_module ll_backend.continuation_info.
+:- import_module ll_backend.global_data.
:- import_module ll_backend.layout.
:- import_module ll_backend.stack_layout.
:- import_module mdbcomp.prim_data.
@@ -82,7 +87,9 @@
:- import_module map.
:- import_module maybe.
:- import_module pair.
+:- import_module set.
:- import_module string.
+:- import_module svmap.
:- import_module term.
%---------------------------------------------------------------------------%
@@ -1174,9 +1181,9 @@
LeftMode = top_in,
RightMode = top_in
->
- % This shouldn't happen, since mode analysis should
- % avoid creating any tests in the arguments
- % of a construction or deconstruction unification.
+ % This shouldn't happen, since mode analysis should avoid creating
+ % any tests in the arguments of a construction or deconstruction
+ % unification.
unexpected(this_file, "test in arg of [de]construction")
;
% Input - Output== assignment ->
@@ -1241,6 +1248,200 @@
%---------------------------------------------------------------------------%
+:- type active_ground_term == pair(rval, llds_type).
+:- type active_ground_term_map == map(prog_var, active_ground_term).
+
+generate_ground_term(TermVar, Goal, !CI) :-
+ Goal = hlds_goal(GoalExpr, GoalInfo),
+ NonLocals = goal_info_get_nonlocals(GoalInfo),
+ set.to_sorted_list(NonLocals, NonLocalList),
+ (
+ NonLocalList = []
+ % The term being constructed by the scope is not needed, so there is
+ % nothing to do.
+ ;
+ NonLocalList = [NonLocal],
+ ( NonLocal = TermVar ->
+ ( GoalExpr = conj(plain_conj, Conjuncts) ->
+ get_module_info(!.CI, ModuleInfo),
+ VarTypes = get_var_types(!.CI),
+ get_exprn_opts(!.CI, ExprnOpts),
+ UnboxedFloats = get_unboxed_floats(ExprnOpts),
+ get_static_cell_info(!.CI, StaticCellInfo0),
+ map.init(ActiveMap0),
+ generate_ground_term_conjuncts(ModuleInfo, VarTypes, Conjuncts,
+ UnboxedFloats, StaticCellInfo0, StaticCellInfo,
+ ActiveMap0, ActiveMap),
+ map.to_assoc_list(ActiveMap, ActivePairs),
+ ( ActivePairs = [TermVar - GroundTerm] ->
+ add_forward_live_vars(NonLocals, !CI),
+ set_static_cell_info(StaticCellInfo, !CI),
+ GroundTerm = Rval - _,
+ assign_const_to_var(TermVar, Rval, !CI)
+ ;
+ unexpected(this_file,
+ "generate_ground_term: no active pairs")
+ )
+ ;
+ unexpected(this_file, "generate_ground_term: malformed goal")
+ )
+ ;
+ unexpected(this_file, "generate_ground_term: unexpected nonlocal")
+ )
+ ;
+ NonLocalList = [_, _ | _],
+ unexpected(this_file, "generate_ground_term: unexpected nonlocals")
+ ).
+
+:- pred generate_ground_term_conjuncts(module_info::in, vartypes::in,
+ list(hlds_goal)::in, have_unboxed_floats::in,
+ static_cell_info::in, static_cell_info::out,
+ active_ground_term_map::in, active_ground_term_map::out) is det.
+
+generate_ground_term_conjuncts(_ModuleInfo, _VarTypes, [],
+ _UnboxedFloats, !StaticCellInfo, !ActiveMap).
+generate_ground_term_conjuncts(ModuleInfo, VarTypes, [Goal | Goals],
+ UnboxedFloats, !StaticCellInfo, !ActiveMap) :-
+ generate_ground_term_conjunct(ModuleInfo, VarTypes, Goal, UnboxedFloats,
+ !StaticCellInfo, !ActiveMap),
+ generate_ground_term_conjuncts(ModuleInfo, VarTypes, Goals, UnboxedFloats,
+ !StaticCellInfo, !ActiveMap).
+
+:- pred generate_ground_term_conjunct(module_info::in, vartypes::in,
+ hlds_goal::in, have_unboxed_floats::in,
+ static_cell_info::in, static_cell_info::out,
+ active_ground_term_map::in, active_ground_term_map::out) is det.
+
+generate_ground_term_conjunct(ModuleInfo, VarTypes, Goal, UnboxedFloats,
+ !StaticCellInfo, !ActiveMap) :-
+ Goal = hlds_goal(GoalExpr, _GoalInfo),
+ (
+ GoalExpr = unify(_, _, _, Unify, _),
+ Unify = construct(Var, ConsId, Args, _, _, _, SubInfo),
+ SubInfo = no_construct_sub_info
+ ->
+ map.lookup(VarTypes, Var, Type),
+ ConsTag = cons_id_to_tag(ModuleInfo, Type, ConsId),
+ generate_ground_term_conjunct_tag(Var, ConsTag, Args, UnboxedFloats,
+ !StaticCellInfo, !ActiveMap)
+ ;
+ unexpected(this_file,
+ "generate_ground_term_conjunct: malformed goal")
+ ).
+
+:- pred generate_ground_term_conjunct_tag(prog_var::in, cons_tag::in,
+ list(prog_var)::in, have_unboxed_floats::in,
+ static_cell_info::in, static_cell_info::out,
+ active_ground_term_map::in, active_ground_term_map::out) is det.
+
+generate_ground_term_conjunct_tag(Var, ConsTag, Args, UnboxedFloats,
+ !StaticCellInfo, !ActiveMap) :-
+ (
+ (
+ ConsTag = string_tag(String),
+ Const = llconst_string(String),
+ Type = string
+ ;
+ ConsTag = int_tag(Int),
+ Const = llconst_int(Int),
+ Type = integer
+ ;
+ ConsTag = foreign_tag(Lang, Val),
+ expect(unify(Lang, lang_c), this_file,
+ "foreign_tag for language other than C"),
+ Const = llconst_foreign(Val, integer),
+ Type = integer
+ ;
+ ConsTag = float_tag(Float),
+ Const = llconst_float(Float),
+ (
+ UnboxedFloats = have_unboxed_floats,
+ Type = float
+ ;
+ UnboxedFloats = do_not_have_unboxed_floats,
+ Type = data_ptr
+ )
+ ),
+ ActiveGroundTerm = const(Const) - Type,
+ svmap.det_insert(Var, ActiveGroundTerm, !ActiveMap)
+ ;
+ ConsTag = shared_local_tag(Ptag, Stag),
+ Rval = mkword(Ptag, unop(mkbody, const(llconst_int(Stag)))),
+ ActiveGroundTerm = Rval - data_ptr,
+ svmap.det_insert(Var, ActiveGroundTerm, !ActiveMap)
+ ;
+ ConsTag = reserved_address_tag(RA),
+ Rval = generate_reserved_address(RA),
+ rval_type(Rval, RvalType),
+ ActiveGroundTerm = Rval - RvalType,
+ svmap.det_insert(Var, ActiveGroundTerm, !ActiveMap)
+ ;
+ ConsTag = shared_with_reserved_addresses_tag(_, ActualConsTag),
+ generate_ground_term_conjunct_tag(Var, ActualConsTag, Args,
+ UnboxedFloats, !StaticCellInfo, !ActiveMap)
+ ;
+ ConsTag = no_tag,
+ (
+ Args = [],
+ unexpected(this_file,
+ "generate_ground_term_conjunct_tag: no_tag arity != 1")
+ ;
+ Args = [Arg],
+ svmap.det_remove(Arg, RvalType, !ActiveMap),
+ svmap.det_insert(Var, RvalType, !ActiveMap)
+ ;
+ Args = [_, _ | _],
+ unexpected(this_file,
+ "generate_ground_term_conjunct_tag: no_tag arity != 1")
+ )
+ ;
+ (
+ ConsTag = single_functor_tag,
+ Ptag = 0
+ ;
+ ConsTag = unshared_tag(Ptag)
+ ),
+ generate_ground_term_args(Args, ArgRvalsTypes, !ActiveMap),
+ add_scalar_static_cell(ArgRvalsTypes, DataAddr, !StaticCellInfo),
+ MaybeOffset = no,
+ CellPtrConst = const(llconst_data_addr(DataAddr, MaybeOffset)),
+ Rval = mkword(Ptag, CellPtrConst),
+ ActiveGroundTerm = Rval - data_ptr,
+ svmap.det_insert(Var, ActiveGroundTerm, !ActiveMap)
+ ;
+ ConsTag = shared_remote_tag(Ptag, Stag),
+ generate_ground_term_args(Args, ArgRvalsTypes, !ActiveMap),
+ StagRvalType = const(llconst_int(Stag)) - integer,
+ AllRvalsTypes = [StagRvalType | ArgRvalsTypes],
+ add_scalar_static_cell(AllRvalsTypes, DataAddr, !StaticCellInfo),
+ MaybeOffset = no,
+ CellPtrConst = const(llconst_data_addr(DataAddr, MaybeOffset)),
+ Rval = mkword(Ptag, CellPtrConst),
+ ActiveGroundTerm = Rval - data_ptr,
+ svmap.det_insert(Var, ActiveGroundTerm, !ActiveMap)
+ ;
+ ( ConsTag = pred_closure_tag(_, _, _)
+ ; ConsTag = type_ctor_info_tag(_, _, _)
+ ; ConsTag = base_typeclass_info_tag(_, _, _)
+ ; ConsTag = tabling_info_tag(_, _)
+ ; ConsTag = table_io_decl_tag(_, _)
+ ; ConsTag = deep_profiling_proc_layout_tag(_, _)
+ ),
+ unexpected(this_file,
+ "generate_ground_term_conjunct_tag: unexpected tag")
+ ).
+
+:- pred generate_ground_term_args(list(prog_var)::in,
+ assoc_list(rval, llds_type)::out,
+ active_ground_term_map::in, active_ground_term_map::out) is det.
+
+generate_ground_term_args([], [], !ActiveMap).
+generate_ground_term_args([Var | Vars], [RvalType | RvalsTypes], !ActiveMap) :-
+ svmap.det_remove(Var, RvalType, !ActiveMap),
+ generate_ground_term_args(Vars, RvalsTypes, !ActiveMap).
+
+%---------------------------------------------------------------------------%
+
:- pred var_type_msg(mer_type::in, string::out) is det.
var_type_msg(Type, Msg) :-
Index: code_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/code_gen.m,v
retrieving revision 1.178
diff -u -b -r1.178 code_gen.m
--- code_gen.m 23 Dec 2008 01:37:29 -0000 1.178
+++ code_gen.m 2 Jan 2009 15:11:01 -0000
@@ -75,23 +75,22 @@
% the generic data structures before and after the actual code generation,
% which is delegated to goal-specific predicates.
- get_forward_live_vars(!.CI, ForwardLiveVarsBeforeGoal),
-
- % This block of code should be optimized away if the trace goals
- % are not enabled.
+ trace [compiletime(flag("codegen_goal")), io(!IO)] (
+ some [ModuleInfo, VarSet, GoalDesc] (
code_info.get_module_info(!.CI, ModuleInfo),
code_info.get_varset(!.CI, VarSet),
GoalDesc = describe_goal(ModuleInfo, VarSet, Goal),
- trace [compiletime(flag("codegen_goal")), io(!IO)] (
( should_trace_code_gen(!.CI) ->
io.format("\nGOAL START: %s\n", [s(GoalDesc)], !IO)
;
true
)
+ )
),
% Make any changes to liveness before Goal.
+ get_forward_live_vars(!.CI, ForwardLiveVarsBeforeGoal),
Goal = hlds_goal(GoalExpr, GoalInfo),
HasSubGoals = goal_expr_has_subgoals(GoalExpr),
pre_goal_update(GoalInfo, HasSubGoals, !CI),
@@ -181,6 +180,11 @@
Code = empty
),
trace [compiletime(flag("codegen_goal")), io(!IO)] (
+ some [ModuleInfo, VarSet, GoalDesc] (
+ code_info.get_module_info(!.CI, ModuleInfo),
+ code_info.get_varset(!.CI, VarSet),
+ GoalDesc = describe_goal(ModuleInfo, VarSet, Goal),
+
( should_trace_code_gen(!.CI) ->
io.format("\nGOAL FINISH: %s\n", [s(GoalDesc)], !IO),
InstrLists = tree.flatten(Code),
@@ -189,6 +193,7 @@
;
true
)
+ )
).
:- func compute_deep_save_excp_vars(proc_info) = list(prog_var).
@@ -257,9 +262,14 @@
switch_gen.generate_switch(CodeModel, Var, CanFail, CaseList, GoalInfo,
Code, !CI)
;
- GoalExpr = scope(Reason, Goal),
+ GoalExpr = scope(Reason, SubGoal),
+ ( Reason = from_ground_term(TermVar, from_ground_term_construct) ->
+ unify_gen.generate_ground_term(TermVar, SubGoal, !CI),
+ Code = empty
+ ;
commit_gen.generate_scope(Reason, CodeModel, GoalInfo,
- ForwardLiveVarsBeforeGoal, Goal, Code, !CI)
+ ForwardLiveVarsBeforeGoal, SubGoal, Code, !CI)
+ )
;
GoalExpr = generic_call(GenericCall, Args, Modes, Det),
call_gen.generate_generic_call(CodeModel, GenericCall, Args,
Index: code_info.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/code_info.m,v
retrieving revision 1.370
diff -u -b -r1.370 code_info.m
--- code_info.m 2 Jan 2009 03:12:06 -0000 1.370
+++ code_info.m 2 Jan 2009 12:59:33 -0000
@@ -51,6 +51,7 @@
:- import_module assoc_list.
:- import_module bool.
:- import_module counter.
+:- import_module io.
:- import_module list.
:- import_module map.
:- import_module maybe.
@@ -76,9 +77,9 @@
:- import_module ll_backend.opt_debug.
:- import_module ll_backend.var_locn.
:- import_module parse_tree.prog_type.
+:- import_module parse_tree.mercury_to_mercury.
:- import_module int.
-:- import_module io.
:- import_module pair.
:- import_module set.
:- import_module stack.
@@ -3245,6 +3246,9 @@
:- interface.
+:- pred add_forward_live_vars(set(prog_var)::in,
+ code_info::in, code_info::out) is det.
+
:- pred get_known_variables(code_info::in, list(prog_var)::out) is det.
:- pred variable_is_forward_live(code_info::in, prog_var::in) is semidet.
@@ -3259,9 +3263,6 @@
:- implementation.
-:- pred add_forward_live_vars(set(prog_var)::in,
- code_info::in, code_info::out) is det.
-
:- pred rem_forward_live_vars(set(prog_var)::in,
code_info::in, code_info::out) is det.
@@ -4607,6 +4608,20 @@
%
:- pred should_trace_code_gen(code_info::in) is semidet.
+:- type code_info_component
+ ---> cic_forward_live_vars
+ ; cic_zombies
+ ; cic_temps_in_use
+ ; cic_par_conj_depth.
+
+ % Print the selected parts of the code_info.
+ %
+ % If you need to print a part that is not currently selectable, make it
+ % selectable.
+ %
+:- pred output_code_info(list(code_info_component)::in, code_info::in,
+ io::di, io::uo) is det.
+
:- implementation.
should_trace_code_gen(CI) :-
@@ -4617,6 +4632,39 @@
globals.lookup_int_option(Globals, debug_code_gen_pred_id, DebugPredIdInt),
PredIdInt = DebugPredIdInt.
+output_code_info(Components, CI, !IO) :-
+ CI = code_info(Static, LocDep, _Persistent),
+ VarSet = Static ^ cis_varset,
+ LocDep = code_info_loc_dep(ForwardLiveVars, _InstMap, Zombies,
+ _VarLocnInfo, TempsInUse, _FailInfo, ParConjDepth),
+ ( list.member(cic_forward_live_vars, Components) ->
+ io.write_string("forward live vars: ", !IO),
+ mercury_output_vars(VarSet, yes, set.to_sorted_list(ForwardLiveVars),
+ !IO),
+ io.nl(!IO)
+ ;
+ true
+ ),
+ ( list.member(cic_zombies, Components) ->
+ io.write_string("zombies: ", !IO),
+ mercury_output_vars(VarSet, yes, set.to_sorted_list(Zombies), !IO),
+ io.nl(!IO)
+ ;
+ true
+ ),
+ ( list.member(cic_temps_in_use, Components) ->
+ io.write_string("temps_in_use: ", !IO),
+ io.write_string(dump_lvals(no, set.to_sorted_list(TempsInUse)), !IO),
+ io.nl(!IO)
+ ;
+ true
+ ),
+ ( list.member(cic_par_conj_depth, Components) ->
+ io.format("par_conj_depth: %d\n", [i(ParConjDepth)], !IO)
+ ;
+ true
+ ).
+
:- pred output_resume_map(prog_varset::in, map(prog_var, set(lval))::in,
io::di, io::uo) is det.
Index: opt_debug.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/opt_debug.m,v
retrieving revision 1.208
diff -u -b -r1.208 opt_debug.m
--- opt_debug.m 28 Nov 2008 06:36:59 -0000 1.208
+++ opt_debug.m 2 Jan 2009 12:48:16 -0000
@@ -69,12 +69,12 @@
:- func dump_livevals(maybe(proc_label), lvalset) = string.
-:- func dump_livelist(maybe(proc_label), list(lval)) = string.
-
:- func dump_reg(reg_type, int) = string.
:- func dump_lval(maybe(proc_label), lval) = string.
+:- func dump_lvals(maybe(proc_label), list(lval)) = string.
+
:- func dump_rval(maybe(proc_label), rval) = string.
:- func dump_rvals(maybe(proc_label), list(rval)) = string.
@@ -259,17 +259,7 @@
dump_livemaplist(MaybeProcLabel, Livemaplist).
dump_livevals(MaybeProcLabel, Lvalset) =
- dump_livelist(MaybeProcLabel, set.to_sorted_list(Lvalset)).
-
-dump_livelist(MaybeProcLabel, Lvals) =
- dump_livelist_2(MaybeProcLabel, Lvals, "").
-
-:- func dump_livelist_2(maybe(proc_label), list(lval), string) = string.
-
-dump_livelist_2(_, [], _) = "".
-dump_livelist_2(MaybeProcLabel, [Lval | Lvallist], Prefix) =
- Prefix ++ dump_lval(MaybeProcLabel, Lval) ++
- dump_livelist_2(MaybeProcLabel, Lvallist, " ").
+ dump_lvals(MaybeProcLabel, set.to_sorted_list(Lvalset)).
dump_reg(reg_r, N) =
"r" ++ int_to_string(N).
@@ -318,6 +308,16 @@
dump_lval(_, global_var_ref(env_var_ref(VarName))) =
"global_var_ref(env_var_ref(" ++ VarName ++ "))".
+dump_lvals(MaybeProcLabel, Lvals) =
+ dump_lvals_2(MaybeProcLabel, Lvals, "").
+
+:- func dump_lvals_2(maybe(proc_label), list(lval), string) = string.
+
+dump_lvals_2(_, [], _) = "".
+dump_lvals_2(MaybeProcLabel, [Lval | Lvallist], Prefix) =
+ Prefix ++ dump_lval(MaybeProcLabel, Lval) ++
+ dump_lvals_2(MaybeProcLabel, Lvallist, " ").
+
dump_rval(MaybeProcLabel, lval(Lval)) =
dump_lval(MaybeProcLabel, Lval).
dump_rval(_, var(Var)) =
--------------------------------------------------------------------------
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