mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-17 06:47:17 +00:00
Estimated hours taken: 20 Branches: main Implement a second version of the subterm dependency tracking algorithm that uses the following heuristic to speed things up: If the subterm is being tracked through an output argument, and there is an input argument with the same name as the output argumnet, except for a numerical suffix, then the new algorithm will check if the subterm appears in the same position in the input argument. If it does then it will continue tracking the subterm in the input argument, thus bypassing the subtree rooted at the call. Since dereferencing a subterm in a large structure can be expensive, the new algorithm will only try to bypass calls to procedures it has not tried to bypass before. The set of procedures it has tried is reset each time a new explicit subtree or supertree is generated. Add a `track' command that behaves in the same way as `mark', except that it doesn't assert that the node is erroneous or inadmissible. Add an optional `--accurate' argument which tells the declarative debugger to use the original tracking algorithm. We still allow the old algorithm to be used, because there are situations where the new algorithm could find the wrong call (i.e. when a subterm appears in the same position in an input argument, but the subterm in the output argument is actually bound by a descendent call -- it just happens to be bound to the same value as the input subterm). doc/user_guide.texi: Change the documentation accordingly. browser/browse.m: browser/browser_info.m: browser/parse.m: browser/declarative_user.m: Add a `track' command that does the same thing as a `mark' command, except it doesn't assert the atom to be erroneous or inadmissible. Allow an `--accurate' or `-a' argument for the `mark' and `track' commands which indicates that the old subterm dependency tracking algorithm should be used. Pass information about tracked subterms to the declarative debugger. Do not allow a whole atom to be tracked or marked as this doesn't make sense. browser/declarative_analyser.m: browser/declarative_debugger.m: browser/declarative_edt.m: browser/declarative_oracle.m: Implement the new tracking algorithm. browser/term_rep.m: Add a predicate to dereference a subterm in another term. mdbcomp/rtti_access.m: Add a predicate to find a candidate input argument on which to apply the new heuristic. runtime/Mmakefile: runtime/mercury_layout_util.h: runtime/mercury_stack_layout.h: trace/mercury_trace_vars.c: trace/mercury_trace_vars.h: Move the function for finding the name of a variable to the runtime, so that it can be called from the declarative debugger. tests/debugger/declarative/Mmakefile: tests/debugger/declarative/nodescend_tracking.exp: tests/debugger/declarative/nodescend_tracking.inp: tests/debugger/declarative/nodescend_tracking.m: Test the new heuristic. tests/debugger/declarative/closure_dependency.inp2: tests/debugger/declarative/closure_dependency.exp2: Expect an error message when marking a whole atom.
185 lines
8.3 KiB
C
185 lines
8.3 KiB
C
/*
|
|
** vim:sw=4 ts=4 expandtab
|
|
*/
|
|
/*
|
|
** Copyright (C) 1998-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.
|
|
*/
|
|
|
|
#ifndef MERCURY_LAYOUT_UTIL_H
|
|
#define MERCURY_LAYOUT_UTIL_H
|
|
|
|
#include "mercury_std.h"
|
|
#include "mercury_types.h" /* for MR_Word, etc. */
|
|
#include "mercury_stack_layout.h" /* for MR_Label_Layout, etc. */
|
|
#include "mercury_type_info.h" /* for MR_TypeInfoParams, etc. */
|
|
#include "mercury_ho_call.h" /* for MR_Closure */
|
|
|
|
/*
|
|
** These two functions copy the register state to and from the provided
|
|
** saved_regs array, which should have room for MR_MAX_FAKE_REG MR_Words.
|
|
*/
|
|
|
|
extern void MR_copy_regs_to_saved_regs(int max_mr_num, MR_Word *saved_regs);
|
|
extern void MR_copy_saved_regs_to_regs(int max_mr_num, MR_Word *saved_regs);
|
|
|
|
/*
|
|
** A MR_Label_Layout describes the variables that are live at a given
|
|
** program point. Some of the types of these variables may contain type
|
|
** variables. Since the values of those type variables are not known until
|
|
** runtime, the MR_Label_Layout cannot include full typeinfos for the
|
|
** variables. Instead, it contains pseudo-typeinfos, in which some parts
|
|
** of some typeinfo structures may contain an indication "this data is
|
|
** not available at compile time, but at runtime it will be in this location".
|
|
**
|
|
** MR_materialize_type_params takes as input a MR_Label_Layout structure.
|
|
** It returns a vector of typeinfos which has one entry for each
|
|
** type variable in the MR_Label_Layout structure, with this typeinfo
|
|
** being the value of the corresponding type variable.
|
|
** Since type variable numbers start at one, the element of this array at
|
|
** index zero will not have a type_info in it. We store a dummy type_ctor_info
|
|
** there, so that the array will itself look like a typeinfo.
|
|
**
|
|
** The vector returned by MR_materialize_type_params is from MR_malloc;
|
|
** it should be MR_freed after last use.
|
|
**
|
|
** MR_materialize_type_params looks up locations in the current
|
|
** environment, as indicated by the set of saved registers (including MR_sp
|
|
** and MR_curfr). MR_materialize_typeinfos_base does the same job but
|
|
** assumes the environment is given by the given values of MR_sp and MR_curfr,
|
|
** and does not assume that the registers have valid contents unless saved_regs
|
|
** is non-null.
|
|
**
|
|
** MR_materialize_closure_type_params does much the same except that
|
|
** it takes an MR_Closure rather than an MR_Label_Layout,
|
|
** and it gets the type_infos from a closure using the closure_layout,
|
|
** rather than getting them from the registers/stacks using a label_layout.
|
|
**
|
|
** MR_materialize_typeclass_info_type_params is the same as
|
|
** MR_materialize_closure_type_params except that it takes
|
|
** a typeclass_info and a closure layout (for the type class method)
|
|
** and it gets the type_infos from the typeclass_info.
|
|
*/
|
|
|
|
extern MR_TypeInfoParams MR_materialize_type_params(
|
|
const MR_Label_Layout *label_layout,
|
|
MR_Word *saved_regs);
|
|
extern MR_TypeInfoParams MR_materialize_type_params_base(
|
|
const MR_Label_Layout *label_layout,
|
|
MR_Word *saved_regs,
|
|
MR_Word *base_sp, MR_Word *base_curfr);
|
|
extern MR_TypeInfoParams MR_materialize_closure_type_params(
|
|
MR_Closure *closure);
|
|
extern MR_TypeInfoParams MR_materialize_typeclass_info_type_params(
|
|
MR_Word typeclass_info,
|
|
MR_Closure_Layout *closure_layout);
|
|
extern MR_TypeInfoParams MR_materialize_answer_block_type_params(
|
|
const MR_Type_Param_Locns *tvar_locns,
|
|
MR_Word *answer_block, int block_size);
|
|
|
|
/*
|
|
** If the given encoded location refers to a register, return its number.
|
|
** If it does not, return -1.
|
|
*/
|
|
|
|
extern int MR_get_register_number_long(MR_Long_Lval locn);
|
|
extern int MR_get_register_number_short(MR_Short_Lval locn);
|
|
|
|
/*
|
|
** Given an location either in a long or short form, return the value
|
|
** at that location if possible. *succeeded will say whether the attempt
|
|
** was successful.
|
|
**
|
|
** MR_lookup_{long,short}_lval looks up locations in the current environment,
|
|
** as indicated by the set of saved registers (including MR_sp and MR_curfr).
|
|
** MR_lookup_{long,short}_lval_base does the same job but assumes the
|
|
** environment is given by the given values of MR_sp and MR_curfr, and does
|
|
** not assume that the registers have valid contents unless saved_regs is
|
|
** non-null.
|
|
*/
|
|
|
|
extern MR_Word MR_lookup_long_lval(MR_Long_Lval locn,
|
|
MR_Word *saved_regs, MR_bool *succeeded);
|
|
extern MR_Word MR_lookup_long_lval_base(MR_Long_Lval locn,
|
|
MR_Word *saved_regs, MR_Word *base_sp,
|
|
MR_Word *base_curfr, MR_bool *succeeded);
|
|
extern MR_Word MR_lookup_short_lval(MR_Short_Lval locn,
|
|
MR_Word *saved_regs, MR_bool *succeeded);
|
|
extern MR_Word MR_lookup_short_lval_base(MR_Short_Lval locn,
|
|
MR_Word *saved_regs, MR_Word *base_sp,
|
|
MR_Word *base_curfr, MR_bool *succeeded);
|
|
|
|
/*
|
|
** Given information about the location of a variable (var) and a vector giving
|
|
** the typeinfos corresponding to the type variables that may occur in
|
|
** the type of that variable (type_params), try to return the value of the
|
|
** variable in *value and the typeinfo describing its type in *type_info.
|
|
** *succeeded will say whether the attempt was successful.
|
|
**
|
|
** The type_params array should have the same format as the array returned
|
|
** by MR_materialize_type_params.
|
|
**
|
|
** MR_get_type_and_value looks up locations in the current environment,
|
|
** as indicated by the set of saved registers (including MR_sp and MR_curfr).
|
|
** MR_get_type_and_value_base does the same job but assumes the
|
|
** environment is given by the given values of MR_sp and MR_curfr, and does
|
|
** not assume that the registers have valid contents unless saved_regs is
|
|
** non-null.
|
|
**
|
|
** MR_get_type and MR_get_type_base are similar but do not
|
|
** return the value.
|
|
**
|
|
** All of these functions may need to allocate memory (to hold the
|
|
** type_infos that they return); any memory that they allocate will
|
|
** be allocated on the Mercury heap.
|
|
*/
|
|
|
|
extern MR_bool MR_get_type_and_value(const MR_Label_Layout *label_layout,
|
|
int var, MR_Word *saved_regs, MR_TypeInfo *type_params,
|
|
MR_TypeInfo *type_info, MR_Word *value);
|
|
extern MR_bool MR_get_type_and_value_base(const MR_Label_Layout *label_layout,
|
|
int var, MR_Word *saved_regs,
|
|
MR_Word *base_sp, MR_Word *base_curfr,
|
|
MR_TypeInfo *type_params, MR_TypeInfo *type_info,
|
|
MR_Word *value);
|
|
extern MR_bool MR_get_type(const MR_Label_Layout *label_layout, int var,
|
|
MR_Word *saved_regs, MR_TypeInfo *type_params,
|
|
MR_TypeInfo *type_info);
|
|
extern MR_bool MR_get_type_base(const MR_Label_Layout *label_layout, int var,
|
|
MR_Word *saved_regs, MR_Word *base_sp,
|
|
MR_Word *base_curfr, MR_TypeInfo *type_params,
|
|
MR_TypeInfo *type_info);
|
|
|
|
/*
|
|
** MR_write_variable: write a variable to stdout.
|
|
** This uses the fake_reg copies of the registers,
|
|
** and it may also clobber the real registers.
|
|
*/
|
|
|
|
extern void MR_write_variable(MR_TypeInfo type_info, MR_Word value);
|
|
|
|
/*
|
|
** Return the name of a procedure specified by the given proc layout in three
|
|
** pieces: the name of the procedure in *proc_name_ptr, its arity in
|
|
** *arity_ptr, and a boolean that is true iff procedure is a function
|
|
** in *is_func_ptr,
|
|
*/
|
|
|
|
extern void MR_generate_proc_name_from_layout(const MR_Proc_Layout
|
|
*proc_layout, MR_ConstString *proc_name_ptr,
|
|
int *arity_ptr, MR_Word *is_func_ptr);
|
|
|
|
/*
|
|
** Return the user-visible arity of the procedure (including the return value
|
|
** for functions), the number of typeinfo and/or typeclassinfo arguments added
|
|
** by the compiler, and an indication whether the procedure is from a predicate
|
|
** or a function.
|
|
*/
|
|
|
|
extern void MR_proc_id_arity_addedargs_predfunc(const MR_Proc_Layout *proc,
|
|
int *arity_ptr, int *num_added_args_ptr,
|
|
MR_PredFunc *pred_or_func_ptr);
|
|
|
|
#endif /* MERCURY_LAYOUT_UTIL_H */
|