[m-dev.] for review: --suppress-trace
Mark Anthony BROWN
dougl at cs.mu.OZ.AU
Mon Oct 2 02:04:41 AEDT 2000
Zoltan Somogyi writes:
>
> Implement a general mechanism for suppressing selected aspects of execution
> tracing.
>
> compiler/trace_params.m:
> This new file contains two abstract data types that define the
> parameters of the execution tracing system, and the operations
> on them.
>
> The two ADTs are the trace level (moved from globals.m) and a new one,
> trace_suppress_items, which replaces --no-trace-internal,
> --no-trace-redo and --no-trace-return, and provides additional
> capabilities requested by Erwan.
>
> Basically any given port can now be suppressed, with the exception of
> call (because the call event's layout structure is needed for
> implementing redo from any other event) and excp (because they are
> created on the fly by exception.m, and are not put into object
> code in the first place).
>
> compiler/globals.m:
> Delete the stuff now migrated to trace_params.m. Make
> trace_suppress_items part of the globals structure.
>
> compiler/code_gen.m:
> compiler/trace.m:
> Allow the suppression of individual ports.
>
> compiler/stack_layout.m:
> Allow the suppression of parts of layout structures.
>
> compiler/*.m:
> Minor changes, mainly importing trace_params, to conform to the main
> modifications.
>
> compiler/options.m:
> Delete --no-trace-internal, --no-trace-redo and --no-trace-return.
> Add --suppress-trace, but do not document it, since it is really
> intended only for implementors.
>
> doc/user_guide.texi:
> Delete the documentation of --no-trace-internal, --no-trace-redo and
> --no-trace-return. Do not document it --suppress-trace, since it is
> really intended only for implementors. (The only reason why other three
> were documented is that most consumers of the users' guide then *were*
> implementors.)
>
> Zoltan.
>
This change looks good. I have just a few comments:
> Index: compiler/trace_params.m
> ===================================================================
> RCS file: trace_params.m
> diff -N trace_params.m
> --- /dev/null Thu Sep 2 15:00:04 1999
> +++ trace_params.m Fri Sep 29 13:37:25 2000
> @@ -0,0 +1,282 @@
> +%-----------------------------------------------------------------------------%
> +% Copyright (C) 2000 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: trace_params.m.
> +%
> +% Author: zs.
> +%
> +% This module defines the parameters of execution tracing at various trace
> +% levels and with various settings of the --suppress-trace option.
> +
> +%-----------------------------------------------------------------------------%
> +
> +:- module trace_params.
> +
> +:- interface.
> +
> +:- import_module llds.
> +:- import_module bool.
> +
> +:- type trace_level.
> +:- type trace_suppress_items.
> +
> + % the bool should be the setting of the `require_tracing' option.
> +:- pred convert_trace_level(string::in, bool::in, trace_level::out) is semidet.
> +
> +:- pred convert_trace_suppress(string::in, trace_suppress_items::out)
> + is semidet.
> +
> + % These functions check for various properties of the trace level.
> +:- func trace_level_is_none(trace_level) = bool.
> +:- 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_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.
> +:- func trace_needs_port(trace_level, trace_suppress_items, trace_port) = bool.
> +
> +:- func trace_level_none = trace_level.
> +
> +:- implementation.
> +
> +:- import_module char, string, list, set.
> +
> +:- type trace_level
> + ---> none
> + ; shallow
> + ; deep
> + ; decl
> + ; decl_rep.
> +
> +:- type trace_suppress_item
> + ---> port(trace_port)
> + ; return_info
> + ; all_var_names
> + ; proc_body_reps.
> +
> +:- type trace_suppress_items == set(trace_suppress_item).
> +
> +trace_level_none = none.
> +
> +convert_trace_level("minimum", no, none).
> +convert_trace_level("minimum", yes, shallow).
> +convert_trace_level("shallow", _, shallow).
> +convert_trace_level("deep", _, deep).
> +convert_trace_level("decl", _, decl).
> +convert_trace_level("rep", _, decl_rep).
> +convert_trace_level("default", no, none).
> +convert_trace_level("default", yes, deep).
> +
> +trace_level_is_none(none) = yes.
> +trace_level_is_none(shallow) = no.
> +trace_level_is_none(deep) = no.
> +trace_level_is_none(decl) = no.
> +trace_level_is_none(decl_rep) = no.
> +
> +trace_level_needs_fixed_slots(none) = no.
> +trace_level_needs_fixed_slots(shallow) = yes.
> +trace_level_needs_fixed_slots(deep) = yes.
> +trace_level_needs_fixed_slots(decl) = yes.
> +trace_level_needs_fixed_slots(decl_rep) = yes.
> +
> +trace_level_needs_from_full_slot(none) = no.
> +trace_level_needs_from_full_slot(shallow) = yes.
> +trace_level_needs_from_full_slot(deep) = no.
> +trace_level_needs_from_full_slot(decl) = no.
> +trace_level_needs_from_full_slot(decl_rep) = no.
> +
> +trace_level_needs_decl_debug_slots(none) = no.
> +trace_level_needs_decl_debug_slots(shallow) = no.
> +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_needs_return_info(TraceLevel, TraceSuppressItems) = Need :-
> + (
> + trace_level_has_return_info(TraceLevel) = yes,
> + \+ set__member(return_info, TraceSuppressItems)
> + ->
> + Need = yes
> + ;
> + Need = no
> + ).
> +
> +trace_needs_all_var_names(TraceLevel, TraceSuppressItems) = Need :-
> + (
> + trace_level_has_all_var_names(TraceLevel) = yes,
> + \+ set__member(all_var_names, TraceSuppressItems)
> + ->
> + Need = yes
> + ;
> + Need = no
> + ).
> +
> +trace_needs_proc_body_reps(TraceLevel, TraceSuppressItems) = Need :-
> + (
> + trace_level_has_proc_body_reps(TraceLevel) = yes,
> + \+ set__member(proc_body_reps, TraceSuppressItems)
> + ->
> + Need = yes
> + ;
> + Need = no
> + ).
> +
> +:- func trace_level_has_return_info(trace_level) = bool.
> +:- func trace_level_has_all_var_names(trace_level) = bool.
> +:- func trace_level_has_proc_body_reps(trace_level) = bool.
> +
> +trace_level_has_return_info(none) = no.
> +trace_level_has_return_info(shallow) = yes.
> +trace_level_has_return_info(deep) = yes.
> +trace_level_has_return_info(decl) = yes.
> +trace_level_has_return_info(decl_rep) = yes.
> +
> +trace_level_has_all_var_names(none) = no.
> +trace_level_has_all_var_names(shallow) = no.
> +trace_level_has_all_var_names(deep) = no.
> +trace_level_has_all_var_names(decl) = yes.
> +trace_level_has_all_var_names(decl_rep) = yes.
> +
> +trace_level_has_proc_body_reps(none) = no.
> +trace_level_has_proc_body_reps(shallow) = no.
> +trace_level_has_proc_body_reps(deep) = no.
> +trace_level_has_proc_body_reps(decl) = no.
> +trace_level_has_proc_body_reps(decl_rep) = yes.
> +
> +convert_trace_suppress(SuppressString, SuppressItemSet) :-
> + SuppressWords = string__words(char_is_comma, SuppressString),
> + list__map(convert_item_name, SuppressWords, SuppressItemLists),
> + list__condense(SuppressItemLists, SuppressItems),
> + set__list_to_set(SuppressItems, SuppressItemSet).
> +
> +:- pred char_is_comma(char::in) is semidet.
> +
> +char_is_comma(',').
> +
> +:- func convert_port_name(string) = trace_port is semidet.
> +
> + % The call port cannot be disabled, because its layout structure is
> + % referred to implicitly by the redo command in mdb.
> + %
> + % The exception port cannot be disabled, because it is never put into
> + % compiler-generated code in the first place; such events are created
> + % on the fly by library/exception.m.
> +% convert_port_name("call") = call.
> +convert_port_name("exit") = exit.
> +convert_port_name("fail") = fail.
> +convert_port_name("redo") = redo.
> +% convert_port_name("excp") = exception.
> +convert_port_name("exception") = exception.
> +convert_port_name("cond") = ite_cond.
> +convert_port_name("ite_cond") = ite_cond.
> +convert_port_name("then") = ite_then.
> +convert_port_name("ite_then") = ite_then.
> +convert_port_name("else") = ite_else.
> +convert_port_name("ite_else") = ite_else.
> +convert_port_name("nege") = neg_enter.
> +convert_port_name("neg_enter") = neg_enter.
> +convert_port_name("negs") = neg_success.
> +convert_port_name("neg_success") = neg_success.
> +convert_port_name("negf") = neg_failure.
> +convert_port_name("neg_failure") = neg_failure.
> +convert_port_name("swtc") = switch.
> +convert_port_name("switch") = switch.
> +convert_port_name("disj") = disj.
> +convert_port_name("frst") = nondet_pragma_first.
> +convert_port_name("nondet_pragma_first") = nondet_pragma_first.
> +convert_port_name("latr") = nondet_pragma_first.
> +convert_port_name("nondet_pragma_later") = nondet_pragma_later.
> +
> +:- func convert_port_class_name(string) = list(trace_port) is semidet.
> +
> +convert_port_class_name("interface") =
> + [call, exit, redo, fail, exception].
> +convert_port_class_name("internal") =
> + [ite_then, ite_else, switch, disj].
> +convert_port_class_name("context") =
> + [ite_cond, neg_enter, neg_success, neg_failure].
> +
> +:- func convert_other_name(string) = trace_suppress_item is semidet.
> +
> +convert_other_name("return") = return_info.
> +convert_other_name("return_info") = return_info.
> +convert_other_name("names") = all_var_names.
> +convert_other_name("all_var_names") = all_var_names.
> +convert_other_name("bodies") = proc_body_reps.
> +convert_other_name("proc_body_reps") = proc_body_reps.
> +
> +:- pred convert_item_name(string::in, list(trace_suppress_item)::out)
> + is semidet.
> +
> +convert_item_name(String, Names) :-
> + ( convert_port_name(String) = PortName ->
> + Names = [port(PortName)]
> + ; convert_port_class_name(String) = PortNames ->
> + list__map(wrap_port, PortNames, Names)
> + ; convert_other_name(String) = OtherName ->
> + Names = [OtherName]
> + ;
> + fail
> + ).
> +
> +:- pred wrap_port(trace_port::in, trace_suppress_item::out) is det.
> +
> +wrap_port(Port, port(Port)).
> +
> +%-----------------------------------------------------------------------------%
> +
> +:- type port_category
> + ---> interface
> + ; internal
> + ; context.
> +
> +:- func trace_port_category(trace_port) = port_category.
> +
> +trace_port_category(call) = interface.
> +trace_port_category(exit) = interface.
> +trace_port_category(fail) = interface.
> +trace_port_category(redo) = interface.
> +trace_port_category(exception) = interface.
> +trace_port_category(ite_cond) = context.
> +trace_port_category(ite_then) = internal.
> +trace_port_category(ite_else) = internal.
> +trace_port_category(neg_enter) = context.
> +trace_port_category(neg_success) = context.
> +trace_port_category(neg_failure) = context.
> +trace_port_category(switch) = internal.
> +trace_port_category(disj) = internal.
> +trace_port_category(nondet_pragma_first) = internal.
> +trace_port_category(nondet_pragma_later) = internal.
> +
> +:- func trace_level_port_categories(trace_level) = list(port_category).
> +
> +trace_level_port_categories(none) = [].
> +trace_level_port_categories(shallow) = [interface].
> +trace_level_port_categories(deep) = [interface, internal].
> +trace_level_port_categories(decl) = [interface, internal, context].
> +trace_level_port_categories(decl_rep) = [interface, internal, context].
> +
> +:- func trace_level_allows_port_suppression(trace_level) = bool.
> +
> +trace_level_allows_port_suppression(none) = no. % no ports exist
> +trace_level_allows_port_suppression(shallow) = yes.
> +trace_level_allows_port_suppression(deep) = yes.
> +trace_level_allows_port_suppression(decl) = no.
> +trace_level_allows_port_suppression(decl_rep) = no.
> +
> +trace_needs_port(TraceLevel, TraceSuppressItems, Port) = NeedsPort :-
> + (
> + trace_port_category(Port) = Category,
> + list__member(Category,
> + trace_level_port_categories(TraceLevel)),
> + ( trace_level_allows_port_suppression(TraceLevel) = yes =>
> + \+ set__member(port(Port), TraceSuppressItems) )
IMHO, the logic would be clearer if that last conjunct was
\+ (
trace_level_allows_port_suppression(Trace_Level) = yes,
set__member(port(Port), TraceSuppressItems)
)
> + ->
> + NeedsPort = yes
> + ;
> + NeedsPort = no
> + ).
> 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.220
> diff -u -r1.220 user_guide.texi
> --- doc/user_guide.texi 2000/09/17 09:19:12 1.220
> +++ doc/user_guide.texi 2000/09/29 02:42:49
> @@ -1440,62 +1440,63 @@
> MCFLAGS-bar = --trace shallow
> @end example
>
> - at node Selecting trace events
> - at section Selecting trace events
> + at node Tracing and optimization trace events
> + at section Tracing and optimization trace events
I'd call this section "Tracing and compiler optimization", or maybe
"Tracing optimized code".
>
> - at c XXX anybody got a better title for this section?
> -
> -In preparing a Mercury program for debugging,
> -the Mercury compiler provides two options that you can use
> -to say that you are not interested in certain kinds of events,
> -and that the compiler should therefore not generate code for those events.
> -This makes the executable smaller and faster.
> -
> -The first of these options is @samp{--no-trace-internal}.
> -If you specify this when you compile a module,
> -you will not get any internal events
> -from predicates and functions defined in that module,
> -even if the trace level is @samp{deep};
> -you will only get external events.
> -These are sufficient to tell you what a predicate or function does,
> -i.e. what outputs it computes from what inputs.
> -They do not tell you how it computed those outputs,
> -i.e. what path control took through the predicate or function,
> -but that is sometimes of no particular interest.
> -In any case, much of the time you can deduce the path
> -from the events that result from
> -calls made by the predicate or function in question.
> -
> -The second of these options is @samp{--no-trace-redo},
> -which can be specified independently of @samp{--no-trace-internal}.
> -If you specify this when you compile a module,
> -you will not get any redo events
> -from predicates and functions defined in that module.
> -If you are not interested in how backtracking arrives
> -at a program point where forward execution can resume after a failure,
> -this is an entirely reasonable thing to do.
> -In any case, with sufficient thought and a memory of previous events
> -you can reconstruct the sequence of redo events
> -that would normally be present between the fail event
> -and the event that represents the resumption of forward execution.
> -This sequence has a redo event
> -for every call to a procedure that can succeed more than once
> -that occurred after the call to the procedure
> -in which the resumption event occurs,
> -provided that that call has not failed yet,
> -and in reverse chronological order.
> -
> -Normally, when it compiles a module with a trace level other than @samp{none},
> -the compiler will include in the module's object file
> -information about all the call return sites in that module.
> -This information allows the debugger to print stack dumps,
> -as well as the values of variables in ancestors of current call.
> -However, if you specify the @samp{--no-trace-return} option,
> -the compiler will not include this information in the object file,
> -reducing its size but losing the above functionality.
> -
> - at c XXX should we document --stack-trace-higher-order
> - at c it has not really been tested yet
> + at c @c XXX anybody got a better title for this section?
There is an extra `@c' here.
> + at c
> + at c In preparing a Mercury program for debugging,
> + at c the Mercury compiler provides two options that you can use
> + at c to say that you are not interested in certain kinds of events,
> + at c and that the compiler should therefore not generate code for those events.
> + at c This makes the executable smaller and faster.
> + at c
> + at c The first of these options is @samp{--no-trace-internal}.
> + at c If you specify this when you compile a module,
> + at c you will not get any internal events
> + at c from predicates and functions defined in that module,
> + at c even if the trace level is @samp{deep};
> + at c you will only get external events.
> + at c These are sufficient to tell you what a predicate or function does,
> + at c i.e. what outputs it computes from what inputs.
> + at c They do not tell you how it computed those outputs,
> + at c i.e. what path control took through the predicate or function,
> + at c but that is sometimes of no particular interest.
> + at c In any case, much of the time you can deduce the path
> + at c from the events that result from
> + at c calls made by the predicate or function in question.
> + at c
> + at c The second of these options is @samp{--no-trace-redo},
> + at c which can be specified independently of @samp{--no-trace-internal}.
> + at c If you specify this when you compile a module,
> + at c you will not get any redo events
> + at c from predicates and functions defined in that module.
> + at c If you are not interested in how backtracking arrives
> + at c at a program point where forward execution can resume after a failure,
> + at c this is an entirely reasonable thing to do.
> + at c In any case, with sufficient thought and a memory of previous events
> + at c you can reconstruct the sequence of redo events
> + at c that would normally be present between the fail event
> + at c and the event that represents the resumption of forward execution.
> + at c This sequence has a redo event
> + at c for every call to a procedure that can succeed more than once
> + at c that occurred after the call to the procedure
> + at c in which the resumption event occurs,
> + at c provided that that call has not failed yet,
> + at c and in reverse chronological order.
> + at c
> + at c Normally, when it compiles a module
> + at c with a trace level other than @samp{none},
> + at c the compiler will include in the module's object file
> + at c information about all the call return sites in that module.
> + at c This information allows the debugger to print stack dumps,
> + at c as well as the values of variables in ancestors of current call.
> + at c However, if you specify the @samp{--no-trace-return} option,
> + at c the compiler will not include this information in the object file,
> + at c reducing its size but losing the above functionality.
> + at c
Even if it is commented out, it would be nicer to update this so that it
refers to the new option.
> + at c @c XXX should we document --stack-trace-higher-order
> + at c @c it has not really been tested yet
Extra `@c's here too.
>
> By default, all trace levels other than @samp{none}
> turn off all compiler optimizations
Cheers,
Mark.
--------------------------------------------------------------------------
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