[m-dev.] for review: delaying death
Mark Anthony BROWN
dougl at cs.mu.OZ.AU
Tue Jan 9 06:10:43 AEDT 2001
Zoltan Somogyi writes:
> For review by anyone.
>
> Estimated hours taken: 8
>
> If the trace level is `deep' or some level (e.g. `decl') whose functionality
> includes the functionality of `deep', then by default delay the deaths of
> named variables until as late as possible, in order to make their values
> accessible in the debugger at as many events as possible. Add an option,
> --no-delay-death, to preserve the old behavior.
>
> This change increases the runtime of a compiler compiled in the debugging grade
> by about 2.3%, and increases its size by 20.5%, from 27.2 to 32.7 Mb. The size
> increase is mostly to read-only data increasing from 10.2 to 15.5 Mb, though
> the code size also increases a bit, from 16.8 to 17.5 Mb, due to the larger
> number of stores onto the stack.
>
> I expect that the space penalty will be substantially reduced when I move
> variable type information from label layouts to procedure layouts, since
> at present the type of a variable that is live at many labels is recorded
> many times.
>
> compiler/liveness.m:
> Add an optional pass after the initial computation of deadness to
> delays deaths as late as possible.
>
> compiler/trace_params.m:
> Add a predicate to test whether delaying deaths make sense.
>
> compiler/options.m:
> doc_/user_guide.texi:
s/doc_/doc/
> Add the new option.
>
> Zoltan.
>
> cvs diff: Diffing .
> 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/include
> cvs diff: Diffing boehm_gc/include/private
> cvs diff: Diffing browser
> cvs diff: Diffing bytecode
> cvs diff: Diffing compiler
> Index: compiler/liveness.m
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/compiler/liveness.m,v
> retrieving revision 1.114
> diff -u -b -r1.114 liveness.m
> --- compiler/liveness.m 2000/11/23 04:32:38 1.114
> +++ compiler/liveness.m 2001/01/05 03:25:33
> @@ -28,7 +28,7 @@
> % as late as possible (but before the first possible use), and the
> % death should be as early as possible (but after the last possible use).
> %
> -% We compute liveness related information in three distinct passes.
> +% We compute liveness related information in four distinct passes.
> %
> % The first pass, detect_liveness_in_goal, finds the first value-giving
> % occurrence of each variable on each computation path. Goals containing
> @@ -46,7 +46,18 @@
> % used at all include a pre-death set listing the variables that
> % have died in parallel branches.
> %
> -% The third pass, detect_resume_points_in_goal, finds goals that
> +% The third pass is optional: it delays the deaths of named variables until
> +% the last possible moment. This can be useful if debugging is enabled, as it
> +% allows the programmer to look at the values of such variables at as many
> +% trace events as possible. If debugging is not enabled, this pass is a pure
> +% pessimization (it increases stack slot pressure and thus probably increases
> +% the size of the procedure's stack frame), and therefore should not be
> +% enabled.
> +%
> +% The second and third passes cannot be combined, because the second pass
> +% traverses goals backwards while the third pass traverses goals forwards.
> +%
> +% The fourth pass, detect_resume_points_in_goal, finds goals that
> % establish resume points and attaches to them a resume_point
> % annotation listing the variables that may be referenced by the
> % code at that resume point as well as the nature of the required
> @@ -180,13 +191,13 @@
> requantify_proc(ProcInfo0, ProcInfo1),
>
> proc_info_goal(ProcInfo1, Goal0),
> - proc_info_varset(ProcInfo1, Varset),
> + proc_info_varset(ProcInfo1, VarSet),
> proc_info_vartypes(ProcInfo1, VarTypes),
> proc_info_typeinfo_varmap(ProcInfo1, TVarMap),
> module_info_globals(ModuleInfo, Globals),
> module_info_pred_info(ModuleInfo, PredId, PredInfo),
> body_should_use_typeinfo_liveness(PredInfo, Globals, TypeInfoLiveness),
> - live_info_init(ModuleInfo, TypeInfoLiveness, VarTypes, TVarMap, Varset,
> + live_info_init(ModuleInfo, TypeInfoLiveness, VarTypes, TVarMap, VarSet,
> LiveInfo),
>
> initial_liveness(ProcInfo1, PredId, ModuleInfo, Liveness0),
> @@ -196,13 +207,25 @@
> initial_deadness(ProcInfo1, LiveInfo, ModuleInfo, Deadness0),
> detect_deadness_in_goal(Goal1, Deadness0, LiveInfo, _, Goal2),
>
> + (
> + globals__get_trace_level(Globals, TraceLevel),
> + AllowDelayDeath = trace_level_allows_delay_death(TraceLevel),
> + AllowDelayDeath = yes,
> + globals__lookup_bool_option(Globals, delay_death, DelayDeath),
> + DelayDeath = yes
> + ->
> + delay_death_proc_body(Goal2, VarSet, Liveness0, Goal3)
> + ;
> + Goal3 = Goal2
> + ),
> +
> globals__get_trace_level(Globals, TraceLevel),
> ( trace_level_is_none(TraceLevel) = no ->
> trace__fail_vars(ModuleInfo, ProcInfo0, ResumeVars0)
> ;
> set__init(ResumeVars0)
> ),
> - detect_resume_points_in_goal(Goal2, Liveness0, LiveInfo,
> + detect_resume_points_in_goal(Goal3, Liveness0, LiveInfo,
> ResumeVars0, Goal, _),
>
> proc_info_set_goal(ProcInfo1, Goal, ProcInfo2),
> @@ -645,6 +668,288 @@
> %-----------------------------------------------------------------------------%
> %-----------------------------------------------------------------------------%
>
> +% The delay_death pass works by maintaining a set of variables (all named)
> +% that, according to the deadness pass should have died by now, but which
> +% are being kept alive so that their values are accessible to the debugger.
> +% Variables in this DelayedDead set are finally killed when we come to the end
> +% of the goal in which they were born. This is because if a variable is born in
> +% one arm of a branched control structure (e.g. a switch), it cannot live
> +% beyond the control structure, because it is not given a value in other
> +% branches.
> +%
> +% The correctness of this pass with typeinfo_liveness depends on the fact that
> +% typeinfo and typeclass_info variables are all named. If they weren't, then it
> +% would be possible for a (named) variable to have its death delayed without
> +% the type(class)info variable describing part of its type having its death
> +% delayed as well. In fact, its delay will be delayed by at least as much,
s/its delay/its death/
> +% since a variable cannot be live on entry to a branched control structure
> +% without the type(class)info variables describing its type being live there as
> +% well.
> +
> +:- pred delay_death_proc_body(hlds_goal::in, prog_varset::in, set(prog_var)::in,
> + hlds_goal::out) is det.
> +
> +delay_death_proc_body(Goal0, VarSet, BornVars0, Goal) :-
> + delay_death_goal(Goal0, BornVars0, set__init, VarSet,
> + Goal1, _, DelayedDead),
> + Goal1 = GoalExpr - GoalInfo1,
> + goal_info_get_post_deaths(GoalInfo1, PostDeaths1),
> + set__union(PostDeaths1, DelayedDead, PostDeaths),
> + goal_info_set_post_deaths(GoalInfo1, PostDeaths, GoalInfo),
> + Goal = GoalExpr - GoalInfo.
> +
> +:- pred delay_death_goal(hlds_goal::in, set(prog_var)::in, set(prog_var)::in,
> + prog_varset::in,
> + hlds_goal::out, set(prog_var)::out, set(prog_var)::out) is det.
> +
> +delay_death_goal(GoalExpr0 - GoalInfo0, BornVars0, DelayedDead0, VarSet,
> + GoalExpr - GoalInfo, BornVars, DelayedDead) :-
> + goal_info_get_pre_births(GoalInfo0, PreBirths),
> + goal_info_get_pre_deaths(GoalInfo0, PreDeaths0),
> +
> + set__union(BornVars0, PreBirths, BornVars1),
> + set__divide(var_is_named(VarSet), PreDeaths0,
> + PreDelayedDead, UnnamedPreDeaths),
> + set__union(DelayedDead0, PreDelayedDead, DelayedDead1),
> + goal_info_set_pre_deaths(GoalInfo0, UnnamedPreDeaths, GoalInfo1),
> +
> + delay_death_goal_expr(GoalExpr0, GoalInfo1, BornVars1, DelayedDead1,
> + VarSet, GoalExpr, GoalInfo2, BornVars2, DelayedDead2),
> +
> + goal_info_get_post_births(GoalInfo2, PostBirths),
> + goal_info_get_post_deaths(GoalInfo2, PostDeaths2),
> +
> + set__union(BornVars2, PostBirths, BornVars),
> + set__divide(var_is_named(VarSet), PostDeaths2,
> + PostDelayedDead, UnnamedPostDeaths),
> + set__union(DelayedDead2, PostDelayedDead, DelayedDead3),
> + set__divide(set__contains(BornVars0), DelayedDead3,
> + DelayedDead, ToBeKilled),
> + set__union(UnnamedPostDeaths, ToBeKilled, PostDeaths),
> + goal_info_set_post_deaths(GoalInfo2, PostDeaths, GoalInfo).
> +
> +:- pred var_is_named(prog_varset::in, prog_var::in) is semidet.
> +
> +var_is_named(VarSet, Var) :-
> + varset__search_name(VarSet, Var, _).
> +
> +:- pred delay_death_goal_expr(hlds_goal_expr::in, hlds_goal_info::in,
> + set(prog_var)::in, set(prog_var)::in, prog_varset::in,
> + hlds_goal_expr::out, hlds_goal_info::out,
> + set(prog_var)::out, set(prog_var)::out) is det.
> +
> +delay_death_goal_expr(GoalExpr0, GoalInfo0, BornVars0, DelayedDead0, VarSet,
> + GoalExpr, GoalInfo, BornVars, DelayedDead) :-
> + (
> + GoalExpr0 = call(_, _, _, _, _, _),
> + GoalExpr = GoalExpr0,
> + GoalInfo = GoalInfo0,
> + BornVars = BornVars0,
> + DelayedDead = DelayedDead0
> + ;
> + GoalExpr0 = generic_call(_, _, _, _),
> + GoalExpr = GoalExpr0,
> + GoalInfo = GoalInfo0,
> + BornVars = BornVars0,
> + DelayedDead = DelayedDead0
> + ;
> + GoalExpr0 = unify(_, _, _, _, _),
> + GoalExpr = GoalExpr0,
> + GoalInfo = GoalInfo0,
> + BornVars = BornVars0,
> + DelayedDead = DelayedDead0
> + ;
> + GoalExpr0 = pragma_foreign_code(_, _, _, _, _, _, _),
> + GoalExpr = GoalExpr0,
> + GoalInfo = GoalInfo0,
> + BornVars = BornVars0,
> + DelayedDead = DelayedDead0
> + ;
> + GoalExpr0 = conj(Goals0),
> + delay_death_conj(Goals0, BornVars0, DelayedDead0, VarSet,
> + Goals, BornVars, DelayedDead),
> + GoalExpr = conj(Goals),
> + GoalInfo = GoalInfo0
> + ;
> + GoalExpr0 = par_conj(Goals0, SM),
> + delay_death_conj(Goals0, BornVars0, DelayedDead0, VarSet,
> + Goals, BornVars, DelayedDead),
> + GoalExpr = par_conj(Goals, SM),
> + GoalInfo = GoalInfo0
> + ;
> + GoalExpr0 = disj(Goals0, SM),
> + delay_death_disj(Goals0, BornVars0, DelayedDead0, VarSet,
> + GoalDeaths, MaybeBornVarsDelayedDead),
> + (
> + MaybeBornVarsDelayedDead = yes(BornVars - DelayedDead),
> + Goals = list__map(
> + kill_excess_delayed_dead_goal(DelayedDead),
> + GoalDeaths),
> + GoalExpr = disj(Goals, SM),
> + GoalInfo = GoalInfo0
> + ;
> + MaybeBornVarsDelayedDead = no,
> + % Empty disjunctions represent the goal `fail',
> + % so we process them as if they were primitive goals.
> + GoalExpr = GoalExpr0,
> + GoalInfo = GoalInfo0,
> + BornVars = BornVars0,
> + DelayedDead = DelayedDead0
> + )
> + ;
> + GoalExpr0 = switch(Var, CanFail, Cases0, SM),
> + delay_death_cases(Cases0, BornVars0, DelayedDead0, VarSet,
> + CaseDeaths, MaybeBornVarsDelayedDead),
> + (
> + MaybeBornVarsDelayedDead = yes(BornVars - DelayedDead),
> + Cases = list__map(
> + kill_excess_delayed_dead_case(DelayedDead),
> + CaseDeaths),
> + GoalExpr = switch(Var, CanFail, Cases, SM),
> + GoalInfo = GoalInfo0
> + ;
> + MaybeBornVarsDelayedDead = no,
> + error("delay_death_goal_expr: empty switch")
> + )
> + ;
> + GoalExpr0 = not(Goal0),
> + delay_death_goal(Goal0, BornVars0, DelayedDead0, VarSet,
> + Goal, _BornVars, DelayedDead),
> + GoalExpr = not(Goal),
> + GoalInfo = GoalInfo0,
> + BornVars = BornVars0
> + ;
> + GoalExpr0 = if_then_else(QuantVars, Cond0, Then0, Else0, SM),
> + delay_death_goal(Cond0, BornVars0, DelayedDead0, VarSet,
> + Cond, BornVarsCond, DelayedDeadCond),
> + delay_death_goal(Then0, BornVarsCond, DelayedDeadCond, VarSet,
> + Then1, BornVarsThen, DelayedDeadThen),
> + delay_death_goal(Else0, BornVars0, DelayedDead0, VarSet,
> + Else1, BornVarsElse, DelayedDeadElse),
> + set__intersect(BornVarsThen, BornVarsElse, BornVars),
> + set__intersect(DelayedDeadThen, DelayedDeadElse, DelayedDead),
> + Then = kill_excess_delayed_dead_goal(DelayedDead,
> + Then1 - DelayedDeadThen),
> + Else = kill_excess_delayed_dead_goal(DelayedDead,
> + Else1 - DelayedDeadElse),
> + GoalExpr = if_then_else(QuantVars, Cond, Then, Else, SM),
> + GoalInfo = GoalInfo0
> + ;
> + GoalExpr0 = some(QuantVars, CanRemove, Goal0),
> + delay_death_goal(Goal0, BornVars0, DelayedDead0, VarSet,
> + Goal, _BornVars, DelayedDead),
> + GoalExpr = some(QuantVars, CanRemove, Goal),
> + GoalInfo = GoalInfo0,
> + BornVars = BornVars0
> + ;
> + GoalExpr0 = bi_implication(_, _),
> + error("delay_death_goal_expr: bi_implication")
> + ).
> +
> +:- pred delay_death_conj(list(hlds_goal)::in,
> + set(prog_var)::in, set(prog_var)::in, prog_varset::in,
> + list(hlds_goal)::out, set(prog_var)::out, set(prog_var)::out) is det.
> +
> +delay_death_conj([], BornVars, DelayedDead, _, [], BornVars, DelayedDead).
> +delay_death_conj([Goal0 | Goals0], BornVars0, DelayedDead0, VarSet,
> + [Goal | Goals], BornVars, DelayedDead) :-
> + delay_death_goal(Goal0, BornVars0, DelayedDead0, VarSet,
> + Goal, BornVars1, DelayedDead1),
> + delay_death_conj(Goals0, BornVars1, DelayedDead1, VarSet,
> + Goals, BornVars, DelayedDead).
> +
> +:- pred delay_death_par_conj(list(hlds_goal)::in,
> + set(prog_var)::in, set(prog_var)::in, prog_varset::in,
> + list(hlds_goal)::out, set(prog_var)::out, set(prog_var)::out) is det.
> +
> +delay_death_par_conj([], BornVars, DelayedDead, _, [], BornVars, DelayedDead).
> +delay_death_par_conj([Goal0 | Goals0], BornVars0, DelayedDead0, VarSet,
> + [Goal | Goals], BornVars, DelayedDead) :-
> + delay_death_goal(Goal0, BornVars0, DelayedDead0, VarSet,
> + Goal, BornVarsGoal, DelayedDeadGoal),
> + delay_death_par_conj(Goals0, BornVars0, DelayedDead0, VarSet,
> + Goals, BornVarsGoals, DelayedDeadGoals),
> + set__union(BornVarsGoal, BornVarsGoals, BornVars),
> + set__union(DelayedDeadGoal, DelayedDeadGoals, DelayedDead).
> +
> +:- pred delay_death_disj(list(hlds_goal)::in,
> + set(prog_var)::in, set(prog_var)::in, prog_varset::in,
> + assoc_list(hlds_goal, set(prog_var))::out,
> + maybe(pair(set(prog_var)))::out) is det.
> +
> +delay_death_disj([], _, _, _, [], no).
> +delay_death_disj([Goal0 | Goals0], BornVars0, DelayedDead0, VarSet,
> + [Goal - DelayedDeadGoal | Goals],
> + yes(BornVars - DelayedDead)) :-
> + delay_death_goal(Goal0, BornVars0, DelayedDead0, VarSet,
> + Goal, BornVarsGoal, DelayedDeadGoal),
> + delay_death_disj(Goals0, BornVars0, DelayedDead0, VarSet,
> + Goals, MaybeBornVarsDelayedDead),
> + (
> + MaybeBornVarsDelayedDead =
> + yes(BornVarsGoals - DelayedDeadGoals),
> + set__intersect(BornVarsGoal, BornVarsGoals, BornVars),
> + set__intersect(DelayedDeadGoal, DelayedDeadGoals, DelayedDead)
> + ;
> + MaybeBornVarsDelayedDead = no,
> + BornVars = BornVarsGoal,
> + DelayedDead = DelayedDeadGoal
> + ).
> +
> +:- pred delay_death_cases(list(case)::in,
> + set(prog_var)::in, set(prog_var)::in, prog_varset::in,
> + assoc_list(case, set(prog_var))::out, maybe(pair(set(prog_var)))::out)
> + is det.
> +
> +delay_death_cases([], _, _, _, [], no).
> +delay_death_cases([case(ConsId, Goal0) | Cases0], BornVars0, DelayedDead0,
> + VarSet, [case(ConsId, Goal) - DelayedDeadGoal | Cases],
> + yes(BornVars - DelayedDead)) :-
> + delay_death_goal(Goal0, BornVars0, DelayedDead0, VarSet,
> + Goal, BornVarsGoal, DelayedDeadGoal),
> + delay_death_cases(Cases0, BornVars0, DelayedDead0, VarSet,
> + Cases, MaybeBornVarsDelayedDead),
> + (
> + MaybeBornVarsDelayedDead =
> + yes(BornVarsCases - DelayedDeadCases),
> + set__intersect(BornVarsGoal, BornVarsCases, BornVars),
> + set__intersect(DelayedDeadGoal, DelayedDeadCases, DelayedDead)
> + ;
> + MaybeBornVarsDelayedDead = no,
> + BornVars = BornVarsGoal,
> + DelayedDead = DelayedDeadGoal
> + ).
> +
> +% The kill_excess_delayed_dead_* functions are called on each branch of a
> +% branched control structure to make sure that all branches kill the same
> +% set of variables.
> +
> +:- func kill_excess_delayed_dead_goal(set(prog_var),
> + pair(hlds_goal, set(prog_var))) = hlds_goal.
> +
> +kill_excess_delayed_dead_goal(FinalDelayedDead, Goal0 - DelayedDead0) = Goal :-
> + set__difference(DelayedDead0, FinalDelayedDead, ToBeKilled),
> + Goal0 = GoalExpr - GoalInfo0,
> + goal_info_get_post_deaths(GoalInfo0, PostDeath0),
> + set__union(PostDeath0, ToBeKilled, PostDeath),
> + goal_info_set_post_deaths(GoalInfo0, PostDeath, GoalInfo),
> + Goal = GoalExpr - GoalInfo.
> +
> +:- func kill_excess_delayed_dead_case(set(prog_var),
> + pair(case, set(prog_var))) = case.
> +
> +kill_excess_delayed_dead_case(FinalDelayedDead,
> + case(ConsId, Goal0) - DelayedDead0) = case(ConsId, Goal) :-
> + set__difference(DelayedDead0, FinalDelayedDead, ToBeKilled),
> + Goal0 = GoalExpr - GoalInfo0,
> + goal_info_get_post_deaths(GoalInfo0, PostDeath0),
> + set__union(PostDeath0, ToBeKilled, PostDeath),
> + goal_info_set_post_deaths(GoalInfo0, PostDeath, GoalInfo),
> + Goal = GoalExpr - GoalInfo.
> +
> +%-----------------------------------------------------------------------------%
> +%-----------------------------------------------------------------------------%
> +
> :- pred detect_resume_points_in_goal(hlds_goal, set(prog_var), live_info,
> set(prog_var), hlds_goal, set(prog_var)).
> :- mode detect_resume_points_in_goal(in, in, in, in, out, out) is det.
> @@ -976,12 +1281,12 @@
> ->
> true
> ;
> - Varset = LiveInfo^varset,
> + VarSet = LiveInfo ^ varset,
> set__to_sorted_list(LivenessFirst, FirstVarsList),
> set__to_sorted_list(LivenessRest, RestVarsList),
> - list__map(varset__lookup_name(Varset),
> + list__map(varset__lookup_name(VarSet),
> FirstVarsList, FirstVarNames),
> - list__map(varset__lookup_name(Varset),
> + list__map(varset__lookup_name(VarSet),
> RestVarsList, RestVarNames),
> Pad = lambda([S0::in, S::out] is det,
> string__append(S0, " ", S)),
> @@ -1071,7 +1376,7 @@
> % typeinfos need to be added to these.
> proc_info_typeinfo_varmap(ProcInfo, TVarMap),
> proc_info_maybe_complete_with_typeinfo_vars(Deadness2,
> - LiveInfo^typeinfo_liveness, VarTypes, TVarMap, Deadness).
> + LiveInfo ^ typeinfo_liveness, VarTypes, TVarMap, Deadness).
>
> :- pred initial_deadness_2(list(prog_var), list(mode), list(type),
> module_info, set(prog_var), set(prog_var)).
> @@ -1126,11 +1431,11 @@
> find_value_giving_occurrences([], _, _, ValueVars, ValueVars).
> find_value_giving_occurrences([Var | Vars], LiveInfo, InstMapDelta,
> ValueVars0, ValueVars) :-
> - VarTypes = LiveInfo^vartypes,
> + VarTypes = LiveInfo ^ vartypes,
> map__lookup(VarTypes, Var, Type),
> (
> instmap_delta_search_var(InstMapDelta, Var, Inst),
> - ModuleInfo = LiveInfo^module_info,
> + ModuleInfo = LiveInfo ^ module_info,
> mode_to_arg_mode(ModuleInfo, (free -> Inst), Type, top_out)
> ->
> set__insert(ValueVars0, Var, ValueVars1)
> @@ -1160,8 +1465,8 @@
>
> liveness__maybe_complete_with_typeinfos(LiveInfo, Vars0, Vars) :-
> proc_info_maybe_complete_with_typeinfo_vars(Vars0,
> - LiveInfo^typeinfo_liveness, LiveInfo^vartypes,
> - LiveInfo^type_info_varmap, Vars).
> + LiveInfo ^ typeinfo_liveness, LiveInfo ^ vartypes,
> + LiveInfo ^ type_info_varmap, Vars).
>
> %-----------------------------------------------------------------------------%
> %-----------------------------------------------------------------------------%
> @@ -1178,7 +1483,7 @@
> :- pred live_info_init(module_info::in, bool::in, vartypes::in,
> type_info_varmap::in, prog_varset::in, live_info::out) is det.
>
> -live_info_init(ModuleInfo, ProcInfo, TypeInfoLiveness, VarTypes, Varset,
> - live_info(ModuleInfo, ProcInfo, TypeInfoLiveness, VarTypes, Varset)).
> +live_info_init(ModuleInfo, ProcInfo, TypeInfoLiveness, VarTypes, VarSet,
> + live_info(ModuleInfo, ProcInfo, TypeInfoLiveness, VarTypes, VarSet)).
>
> %-----------------------------------------------------------------------------%
> Index: compiler/options.m
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/compiler/options.m,v
> retrieving revision 1.304
> diff -u -b -r1.304 options.m
> --- compiler/options.m 2000/12/10 07:39:40 1.304
> +++ compiler/options.m 2001/01/05 03:05:09
> @@ -99,6 +99,7 @@
> ; trace_optimized
> ; trace_table_io
> ; trace_table_io_states
> + ; delay_death
> ; suppress_trace
> ; stack_trace_higher_order
> ; generate_bytecode
> @@ -504,6 +505,7 @@
> trace_table_io - bool(no),
> trace_table_io_states - bool(no),
> suppress_trace - string(""),
> + delay_death - bool(yes),
> stack_trace_higher_order - bool(no),
> generate_bytecode - bool(no),
> generate_prolog - bool(no),
> @@ -903,6 +905,7 @@
> long_option("trace-table-io", trace_table_io).
> long_option("trace-table-io-states", trace_table_io_states).
> long_option("suppress-trace", suppress_trace).
> +long_option("delay-death", delay_death).
> long_option("stack-trace-higher-order", stack_trace_higher_order).
> long_option("generate-bytecode", generate_bytecode).
> long_option("generate-prolog", generate_prolog).
> @@ -1719,6 +1722,12 @@
> % "\tWhen tabling I/O actions, table the io__state arguments",
> % "\ttogether with the others. This should be required iff",
> % "\tvalues of type io__state actually contain information.",
> + "--no-delay-death",
> + "\tNormally, the compiler preserves the values of variables",
> + "\tas long as possible, even beyond the point where they would",
> + "\tnormally die, in order to make them accessible from as many",
> + "\tdebugger events as possible, when the trace level is `deep'.",
Someone reading this may miss the qualification "when the trace level is
`deep'" because it is right at the end. I would change that to something
like:
When the trace level is `deep', the compiler normally preserves ...
Also, the second occurrence of "normally" might be a bit confusing. Perhaps
you could say "the point where they would die if the trace level was `none'"?
> + "\tHowever, it will not do this if this option is given.",
> "--stack-trace-higher-order",
> "\tEnable stack traces through predicates and functions with",
> "\thigher-order arguments, even if stack tracing is not",
> Index: compiler/trace_params.m
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/compiler/trace_params.m,v
> retrieving revision 1.3
> diff -u -b -r1.3 trace_params.m
> --- compiler/trace_params.m 2000/11/10 01:00:56 1.3
> +++ compiler/trace_params.m 2001/01/05 03:29:47
> @@ -34,6 +34,7 @@
> :- func trace_level_needs_fixed_slots(trace_level) = bool.
> :- func trace_level_needs_from_full_slot(trace_level) = bool.
> :- func trace_level_needs_decl_debug_slots(trace_level) = bool.
> +:- func trace_level_allows_delay_death(trace_level) = bool.
> :- func trace_needs_return_info(trace_level, trace_suppress_items) = bool.
> :- func trace_needs_all_var_names(trace_level, trace_suppress_items) = bool.
> :- func trace_needs_proc_body_reps(trace_level, trace_suppress_items) = bool.
> @@ -97,6 +98,12 @@
> trace_level_needs_decl_debug_slots(deep) = no.
> trace_level_needs_decl_debug_slots(decl) = yes.
> trace_level_needs_decl_debug_slots(decl_rep) = yes.
> +
> +trace_level_allows_delay_death(none) = no.
> +trace_level_allows_delay_death(shallow) = no.
> +trace_level_allows_delay_death(deep) = yes.
> +trace_level_allows_delay_death(decl) = yes.
> +trace_level_allows_delay_death(decl_rep) = yes.
>
> trace_needs_return_info(TraceLevel, TraceSuppressItems) = Need :-
> (
> cvs diff: Diffing compiler/notes
> cvs diff: Diffing debian
> cvs diff: Diffing doc
> Index: doc/user_guide.texi
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/doc/user_guide.texi,v
> retrieving revision 1.229
> diff -u -b -r1.229 user_guide.texi
> --- doc/user_guide.texi 2001/01/01 04:03:41 1.229
> +++ doc/user_guide.texi 2001/01/05 03:05:39
> @@ -3140,10 +3140,12 @@
> @item --trace-optimized
> Do not disable optimizations that can change the trace.
>
> - at c --trace-decl is commented out in the absence of runtime support
> - at c @item --trace-decl
> - at c Make the generated tracing code include support
> - at c for an experimental declarative debugger.
> + at item --no-delay-death
> +Normally, the compiler preserves the values of variables
> +as long as possible, even beyond the point where they would
> +normally die, in order to make them accessible from as many
> +debugger events as possible, when the trace level is @samp{deep}.
> +However, it will not do this if this option is given.
See above.
>
> @item --stack-trace-higher-order
> Enable stack traces through predicates and functions with
> cvs diff: Diffing extras
> cvs diff: Diffing extras/aditi
> 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/curses
> cvs diff: Diffing extras/curses/sample
> cvs diff: Diffing extras/dynamic_linking
> cvs diff: Diffing extras/graphics
> 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/maze
> cvs diff: Diffing extras/graphics/samples/pent
> cvs diff: Diffing extras/lazy_evaluation
> cvs diff: Diffing extras/logged_output
> cvs diff: Diffing extras/moose
> cvs diff: Diffing extras/moose/samples
> 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/odbc
> cvs diff: Diffing extras/posix
> cvs diff: Diffing extras/references
> cvs diff: Diffing extras/references/samples
> cvs diff: Diffing extras/references/tests
> cvs diff: Diffing extras/stream
> cvs diff: Diffing extras/trailed_update
> cvs diff: Diffing extras/trailed_update/samples
> cvs diff: Diffing extras/trailed_update/tests
> cvs diff: Diffing extras/xml
> cvs diff: Diffing extras/xml/samples
> cvs diff: Diffing library
> 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/diff
> cvs diff: Diffing samples/muz
> cvs diff: Diffing samples/rot13
> cvs diff: Diffing samples/solutions
> 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 tests
> 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/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/tabling
> cvs diff: Diffing tests/term
> cvs diff: Diffing tests/valid
> cvs diff: Diffing tests/warnings
> cvs diff: Diffing tools
> cvs diff: Diffing trace
> cvs diff: Diffing trial
> cvs diff: Diffing util
> --------------------------------------------------------------------------
> mercury-developers mailing list
> Post messages to: mercury-developers at cs.mu.oz.au
> Administrative Queries: owner-mercury-developers at cs.mu.oz.au
> Subscriptions: mercury-developers-request at cs.mu.oz.au
> --------------------------------------------------------------------------
>
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to: mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions: mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------
More information about the developers
mailing list