Files
mercury/tests/debugger/tailrec1.data
Zoltan Somogyi 53286dd4bf Implement a new compiler option, --exec-trace-tail-rec, that preserves direct
Estimated hours taken: 30
Branches: main

Implement a new compiler option, --exec-trace-tail-rec, that preserves direct
tail recursion in det and semidet procedures even when debugging is enabled.
This should allow the debugging of programs that previously ran out of stack.

The problem arose because even a directly tail-recursive call had some code
after it: the code for the EXIT event, like this:

	p:
		incr_sp
		fill in the usual debug slots
		CALL EVENT
		...
		/* tail call */
		move arguments to registers as usual
		call p, return to p_ret
	p_ret:
		/* code to move output arguments to right registers is empty */
		EXIT EVENT
		decr_sp
		return

If the new option is enabled, the compiler will now generate code like this:

	p:
		incr_sp
		fill in the usual debug slots
		fill in new "stack frame reuse count" slot with 0
		CALL EVENT
	p_1:
		...
		/* tail call */
		move arguments to registers as usual
		update the usual debug slots
		increment the "stack frame reuse count" slot
		TAILCALL EVENT
		goto p_1

The new TAIL event takes place in the caller's stack frame, so that the local
variables of the caller are available. This includes the arguments of the
recursive call (though if they are unnamed variables, the debugger will not
show them). The TAIL event serves as a replacement for the CALL event
of the recursive invocation.

compiler/options.m:
	Add the new option.

compiler/handle_options.m:
	Handle an implication of the new option: the declarative debugger
	does not (yet) understand TAIL events.

compiler/mark_tail_calls.m:
	New module to mark directly tail recursive calls and the procedures
	containing them as such.

compiler/hlds.m:
compiler/notes/compiler_design.html:
	Mention the new module.

compiler/mercury_compile.m:
	Invoke the new module when the new option asks us to.

compiler/hlds_goal.m:
	Add the feature used to mark tail recursive calls for the debugger.
	Rename an existing feature with a similar but not identical purpose
	to avoid possible confusion.

compiler/hlds_pred.m:
	Add a field to proc_infos that says whether the procedure contains
	tail recursive calls.

	Minor style improvements.

compiler/passes_aux.m:
	Minor change to accommodate the needs of the new module.

compiler/code_info.m:
	Transmit the information from mark_tail_calls to the code generator.

compiler/call_gen.m:
	Implement the new option.

compiler/trace_gen.m:
	Reserve the extra slot needed for the new option.

	Switch to state variable notation in the code that does the slot
	allocation, since this is less error-prone than the previous approach.

compiler/layout.m:
compiler/layout_out.m:
compiler/stack_layout.m:
	Remember what stack slot holds the stack frame reuse counter,
	for transmission to the runtime system.

compiler/proc_gen.m:
	Add the new label needed for tail recursion.

	Put the arguments of some procedures into a more logical order.

compiler/deep_profiling.m:
compiler/deforest.m:
compiler/saved_vars.m:
compiler/table_gen.m:
	Conform to the changes above.

compiler/trace_params.m:
mdbcomp/prim_data.m:
runtime/mercury_trace_base.[ch]:
	Add the new event type.

	Convert mercury_trace_base.h to four-space indentation.

runtime/mercury_stack_layout.h:
	Add a field to the execution trace information we have for each
	procedure that gives the number of the stack slot (if any) that holds
	the stack frame reuse counter. Add a macro to get the value in the
	counter.

	Convert this header file to four-space indentation.

runtime/mercury_stack_trace.[ch]:
	When walking the stack, we now have to be prepared to encounter stack
	frames that have been reused. Modify the algorithms in this module
	accordingly, and modify the interfaces of the exported functions
	to allow the functions' callers to behave accordingly as well.

	Group the information we gather about stack frame for printing into
	one structure, and document it.

	Convert the header to four-space indentation.

library/exception.m:
mdbcomp/trace_counts.m:
	Conform to the changes above.

	In trace_counts.m, fix an apparent cut-and-paste error (that hasn't
	caused any test case failures yet).

trace/mercury_trace.c:
	Modify the implementation of the "next" and "finish" commands
	to accommodate the possibility that the procedure at the selected
	depth may have had its stack frame reused. In such cases

tests/debugger/tailrec1.{m,inp,exp,data}:
	A new test case to check the handling of tail recursive procedures.
2008-11-25 07:46:57 +00:00

7 lines
24 B
Plaintext