Files
mercury/runtime/mercury_debug.h
Zoltan Somogyi 04e614485d Implement deep profiling; merge the changes on the deep2 branch back
Estimated hours taken: 500
Branches: main

Implement deep profiling; merge the changes on the deep2 branch back
onto the trunk.

The main documentation on the general architecture of the deep profiler
is the deep profiling paper.

doc/user_guide.texi:
	Document how to use the deep profiler.

deep_profiler:
deep_profiler/Mmakefile:
	A new directory holding the deep profiler and its mmakefile.

Mmakefile:
	Add targets for the new directory.

	Add support for removing inappropriate files from directories.

deep_profiler/interface.m:
	The deep profiler consists of two programs: mdprof_cgi.m, which acts
	as a CGI "script", and mdprof_server.m, which implements the server
	process that the CGI script talks to. Interface.m defines the
	interface between them.

script/mdprof.in:
	A shell script template. ../configure uses it to generate mdprof,
	which is a wrapper around mdprof_cgi that tells it how to find
	mdprof_server.

deep_profiler/mdprof_cgi.m:
	The CGI "script" program.

deep_profiler/mdprof_server.m:
	The top level predicates of the server.

deep_profiler/profile.m:
	The main data structures of the server and their operations.

deep_profiler/read_profile.m:
	Code for reading in profiling data files.

deep_profiler/startup.m:
	Code for post-processing the information in profiling data files,
	propagating costs from procedures to their ancestors and performing
	various kinds of summaries.

deep_profiler/server.m:
	Code for responding to requests from the CGI script.

deep_profiler/cliques.m:
	Code to find cliques in graphs.

deep_profiler/array_util.m:
deep_profiler/util.m:
	Utility predicates.

deep_profiler/dense_bitset.m:
	An implementation of (part of) the set ADT with dense bit vectors.

deep_profiler/measurements.m:
	Operations on profiling measurements.

deep_profiler/timeout.m:
	An implementation of a timeout facility.

deep_profiler/conf.m:
	Functions that depend on autoconfigured settings.

configure.in:
	Find out what command to use to find the name of the local host.

	Install deep profiling versions of the standard library along with the
	other profiling versions.

runtime/mercury_conf.h.in:
	Add some macros for deep_profiler/conf.m to use.

library/profiling_builtin.m:
runtime/mercury_deep_call_port_body.h:
runtime/mercury_deep_leave_port_body.h:
runtime/mercury_deep_redo_port_body.h:
	A new library module that implements deep profiling primitives.
	Some of these primitives have many versions, whose common code is
	factor is factored out in three new include files in the runtime.

compiler/deep_profiling.m:
	New module to perform the program transformations described in the
	paper.

compiler/notes/compiler_design.html:
	Document the new compiler module.

compiler/mercury_compiler.m:
	Invoke the new module in deep profiling grades. Allow global static
	data to be generated by deep_profiling.m.

compiler/options.m:
	Add options to turn on deep profiling and (for benchmarking purposes)
	control its implementation.

	Add an optiooption disable tailcall optimization in the LLDS backend,
	to help benchmarking deep profiling.

compiler/jumpopt.m:
compiler/optimize.m:
	Obey the option to disable tailcalls.

compiler/handle_options.m:
	Handle the implications of deep profiling.

compiler/modules.m:
	In deep profiling grades, automatically import profiling_builtin.m.

compiler/prog_util.m:
doc/Makefile:
library/library.m:
	Handle the new builtin module.

compiler/export.m:
	In deep profiling grades, wrap deep profiling code around exported
	procedures to handle the "unscheduled call" aspects of callbacks to
	Mercury from the foreign language.

compiler/higher_order.m:
profiler/demangle.m:
util/demangle.c:
	When creating a name for a higher-order-specialized predicate, include
	the mode number in the name.

compiler/add_trail_ops.m:
compiler/type_util.m:
	Move c_pointer_type from add_trail_ops to type_util, so it can also be
	used by deep_profiling.m.

compiler/hlds_goal.m:
	Add a new goal feature that marks a tail call, for use by
	deep_profiling.m.

compiler/hlds_pred.m:
	Add a new field to proc_info structures for use by deep_profiling.m.

	Add a mechanism for getting proc_ids for procedure clones.

	Remove next_proc_id, an obsolete and unused predicate.

compiler/hlds_data.m:
	Add a new cons_id to refer to the proc_static structure of a procedure.

compiler/bytecode_gen.m:
compiler/code_util.m:
compiler/dependency_graph.m:
compiler/hlds_out.m:
compiler/mercury_to_mercury.m:
compiler/ml_unify_gen.m:
compiler/opt_debug.m:
compiler/prog_rep.m:
compiler/rl_exprn.m:
compiler/switch_util.m:
compiler/unify_gen.m:
	Trivial changes to handle the new cons_id, goal feature and/or
	proc_info argument.

compiler/rtti.m:
	Add a utility predicate for extracting pred_id and proc_id from an
	rtti_proc_label, for use by hlds_out.m

compiler/layout.m:
compiler/layout_out.m:
compiler/llds.m:
compiler/llds_common.m:
	Add support for proc_static and call_site_static structures.

compiler/layout_out.m:
compiler/llds_out.m:
	Add code for the output of proc_static structures.

compiler/code_util.m:
	Make code_util__make_proc_label_from_rtti a function, and export it.

util/mkinit.c:
compiler/llds_out.m:
compiler/layout.m:
compiler/modules.m:
	Add support for a fourth per-module C function, for writing out
	proc_static structures (and the call_site_static structures they
	contains).

	Since proc_static structures can be referred to from LLDS code (and not
	just from other static structures and compiler-generated C code),
	reorganize the declarations of static structures slightly.

	Change the schema for the name of the first per-module C function
	slightly, to make it the addition of the fourth function easier.
	The scheme now is:

		mercury__<modulename>__init
		mercury__<modulename>__init_type_tables
		mercury__<modulename>__init_debugger
		mercury__<modulename>__write_out_proc_statics

	Improve formatting of the generated C code.

library/*.m:
runtime/mercury.c:
runtime/mercury_context.c:
runtime/mercury_engine.c:
runtime/mercury_ho_call.c:
runtime/mercury_tabling.c:
runtime/mercury_trace_base.c:
runtime/mercury_wrapper.c:
trace/mercrury_trace.[ch]:
trace/mercrury_trace_declarative.c:
trace/mercrury_trace_external.c:
trace/mercrury_trace_internal.c:
	Conform to the new scheme for initialization functions for hand-written
	modules.

compiler/mercury_compile.m:
library/benchmarking.m:
runtime/mercury_conf_param.h:
runtime/mercury.h:
runtime/mercury_engine.c:
runtime/mercury_goto.c:
runtime/mercury_grade.h:
runtime/mercury_ho_call.c:
runtime/mercury_label.[ch]:
runtime/mercury_prof.[ch]:
	Add an MR_MPROF_ prefix in front of the C macros used to control the
	old profiler.

compiler/handle_options.m:
runtime/mercury_grade.h:
scripts/canonical_grade.sh-subr:
scripts/init_grade_options.sh-subr:
scripts/parse_grade_options.sh-subr:
	Make deep profiling completely separate from the old profiling system,
	by making the deep profiling grade independent of MR_MPROF_PROFILE_TIME
	and the compiler option --profile-time.

library/array.m:
library/builtin.m:
library/std_util.m:
runtime/mercury_hand_unify_body.h:
runtime/mercury_hand_compare_body.h:
	In deep profiling grades, wrap the deep profiling call, exit, fail
	and redo codes around the bodies of hand-written unification
	and comparison procedures.

	Make the reporting of array bounds violations switchable between
	making them fatal errors, as we currently, and reporting them by
	throwing an exception. Throwing an exception makes debugging code
	using arrays easier, but since exceptions aren't (yet) propagated
	across engine boundaries, we keep the old behaviour as the default;
	the new behaviour is for implementors.

runtime/mercury_deep_profiling_hand.h:
	New file that defines macros for use in Mercury predicates whose
	definition is in hand-written C code.

library/exception.m:
runtime/mercury_exception_catch_body.h:
runtime/mercury_stacks.h:
	In deep profiling grades, wrap the deep profiling call, exit, fail
	and redo codes around the bodies of the various modes of builtin_catch.

	Provide a function that C code can use to throw exceptions.

library/benchmarking.m:
library/exception.m:
library/gc.m:
library/std_util.m:
runtime/mercury_context.[ch]:
runtime/mercury_engine.[ch]:
runtime/mercury_debug.c:
runtime/mercury_deep_copy.c:
runtime/mercury_overflow.h:
runtime/mercury_regs.h:
runtime/mercury_stacks.h:
runtime/mercury_thread.c:
runtime/mercury_wrapper.c:
	Add prefixes to the names of the fields in the engine and context
	structures, to make code using them easier to understand and modify.

runtime/mercury_deep_profiling.[ch]:
	New module containing support functions for deep profiling and
	functions for writing out a deep profiling data file at the end of
	execution.

runtime/mercury_debug.[ch]:
	Add support for debugging deep profiling.

	Add support for watching the value at a given address.

	Make the buffered/unbuffered nature of debugging output controllable
	via the -du option.

	Print register contents only if -dr is specified.

runtime/mercury_goto.h:
runtime/mercury_std.h:
	Use the macros in mercury_std.h instead of defining local variants.

runtime/mercury_goto.h:
runtime/mercury_stack_layout.h:
runtime/mercury_stack_trace.c:
runtime/mercury_tabling.c:
trace/mercury_trace.c:
trace/mercury_trace_declarative.c:
trace/mercury_trace_external.c:
trace/mercury_trace_vars.c:
	Standardize some of the macro names with those used in the debugger
	paper.

runtime/mercury_heap.h:
	Add support for memory profiling with the deep profiler.

runtime/mercury_prof.[ch]:
runtime/mercury_prof_time.[ch]:
	Move the functionality that both the old profiler and the deep profiler
	need into the new module mercury_prof_time. Leave mercury_prof
	containing stuff that is only relevant to the old profiler.

runtime/mercury_prof.[ch]:
runtime/mercury_strerror.[ch]:
	Move the definition of strerror from mercury_prof to its own file.

runtime/mercury_wrapper.[ch]:
	Add support for deep profiling.

	Add suppory for controlling whether debugging output is buffered or
	not.

	Add support for watching the value at a given address.

runtime/Mmakefile:
	Mention all the added files.

scripts/mgnuc.in:
	Add an option for turning on deep profiling.

	Add options for controlling the details of deep profiling. These
	are not documented because they are intended only for benchmarking
	the deep profiler itself, for the paper; they are not for general use.

tools/bootcheck:
	Compile the deep_profiler directory as well as the other directories
	containing Mercury code.

	Turn off the creation of deep profiling data files during bootcheck,
	since all but one of these in each directory will be overwritten
	anyway.

	Add support for turning on --keep-objs by default in a workspace.

tools/speedtest:
	Preserve any deep profiling data files created by the tests.

trace/mercury_trace.c:
	Trap attempts to perform retries in deep profiling grades, since they
	would lead to core dumps otherwise.

util/Mmakefile:
	Avoid compile-time warnings when compiling getopt.

tests/*/Mmakefile:
tests/*/*/Mmakefile:
	In deep profiling grades, switch off the tests that test features
	that don't work with deep profiling, either by design or because
	the combination hasn't been implemented yet.
2001-05-31 06:00:27 +00:00

196 lines
6.1 KiB
C

/*
** Copyright (C) 1995-2001 The University of Melbourne.
** This file may only be copied under the terms of the GNU Library General
** Public License - see the file COPYING.LIB in the Mercury distribution.
*/
/* mercury_debug.h - definitions for debugging messages */
#ifndef MERCURY_DEBUG_H
#define MERCURY_DEBUG_H
#include "mercury_types.h" /* for MR_Word and MR_Code */
#include "mercury_deep_profiling.h" /* for MR_CallSiteDynamic */
#include <stdio.h> /* for FILE */
/*---------------------------------------------------------------------------*/
#ifdef MR_DEBUG_ON
#define MR_DEBUG(X) X
#else
#define MR_DEBUG(X)
#endif
#if !defined(MR_DEBUG_GOTOS)
#define MR_debuggoto(label) ((void)0)
#define MR_debugsreg() ((void)0)
#else
#define MR_debuggoto(label) \
(MR_assert(label), \
MR_IF (MR_gotodebug, \
(MR_save_transient_registers(), MR_goto_msg(label))))
#define MR_debugsreg() \
MR_IF (MR_sregdebug, \
(MR_save_transient_registers(), MR_reg_msg()))
#endif
#ifndef MR_LOWLEVEL_DEBUG
#define MR_debugcr1(val0, hp) ((void)0)
#define MR_debugcr2(val0, val1, hp) ((void)0)
#define MR_debugincrhp(val, hp) ((void)0)
#define MR_debugincrsp(val, sp) ((void)0)
#define MR_debugdecrsp(val, sp) ((void)0)
#define MR_debugregs(msg) ((void)0)
#define MR_debugframe(msg) ((void)0)
#define MR_debugmkframe(predname) ((void)0)
#define MR_debugsucceed() ((void)0)
#define MR_debugsucceeddiscard() ((void)0)
#define MR_debugfail() ((void)0)
#define MR_debugredo() ((void)0)
#define MR_debugcall(proc, succ_cont) ((void)0)
#define MR_debugtailcall(proc) ((void)0)
#define MR_debugproceed() ((void)0)
#define MR_debugmsg0(msg) ((void)0)
#define MR_debugmsg1(msg, arg1) ((void)0)
#define MR_debugmsg2(msg, arg1, arg2) ((void)0)
#define MR_debugmsg3(msg, arg1, arg2, arg3) ((void)0)
#else
#define MR_debugcr1(val0, hp) \
MR_IF (MR_heapdebug, \
(MR_save_transient_registers(), MR_cr1_msg(val0, hp)))
#define MR_debugcr2(val0, val1, hp) \
MR_IF (MR_heapdebug, \
(MR_save_transient_registers(), MR_cr2_msg(val0, val1, hp)))
#define MR_debugincrhp(val, hp) \
MR_IF (MR_heapdebug, \
(MR_save_transient_registers(), MR_incr_hp_debug_msg((val), (hp))))
#define MR_debugincrsp(val, sp) \
MR_IF (MR_detstackdebug, \
(MR_save_transient_registers(), MR_incr_sp_msg((val), (sp))))
#define MR_debugdecrsp(val, sp) \
MR_IF (MR_detstackdebug, \
(MR_save_transient_registers(), MR_decr_sp_msg((val), (sp))))
#define MR_debugregs(msg) \
MR_IF (MR_progdebug, (MR_save_transient_registers(), MR_printregs(msg)))
#define MR_debugmkframe(predname) \
MR_IF (MR_nondstackdebug, \
(MR_save_transient_registers(), MR_mkframe_msg(predname)))
#define MR_debugframe(msg) \
MR_IF (MR_progdebug, \
(MR_save_transient_registers(), MR_printframe(msg)))
#define MR_debugsucceed() \
MR_IF (MR_calldebug, \
(MR_save_transient_registers(), MR_succeed_msg()))
#define MR_debugsucceeddiscard() \
MR_IF (MR_calldebug, \
(MR_save_transient_registers(), MR_succeeddiscard_msg()))
#define MR_debugfail() \
MR_IF (MR_calldebug, \
(MR_save_transient_registers(), MR_fail_msg()))
#define MR_debugredo() \
MR_IF (MR_calldebug, \
(MR_save_transient_registers(), MR_redo_msg()))
#define MR_debugcall(proc, succ_cont) \
MR_IF (MR_calldebug, \
(MR_save_transient_registers(), MR_call_msg(proc, succ_cont)))
#define MR_debugtailcall(proc) \
MR_IF (MR_calldebug, \
(MR_save_transient_registers(), MR_tailcall_msg(proc)))
#define MR_debugproceed() \
MR_IF (MR_calldebug, (MR_save_transient_registers(), MR_proceed_msg()))
#define MR_debugmsg0(msg) \
MR_IF (MR_progdebug, (printf(msg)))
#define MR_debugmsg1(msg, arg1) \
MR_IF (MR_progdebug, (printf(msg, arg1)))
#define MR_debugmsg2(msg, arg1, arg2) \
MR_IF (MR_progdebug, (printf(msg, arg1, arg2)))
#define MR_debugmsg3(msg, arg1, arg2, arg3) \
MR_IF (MR_progdebug, (printf(msg, arg1, arg2, arg3)))
#endif /* MR_LOWLEVEL_DEBUG */
#define MR_print_deep_prof_vars(fp) \
do { \
MR_print_deep_prof_var(stdout, "current_call_site_dynamic", \
MR_current_call_site_dynamic); \
MR_print_deep_prof_var(stdout, "next_call_site_dynamic", \
MR_next_call_site_dynamic); \
} while (0)
/*---------------------------------------------------------------------------*/
#ifdef MR_LOWLEVEL_DEBUG
extern void MR_mkframe_msg(const char *);
extern void MR_succeed_msg(void);
extern void MR_succeeddiscard_msg(void);
extern void MR_fail_msg(void);
extern void MR_redo_msg(void);
extern void MR_call_msg(/* const */ MR_Code *proc,
/* const */ MR_Code *succcont);
extern void MR_tailcall_msg(/* const */ MR_Code *proc);
extern void MR_proceed_msg(void);
extern void MR_cr1_msg(MR_Word val0, const MR_Word *addr);
extern void MR_cr2_msg(MR_Word val0, MR_Word val1, const MR_Word *addr);
extern void MR_incr_hp_debug_msg(MR_Word val, const MR_Word *addr);
extern void MR_incr_sp_msg(MR_Word val, const MR_Word *addr);
extern void MR_decr_sp_msg(MR_Word val, const MR_Word *addr);
#endif
#ifdef MR_DEBUG_GOTOS
extern void MR_goto_msg(/* const */ MR_Code *addr);
extern void MR_reg_msg(void);
#endif
#ifdef MR_LOWLEVEL_DEBUG
extern void MR_printint(MR_Word n);
extern void MR_printstring(const char *s);
extern void MR_printheap(const MR_Word *h);
extern void MR_dumpframe(/* const */ MR_Word *);
extern void MR_dumpnondstack(void);
extern void MR_printlist(MR_Word p);
extern void MR_printframe(const char *);
extern void MR_printregs(const char *msg);
#endif
extern void MR_printdetstack(const MR_Word *s);
extern void MR_printdetstackptr(const MR_Word *s);
extern void MR_print_detstackptr(FILE *fp, const MR_Word *s);
extern void MR_printnondstack(const MR_Word *s);
extern void MR_printnondstackptr(const MR_Word *s);
extern void MR_print_nondstackptr(FILE *fp, const MR_Word *s);
extern void MR_print_heapptr(FILE *fp, const MR_Word *s);
extern void MR_print_label(FILE *fp, /* const */ MR_Code *w);
extern void MR_printlabel(FILE *fp, /* const */ MR_Code *w);
extern void MR_print_deep_prof_var(FILE *fp, const char *name,
MR_CallSiteDynamic *csd);
/*---------------------------------------------------------------------------*/
#endif /* not MERCURY_DEBUG_H */