[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