mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-12 04:14:06 +00:00
Estimated hours taken: weeks Branches: main Implement a mechanism to generate the information required to determine the algorithmic complexity of selected procedures. The basis of the mechanism is a program transformation that wraps up the body of each selected procedure in code that detects top-level (non-recursive) calls, and for each top-level call, records the sizes of the input arguments and information about the cost of the call. For now, the cost information consists only of the number of cells and words allocated during the call, but there is provision for later adding information from a real-time clock. compiler/complexity.m: A new module containing the new transformation. compiler/transform_hlds.m: Add complexity.m to the list of submodules. compiler/mercury_compile.m: Invoke the new module. compiler/notes/compiler_design.html: Mention the new module. compiler/options.m: Add an option, --experimental-complexity. Its argument is a filename that specifies the list of procedures to transform. Add an option, --no-allow-inlining, to disallow all inlining. This is simpler to use than specifying several options to turn off each potential reason to inline procedures. doc/user_guide.texi: Document the new options. The documentation present now is only a shell; it will be expanded later. compiler/table_gen.m: compiler/goal_util.m: Move the predicate for creating renamings from table_gen.m to goal_util.m, since complexity.m also needs it now. In the process, make it more general by allowing outputs to have more complex modes than simply `out'. compiler/goal_util.m: Fix a bug exposed by the new transformation: when renaming goals (e.g. for quantification), rename the variables holding information about term sizes. compiler/handle_options.m: Disable inlining if experimental complexity analysis is enabled. compiler/compile_target_code.m: Pass the --experimental-complexity option on to the linker. library/term_size_prof_builtin.m: Add the Mercury predicates that serve as interfaces to the primitives needed by the experimental complexity transformation. runtime/mercury_term_size.[ch]: Add the implementations of the primitives needed by the experimental complexity transformation. runtime/mercury_wrapper.[ch]: Add global variables holding counters of the numbers of words and cells allocated so far. runtime/mercury_heap.h: Update these global variables when allocating memory. runtime/mercury_complexity.h: New file that contains the definition of the data structures holding the data collected by the experimental complexity transformation. This is separate from mercury_term_size.h, because it needs to be #included in mercury_init.h, the header file of the mkinit-generated <program>_init.c files. runtime/mercury_init.h: runtime/mercury_imp.h: #include mercury_complexity.h. util/mkinit.c: Define and initialize the data structures holding complexity information when given the -X option (mkinit doesn't have long options). Fix some deviations from our coding style. scripts/parse_ml_options.sh-subr.in: Accept the --experiment-complexity option. scripts/c2init.in: Pass the --experiment-complexity option on to mkinit.c. tools/bootcheck: Preserve the files containing the results of complexity analysis, if they exist. tools/makebatch: Allow the specification of EXTRA_MLFLAGS in the generated Mmake.stage.params files.
90 lines
3.4 KiB
C
90 lines
3.4 KiB
C
/*
|
|
** vim:ts=4 sw=4 expandtab
|
|
*/
|
|
/*
|
|
** Copyright (C) 2003, 2005 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_term_size.h
|
|
**
|
|
** This module declares functions for returning the sizes of terms.
|
|
*/
|
|
|
|
#ifndef MR_MERCURY_TERM_SIZE_H
|
|
#define MR_MERCURY_TERM_SIZE_H
|
|
|
|
#include "mercury_std.h" /* for MR_bool */
|
|
#include "mercury_types.h" /* for the typedefs of the structs we define */
|
|
|
|
#include "mercury_complexity.h" /* for MR_ComplexityProc, etc */
|
|
|
|
#ifdef MR_RECORD_TERM_SIZES
|
|
|
|
extern MR_ComplexityCounter MR_complexity_word_counter;
|
|
extern MR_ComplexityCounter MR_complexity_cell_counter;
|
|
extern MR_ComplexityCounter MR_complexity_tick_counter;
|
|
|
|
#define MR_complexity_is_active(numprocs, procnum, name, inputs, is_active) \
|
|
do { \
|
|
is_active = MR_complexity_is_active_func((numprocs), (procnum), \
|
|
(name), (inputs)); \
|
|
} while (0)
|
|
|
|
#define MR_complexity_call_proc(procnum, slot) \
|
|
do { \
|
|
slot = MR_complexity_call_func(procnum); \
|
|
} while (0)
|
|
|
|
#define MR_complexity_exit_proc(procnum, slot) \
|
|
do { \
|
|
MR_complexity_leave_func(procnum, slot); \
|
|
} while (0)
|
|
|
|
#define MR_complexity_fail_proc(procnum, slot) \
|
|
do { \
|
|
MR_complexity_leave_func(procnum, slot); \
|
|
} while (0)
|
|
|
|
#define MR_complexity_redo_proc(procnum, slot) \
|
|
do { \
|
|
MR_complexity_redo_func(procnum, slot); \
|
|
} while (0)
|
|
|
|
extern MR_Unsigned MR_term_size(MR_TypeInfo type_info, MR_Word term);
|
|
|
|
extern void MR_init_complexity_proc(int proc_num, const char *fullname,
|
|
int num_profiled_args, int num_args,
|
|
MR_ComplexityArgInfo *arg_infos);
|
|
extern void MR_check_complexity_init(void);
|
|
|
|
extern void MR_write_complexity_procs(void);
|
|
|
|
extern MR_ComplexityIsActive
|
|
MR_complexity_is_active_func(int num_procs, int proc_num,
|
|
const char *name, int num_inputs);
|
|
extern int MR_complexity_call_func(int procnum);
|
|
extern void MR_complexity_leave_func(int procnum, int slot);
|
|
extern void MR_complexity_redo_func(int procnum, int slot);
|
|
extern void MR_complexity_fill_size_slot(MR_ComplexityProc *proc, int slot,
|
|
int num_input_args, int argnum, int size);
|
|
|
|
#else /* MR_RECORD_TERM_SIZES */
|
|
|
|
/*
|
|
** Term sizes are not meaningful if MR_RECORD_TERM_SIZES is not defined.
|
|
** This macro, and others in mercury_heap.h, allows us to write code to
|
|
** compute term sizes without worrying about whether MR_RECORD_TERM_SIZES
|
|
** is defined or not.
|
|
*/
|
|
|
|
#define MR_term_size(type_info, term) 0
|
|
|
|
#endif /* MR_RECORD_TERM_SIZES */
|
|
|
|
#endif /* MR_MERCURY_TERM_SIZE_H */
|
|
|
|
#define MR_COMPLEXITY_SLOTS_PER_CHUNK 1024
|