[m-rev.] diff: hlds_statistics.m
Zoltan Somogyi
zs at csse.unimelb.edu.au
Thu Feb 4 10:17:02 AEDT 2010
For post-commit review by anyone.
Zoltan.
Add a new option, --proc-size-statistics <filename>. When specified, the
compiler will append statistics about the sizes of procedures to the named
file.
compiler/hlds_statistics.m:
New module that does this.
compiler/options.m:
doc/user_guide.texi:
Document the new option.
compiler/mercury_compile_front_end.m:
Invoke the code to gather and print statistics if the option is
specified.
compiler/hlds_pred.m:
Improve the style of some old code.
cvs diff: Diffing .
cvs diff: Diffing analysis
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/doc
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing boehm_gc/libatomic_ops-1.2
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/doc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/gcc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/hpc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/ibmc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/icc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/msftc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/sunc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/tests
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing boehm_gc/windows-untested
cvs diff: Diffing boehm_gc/windows-untested/vc60
cvs diff: Diffing boehm_gc/windows-untested/vc70
cvs diff: Diffing boehm_gc/windows-untested/vc71
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
Index: compiler/hlds.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds.m,v
retrieving revision 1.226
diff -u -b -r1.226 hlds.m
--- compiler/hlds.m 14 Oct 2009 05:28:33 -0000 1.226
+++ compiler/hlds.m 3 Feb 2010 23:05:39 -0000
@@ -54,6 +54,7 @@
:- include_module mark_static_terms.
:- include_module mark_tail_calls.
:- include_module passes_aux.
+:- include_module hlds_statistics.
%-----------------------------------------------------------------------------%
Index: compiler/hlds_pred.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds_pred.m,v
retrieving revision 1.255
diff -u -b -r1.255 hlds_pred.m
--- compiler/hlds_pred.m 4 Sep 2009 02:27:51 -0000 1.255
+++ compiler/hlds_pred.m 3 Feb 2010 23:05:39 -0000
@@ -1390,9 +1390,9 @@
PredInfo ^ exist_quant_tvars, PredInfo ^ arg_types).
pred_info_set_arg_types(TypeVarSet, ExistQVars, ArgTypes, !PredInfo) :-
- !:PredInfo = !.PredInfo ^ decl_typevarset := TypeVarSet,
- !:PredInfo = !.PredInfo ^ exist_quant_tvars := ExistQVars,
- !:PredInfo = !.PredInfo ^ arg_types := ArgTypes.
+ !PredInfo ^ decl_typevarset := TypeVarSet,
+ !PredInfo ^ exist_quant_tvars := ExistQVars,
+ !PredInfo ^ arg_types := ArgTypes.
pred_info_proc_info(PredInfo, ProcId, ProcInfo) :-
ProcInfo = map.lookup(PredInfo ^ procedures, ProcId).
@@ -2521,11 +2521,11 @@
RttiVarMaps, eval_normal, ProcSubInfo).
proc_info_set_body(VarSet, VarTypes, HeadVars, Goal, RttiVarMaps, !ProcInfo) :-
- !:ProcInfo = !.ProcInfo ^ prog_varset := VarSet,
- !:ProcInfo = !.ProcInfo ^ var_types := VarTypes,
- !:ProcInfo = !.ProcInfo ^ head_vars := HeadVars,
- !:ProcInfo = !.ProcInfo ^ body := Goal,
- !:ProcInfo = !.ProcInfo ^ proc_rtti_varmaps := RttiVarMaps.
+ !ProcInfo ^ prog_varset := VarSet,
+ !ProcInfo ^ var_types := VarTypes,
+ !ProcInfo ^ head_vars := HeadVars,
+ !ProcInfo ^ body := Goal,
+ !ProcInfo ^ proc_rtti_varmaps := RttiVarMaps.
proc_info_get_context(PI, PI ^ proc_context).
proc_info_get_varset(PI, PI ^ prog_varset).
@@ -2698,16 +2698,15 @@
Termination2Info = ProcInfo ^ proc_sub_info ^ termination2.
proc_info_set_termination2_info(Termination2Info, !ProcInfo) :-
- !:ProcInfo = !.ProcInfo ^ proc_sub_info ^ termination2 :=
- Termination2Info.
+ !ProcInfo ^ proc_sub_info ^ termination2 := Termination2Info.
proc_info_get_structure_sharing(ProcInfo, MaybeSharing) :-
MaybeSharing = ProcInfo ^ proc_sub_info ^ structure_sharing
^ maybe_sharing.
proc_info_set_structure_sharing(Sharing, !ProcInfo) :-
- !:ProcInfo = !.ProcInfo ^ proc_sub_info ^ structure_sharing
- ^ maybe_sharing := yes(Sharing).
+ !ProcInfo ^ proc_sub_info ^ structure_sharing ^ maybe_sharing :=
+ yes(Sharing).
proc_info_get_imported_structure_sharing(ProcInfo, HeadVars, Types, Sharing) :-
MaybeImportedSharing = ProcInfo ^ proc_sub_info ^ structure_sharing
@@ -2719,19 +2718,18 @@
!ProcInfo) :-
ImportedSharing = imported_sharing(HeadVars, Types, Sharing),
MaybeImportedSharing = yes(ImportedSharing),
- !:ProcInfo = !.ProcInfo ^ proc_sub_info ^ structure_sharing
- ^ maybe_imported_sharing := MaybeImportedSharing.
+ !ProcInfo ^ proc_sub_info ^ structure_sharing ^ maybe_imported_sharing :=
+ MaybeImportedSharing.
proc_info_reset_imported_structure_sharing(!ProcInfo) :-
- !:ProcInfo = !.ProcInfo ^ proc_sub_info ^ structure_sharing
- ^ maybe_imported_sharing := no.
+ !ProcInfo ^ proc_sub_info ^ structure_sharing ^ maybe_imported_sharing :=
+ no.
proc_info_get_structure_reuse(ProcInfo, MaybeReuse) :-
MaybeReuse = ProcInfo ^ proc_sub_info ^ structure_reuse ^ maybe_reuse.
proc_info_set_structure_reuse(Reuse, !ProcInfo) :-
- !:ProcInfo = !.ProcInfo ^ proc_sub_info ^ structure_reuse
- ^ maybe_reuse := yes(Reuse).
+ !ProcInfo ^ proc_sub_info ^ structure_reuse ^ maybe_reuse := yes(Reuse).
proc_info_get_imported_structure_reuse(ProcInfo, HeadVars, Types, Reuse) :-
MaybeImportedReuse = ProcInfo ^ proc_sub_info ^ structure_reuse
@@ -2743,12 +2741,11 @@
!ProcInfo) :-
ImportedReuse = imported_reuse(HeadVars, Types, Reuse),
MaybeImportedReuse = yes(ImportedReuse),
- !:ProcInfo = !.ProcInfo ^ proc_sub_info ^ structure_reuse
- ^ maybe_imported_reuse := MaybeImportedReuse.
+ !ProcInfo ^ proc_sub_info ^ structure_reuse ^ maybe_imported_reuse :=
+ MaybeImportedReuse.
proc_info_reset_imported_structure_reuse(!ProcInfo) :-
- !:ProcInfo = !.ProcInfo ^ proc_sub_info ^ structure_reuse
- ^ maybe_imported_reuse := no.
+ !ProcInfo ^ proc_sub_info ^ structure_reuse ^ maybe_imported_reuse := no.
proc_info_ensure_unique_names(!ProcInfo) :-
proc_info_get_vartypes(!.ProcInfo, VarTypes),
Index: compiler/hlds_statistics.m
===================================================================
RCS file: compiler/hlds_statistics.m
diff -N compiler/hlds_statistics.m
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ compiler/hlds_statistics.m 3 Feb 2010 23:05:39 -0000
@@ -0,0 +1,450 @@
+%-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
+% Copyright (C) 2010 The University of Melbourne.
+% This file may only be copied under the terms of the GNU General
+% Public License - see the file COPYING in the Mercury distribution.
+%-----------------------------------------------------------------------------%
+%
+% File: hlds_statistics.m.
+% Author: zs.
+%
+% Write out statistics about various aspects of the HLDS.
+%
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- module hlds.hlds_statistics.
+:- interface.
+
+:- import_module hlds.hlds_module.
+:- import_module io.
+
+ % Write out size statistics about each procedure in the module.
+ % The statistics state the size of the procedure's body (the number of
+ % subgoals of each possible kind) and the number of its variables.
+ %
+:- pred write_proc_stats_for_module(io.output_stream::in, string::in,
+ module_info::in, io::di, io::uo) is det.
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module hlds.hlds_goal.
+:- import_module hlds.hlds_pred.
+:- import_module hlds.hlds_error_util.
+:- import_module mdbcomp.prim_data.
+:- import_module parse_tree.error_util.
+:- import_module parse_tree.prog_data.
+
+:- import_module int.
+:- import_module list.
+:- import_module map.
+:- import_module pair.
+:- import_module set_tree234.
+:- import_module string.
+:- import_module term.
+:- import_module varset.
+
+%-----------------------------------------------------------------------------%
+
+write_proc_stats_for_module(OutStream, Msg, ModuleInfo, !IO) :-
+ module_info_get_name(ModuleInfo, ModuleSymName),
+ ModuleName = sym_name_to_string(ModuleSymName),
+ io.format(OutStream, "MODULE %s\n", [s(ModuleName)], !IO),
+
+ module_info_preds(ModuleInfo, PredTable),
+ map.to_assoc_list(PredTable, Preds),
+ list.foldl(write_proc_stats_for_pred(OutStream, Msg, ModuleInfo),
+ Preds, !IO).
+
+:- pred write_proc_stats_for_pred(io.output_stream::in, string::in,
+ module_info::in, pair(pred_id, pred_info)::in, io::di, io::uo) is det.
+
+write_proc_stats_for_pred(OutStream, Msg, ModuleInfo, PredId - PredInfo, !IO) :-
+ (
+ ( pred_info_is_imported(PredInfo)
+ ; is_unify_or_compare_pred(PredInfo)
+ )
+ ->
+ true
+ ;
+ pred_info_get_procedures(PredInfo, ProcTable),
+ map.to_assoc_list(ProcTable, Procs),
+ list.foldl(
+ write_proc_stats_for_proc(OutStream, Msg, ModuleInfo, PredId),
+ Procs, !IO)
+ ).
+
+:- pred write_proc_stats_for_proc(io.output_stream::in, string::in,
+ module_info::in, pred_id::in, pair(proc_id, proc_info)::in,
+ io::di, io::uo) is det.
+
+write_proc_stats_for_proc(OutStream, Msg, ModuleInfo,
+ PredId, ProcId - ProcInfo, !IO) :-
+ NamePieces = describe_one_proc_name(ModuleInfo, should_not_module_qualify,
+ proc(PredId, ProcId)),
+ Name = error_pieces_to_string(NamePieces),
+
+ proc_info_get_goal(ProcInfo, Goal),
+ UsedVars0 = set_tree234.init,
+ Stats0 = init_proc_stats,
+ accumulate_proc_stats_in_goal(Goal, UsedVars0, UsedVars, Stats0, Stats),
+
+ proc_info_get_varset(ProcInfo, VarSet),
+ do_write_proc_stats(OutStream, Msg, Name, PredId, ProcId, Stats,
+ UsedVars, VarSet, !IO).
+
+%-----------------------------------------------------------------------------%
+
+:- pred accumulate_proc_stats_in_goal(hlds_goal::in,
+ set_tree234(prog_var)::in, set_tree234(prog_var)::out,
+ proc_stats::in, proc_stats::out) is det.
+
+accumulate_proc_stats_in_goal(Goal, !UsedVars, !Stats) :-
+ Goal = hlds_goal(GoalExpr, _GoalInfo),
+ (
+ GoalExpr = unify(LHS, RHS, _, Uni, _),
+ (
+ Uni = construct(CellVar, _, ArgVars, _, _, _, _),
+ set_tree234.insert(CellVar, !UsedVars),
+ set_tree234.insert_list(ArgVars, !UsedVars),
+ !Stats ^ ps_unify_constructs := !.Stats ^ ps_unify_constructs + 1
+ ;
+ Uni = deconstruct(CellVar, _, ArgVars, _, _, _),
+ set_tree234.insert(CellVar, !UsedVars),
+ set_tree234.insert_list(ArgVars, !UsedVars),
+ !Stats ^ ps_unify_deconstructs :=
+ !.Stats ^ ps_unify_deconstructs + 1
+ ;
+ Uni = assign(ToVar, FromVar),
+ set_tree234.insert(ToVar, !UsedVars),
+ set_tree234.insert(FromVar, !UsedVars),
+ !Stats ^ ps_unify_assigns := !.Stats ^ ps_unify_assigns + 1
+ ;
+ Uni = simple_test(VarA, VarB),
+ set_tree234.insert(VarA, !UsedVars),
+ set_tree234.insert(VarB, !UsedVars),
+ !Stats ^ ps_unify_tests := !.Stats ^ ps_unify_tests + 1
+ ;
+ Uni = complicated_unify(_, _, _),
+ set_tree234.insert(LHS, !UsedVars),
+ (
+ RHS = rhs_var(RHSVar),
+ set_tree234.insert(RHSVar, !UsedVars),
+ !Stats ^ ps_unify_complicateds :=
+ !.Stats ^ ps_unify_complicateds + 1
+ ;
+ RHS = rhs_functor(_, _, RHSVars),
+ set_tree234.insert_list(RHSVars, !UsedVars),
+ !Stats ^ ps_unify_complicateds :=
+ !.Stats ^ ps_unify_complicateds + 1
+ ;
+ RHS = rhs_lambda_goal(_, _, _, _, NonLocals, QuantVars, _, _,
+ LambdaGoal),
+ set_tree234.insert_list(NonLocals, !UsedVars),
+ set_tree234.insert_list(QuantVars, !UsedVars),
+ !Stats ^ ps_unify_complicateds :=
+ !.Stats ^ ps_unify_complicateds + 1,
+ accumulate_proc_stats_in_goal(LambdaGoal, !UsedVars, !Stats)
+ )
+ )
+ ;
+ GoalExpr = plain_call(_, _, ArgVars, _, _, _),
+ set_tree234.insert_list(ArgVars, !UsedVars),
+ !Stats ^ ps_plain_calls := !.Stats ^ ps_plain_calls + 1
+ ;
+ GoalExpr = call_foreign_proc(_, _, _, Args, ExtraArgs, _, _),
+ ArgVars = list.map(foreign_arg_var, Args),
+ ExtraArgVars = list.map(foreign_arg_var, ExtraArgs),
+ set_tree234.insert_list(ArgVars, !UsedVars),
+ set_tree234.insert_list(ExtraArgVars, !UsedVars),
+ !Stats ^ ps_foreign_calls := !.Stats ^ ps_foreign_calls + 1
+ ;
+ GoalExpr = generic_call(CallKind, ArgVars, _, _),
+ set_tree234.insert_list(ArgVars, !UsedVars),
+ (
+ CallKind = higher_order(HOVar, _, _, _),
+ set_tree234.insert(HOVar, !UsedVars),
+ !Stats ^ ps_ho_calls := !.Stats ^ ps_ho_calls + 1
+ ;
+ CallKind = class_method(TCIVar, _, _, _),
+ set_tree234.insert(TCIVar, !UsedVars),
+ !Stats ^ ps_method_calls := !.Stats ^ ps_method_calls + 1
+ ;
+ CallKind = event_call(_),
+ !Stats ^ ps_event_calls := !.Stats ^ ps_event_calls + 1
+ ;
+ CallKind = cast(_),
+ !Stats ^ ps_casts := !.Stats ^ ps_casts + 1
+ )
+ ;
+ GoalExpr = conj(ConjType, Conjs),
+ (
+ ConjType = plain_conj,
+ !Stats ^ ps_plain_conjs := !.Stats ^ ps_plain_conjs + 1,
+ accumulate_proc_stats_in_plain_conj(Conjs, !UsedVars, !Stats)
+ ;
+ ConjType = parallel_conj,
+ !Stats ^ ps_parallel_conjs := !.Stats ^ ps_parallel_conjs + 1,
+ accumulate_proc_stats_in_parallel_conj(Conjs, !UsedVars, !Stats)
+ )
+ ;
+ GoalExpr = disj(Disjs),
+ !Stats ^ ps_disjs := !.Stats ^ ps_disjs + 1,
+ accumulate_proc_stats_in_disj(Disjs, !UsedVars, !Stats)
+ ;
+ GoalExpr = switch(SwitchVar, _, Cases),
+ set_tree234.insert(SwitchVar, !UsedVars),
+ !Stats ^ ps_switches := !.Stats ^ ps_switches + 1,
+ accumulate_proc_stats_in_switch(Cases, !UsedVars, !Stats)
+ ;
+ GoalExpr = if_then_else(_, CondGoal, ThenGoal, ElseGoal),
+ !Stats ^ ps_ites := !.Stats ^ ps_ites + 1,
+ accumulate_proc_stats_in_goal(CondGoal, !UsedVars, !Stats),
+ accumulate_proc_stats_in_goal(ThenGoal, !UsedVars, !Stats),
+ accumulate_proc_stats_in_goal(ElseGoal, !UsedVars, !Stats)
+ ;
+ GoalExpr = negation(SubGoal),
+ !Stats ^ ps_negations := !.Stats ^ ps_negations + 1,
+ accumulate_proc_stats_in_goal(SubGoal, !UsedVars, !Stats)
+ ;
+ GoalExpr = scope(_, SubGoal),
+ !Stats ^ ps_scopes := !.Stats ^ ps_scopes + 1,
+ accumulate_proc_stats_in_goal(SubGoal, !UsedVars, !Stats)
+ ;
+ GoalExpr = shorthand(ShortHand),
+ (
+ ShortHand = bi_implication(GoalA, GoalB),
+ !Stats ^ ps_bi_implications := !.Stats ^ ps_bi_implications + 1,
+ accumulate_proc_stats_in_goal(GoalA, !UsedVars, !Stats),
+ accumulate_proc_stats_in_goal(GoalB, !UsedVars, !Stats)
+ ;
+ ShortHand = atomic_goal(_, _, _, _, MainGoal, OrElseGoals, _),
+ !Stats ^ ps_atomic_goals := !.Stats ^ ps_atomic_goals + 1,
+ accumulate_proc_stats_in_goal(MainGoal, !UsedVars, !Stats),
+ list.foldl2(accumulate_proc_stats_in_goal, OrElseGoals,
+ !UsedVars, !Stats)
+ ;
+ ShortHand = try_goal(_, _, SubGoal),
+ !Stats ^ ps_try_goals := !.Stats ^ ps_try_goals + 1,
+ accumulate_proc_stats_in_goal(SubGoal, !UsedVars, !Stats)
+ )
+ ).
+
+%-----------------------------------------------------------------------------%
+
+:- pred accumulate_proc_stats_in_plain_conj(list(hlds_goal)::in,
+ set_tree234(prog_var)::in, set_tree234(prog_var)::out,
+ proc_stats::in, proc_stats::out) is det.
+
+accumulate_proc_stats_in_plain_conj([], !UsedVars, !Stats).
+accumulate_proc_stats_in_plain_conj([Goal | Goals], !UsedVars, !Stats) :-
+ !Stats ^ ps_plain_conjuncts := !.Stats ^ ps_plain_conjuncts + 1,
+ accumulate_proc_stats_in_goal(Goal, !UsedVars, !Stats),
+ accumulate_proc_stats_in_plain_conj(Goals, !UsedVars, !Stats).
+
+:- pred accumulate_proc_stats_in_parallel_conj(list(hlds_goal)::in,
+ set_tree234(prog_var)::in, set_tree234(prog_var)::out,
+ proc_stats::in, proc_stats::out) is det.
+
+accumulate_proc_stats_in_parallel_conj([], !UsedVars, !Stats).
+accumulate_proc_stats_in_parallel_conj([Goal | Goals], !UsedVars, !Stats) :-
+ !Stats ^ ps_parallel_conjuncts := !.Stats ^ ps_parallel_conjuncts + 1,
+ accumulate_proc_stats_in_goal(Goal, !UsedVars, !Stats),
+ accumulate_proc_stats_in_parallel_conj(Goals, !UsedVars, !Stats).
+
+:- pred accumulate_proc_stats_in_disj(list(hlds_goal)::in,
+ set_tree234(prog_var)::in, set_tree234(prog_var)::out,
+ proc_stats::in, proc_stats::out) is det.
+
+accumulate_proc_stats_in_disj([], !UsedVars, !Stats).
+accumulate_proc_stats_in_disj([Goal | Goals], !UsedVars, !Stats) :-
+ !Stats ^ ps_disjuncts := !.Stats ^ ps_disjuncts + 1,
+ accumulate_proc_stats_in_goal(Goal, !UsedVars, !Stats),
+ accumulate_proc_stats_in_disj(Goals, !UsedVars, !Stats).
+
+:- pred accumulate_proc_stats_in_switch(list(case)::in,
+ set_tree234(prog_var)::in, set_tree234(prog_var)::out,
+ proc_stats::in, proc_stats::out) is det.
+
+accumulate_proc_stats_in_switch([], !UsedVars, !Stats).
+accumulate_proc_stats_in_switch([Case | Cases], !UsedVars, !Stats) :-
+ !Stats ^ ps_switch_arms := !.Stats ^ ps_switch_arms + 1,
+ Case = case(_, _, Goal),
+ accumulate_proc_stats_in_goal(Goal, !UsedVars, !Stats),
+ accumulate_proc_stats_in_switch(Cases, !UsedVars, !Stats).
+
+%-----------------------------------------------------------------------------%
+
+:- type proc_stats
+ ---> proc_stats(
+ ps_unify_constructs :: int,
+ ps_unify_deconstructs :: int,
+ ps_unify_assigns :: int,
+ ps_unify_tests :: int,
+ ps_unify_complicateds :: int,
+
+ ps_plain_calls :: int,
+
+ ps_foreign_calls :: int,
+
+ ps_ho_calls :: int,
+ ps_method_calls :: int,
+ ps_event_calls :: int,
+ ps_casts :: int,
+
+ ps_plain_conjs :: int,
+ ps_plain_conjuncts :: int,
+ ps_parallel_conjs :: int,
+ ps_parallel_conjuncts :: int,
+
+ ps_disjs :: int,
+ ps_disjuncts :: int,
+
+ ps_switches :: int,
+ ps_switch_arms :: int,
+
+ ps_ites :: int,
+
+ ps_negations :: int,
+
+ ps_scopes :: int,
+
+ ps_bi_implications :: int,
+ ps_atomic_goals :: int,
+ ps_try_goals :: int
+ ).
+
+:- func init_proc_stats = proc_stats.
+
+init_proc_stats = Stats :-
+ Stats = proc_stats(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0).
+
+:- pred write_proc_stat_components(io.output_stream::in, string::in,
+ string::in, pred_id::in, proc_id::in, proc_stats::in, io::di, io::uo)
+ is det.
+
+write_proc_stat_components(OutStream, Msg, Name, PredId, ProcId, Stats, !IO) :-
+ Stats = proc_stats(UnifyConstructs, UnifyDeconstructs,
+ UnifyAssigns, UnifyTests, UnifyComplicateds,
+ PlainCalls, ForeignCalls, HOCalls, MethodCalls, EventCalls, Casts,
+ PlainConjs, PlainConjuncts, ParallelConjs, ParallelConjuncts,
+ Disjs, Disjuncts, Switches, SwitchArms,
+ IfThenElses, Negations, Scopes, BiImplications, AtomicGoals, TryGoals),
+
+ Total =
+ UnifyConstructs + UnifyDeconstructs +
+ UnifyAssigns + UnifyTests + UnifyComplicateds +
+ PlainCalls + ForeignCalls +
+ HOCalls + MethodCalls + EventCalls + Casts +
+ PlainConjs + ParallelConjs +
+ Disjs + Switches +
+ IfThenElses + Negations + Scopes +
+ BiImplications + AtomicGoals + TryGoals,
+
+ output_proc_stat_component(OutStream, Msg, Name, PredId, ProcId,
+ "unify_contructs", UnifyConstructs, !IO),
+ output_proc_stat_component(OutStream, Msg, Name, PredId, ProcId,
+ "unify_decontructs", UnifyDeconstructs, !IO),
+ output_proc_stat_component(OutStream, Msg, Name, PredId, ProcId,
+ "unify_assigns", UnifyAssigns, !IO),
+ output_proc_stat_component(OutStream, Msg, Name, PredId, ProcId,
+ "unify_tests", UnifyTests, !IO),
+ output_proc_stat_component(OutStream, Msg, Name, PredId, ProcId,
+ "unify_complicateds", UnifyComplicateds, !IO),
+
+ output_proc_stat_component(OutStream, Msg, Name, PredId, ProcId,
+ "plain_calls", PlainCalls, !IO),
+ output_proc_stat_component(OutStream, Msg, Name, PredId, ProcId,
+ "foreign_calls", ForeignCalls, !IO),
+ output_proc_stat_component(OutStream, Msg, Name, PredId, ProcId,
+ "ho_calls", HOCalls, !IO),
+ output_proc_stat_component(OutStream, Msg, Name, PredId, ProcId,
+ "method_calls", MethodCalls, !IO),
+ output_proc_stat_component(OutStream, Msg, Name, PredId, ProcId,
+ "event_calls", EventCalls, !IO),
+ output_proc_stat_component(OutStream, Msg, Name, PredId, ProcId,
+ "casts", Casts, !IO),
+
+ output_proc_stat_component(OutStream, Msg, Name, PredId, ProcId,
+ "plain_conjs", PlainConjs, !IO),
+ output_proc_stat_component(OutStream, Msg, Name, PredId, ProcId,
+ "plain_conjuncts", PlainConjuncts, !IO),
+ output_proc_stat_component(OutStream, Msg, Name, PredId, ProcId,
+ "parallel_conjs", ParallelConjs, !IO),
+ output_proc_stat_component(OutStream, Msg, Name, PredId, ProcId,
+ "parallel_conjuncts", ParallelConjuncts, !IO),
+
+ output_proc_stat_component(OutStream, Msg, Name, PredId, ProcId,
+ "disjs", Disjs, !IO),
+ output_proc_stat_component(OutStream, Msg, Name, PredId, ProcId,
+ "disjunctions", Disjuncts, !IO),
+ output_proc_stat_component(OutStream, Msg, Name, PredId, ProcId,
+ "switches", Switches, !IO),
+ output_proc_stat_component(OutStream, Msg, Name, PredId, ProcId,
+ "switch_arms", SwitchArms, !IO),
+
+ output_proc_stat_component(OutStream, Msg, Name, PredId, ProcId,
+ "if_then_elses", IfThenElses, !IO),
+ output_proc_stat_component(OutStream, Msg, Name, PredId, ProcId,
+ "negations", Negations, !IO),
+ output_proc_stat_component(OutStream, Msg, Name, PredId, ProcId,
+ "scopes", Scopes, !IO),
+ output_proc_stat_component(OutStream, Msg, Name, PredId, ProcId,
+ "bi_implications", BiImplications, !IO),
+ output_proc_stat_component(OutStream, Msg, Name, PredId, ProcId,
+ "atomic_goals", AtomicGoals, !IO),
+ output_proc_stat_component(OutStream, Msg, Name, PredId, ProcId,
+ "try_goals", TryGoals, !IO),
+
+ output_proc_stat_component(OutStream, Msg, Name, PredId, ProcId,
+ "total_size", Total, !IO).
+
+%-----------------------------------------------------------------------------%
+
+:- pred do_write_proc_stats(io.output_stream::in,
+ string::in, string::in, pred_id::in, proc_id::in,
+ proc_stats::in, set_tree234(prog_var)::in, prog_varset::in,
+ io::di, io::uo) is det.
+
+do_write_proc_stats(OutStream, Msg, Name, PredId, ProcId,
+ Stats, UsedVars, VarSet, !IO) :-
+ PredIdInt = pred_id_to_int(PredId),
+ ProcIdInt = proc_id_to_int(ProcId),
+ io.format(OutStream, "PROC %d %d %s\n",
+ [i(PredIdInt), i(ProcIdInt), s(Name)], !IO),
+
+ write_proc_stat_components(OutStream, Msg, Name, PredId, ProcId, Stats,
+ !IO),
+
+ varset.new_var(VarSet, Var, _UpdatedVarSet),
+ term.var_to_int(Var, VarInt),
+ NumUsedVars = set_tree234.count(UsedVars),
+ io.format(OutStream, "VARS %d %d\n", [i(VarInt), i(NumUsedVars)], !IO).
+
+:- pred output_proc_stat_component(io.output_stream::in,
+ string::in, string::in, pred_id::in, proc_id::in,
+ string::in, int::in, io::di, io::uo) is det.
+
+output_proc_stat_component(OutStream, _Msg, _Name, _PredId, _ProcId,
+ ComponentName, ComponentCount, !IO) :-
+ ( ComponentCount > 0 ->
+ io.format(OutStream, "GOAL %s: %d\n",
+ [s(ComponentName), i(ComponentCount)], !IO)
+ ;
+ true
+ ).
+
+%-----------------------------------------------------------------------------%
+
+:- func this_file = string.
+
+this_file = "hlds_statistics.m".
+
+%-----------------------------------------------------------------------------%
+:- end_module hlds.hlds_statistics.
+%-----------------------------------------------------------------------------%
Index: compiler/mercury_compile_front_end.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mercury_compile_front_end.m,v
retrieving revision 1.2
diff -u -b -r1.2 mercury_compile_front_end.m
--- compiler/mercury_compile_front_end.m 16 Oct 2009 06:53:01 -0000 1.2
+++ compiler/mercury_compile_front_end.m 3 Feb 2010 23:05:39 -0000
@@ -86,6 +86,7 @@
:- import_module check_hlds.unique_modes.
:- import_module check_hlds.unused_imports.
:- import_module hlds.hlds_error_util.
+:- import_module hlds.hlds_statistics.
:- import_module libs.compiler_util.
:- import_module libs.file_util.
:- import_module libs.globals.
@@ -468,6 +469,9 @@
!HLDS, !Specs, !IO),
maybe_dump_hlds(!.HLDS, 65, "frontend_simplify", !DumpInfo, !IO),
+ maybe_proc_statistics(Verbose, Stats, "AfterFrontEnd", !HLDS,
+ !Specs, !IO),
+
% Work out whether we encountered any errors.
module_info_get_num_errors(!.HLDS, NumErrors),
io.get_exit_status(ExitStatus, !IO),
@@ -866,8 +870,7 @@
->
list.cons(simp_constant_prop, !SimpList)
;
- !:SimpList = list.delete_all(!.SimpList,
- simp_constant_prop)
+ !:SimpList = list.delete_all(!.SimpList, simp_constant_prop)
),
list.cons(simp_do_once, !SimpList),
list.cons(simp_elim_removable_scopes, !SimpList)
@@ -901,6 +904,37 @@
SimpList = []
).
+:- pred maybe_proc_statistics(bool::in, bool::in, string::in,
+ module_info::in, module_info::out,
+ list(error_spec)::in, list(error_spec)::out, io::di, io::uo) is det.
+
+maybe_proc_statistics(Verbose, Stats, Msg, !HLDS, !Specs, !IO) :-
+ module_info_get_globals(!.HLDS, Globals),
+ maybe_write_out_errors(Verbose, Globals, !HLDS, !Specs, !IO),
+
+ globals.lookup_string_option(Globals, proc_size_statistics, StatsFileName),
+ ( StatsFileName = "" ->
+ % The user has not asked us to print these statistics.
+ true
+ ;
+ io.open_append(StatsFileName, StatsFileNameResult, !IO),
+ (
+ StatsFileNameResult = ok(StatsFileStream),
+ maybe_write_string(Verbose,
+ "% Generating proc statistics...\n", !IO),
+ write_proc_stats_for_module(StatsFileStream, Msg, !.HLDS, !IO),
+ maybe_write_string(Verbose, "% done.\n", !IO),
+ maybe_report_stats(Stats, !IO)
+ ;
+ StatsFileNameResult = error(StatsFileError),
+ io.error_message(StatsFileError, StatsFileErrorMsg),
+ maybe_write_string(Verbose,
+ "% Cannot write proc statistics: ", !IO),
+ maybe_write_string(Verbose, StatsFileErrorMsg, !IO),
+ maybe_write_string(Verbose, "\n", !IO)
+ )
+ ).
+
%-----------------------------------------------------------------------------%
:- func this_file = string.
Index: compiler/options.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/options.m,v
retrieving revision 1.666
diff -u -b -r1.666 options.m
--- compiler/options.m 28 Jan 2010 04:32:03 -0000 1.666
+++ compiler/options.m 3 Feb 2010 23:05:39 -0000
@@ -148,6 +148,7 @@
; output_compile_error_lines
; statistics
; detailed_statistics
+ ; proc_size_statistics
; debug_types
; debug_modes
; debug_modes_statistics
@@ -1082,6 +1083,7 @@
output_compile_error_lines - int(15),
statistics - bool(no),
detailed_statistics - bool(no),
+ proc_size_statistics - string(""),
debug_types - bool(no),
debug_modes - bool(no),
debug_modes_statistics - bool(no),
@@ -1909,6 +1911,7 @@
long_option("output-compile-error-lines", output_compile_error_lines).
long_option("statistics", statistics).
long_option("detailed-statistics", detailed_statistics).
+long_option("proc-size-statistics", proc_size_statistics).
long_option("debug-types", debug_types).
long_option("debug-modes", debug_modes).
long_option("debug-modes-statistics", debug_modes_statistics).
@@ -3442,6 +3445,9 @@
% "--detailed-statistics",
% "\tOutput more detailed messages about the compiler's",
% "\ttime/space usage.",
+ "--proc-size-statistics <filename>",
+ "\tAppend information about the size of each procedure in the module",
+ "\tin terms of goals and variables to the end of the named file.",
% --debug-types works only if the compiler was compiled with
% "--trace-flag type_checkpoint".
% "-T, --debug-types",
cvs diff: Diffing compiler/notes
cvs diff: Diffing debian
cvs diff: Diffing debian/patches
cvs diff: Diffing deep_profiler
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
Index: doc/user_guide.texi
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/doc/user_guide.texi,v
retrieving revision 1.602
diff -u -b -r1.602 user_guide.texi
--- doc/user_guide.texi 28 Jan 2010 04:05:07 -0000 1.602
+++ doc/user_guide.texi 3 Feb 2010 23:05:39 -0000
@@ -6496,6 +6496,12 @@
@findex --no-trad-passes
@findex --trad-passes
+ at sp 1
+ at item --proc-size-statistics @var{filename}
+ at findex --proc-size-statistics
+Append information about the size of each procedure in the module
+in terms of goals and variables to the end of the named file.
+
@c @sp 1
@c @item -T
@c @itemx --debug-types
cvs diff: Diffing extras
cvs diff: Diffing extras/base64
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/concurrency
cvs diff: Diffing extras/curs
cvs diff: Diffing extras/curs/samples
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/error
cvs diff: Diffing extras/fixed
cvs diff: Diffing extras/gator
cvs diff: Diffing extras/gator/generations
cvs diff: Diffing extras/gator/generations/1
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/easyx
cvs diff: Diffing extras/graphics/easyx/samples
cvs diff: Diffing extras/graphics/mercury_allegro
cvs diff: Diffing extras/graphics/mercury_allegro/examples
cvs diff: Diffing extras/graphics/mercury_allegro/samples
cvs diff: Diffing extras/graphics/mercury_allegro/samples/demo
cvs diff: Diffing extras/graphics/mercury_allegro/samples/mandel
cvs diff: Diffing extras/graphics/mercury_allegro/samples/pendulum2
cvs diff: Diffing extras/graphics/mercury_allegro/samples/speed
cvs diff: Diffing extras/graphics/mercury_glut
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/gears
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/lex
cvs diff: Diffing extras/lex/samples
cvs diff: Diffing extras/lex/tests
cvs diff: Diffing extras/log4m
cvs diff: Diffing extras/logged_output
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/moose/tests
cvs diff: Diffing extras/mopenssl
cvs diff: Diffing extras/morphine
cvs diff: Diffing extras/morphine/non-regression-tests
cvs diff: Diffing extras/morphine/scripts
cvs diff: Diffing extras/morphine/source
cvs diff: Diffing extras/net
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/posix/samples
cvs diff: Diffing extras/quickcheck
cvs diff: Diffing extras/quickcheck/tutes
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/solver_types
cvs diff: Diffing extras/solver_types/library
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/windows_installer_generator
cvs diff: Diffing extras/windows_installer_generator/sample
cvs diff: Diffing extras/windows_installer_generator/sample/images
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing extras/xml_stylesheets
cvs diff: Diffing java
cvs diff: Diffing java/runtime
cvs diff: Diffing library
cvs diff: Diffing mdbcomp
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
cvs diff: Diffing runtime/GETOPT
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/standalone_c
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
cvs diff: Diffing samples/solver_types
cvs diff: Diffing samples/tests
cvs diff: Diffing samples/tests/c_interface
cvs diff: Diffing samples/tests/c_interface/c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/tests/c_interface/mercury_calls_c
cvs diff: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/tests/diff
cvs diff: Diffing samples/tests/muz
cvs diff: Diffing samples/tests/rot13
cvs diff: Diffing samples/tests/solutions
cvs diff: Diffing samples/tests/toplevel
cvs diff: Diffing scripts
cvs diff: Diffing slice
cvs diff: Diffing ssdb
cvs diff: Diffing tests
cvs diff: Diffing tests/analysis
cvs diff: Diffing tests/analysis/ctgc
cvs diff: Diffing tests/analysis/excp
cvs diff: Diffing tests/analysis/ext
cvs diff: Diffing tests/analysis/sharing
cvs diff: Diffing tests/analysis/table
cvs diff: Diffing tests/analysis/trail
cvs diff: Diffing tests/analysis/unused_args
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
cvs diff: Diffing tests/debugger/declarative
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/general/string_format
cvs diff: Diffing tests/general/structure_reuse
cvs diff: Diffing tests/grade_subdirs
cvs diff: Diffing tests/hard_coded
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/purity
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/invalid/purity
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/mmc_make
cvs diff: Diffing tests/mmc_make/lib
cvs diff: Diffing tests/par_conj
cvs diff: Diffing tests/recompilation
cvs diff: Diffing tests/stm
cvs diff: Diffing tests/stm/orig
cvs diff: Diffing tests/stm/orig/stm-compiler
cvs diff: Diffing tests/stm/orig/stm-compiler/test1
cvs diff: Diffing tests/stm/orig/stm-compiler/test10
cvs diff: Diffing tests/stm/orig/stm-compiler/test2
cvs diff: Diffing tests/stm/orig/stm-compiler/test3
cvs diff: Diffing tests/stm/orig/stm-compiler/test4
cvs diff: Diffing tests/stm/orig/stm-compiler/test5
cvs diff: Diffing tests/stm/orig/stm-compiler/test6
cvs diff: Diffing tests/stm/orig/stm-compiler/test7
cvs diff: Diffing tests/stm/orig/stm-compiler/test8
cvs diff: Diffing tests/stm/orig/stm-compiler/test9
cvs diff: Diffing tests/stm/orig/stm-compiler-par
cvs diff: Diffing tests/stm/orig/stm-compiler-par/bm1
cvs diff: Diffing tests/stm/orig/stm-compiler-par/bm2
cvs diff: Diffing tests/stm/orig/stm-compiler-par/stmqueue
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test1
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test10
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test11
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test2
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test3
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test4
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test5
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test6
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test7
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test8
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test9
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test1
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test2
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test3
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test4
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test5
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test6
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test7
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test8
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test9
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/trailing
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
cvs diff: Diffing util
cvs diff: Diffing vim
cvs diff: Diffing vim/after
cvs diff: Diffing vim/ftplugin
cvs diff: Diffing vim/syntax
--------------------------------------------------------------------------
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