Implement conditional structure reuse for LLDS backends using Boehm GC.

Estimated hours taken: 15
Branches: main

Implement conditional structure reuse for LLDS backends using Boehm GC.
Verify at run time, just before reusing a dead cell, that the base address of
the cell was dynamically allocated.  If not, fall back to allocating a new
object on the heap.  This makes structure reuse safe without having to disable
static data.

In the simple case, the generated C code looks like this:

    MR_tag_reuse_or_alloc_heap(dest, tag, addr_of_reuse_cell,
	MR_tag_alloc_heap(dest, tag, count));
    ...assign fields...

If some of the fields are known to already have the correct values then we can
avoid assigning them.  We need to handle both reuse and non-reuse cases:

    MR_tag_reuse_or_alloc_heap_flag(dest, flag_reg, tag, addr_of_reuse_cell,
	MR_tag_alloc_heap(dest, tag, count));
    /* flag_reg is non-zero iff reuse is possible */
    if (flag_reg) {
	goto skip;
    }
    ...assign fields which don't need to be assigned in reuse case...
  skip:
    ...assign fields which must be assigned in both cases...

It may be that it is not worth the branch to avoid assigning known fields.
I haven't yet checked.


compiler/llds.m:
	Extend the `incr_hp' instruction to hold information for structure
	reuse.

compiler/code_info.m:
	Generate a label and pass it to `var_locn_assign_cell_to_var'.  The
	label is only needed for the type of code shown above.

compiler/var_locn.m:
	Change the code generated for cell reuse.  Rather than assigning the
	dead cell's address to the target lval unconditionally, generate an
	`incr_hp' instruction with the reuse field filled in.

	Generate code that avoids filling in known fields if possible.

	Abort if we see `construct_statically(_)' in
	`var_locn_assign_dynamic_cell_to_var'.

runtime/mercury_heap.h:
runtime/mercury_conf_param.h:
	Add a macro to check if an address is between
	`GC_least_plausible_heap_addr' and `GC_greatest_plausible_heap_addr',
	which are therefore in the heap.

	Add macros to conditionally reuse a cell or otherwise fall back to
	allocating a new object.

	Make it possible to revert to unconditional structure reuse by
	defining the C macro `MR_UNCONDITIONAL_STRUCTURE_REUSE'.

compiler/llds_out.m:
	Call the new macros in `mercury_heap.h' for `incr_hp' instructions
	with reuse information filled in.

compiler/dupelim.m:
compiler/dupproc.m:
compiler/exprn_aux.m:
compiler/global_data.m:
compiler/jumpopt.m:
compiler/livemap.m:
compiler/llds_to_x86_64.m:
compiler/middle_rec.m:
compiler/opt_debug.m:
compiler/opt_util.m:
compiler/reassign.m:
compiler/unify_gen.m:
compiler/use_local_vars.m:
	Conform to the changed `incr_hp' instruction.
This commit is contained in:
Peter Wang
2008-02-11 03:56:13 +00:00
parent 5aefec444b
commit e0ff2b1903
19 changed files with 746 additions and 319 deletions

View File

@@ -793,7 +793,7 @@ dump_instr(ProcLabel, PrintComments, Instr) = Str :-
Str = "restore_maxfr(" ++ dump_lval(yes(ProcLabel), Lval) ++ ")"
;
Instr = incr_hp(Lval, MaybeTag, MaybeOffset, Size, _, MayUseAtomic,
MaybeRegionRval),
MaybeRegionRval, MaybeReuse),
(
MaybeTag = no,
T_str = "no"
@@ -815,10 +815,27 @@ dump_instr(ProcLabel, PrintComments, Instr) = Str :-
MaybeRegionRval = yes(RegionRval),
Region_str = dump_rval(no, RegionRval)
),
(
MaybeReuse = no_llds_reuse,
Reuse_str = "no",
Flag_str = "no"
;
MaybeReuse = llds_reuse(ReuseRval, MaybeFlagLval),
Reuse_str = dump_rval(no, ReuseRval),
(
MaybeFlagLval = no,
Flag_str = "no"
;
MaybeFlagLval = yes(FlagLval),
Flag_str = dump_lval(yes(ProcLabel), FlagLval)
)
),
Str = "incr_hp(" ++ dump_lval(yes(ProcLabel), Lval) ++ ", " ++
T_str ++ ", " ++ O_str ++ ", " ++
dump_rval(yes(ProcLabel), Size) ++ ", " ++
dump_may_use_atomic(MayUseAtomic) ++ ", " ++ Region_str ++ ")"
dump_may_use_atomic(MayUseAtomic) ++ ", " ++
Region_str ++ ", " ++
Reuse_str ++ ", " ++ Flag_str ++ ")"
;
Instr = mark_hp(Lval),
Str = "mark_hp(" ++ dump_lval(yes(ProcLabel), Lval) ++ ")"