Files
mercury/compiler/stdlabel.m
Zoltan Somogyi b48eaf8073 Add a first draft of the code generator support for region based memory
Estimated hours taken: 30
Branches: main

Add a first draft of the code generator support for region based memory
management. It is known to be incomplete; the missing parts are marked by XXXs.
It may also be buggy; it will be tested after Quan adds the runtime support,
i.e. the C macros invoked by the new LLDS instructions. However, the changes
in this diff shouldn't affect non-RBMM operations.

compiler/llds.m:
	Add five new LLDS instructions. Four are specific to RBMM operations.
	RBMM embeds three new stacks in compiler-reserved temp slots in
	procedure's usual Mercury stack frames, and the new LLDS instructions
	respectively

	(i)   push those stack frames onto their respective stacks,
	(ii)  fill some variable parts of those stack frames,
	(iii) fill fixed slots of those stack frames, and
	(iv)  use the contents of and/or pop those stack frames.

	(The pushing and popping affect only the new embedded stacks, not the
	usual Mercury stacks.)

	The last instruction is a new variant of the old assign instruction.
	It has identical semantics, but restricts optimization. An assign

	(a) can be deleted if its target lval is not used, and
	(b) its target lval can be changed (e.g. to a temp register) as long as
	    all the later instructions referring to that lval are changed to
	    use the new lval instead.

	Neither is permitted for the new keep_assign instruction. This is
	required because in an earlier draft we used it to assign to stack
	variables (parts of the embedded stack frames) that aren't explicitly
	referred to in later LLDS code, but are nevertheless implicitly
	referred to by some instructions (specifically iv above). We now
	use a specialized instruction (iii above) for this (since the macro
	it invokes can refer to C structure names, this makes it easier to
	keep the compiler in sync with the runtime system), but given that
	keep_assign is already implemented, may be useful later and shouldn't
	cause appreciable slowdown of the compiler, this diff keeps it.

	Extend the type that describe the contents of lvals to allow it
	to describe the new kinds of things we can now store in them.

	Add types to manage and describe the new embedded stack frames,
	and some utility functions. Change some existing utility functions
	to make all this more conceptually consistent.

compiler/ite_gen.m:
	Surround the code we generate for the condition of if-then-elses
	with the code required to ensure that regions that are logically
	removed in the condition aren't physically destroyed until we know
	that the condition succeeds (since the region may still be needed
	in the else branch), and to make sure that if the condition fails,
	all the memory allocated since the entry into the condition is
	reclaimed instantly.

compiler/disj_gen.m:
	Surround the code we generate for disjunctions with the code required
	to ensure that regions that are logically removed in a disjunct
	aren't physically destroyed if a later disjunct needs them, and to
	make sure that at entry into a non-first disjunct, all the memory
	allocated since the entry into the disjunction is reclaimed instantly.

compiler/commit_gen.m:
compiler/code_info.m:
	The protection against destruction offered by a disjunction disappears
	when a commit cuts away all later alternatives in that disjunct, so we
	must undo that protection. We therefore surround the scope of a commit
	goal with goal that achieves that objective.

	Add some new utility predicates to code_info. Remove some old utility
	functions that are now in llds.m.

compiler/continuation_info.m:
	Extend the type that describe the contents of stack slots to allow it
	to describe the new kinds of things we can now store in them.

	Rename the function symbols of that type to eliminate some ambiguities.

compiler/code_gen.m:
	Remember the set of variables live at the start of the goal
	(before the pre_goal_update updates it), since the region operations
	need to know this.

	Leave the lookup of AddTrailOps (and now AddRegionOps) to the specific
	kinds of goals that need it (the most frequent goals, unify and call,
	do not). Make both AddTrailOps and AddRegionOps use a self-explanatory
	type instead of a boolean.

compiler/lookup_switch.m:
	Conform to the change to AddTrailOps.

	Fix some misleading variable names.

compiler/options.m:
	Add some options to control the number of stack slots needed for
	various purposes. These have to correspond to the sizes of some C
	structures in the runtime system. Eventually these will be constants,
	but it is handy to keep them easily changeable while the C data
	structures are still being worked on.

	Add an option for optimizing away region ops whereever possible.
	The intention is that these should be on all the time, but we
	will want to turn them off for benchmarking.

compiler/dupelim.m:
compiler/dupproc.m:
compiler/exprn_aux.m:
compiler/frameopt.m:
compiler/global_data.m:
compiler/jumpopt.m:
compiler/livemap.m:
compiler/llds_out.m:
compiler/llds_to_x86_64.m:
compiler/middle_rec.m:
compiler/opt_debug.m:
compiler/opt_util.m:
compiler/par_conj_gen.m:
compiler/reassign.m:
compiler/stack_layout.m:
compiler/stdlabel.m:
compiler/trace_gen.m:
compiler/use_local_vars.m:
	Conform to the changes above, which mostly means handling the new
	LLDS instructions.

	In some cases, factor out existing common code, turn if-then-elses
	into switches, group common cases in switches, rationalize argument
	orders or variable names, and/or put code in execution order.

	In reassign.m, fix some old oversights that could (in some unlikely
	cases) cause bugs in the generated code.

compiler/pragma_c_gen.m:
	Exploit the capabilities of code_info.m.

compiler/prog_type.m:
	Add a utility predicate.
2007-07-31 01:56:41 +00:00

94 lines
3.4 KiB
Mathematica

%-----------------------------------------------------------------------------%
% vim: ft=mercury ts=4 sw=4 et
%-----------------------------------------------------------------------------%
% Copyright (C) 2006-2007 The University of Melbourne.
% This file may only be copied under the terms of the GNU General
% Public License - see the file COPYING in the Mercury distribution.
%-----------------------------------------------------------------------------%
%
% File: stdlabel.m.
% Author: zs.
%
% Module to rename (actually renumber) all the labels in a procedure so that
% the label numbers are in a dense ascending sequence.
%
% This transformation leaves the performance of the program unaffected.
% However, one can use it make the effect of an optimization much more readily
% apparent. The idea is that enabling --standardize-labels when compiling
% a program both with and without a new or modified optimization cleans up
% the output of the diff between the two sets of resulting .c files, by
% eliminating incidental differences in labels that could otherwise overwhelm
% the real differences made by the optimization.
%
%-----------------------------------------------------------------------------%
:- module ll_backend.stdlabel.
:- interface.
:- import_module ll_backend.llds.
:- import_module counter.
:- import_module list.
%-----------------------------------------------------------------------------%
:- pred standardize_labels(list(instruction)::in, list(instruction)::out,
counter::in, counter::out) is det.
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
:- implementation.
:- import_module libs.compiler_util.
:- import_module ll_backend.opt_util.
:- import_module mdbcomp.prim_data.
:- import_module bool.
:- import_module map.
:- import_module pair.
:- import_module svmap.
%-----------------------------------------------------------------------------%
standardize_labels(Instrs0, Instrs, _, !:ProcCounter) :-
opt_util.get_prologue(Instrs0, LabelInstr, Comments, Instrs1),
(
LabelInstr = llds_instr(label(FirstLabel), _),
FirstLabel = entry_label(_, ProcLabel)
->
build_std_map(Instrs1, ProcLabel, counter.init(1), !:ProcCounter,
map.init, Map),
replace_labels_instruction_list(Instrs1, Instrs2, Map, yes, yes),
Instrs = [LabelInstr | Comments] ++ Instrs2
;
unexpected(this_file, "standardize_labels: no proc_label")
).
%-----------------------------------------------------------------------------%
:- pred build_std_map(list(instruction)::in, proc_label::in,
counter::in, counter::out,
map(label, label)::in, map(label, label)::out) is det.
build_std_map([], _, !Counter, !Map).
build_std_map([Instr | Instrs], ProcLabel, !Counter, !Map) :-
( Instr = llds_instr(label(Label), _) ->
counter.allocate(LabelNum, !Counter),
StdLabel = internal_label(LabelNum, ProcLabel),
svmap.det_insert(Label, StdLabel, !Map)
;
true
),
build_std_map(Instrs, ProcLabel, !Counter, !Map).
%-----------------------------------------------------------------------------%
:- func this_file = string.
this_file = "stdlabel.m".
%-----------------------------------------------------------------------------%
:- end_module stdlabel.
%-----------------------------------------------------------------------------%