[m-dev.] for review: --use-local-vars

Zoltan Somogyi zs at cs.mu.OZ.AU
Mon Apr 23 15:01:12 AEST 2001


On 09-Mar-2001, Fergus Henderson <fjh at cs.mu.OZ.AU> wrote:
> Otherwise, that looks fine.

Here is the interdiff of the changes I made in response to your comments.
I will commit this tomorrow unless I hear some objection by then.

Zoltan.

--- compiler/exprn_aux.m
+++ compiler/exprn_aux.m
@@ -44,0 +45,9 @@
+	% exprn_aux__substitute_lval_in_instr(OldLval, NewLval, Instr0, Instr,
+	% SubstCount0, SubstCount): substitute all occurrences of OldLval in
+	% Instr0 with NewLval, yielding Instr. Return the number of
+	% substitutions performed as the difference between SubstCount0 and
+	% SubstCount.
+	%
+	% The other exprn_aux__substitute_lval_in_* predicates are similar,
+	% although many do not return substitution counts.
+
@@ -224 +233 @@
-		Lval0 = field(_, Rval0, Rval1)
+		Lval0 = field(_MaybeTag, Rval0, Rval1)
@@ -268 +277 @@
-			Rval0 = unop(_, Rval1),
+			Rval0 = unop(_Unop, Rval1),
@@ -271 +280 @@
-			Rval0 = binop(_, Rval1, Rval2),
+			Rval0 = binop(_Binop, Rval1, Rval2),
@@ -284 +293 @@
-exprn_aux__lval_contains_rval(field(_, Rval0, Rval1), Rval) :-
+exprn_aux__lval_contains_rval(field(_MaybeTag, Rval0, Rval1), Rval) :-
@@ -309 +318 @@
-exprn_aux__vars_in_rval(unop(_, Rval), Vars) :-
+exprn_aux__vars_in_rval(unop(_Unop, Rval), Vars) :-
@@ -311 +320 @@
-exprn_aux__vars_in_rval(binop(_, Rval0, Rval1), Vars) :-
+exprn_aux__vars_in_rval(binop(_Binop, Rval0, Rval1), Vars) :-
@@ -318,2 +327,2 @@
-exprn_aux__vars_in_lval(reg(_, _), []).
-exprn_aux__vars_in_lval(temp(_, _), []).
+exprn_aux__vars_in_lval(reg(_Type, _RegNum), []).
+exprn_aux__vars_in_lval(temp(_Type, _TmpNum), []).
@@ -325,2 +334,2 @@
-exprn_aux__vars_in_lval(stackvar(_), []).
-exprn_aux__vars_in_lval(framevar(_), []).
+exprn_aux__vars_in_lval(stackvar(_SlotNum), []).
+exprn_aux__vars_in_lval(framevar(_SlotNum), []).
@@ -337 +346 @@
-exprn_aux__vars_in_lval(field(_, Rval0, Rval1), Vars) :-
+exprn_aux__vars_in_lval(field(_MaybeTag, Rval0, Rval1), Vars) :-
@@ -347,3 +356,3 @@
-exprn_aux__vars_in_mem_ref(stackvar_ref(_), []).
-exprn_aux__vars_in_mem_ref(framevar_ref(_), []).
-exprn_aux__vars_in_mem_ref(heap_ref(Rval, _, _), Vars) :-
+exprn_aux__vars_in_mem_ref(stackvar_ref(_SlotNum), []).
+exprn_aux__vars_in_mem_ref(framevar_ref(_SlotNum), []).
+exprn_aux__vars_in_mem_ref(heap_ref(Rval, _Tag, _FieldNum), Vars) :-
@@ -369,3 +377,0 @@
-:- pred exprn_aux__substitute_lval_in_lval(lval::in, lval::in,
-	lval::in, lval::out, int::in, int::out) is det.
-
@@ -373,5 +379,2 @@
-	exprn_aux__substitute_lval_in_lval(OldLval, NewLval, Lval0, Lval,
-		0, _).
-
-:- pred exprn_aux__substitute_lval_in_rval(lval::in, lval::in,
-	rval::in, rval::out, int::in, int::out) is det.
+	exprn_aux__substitute_lval_in_lval_count(OldLval, NewLval, Lval0, Lval,
+		0, _SubstCount).
@@ -380,2 +383,2 @@
-	exprn_aux__substitute_lval_in_rval(OldLval, NewLval, Rval0, Rval,
-		0, _).
+	exprn_aux__substitute_lval_in_rval_count(OldLval, NewLval, Rval0, Rval,
+		0, _SubstCount).
@@ -395 +398 @@
-		Uinstr0 = comment(_),
+		Uinstr0 = comment(_Comment),
@@ -402 +405,2 @@
-			exprn_aux__substitute_lval_in_lval(OldLval, NewLval),
+			exprn_aux__substitute_lval_in_lval_count(OldLval,
+				NewLval),
@@ -414 +418 @@
-		exprn_aux__substitute_lval_in_lval(OldLval, NewLval,
+		exprn_aux__substitute_lval_in_lval_count(OldLval, NewLval,
@@ -416 +420 @@
-		exprn_aux__substitute_lval_in_rval(OldLval, NewLval,
+		exprn_aux__substitute_lval_in_rval_count(OldLval, NewLval,
@@ -437 +441 @@
-		exprn_aux__substitute_lval_in_rval(OldLval, NewLval,
+		exprn_aux__substitute_lval_in_rval_count(OldLval, NewLval,
@@ -447 +451 @@
-		exprn_aux__substitute_lval_in_rval(OldLval, NewLval,
+		exprn_aux__substitute_lval_in_rval_count(OldLval, NewLval,
@@ -452 +456 @@
-		exprn_aux__substitute_lval_in_lval(OldLval, NewLval,
+		exprn_aux__substitute_lval_in_lval_count(OldLval, NewLval,
@@ -454 +458 @@
-		exprn_aux__substitute_lval_in_rval(OldLval, NewLval,
+		exprn_aux__substitute_lval_in_rval_count(OldLval, NewLval,
@@ -459 +463 @@
-		exprn_aux__substitute_lval_in_lval(OldLval, NewLval,
+		exprn_aux__substitute_lval_in_lval_count(OldLval, NewLval,
@@ -464 +468 @@
-		exprn_aux__substitute_lval_in_rval(OldLval, NewLval,
+		exprn_aux__substitute_lval_in_rval_count(OldLval, NewLval,
@@ -469 +473 @@
-		exprn_aux__substitute_lval_in_rval(OldLval, NewLval,
+		exprn_aux__substitute_lval_in_rval_count(OldLval, NewLval,
@@ -474 +478 @@
-		exprn_aux__substitute_lval_in_lval(OldLval, NewLval,
+		exprn_aux__substitute_lval_in_lval_count(OldLval, NewLval,
@@ -479 +483 @@
-		exprn_aux__substitute_lval_in_rval(OldLval, NewLval,
+		exprn_aux__substitute_lval_in_rval_count(OldLval, NewLval,
@@ -492 +496 @@
-		exprn_aux__substitute_lval_in_lval(OldLval, NewLval,
+		exprn_aux__substitute_lval_in_lval_count(OldLval, NewLval,
@@ -497 +501 @@
-		exprn_aux__substitute_lval_in_rval(OldLval, NewLval,
+		exprn_aux__substitute_lval_in_rval_count(OldLval, NewLval,
@@ -525 +529 @@
-		exprn_aux__substitute_lval_in_lval(OldLval, NewLval,
+		exprn_aux__substitute_lval_in_lval_count(OldLval, NewLval,
@@ -534 +538 @@
-		exprn_aux__substitute_lval_in_lval(OldLval, NewLval,
+		exprn_aux__substitute_lval_in_lval_count(OldLval, NewLval,
@@ -539 +543 @@
-		exprn_aux__substitute_lval_in_lval(OldLval, NewLval,
+		exprn_aux__substitute_lval_in_lval_count(OldLval, NewLval,
@@ -583 +587 @@
-exprn_aux__substitute_lval_in_live_lval_info(_, _,
+exprn_aux__substitute_lval_in_live_lval_info(_OldLval, _NewLval,
@@ -588 +592,2 @@
-	list__map_foldl(exprn_aux__substitute_lval_in_lval(OldLval, NewLval),
+	list__map_foldl(
+		exprn_aux__substitute_lval_in_lval_count(OldLval, NewLval),
@@ -598 +603 @@
-	exprn_aux__substitute_lval_in_rval(OldLval, NewLval, Rval0, Rval,
+	exprn_aux__substitute_lval_in_rval_count(OldLval, NewLval, Rval0, Rval,
@@ -608 +613 @@
-	exprn_aux__substitute_lval_in_lval(OldLval, NewLval, Lval0, Lval,
+	exprn_aux__substitute_lval_in_lval_count(OldLval, NewLval, Lval0, Lval,
@@ -612 +617,5 @@
-exprn_aux__substitute_lval_in_rval(OldLval, NewLval, Rval0, Rval, N0, N) :-
+:- pred exprn_aux__substitute_lval_in_rval_count(lval::in, lval::in,
+	rval::in, rval::out, int::in, int::out) is det.
+
+exprn_aux__substitute_lval_in_rval_count(OldLval, NewLval, Rval0, Rval,
+		N0, N) :-
@@ -615 +624 @@
-		exprn_aux__substitute_lval_in_lval(OldLval, NewLval,
+		exprn_aux__substitute_lval_in_lval_count(OldLval, NewLval,
@@ -632 +641 @@
-		exprn_aux__substitute_lval_in_rval(OldLval, NewLval,
+		exprn_aux__substitute_lval_in_rval_count(OldLval, NewLval,
@@ -641 +650 @@
-		exprn_aux__substitute_lval_in_rval(OldLval, NewLval,
+		exprn_aux__substitute_lval_in_rval_count(OldLval, NewLval,
@@ -646 +655 @@
-		exprn_aux__substitute_lval_in_rval(OldLval, NewLval,
+		exprn_aux__substitute_lval_in_rval_count(OldLval, NewLval,
@@ -648 +657 @@
-		exprn_aux__substitute_lval_in_rval(OldLval, NewLval,
+		exprn_aux__substitute_lval_in_rval_count(OldLval, NewLval,
@@ -664 +673 @@
-		MemRef0 = stackvar_ref(_),
+		MemRef0 = stackvar_ref(_SlotNum),
@@ -668 +677 @@
-		MemRef0 = framevar_ref(_),
+		MemRef0 = framevar_ref(_SlotNum),
@@ -672,2 +681,2 @@
-		MemRef0 = heap_ref(Rval0, Tag, Slot),
-		exprn_aux__substitute_lval_in_rval(OldLval, NewLval,
+		MemRef0 = heap_ref(Rval0, Tag, FieldNum),
+		exprn_aux__substitute_lval_in_rval_count(OldLval, NewLval,
@@ -675 +684 @@
-		MemRef = heap_ref(Rval, Tag, Slot)
+		MemRef = heap_ref(Rval, Tag, FieldNum)
@@ -678 +687,5 @@
-exprn_aux__substitute_lval_in_lval(OldLval, NewLval, Lval0, Lval, N0, N) :-
+:- pred exprn_aux__substitute_lval_in_lval_count(lval::in, lval::in,
+	lval::in, lval::out, int::in, int::out) is det.
+
+exprn_aux__substitute_lval_in_lval_count(OldLval, NewLval, Lval0, Lval,
+		N0, N) :-
@@ -683 +696 @@
-		exprn_aux__substitute_lval_in_lval_2(OldLval, NewLval,
+		exprn_aux__substitute_lval_in_lval_count_2(OldLval, NewLval,
@@ -687 +700 @@
-:- pred exprn_aux__substitute_lval_in_lval_2(lval::in, lval::in,
+:- pred exprn_aux__substitute_lval_in_lval_count_2(lval::in, lval::in,
@@ -690 +703,2 @@
-exprn_aux__substitute_lval_in_lval_2(OldLval, NewLval, Lval0, Lval, N0, N) :-
+exprn_aux__substitute_lval_in_lval_count_2(OldLval, NewLval, Lval0, Lval,
+		N0, N) :-
@@ -692 +706 @@
-		Lval0 = reg(_, _),
+		Lval0 = reg(_Type, _RegNum),
@@ -716 +730 @@
-		Lval0 = temp(_, _),
+		Lval0 = temp(_Type, _TmpNum),
@@ -720 +734 @@
-		Lval0 = stackvar(_),
+		Lval0 = stackvar(_SlotNum),
@@ -724 +738 @@
-		Lval0 = framevar(_),
+		Lval0 = framevar(_SlotNum),
@@ -729 +743 @@
-		exprn_aux__substitute_lval_in_rval(OldLval, NewLval,
+		exprn_aux__substitute_lval_in_rval_count(OldLval, NewLval,
@@ -734 +748 @@
-		exprn_aux__substitute_lval_in_rval(OldLval, NewLval,
+		exprn_aux__substitute_lval_in_rval_count(OldLval, NewLval,
@@ -739 +753 @@
-		exprn_aux__substitute_lval_in_rval(OldLval, NewLval,
+		exprn_aux__substitute_lval_in_rval_count(OldLval, NewLval,
@@ -744 +758 @@
-		exprn_aux__substitute_lval_in_rval(OldLval, NewLval,
+		exprn_aux__substitute_lval_in_rval_count(OldLval, NewLval,
@@ -749 +763 @@
-		exprn_aux__substitute_lval_in_rval(OldLval, NewLval,
+		exprn_aux__substitute_lval_in_rval_count(OldLval, NewLval,
@@ -754 +768 @@
-		exprn_aux__substitute_lval_in_rval(OldLval, NewLval,
+		exprn_aux__substitute_lval_in_rval_count(OldLval, NewLval,
@@ -756 +770 @@
-		exprn_aux__substitute_lval_in_rval(OldLval, NewLval,
+		exprn_aux__substitute_lval_in_rval_count(OldLval, NewLval,
@@ -761 +775 @@
-		exprn_aux__substitute_lval_in_rval(OldLval, NewLval,
+		exprn_aux__substitute_lval_in_rval_count(OldLval, NewLval,
@@ -765 +779 @@
-		Lval0 = lvar(_),
+		Lval0 = lvar(_Var),
@@ -785 +799 @@
-		exprn_aux__substitute_lval_in_rval(OldLval, NewLval,
+		exprn_aux__substitute_lval_in_rval_count(OldLval, NewLval,
@@ -805 +819 @@
-			Rval0 = var(_),
+			Rval0 = var(_Var),
@@ -1081,2 +1095,2 @@
-exprn_aux__rval_addrs(var(_), [], []).
-exprn_aux__rval_addrs(create(_, MaybeRvals, _,_,_,_, Reuse),
+exprn_aux__rval_addrs(var(_Var), [], []).
+exprn_aux__rval_addrs(create(_, MaybeRvals, _, _, _, _, Reuse),
@@ -1099 +1113 @@
-exprn_aux__rval_addrs(unop(_, Rval), CodeAddrs, DataAddrs) :-
+exprn_aux__rval_addrs(unop(_Unop, Rval), CodeAddrs, DataAddrs) :-
@@ -1101 +1115 @@
-exprn_aux__rval_addrs(binop(_, Rval1, Rval2), CodeAddrs, DataAddrs) :-
+exprn_aux__rval_addrs(binop(_Binop, Rval1, Rval2), CodeAddrs, DataAddrs) :-
@@ -1112,3 +1126,3 @@
-exprn_aux__lval_addrs(reg(_, _), [], []).
-exprn_aux__lval_addrs(stackvar(_Int), [], []).
-exprn_aux__lval_addrs(framevar(_Int), [], []).
+exprn_aux__lval_addrs(reg(_Type, _RegNum), [], []).
+exprn_aux__lval_addrs(stackvar(_SlotNum), [], []).
+exprn_aux__lval_addrs(framevar(_SlotNum), [], []).
@@ -1136 +1150 @@
-exprn_aux__lval_addrs(temp(_, _), [], []).
+exprn_aux__lval_addrs(temp(_Type, _TmpNum), [], []).
@@ -1163,3 +1177,4 @@
-exprn_aux__mem_ref_addrs(stackvar_ref(_), [], []).
-exprn_aux__mem_ref_addrs(framevar_ref(_), [], []).
-exprn_aux__mem_ref_addrs(heap_ref(Rval, _, _), CodeAddrs, DataAddrs) :-
+exprn_aux__mem_ref_addrs(stackvar_ref(_SlotNum), [], []).
+exprn_aux__mem_ref_addrs(framevar_ref(_SlotNum), [], []).
+exprn_aux__mem_ref_addrs(heap_ref(Rval, _Tag, _FieldNum),
+		CodeAddrs, DataAddrs) :-
@@ -1185 +1200 @@
-exprn_aux__var_lval_to_rval(_, Lval) = lval(Lval).
+exprn_aux__var_lval_to_rval(_Var, Lval) = lval(Lval).
--- compiler/options.m
+++ compiler/options.m
@@ -778 +778 @@
-	use_local_vars		-	bool(yes),
+	use_local_vars		-	bool(no),
@@ -2561,2 +2560,0 @@
-		"--no-use-local-vars",
-		"\tDisable the use of local variables in C code blocks.",
@@ -2571,0 +2570,3 @@
+		"--use-local-vars",
+		"\tDisable the transformation to use local variables in C code",
+		"\tblocks whereever possible.",
--- compiler/trace.m
+++ compiler/trace.m
@@ -808,0 +809 @@
+	% compute the set of live lvals at the event
--- use_local_vars.m
+++ use_local_vars.m
@@ -11,2 +11,12 @@
-% This module transforms the sequence of instructions in a procedure body.
-% It looks for two patterns. The first is
+% This module implements an LLDS->LLDS transformation that optimizes the
+% sequence of instructions in a procedure body by replacing references to
+% relatively expensive locations: fake registers (Mercury abstract machine
+% registers that are not mapped to machine registers) or stack slots with
+% references to cheaper locations: local variables in C blocks, which should
+% be mapped to machine registers by the C compiler. The C blocks should be
+% introduced later by wrap_blocks.m, possibly after the LLDS code has been
+% transformed further. Wrap_blocks will know what local variables to declare
+% in each block by looking for the temp(_, _) lvals that represent those local
+% variables.
+%
+% This module looks for two patterns. The first is
@@ -19,2 +29 @@
-% the fake register with a temporary, which the C compiler can then put into a
-% real machine register.
+% the fake register with a local variable.
@@ -34,5 +43,5 @@
-% with a temporary, but since this time we cannot be sure that the original
-% lval will not be referred to, we assign the temporary to the lval as well.
-% This is a win because the cost of the assignment is less than the savings
-% from replacing the fake register or stack slot references with temporary
-% variable references.
+% with a local variable, but since this time we cannot be sure that the
+% original lval will not be referred to, we assign the local variable to the
+% lval as well. This is a win because the cost of the assignment is less than
+% the savings from replacing the fake register or stack slot references with
+% local variable references.
@@ -127 +136 @@
-		\+ CodeAddr = label(_Label)
+		CodeAddr \= label(_Label)
@@ -260 +269,2 @@
-	% no lvals in their access path.
+	% no lvals in their access path. The NewLvals will be temporaries,
+	% representing local variables in C blocks.
@@ -262,4 +272,15 @@
-	% This predicate takes a conservative view of what may define OldLval.
-	% For some instruction types, we simply give up. Since these
-	% instruction types are relatively rare, the effect on the performance
-	% of the generated code should be negligible.
+	% When control leaves this instruction sequence via a if_val, goto or
+	% call, the local variables of the block in which this instruction
+	% sequence will go out of scope, so we must stop using them. At points
+	% at which control can enter this instruction sequence, i.e. at labels,
+	% the C block ends, so again we must stop using its local variables.
+	% (Livevals pseudo-instructions occur only immediately before
+	% instructions that cause control transfer, so we stop at them too.)
+	% 
+	% Our caller ensures that we can also so stop at any point. By doing so
+	% we may fail to exploit an optimization opportunity, but the code we
+	% generate will still be correct. At the moment we stop at instructions
+	% whose correct handling would be non-trivial and which rarely if ever
+	% appear between the definition and a use of a location we want to
+	% substitute. These include instructions that manipulate stack frames,
+	% the heap, the trail and synchronization data.
--- doc/user_guide.texi	2001/03/18 23:10:06	1.246
+++ doc/user_guide.texi	2001/04/20 12:16:19
@@ -4280,6 +4280,11 @@
 minimize stack consumption, possibly at the expense of speed.
 
 @sp 1
+ at item --use-local-vars
+Disable the transformation to use local variables in C code
+blocks whereever possible.
+
+ at sp 1
 @item --no-optimize-labels
 Disable elimination of dead labels and code.
 
--- compiler/notes/compiler_design.html	2001/01/19 01:50:32	1.57
+++ compiler/notes/compiler_design.html	2001/04/20 12:21:58
@@ -784,6 +784,8 @@
 
 <li> peephole optimization (peephole.m)
 
+<li> introduction of local C variables (use_local_vars.m) <br>
+
 <li> value numbering <br>
 
 	This is done by value_number.m, which has the following sub-modules:
@@ -849,10 +851,18 @@
 		until the tag is known. (Violations of (b) usually cause
 		unaligned accesses, which cause bus errors on many machines.)
 	</dl>
-
-	Several of these modules (and also frameopt, above) use livemap.m,
-	which finds the set of locations live at each label.
 </ul>
+
+<p>
+
+Several of these optimizations (frameopt, use_local_vars and value numbering)
+use livemap.m, a module that finds the set of locations live at each label.
+
+Use_local_vars and value numbering also introduce
+references to temporary variables in extended basic blocks
+in the LLDS representation of the C code.
+The transformation to insert the block scopes
+and declare the temporary variables is performed by wrap_blocks.m.
 
 <p>
 
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to:       mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions:          mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------



More information about the developers mailing list