Made to work with troff

This commit is contained in:
ceriel 1990-06-20 10:05:22 +00:00
parent 97e131bc81
commit 39730420a2
25 changed files with 583 additions and 456 deletions

View file

@ -16,37 +16,40 @@ CA=ca/ca?
EGO=$(INTRO) $(OV) $(IC) $(CF) $(IL) $(SR) $(CS) $(SP) $(CJ) $(BO) \ EGO=$(INTRO) $(OV) $(IC) $(CF) $(IL) $(SR) $(CS) $(SP) $(CJ) $(BO) \
$(UD) $(LV) $(RA) $(CA) $(UD) $(LV) $(RA) $(CA)
REFER=refer REFER=refer
TROFF=troff
TBL=tbl
TARGET=-Tlp
../ego.doc: $(EGO) ../ego.doc: refs.opt refs.stat refs.gen intro/head intro/tail $(EGO)
$(REFER) -sA+T -l4,2 $(REFS) intro/head $(EGO) intro/tail > ../ego.doc $(REFER) -sA+T -l4,2 $(REFS) intro/head $(EGO) intro/tail | $(TBL) > ../ego.doc
ego.f: $(EGO) ego.f: refs.opt refs.stat refs.gen intro/head intro/tail $(EGO)
$(REFER) -sA+T -l4,2 $(REFS) intro/head $(EGO) intro/tail | nroff -ms > ego.f $(REFER) -sA+T -l4,2 $(REFS) intro/head $(EGO) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > ego.f
intro.f: $(INTRO) intro.f: refs.opt refs.stat refs.gen intro/head intro/tail $(INTRO)
$(REFER) -sA+T -l4,2 $(REFS) ov/head $(INTRO) intro/tail | nroff -ms > intro.f $(REFER) -sA+T -l4,2 $(REFS) intro/head $(INTRO) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > intro.f
ov.f: $(OV) ov.f: refs.opt refs.stat refs.gen intro/head intro/tail $(OV)
$(REFER) -sA+T -l4,2 $(REFS) ov/head $(OV) intro/tail | nroff -ms > ov.f $(REFER) -sA+T -l4,2 $(REFS) intro/head $(OV) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > ov.f
ic.f: $(IC) ic.f: refs.opt refs.stat refs.gen intro/head intro/tail $(IC)
$(REFER) -sA+T -l4,2 $(REFS) ic/head $(IC) intro/tail | nroff -ms > ic.f $(REFER) -sA+T -l4,2 $(REFS) intro/head $(IC) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > ic.f
cf.f: $(CF) cf.f: refs.opt refs.stat refs.gen intro/head intro/tail $(CF)
$(REFER) -sA+T -l4,2 $(REFS) cf/head $(CF) intro/tail | nroff -ms > cf.f $(REFER) -sA+T -l4,2 $(REFS) intro/head $(CF) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > cf.f
il.f: $(IL) il.f: refs.opt refs.stat refs.gen intro/head intro/tail $(IL)
$(REFER) -sA+T -l4,2 $(REFS) il/head $(IL) intro/tail | nroff -ms > il.f $(REFER) -sA+T -l4,2 $(REFS) intro/head $(IL) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > il.f
sr.f: $(SR) sr.f: refs.opt refs.stat refs.gen intro/head intro/tail $(SR)
$(REFER) -sA+T -l4,2 $(REFS) sr/head $(SR) intro/tail | nroff -ms > sr.f $(REFER) -sA+T -l4,2 $(REFS) intro/head $(SR) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > sr.f
cs.f: $(CS) cs.f: refs.opt refs.stat refs.gen intro/head intro/tail $(CS)
$(REFER) -sA+T -l4,2 $(REFS) cs/head $(CS) intro/tail | nroff -ms > cs.f $(REFER) -sA+T -l4,2 $(REFS) intro/head $(CS) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > cs.f
sp.f: $(SP) sp.f: refs.opt refs.stat refs.gen intro/head intro/tail $(SP)
$(REFER) -sA+T -l4,2 $(REFS) sp/head $(SP) intro/tail | nroff -ms > sp.f $(REFER) -sA+T -l4,2 $(REFS) intro/head $(SP) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > sp.f
cj.f: $(CJ) cj.f: refs.opt refs.stat refs.gen intro/head intro/tail $(CJ)
$(REFER) -sA+T -l4,2 $(REFS) cj/head $(CJ) intro/tail | nroff -ms > cj.f $(REFER) -sA+T -l4,2 $(REFS) intro/head $(CJ) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > cj.f
bo.f: $(BO) bo.f: refs.opt refs.stat refs.gen intro/head intro/tail $(BO)
$(REFER) -sA+T -l4,2 $(REFS) bo/head $(BO) intro/tail | nroff -ms > bo.f $(REFER) -sA+T -l4,2 $(REFS) intro/head $(BO) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > bo.f
ud.f: $(UD) ud.f: refs.opt refs.stat refs.gen intro/head intro/tail $(UD)
$(REFER) -sA+T -l4,2 $(REFS) ud/head $(UD) intro/tail | nroff -ms > ud.f $(REFER) -sA+T -l4,2 $(REFS) intro/head $(UD) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > ud.f
lv.f: $(LV) lv.f: refs.opt refs.stat refs.gen intro/head intro/tail $(LV)
$(REFER) -sA+T -l4,2 $(REFS) lv/head $(LV) intro/tail | nroff -ms > lv.f $(REFER) -sA+T -l4,2 $(REFS) intro/head $(LV) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > lv.f
ra.f: $(RA) ra.f: refs.opt refs.stat refs.gen intro/head intro/tail $(RA)
$(REFER) -sA+T -l4,2 $(REFS) ra/head $(RA) intro/tail | nroff -ms > ra.f $(REFER) -sA+T -l4,2 $(REFS) intro/head $(RA) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > ra.f
ca.f: $(CA) ca.f: refs.opt refs.stat refs.gen intro/head intro/tail $(CA)
$(REFER) -sA+T -l4,2 $(REFS) ca/head $(CA) intro/tail | nroff -ms > ca.f $(REFER) -sA+T -l4,2 $(REFS) intro/head $(CA) intro/tail | $(TBL) | $(TROFF) $(TARGET) -ms > ca.f

View file

@ -27,20 +27,23 @@ While-loop optimization
The straightforward way to translate a while loop is to The straightforward way to translate a while loop is to
put the test for loop termination at the beginning of the loop. put the test for loop termination at the beginning of the loop.
.DS .DS
while cond loop LAB1: Test cond while cond loop \kyLAB1: \kxTest cond
body of the loop ---> Branch On False To LAB2 body of the loop --->\h'|\nxu'Branch On False To LAB2
end loop code for body of loop end loop\h'|\nxu'code for body of loop
Branch To LAB1 \h'|\nxu'Branch To LAB1
LAB2: \h'|\nyu'LAB2:
Fig. 10.1 Example of Branch Optimization Fig. 10.1 Example of Branch Optimization
.DE .DE
If the condition fails at the Nth iteration, the following code If the condition fails at the Nth iteration, the following code
gets executed (dynamically): gets executed (dynamically):
.DS .DS
.TS
l l l.
N * conditional branch (which fails N-1 times) N * conditional branch (which fails N-1 times)
N-1 * unconditional branch N-1 * unconditional branch
N-1 * body of the loop N-1 * body of the loop
.TE
.DE .DE
An alternative translation is: An alternative translation is:
.DS .DS
@ -53,9 +56,12 @@ LAB2:
.DE .DE
This translation results in the following profile: This translation results in the following profile:
.DS .DS
.TS
l l l.
N * conditional branch (which succeeds N-1 times) N * conditional branch (which succeeds N-1 times)
1 * unconditional branch 1 * unconditional branch
N-1 * body of the loop N-1 * body of the loop
.TE
.DE .DE
So the second translation will be significantly faster if N >> 2. So the second translation will be significantly faster if N >> 2.
If N=2, execution time will be slightly increased. If N=2, execution time will be slightly increased.
@ -79,12 +85,15 @@ the basic block that comes textually next to S must stay
in that position. in that position.
So the transformation in Fig. 10.2 is illegal. So the transformation in Fig. 10.2 is illegal.
.DS .DS
.TS
l l l l l.
LAB1: S1 LAB1: S1 LAB1: S1 LAB1: S1
BRA LAB2 S2 BRA LAB2 S2
... --> BEQ LAB3 ... --> BEQ LAB3
LAB2: S2 ... LAB2: S2 ...
BEQ LAB3 S3 BEQ LAB3 S3
S3 S3
.TE
Fig. 10.2 An illegal transformation of Branch Optimization Fig. 10.2 An illegal transformation of Branch Optimization
.DE .DE
@ -118,6 +127,7 @@ the last instruction of S is a conditional branch
If such a block B is found, the control flow graph is changed If such a block B is found, the control flow graph is changed
as depicted in Fig. 10.3. as depicted in Fig. 10.3.
.DS .DS
.ft 5
| | | |
| v | v
v | v |
@ -146,6 +156,7 @@ v | | | ^ --------- |
|----<--| |----<--|
| |
v v
.ft R
Fig. 10.3 Transformation of the CFG by Branch Optimization Fig. 10.3 Transformation of the CFG by Branch Optimization
.DE .DE

View file

@ -63,13 +63,3 @@ present in the input program).
On the other hand, an identifier may be only internally visible. On the other hand, an identifier may be only internally visible.
If such an identifier is referenced before being defined, If such an identifier is referenced before being defined,
an INA or INP pseudo must be emitted prior to its first reference. an INA or INP pseudo must be emitted prior to its first reference.
.UH
Acknowledgements
.PP
The author would like to thank Andy Tanenbaum for his guidance,
Duk Bekema for implementing the Common Subexpression Elimination phase
and writing the initial documentation of that phase,
Dick Grune for reading the manuscript of this report
and Ceriel Jacobs, Ed Keizer, Martin Kersten, Hans van Staveren
and the members of the S.T.W. user's group for their
interest and assistance.

View file

@ -7,9 +7,12 @@ The optimization below is only possible if
we know for sure that the call to P cannot we know for sure that the call to P cannot
change A. change A.
.DS .DS
.TS
l l.
A := 10; A:= 10; A := 10; A:= 10;
P; -- procedure call --> P; P; -- procedure call --> P;
B := A + 2; B := 12; B := A + 2; B := 12;
.TE
.DE .DE
Although it is not possible to predict exactly Although it is not possible to predict exactly
all the effects a procedure call has, we may all the effects a procedure call has, we may

View file

@ -27,7 +27,8 @@ else
S3 S3
(pseudo) EM: (pseudo) EM:
.TS
l l l.
TEST COND TEST COND TEST COND TEST COND
BNE *1 BNE *1 BNE *1 BNE *1
S1 S1 S1 S1
@ -37,6 +38,7 @@ BRA *2 1:
S2 2: S2 2:
S3 S3 S3 S3
2: 2:
.TE
Fig. 9.1 An example of Cross Jumping Fig. 9.1 An example of Cross Jumping
.DE .DE
@ -62,12 +64,15 @@ as demonstrated by the Fig. 8.2.
EM: EM:
.TS
l l.
... ... ... ...
LOC 4 LOC 5 LOC 4 LOC 5
CAL F CAL G CAL F CAL G
ASP 2 ASP 2 ASP 2 ASP 2
LFR 2 LFR 2 LFR 2 LFR 2
STL X STL X STL X STL X
.TE
Fig. 9.2 Effectiveness of Cross Jumping Fig. 9.2 Effectiveness of Cross Jumping
.DE .DE
@ -92,6 +97,7 @@ blocks must be split into two.
The control flow graphs before and after the optimization are shown The control flow graphs before and after the optimization are shown
in Fig. 9.3 and Fig. 9.4. in Fig. 9.3 and Fig. 9.4.
.DS .DS
.ft 5
-------- -------- -------- --------
| | | | | | | |
@ -103,11 +109,12 @@ in Fig. 9.3 and Fig. 9.4.
|------------------|--------------------| |------------------|--------------------|
| |
v v
.ft R
Fig. 9.3 CFG before optimization Fig. 9.3 CFG before optimization
.DE .DE
.DS .DS
.ft 5
-------- -------- -------- --------
| | | | | | | |
| S1 | | S2 | | S1 | | S2 |
@ -123,6 +130,7 @@ Fig. 9.3 CFG before optimization
-------- --------
| |
v v
.ft R
Fig. 9.4 CFG after optimization Fig. 9.4 CFG after optimization
.DE .DE

View file

@ -18,12 +18,15 @@ but in general it will save space too.
As an example of the application of Common Subexpression Elimination, As an example of the application of Common Subexpression Elimination,
consider the piece of program in Fig. 7.1(a). consider the piece of program in Fig. 7.1(a).
.DS .DS
.TS
l l l.
x := a * b; TMP := a * b; x := a * b; x := a * b; TMP := a * b; x := a * b;
CODE; x := TMP; CODE CODE; x := TMP; CODE
y := c + a * b; CODE y := x; y := c + a * b; CODE y := x;
y := c + TMP; y := c + TMP;
(a) (b) (c) (a) (b) (c)
.TE
Fig. 7.1 Examples of Common Subexpression Elimination Fig. 7.1 Examples of Common Subexpression Elimination
.DE .DE

View file

@ -70,10 +70,13 @@ a common subexpression,
references to the element itself are replaced by references to the element itself are replaced by
indirect references through TMP (see Fig. 7.4). indirect references through TMP (see Fig. 7.4).
.DS .DS
.TS
l l l.
x := A[i]; TMP := &A[i]; x := A[i]; TMP := &A[i];
. . . --> x := *TMP; . . . --> x := *TMP;
A[i] := y; . . . A[i] := y; . . .
*TMP := y; *TMP := y;
.TE
Fig. 7.4 Elimination of an array address computation Fig. 7.4 Elimination of an array address computation
.DE .DE

View file

@ -27,10 +27,13 @@ The value number of the result of an expression depends only
on the kind of operator and the value number(s) of the operand(s). on the kind of operator and the value number(s) of the operand(s).
The expressions need not be textually equal, as shown in Fig. 7.5. The expressions need not be textually equal, as shown in Fig. 7.5.
.DS .DS
.TS
l l.
a := c; (1) a := c; (1)
use(a * b); (2) use(a * b); (2)
d := b; (3) d := b; (3)
use(c * d); (4) use(c * d); (4)
.TE
Fig. 7.5 Different expressions with the same value number Fig. 7.5 Different expressions with the same value number
.DE .DE
@ -43,9 +46,12 @@ and the operator (*) is the same.
.PP .PP
As another example of the value number method, consider Fig. 7.6. As another example of the value number method, consider Fig. 7.6.
.DS .DS
.TS
l l.
use(a * b); (1) use(a * b); (1)
a := 123; (2) a := 123; (2)
use(a * b); (3) use(a * b); (3)
.TE
Fig. 7.6 Identical expressions with the different value numbers Fig. 7.6 Identical expressions with the different value numbers
.DE .DE
@ -64,7 +70,7 @@ of its operands.
A table of "available expressions" is used to do this mapping. A table of "available expressions" is used to do this mapping.
.PP .PP
CS recognizes the following kinds of EM operands, called \fIentities\fR: CS recognizes the following kinds of EM operands, called \fIentities\fR:
.IP .DS
- constant - constant
- local variable - local variable
- external variable - external variable
@ -81,6 +87,7 @@ CS recognizes the following kinds of EM operands, called \fIentities\fR:
- local base - local base
- heap pointer - heap pointer
- ignore mask - ignore mask
.DE
.LP .LP
Whenever a new entity is encountered in the working window, Whenever a new entity is encountered in the working window,
it is entered in the symbol table and given a brand new value number. it is entered in the symbol table and given a brand new value number.

View file

@ -26,26 +26,26 @@ There are groups for all sorts of operators:
unary, binary, and ternary. unary, binary, and ternary.
The groups of operators are further partitioned according to the size The groups of operators are further partitioned according to the size
of their operand(s) and result. of their operand(s) and result.
\" .PP .\" .PP
\" The distinction between operators and expensive loads is not always clear. .\" The distinction between operators and expensive loads is not always clear.
\" The ADP instruction for example, .\" The ADP instruction for example,
\" might seem a unary operator because it pops one item .\" might seem a unary operator because it pops one item
\" (a pointer) from the stack. .\" (a pointer) from the stack.
\" However, two ADP-instructions which pop an item with the same value number .\" However, two ADP-instructions which pop an item with the same value number
\" need not have the same result, .\" need not have the same result,
\" because the attributes (an offset, to be added to the pointer) .\" because the attributes (an offset, to be added to the pointer)
\" can be different. .\" can be different.
\" Is it then a binary operator? .\" Is it then a binary operator?
\" That would give rise to the strange, and undesirable, .\" That would give rise to the strange, and undesirable,
\" situation that some binary operators pop two operands .\" situation that some binary operators pop two operands
\" and others pop one. .\" and others pop one.
\" The conclusion is inevitable: .\" The conclusion is inevitable:
\" we have been fooled by the name (ADd Pointer). .\" we have been fooled by the name (ADd Pointer).
\" The ADP-instruction is an expensive load. .\" The ADP-instruction is an expensive load.
\" In this context LAF, meaning Load Address of oFfsetted, .\" In this context LAF, meaning Load Address of oFfsetted,
\" would have been a better name, .\" would have been a better name,
\" corresponding to LOF, like LAL, .\" corresponding to LOF, like LAL,
\" Load Address of Local, corresponds to LOL. .\" Load Address of Local, corresponds to LOL.
.PP .PP
There are groups for all sorts of stores: There are groups for all sorts of stores:
direct, indirect, array element. direct, indirect, array element.
@ -91,10 +91,13 @@ because EM expressions are postfix.
When we find an instruction to load an operand, When we find an instruction to load an operand,
we load on the fake-stack a struct with the following information: we load on the fake-stack a struct with the following information:
.DS .DS
.TS
l l.
(1) the value number of the operand (1) the value number of the operand
(2) the size of the operand (2) the size of the operand
(3) a pointer to the first line of EM-code (3) a pointer to the first line of EM-code
that constitutes the operand that constitutes the operand
.TE
.DE .DE
In most cases, (3) will point to the line In most cases, (3) will point to the line
that loaded the operand (e.g. LOL, LOC), that loaded the operand (e.g. LOL, LOC),
@ -121,9 +124,12 @@ a recurrence of this expression.
Not only will the operand(s) be popped from the fake-stack, Not only will the operand(s) be popped from the fake-stack,
but the following will be pushed: but the following will be pushed:
.DS .DS
.TS
l l.
(1) the value number of the result (1) the value number of the result
(2) the size of the result (2) the size of the result
(3) a pointer to the first line of the expression (3) a pointer to the first line of the expression
.TE
.DE .DE
In this way an item on the fake-stack always contains In this way an item on the fake-stack always contains
the necessary information. the necessary information.

View file

@ -90,18 +90,22 @@ and let the null item be 0.
Then the tree of fig. 3.1(a) Then the tree of fig. 3.1(a)
can be represented as in fig. 3.1(b). can be represented as in fig. 3.1(b).
.DS .DS
.ft 5
4 4
/ \e
9 12 9 12
/ \e / \e
12 3 4 6 12 3 4 6
/ \e \e /
8 1 5 1 8 1 5 1
.ft R
Fig. 3.1(a) A binary tree Fig. 3.1(a) A binary tree
.ft 5
4 9 12 0 0 3 8 0 0 1 0 0 12 4 0 5 0 0 6 1 0 0 0 4 9 12 0 0 3 8 0 0 1 0 0 12 4 0 5 0 0 6 1 0 0 0
.ft R
Fig. 3.1(b) Its sequential representation Fig. 3.1(b) Its sequential representation
.DE .DE

View file

@ -21,12 +21,15 @@ The syntactic structure of every component
is described by a set of context free syntax rules, is described by a set of context free syntax rules,
with the following conventions: with the following conventions:
.DS .DS
.TS
l l.
x a non-terminal symbol x a non-terminal symbol
A a terminal symbol (in capitals) A a terminal symbol (in capitals)
x: a b c; a grammar rule x: a b c; a grammar rule
a | b a or b a | b a or b
(a)+ 1 or more occurrences of a (a)+ 1 or more occurrences of a
{a} 0 or more occurrences of a {a} 0 or more occurrences of a
.TE
.DE .DE
.NH 3 .NH 3
The object table The object table
@ -70,6 +73,8 @@ identifying number
(see previous section for their use). (see previous section for their use).
.DS .DS
.UL syntax .UL syntax
.TS
lw(1i) l l.
object_table: object_table:
{datablock} ; {datablock} ;
datablock: datablock:
@ -85,6 +90,7 @@ identifying number
SIZE ; -- size of the object in bytes SIZE ; -- size of the object in bytes
value: value:
argument ; argument ;
.TE
.DE .DE
A data block has only one flag: "external", indicating A data block has only one flag: "external", indicating
whether the data label is externally visible. whether the data label is externally visible.
@ -102,6 +108,8 @@ The table has one entry for
every procedure. every procedure.
.DS .DS
.UL syntax .UL syntax
.TS
lw(1i) l l.
procedure_table: procedure_table:
{procedure} {procedure}
procedure: procedure:
@ -122,6 +130,7 @@ every procedure.
FLAGS ; FLAGS ;
ext: ext:
{O_ID} ; -- a set of objects {O_ID} ; -- a set of objects
.TE
.DE .DE
.PP .PP
The number of bytes of formal parameters accessed by The number of bytes of formal parameters accessed by
@ -231,6 +240,8 @@ of arguments), then the list is terminated by a special
argument of type CEND. argument of type CEND.
.DS .DS
.UL syntax .UL syntax
.TS
lw(1i) l l.
em_text: em_text:
{line} ; {line} ;
line: line:
@ -263,6 +274,7 @@ argument of type CEND.
SIZE -- number of bytes SIZE -- number of bytes
string ; -- string representation of (un)signed string ; -- string representation of (un)signed
-- or floating point constant -- or floating point constant
.TE
.DE .DE
.NH 3 .NH 3
The control flow graphs The control flow graphs
@ -306,6 +318,8 @@ the identifiers of every
that the block belongs to (see next section for loops). that the block belongs to (see next section for loops).
.DS .DS
.UL syntax .UL syntax
.TS
lw(1i) l l.
control_flow_graph: control_flow_graph:
{basic_block} ; {basic_block} ;
basic_block: basic_block:
@ -324,6 +338,7 @@ that the block belongs to (see next section for loops).
B_ID ; B_ID ;
loops: loops:
{LP_ID} ; {LP_ID} ;
.TE
.DE .DE
The flag bits can have the values 'firm' and 'strong', The flag bits can have the values 'firm' and 'strong',
which are explained below. which are explained below.
@ -387,19 +402,20 @@ strong nor firm, as it may be skipped during some iterations
.DS .DS
loop loop
if cond1 then if cond1 then
... -- this code will not ... \kx-- this code will not
-- result in a firm or strong block \h'|\nxu'-- result in a firm or strong block
end if; end if;
... -- strong (always executed) ... -- strong (always executed)
exit when cond2; exit when cond2;
... -- firm (not executed on ... \kx-- firm (not executed on last iteration).
-- last iteration).
end loop; end loop;
Fig. 3.2 Example of firm and strong block Fig. 3.2 Example of firm and strong block
.DE .DE
.DS .DS
.UL syntax .UL syntax
.TS
lw(1i) l l.
looptable: looptable:
{loop} ; {loop} ;
loop: loop:
@ -411,4 +427,5 @@ Fig. 3.2 Example of firm and strong block
B_ID ; B_ID ;
end: end:
B_ID ; B_ID ;
.TE
.DE .DE

View file

@ -57,6 +57,8 @@ indicating which part of the EM text belongs
to that block. to that block.
.DS .DS
.UL syntax .UL syntax
.TS
lw(1i) l l.
intermediate_code: intermediate_code:
object_table_file object_table_file
proctable_file proctable_file
@ -77,4 +79,5 @@ to that block.
LLENGTH -- number of loops LLENGTH -- number of loops
control_flow_graph control_flow_graph
looptable ; looptable ;
.TE
.DE .DE

View file

@ -93,8 +93,11 @@ Objects are recognized by looking at the operands
of instructions that reference global data. of instructions that reference global data.
If we come across the instructions: If we come across the instructions:
.DS .DS
.TS
l l.
LDE X+6 -- Load Double External LDE X+6 -- Load Double External
LAE X+20 -- Load Address External LAE X+20 -- Load Address External
.TE
.DE .DE
we conclude that the data block we conclude that the data block
preceded by the data label X contains an object preceded by the data label X contains an object

View file

@ -139,10 +139,10 @@ procedure p (x:integer);
begin begin
x := 20; x := 20;
end; end;
... \&...
a := 10; a := 10; a := 10; \kxa := 10;
p(a); ---> a := 20; p(a); ---> \h'|\nxu'a := 20;
write(a); write(a); write(a); \h'|\nxu'write(a);
.DE .DE
.IP 2. .IP 2.
P changes any of the operands of the P changes any of the operands of the

View file

@ -104,18 +104,21 @@ The following model was developed empirically.
Assume procedure P calls procedure Q. Assume procedure P calls procedure Q.
The call takes place in basic block B. The call takes place in basic block B.
.DS .DS
ZP = # zero parameters .TS
CP = # constant parameters - ZP l l l.
LN = Loop Nesting level (0 if outside any loop) ZP \&= # zero parameters
F = \fIif\fR # formal parameters of Q > 0 \fIthen\fR 1 \fIelse\fR 0 CP \&= # constant parameters - ZP
FT = \fIif\fR Q falls through \fIthen\fR 1 \fIelse\fR 0 LN \&= Loop Nesting level (0 if outside any loop)
S = size(Q) - 1 - # inline_parameters - F F \&= \fIif\fR # formal parameters of Q > 0 \fIthen\fR 1 \fIelse\fR 0
L = \fIif\fR # local variables of P > 0 \fIthen\fR 0 \fIelse\fR -1 FT \&= \fIif\fR Q falls through \fIthen\fR 1 \fIelse\fR 0
A = CP + 2 * ZP S \&= size(Q) - 1 - # inline_parameters - F
N = \fIif\fR LN=0 and P is never called from a loop \fIthen\fR 0 \fIelse\fR (LN+1)**2 L \&= \fIif\fR # local variables of P > 0 \fIthen\fR 0 \fIelse\fR -1
FM = \fIif\fR B is a firm block \fIthen\fR 2 \fIelse\fR 1 A \&= CP + 2 * ZP
N \&= \fIif\fR LN=0 and P is never called from a loop \fIthen\fR 0 \fIelse\fR (LN+1)**2
FM \&= \fIif\fR B is a firm block \fIthen\fR 2 \fIelse\fR 1
pay_off = (100/S + FT + F + L + A) * N * FM pay_off \&= (100/S + FT + F + L + A) * N * FM
.TE
.DE .DE
S stands for the size increase of the program, S stands for the size increase of the program,
which is slightly less than the size of Q. which is slightly less than the size of Q.

View file

@ -165,12 +165,17 @@ These calls are inherited from the called procedure.
We will refer to these invocations as \fInested calls\fR We will refer to these invocations as \fInested calls\fR
(see Fig. 5.1). (see Fig. 5.1).
.DS .DS
.TS
lw(2.5i) l.
procedure p is procedure p is
begin . begin .
a(); . a(); .
b(); . b(); .
end; end;
.TE
.TS
lw(2.5i) l.
procedure r is procedure r is procedure r is procedure r is
begin begin begin begin
x(); x(); x(); x();
@ -178,6 +183,7 @@ begin begin
y(); b(); -- nested call y(); b(); -- nested call
end; y(); end; y();
end; end;
.TE
Fig. 5.1 Example of nested procedure calls Fig. 5.1 Example of nested procedure calls
.DE .DE

View file

@ -22,6 +22,6 @@ the driving routine for doing the substitution
lower level routines that do certain modifications lower level routines that do certain modifications
.IP 3_aux: .IP 3_aux:
implements auxiliary procedures used by subphase 3 implements auxiliary procedures used by subphase 3
.IP aux .IP aux:
implements auxiliary procedures used by several subphases. implements auxiliary procedures used by several subphases.
.LP .LP

View file

@ -1,7 +1,10 @@
.ND .ND
.ll 80m .\".ll 80m
.nr LL 80m .\".nr LL 80m
.nr tl 78m .\".nr tl 78m
.tr ~ .tr ~
.ds >. . .ds >. .
.ds [. " \[ .ds >, ,
.ds [. " [
.ds .] ]
.cs 5 22

View file

@ -1,3 +1,17 @@
.SH
Acknowledgements
.PP
The author would like to thank Andy Tanenbaum for his guidance,
Duk Bekema for implementing the Common Subexpression Elimination phase
and writing the initial documentation of that phase,
Dick Grune for reading the manuscript of this report
and Ceriel Jacobs, Ed Keizer, Martin Kersten, Hans van Staveren
and the members of the S.T.W. user's group for their
interest and assistance.
.bp
.SH
References
.LP
.[ .[
$LIST$ $LIST$
.] .]

View file

@ -76,11 +76,14 @@ EM is the assembly code of a virtual \fIstack machine\fR.
All operations are performed on the top of the stack. All operations are performed on the top of the stack.
For example, the statement "A := B + 3" may be expressed in EM as: For example, the statement "A := B + 3" may be expressed in EM as:
.DS .DS
.TS
l l.
LOL -4 -- push local variable B LOL -4 -- push local variable B
LOC 3 -- push constant 3 LOC 3 -- push constant 3
ADI 2 -- add two 2-byte items on top of ADI 2 -- add two 2-byte items on top of
-- the stack and push the result -- the stack and push the result
STL -2 -- pop A STL -2 -- pop A
.TE
.DE .DE
So EM is essentially a \fIpostfix\fR code. So EM is essentially a \fIpostfix\fR code.
.PP .PP

View file

@ -225,9 +225,12 @@ allocation.
To summarize, the number of bytes a certain allocation would To summarize, the number of bytes a certain allocation would
save is computed as follows: save is computed as follows:
.DS .DS
.TS
l l.
net_bytes_saved = bytes_saved - init_cost net_bytes_saved = bytes_saved - init_cost
bytes_saved = #occurrences * gains_per_occ bytes_saved = #occurrences * gains_per_occ
init_cost = #initializations * costs_per_init init_cost = #initializations * costs_per_init
.TE
.DE .DE
.PP .PP
It is inherently more difficult to estimate the execution It is inherently more difficult to estimate the execution

View file

@ -11,12 +11,15 @@ the stack by the \fIcalling\fR procedure.
The ASP (Adjust Stack Pointer) instruction is used for this purpose. The ASP (Adjust Stack Pointer) instruction is used for this purpose.
A call in EM is shown in Fig. 8.1 A call in EM is shown in Fig. 8.1
.DS .DS
.TS
l l.
Pascal: EM: Pascal: EM:
f(a,2) LOC 2 f(a,2) LOC 2
LOE A LOE A
CAL F CAL F
ASP 4 -- pop 4 bytes ASP 4 -- pop 4 bytes
.TE
Fig. 8.1 An example procedure call in Pascal and EM Fig. 8.1 An example procedure call in Pascal and EM
.DE .DE
@ -35,6 +38,8 @@ A stack adjustment may be delayed if there is some other stack adjustment
later on in the same basic block. later on in the same basic block.
The two ASPs can be combined into one. The two ASPs can be combined into one.
.DS .DS
.TS
l l l.
Pascal: EM: optimized EM: Pascal: EM: optimized EM:
f(a,2) LOC 2 LOC 2 f(a,2) LOC 2 LOC 2
@ -46,6 +51,7 @@ g(3,b,c) LOE A LOE A
LOC 3 CAL G LOC 3 CAL G
CAL G ASP 10 CAL G ASP 10
ASP 6 ASP 6
.TE
Fig. 8.2 An example of local Stack Pollution Fig. 8.2 An example of local Stack Pollution
.DE .DE
@ -85,6 +91,8 @@ the number of bytes pushed since the first ASP.
.LP .LP
Condition 1. is not satisfied in Fig. 8.3. Condition 1. is not satisfied in Fig. 8.3.
.DS .DS
.TS
l l.
Pascal: EM: Pascal: EM:
5 + f(10) + g(30) LOC 5 5 + f(10) + g(30) LOC 5
@ -98,6 +106,8 @@ Pascal: EM:
ASP 2 ASP 2
LFR 2 LFR 2
ADI 2 ADI 2
.TE
Fig. 8.3 An illegal transformation Fig. 8.3 An illegal transformation
.DE .DE
If the first ASP were removed (delayed), the first ADI would add If the first ASP were removed (delayed), the first ADI would add
@ -105,6 +115,8 @@ If the first ASP were removed (delayed), the first ADI would add
.sp .sp
Condition 2. is not satisfied in Fig. 8.4. Condition 2. is not satisfied in Fig. 8.4.
.DS .DS
.TS
l l.
Pascal: EM: Pascal: EM:
f(10) + 5 * g(30) LOC 10 f(10) + 5 * g(30) LOC 10
@ -118,6 +130,7 @@ f(10) + 5 * g(30) LOC 10
LFR 2 LFR 2
MLI 2 -- 5 * g(30) MLI 2 -- 5 * g(30)
ADI 2 ADI 2
.TE
Fig. 8.4 A second illegal transformation Fig. 8.4 A second illegal transformation
.DE .DE

View file

@ -16,13 +16,16 @@ done by the EM Peephole Optimizer.
Strength reduction can also be applied Strength reduction can also be applied
more generally to operators used in a loop. more generally to operators used in a loop.
.DS .DS
.TS
l l.
i := 1; i := 1; i := 1; i := 1;
while i < 100 loop --> TMP := i * 118; while i < 100 loop\ \ \ \ \ \ \ --> TMP := i * 118;
put(i * 118); while i < 100 loop put(i * 118); while i < 100 loop
i := i + 1; put(TMP); i := i + 1; put(TMP);
end loop; i := i + 1; end loop; i := i + 1;
TMP := TMP + 118; TMP := TMP + 118;
end loop; end loop;
.TE
Fig. 6.1 An example of Strenght Reduction Fig. 6.1 An example of Strenght Reduction
.DE .DE

View file

@ -105,11 +105,11 @@ iv_expression * constant
.IP (2) .IP (2)
constant * iv_expression constant * iv_expression
.IP (3) .IP (3)
A[iv-expression] := (assign to array element) A[iv-expression] := \kx(assign to array element)
.IP (4) .IP (4)
A[iv-expression] (use array element) A[iv-expression] \h'|\nxu'(use array element)
.IP (5) .IP (5)
& A[iv-expression] (take address of array element) & A[iv-expression] \h'|\nxu'(take address of array element)
.LP .LP
(Note that EM has different instructions to use an array element, (Note that EM has different instructions to use an array element,
store into one, or take the address of one, resp. LAR, SAR, and AAR). store into one, or take the address of one, resp. LAR, SAR, and AAR).
@ -171,10 +171,13 @@ replaced by TMP.
For array optimizations, the replacement For array optimizations, the replacement
depends on the form: depends on the form:
.DS .DS
.TS
l l l.
\fIform\fR \fIreplacement\fR \fIform\fR \fIreplacement\fR
(3) A[iv-expr] := *TMP := (assign indirect) (3) A[iv-expr] := *TMP := (assign indirect)
(4) A[iv-expr] *TMP (use indirect) (4) A[iv-expr] *TMP (use indirect)
(5) &A[iv-expr] TMP (5) &A[iv-expr] TMP
.TE
.DE .DE
The '*' denotes the indirect operator. (Note that The '*' denotes the indirect operator. (Note that
EM has different instructions to do EM has different instructions to do
@ -199,14 +202,17 @@ must be negated.
.PP .PP
The transformations are demonstrated by an example. The transformations are demonstrated by an example.
.DS .DS
.TS
l l.
i := 100; i := 100; i := 100; i := 100;
while i > 1 loop TMP := (6-i) * 5; while i > 1 loop TMP := (6-i) * 5;
X := (6-i) * 5 + 2; while i > 1 loop X := (6-i) * 5 + 2; while i > 1 loop
Y := (6-i) * 5 - 8; --> X := TMP + 2; Y := (6-i) * 5 - 8;\ \ \ \ \ \ \ --> X := TMP + 2;
i := i - 3; Y := TMP - 8; i := i - 3; Y := TMP - 8;
end loop; i := i - 3; end loop; i := i - 3;
TMP := TMP + 15; TMP := TMP + 15;
end loop; end loop;
.TE
Fig. 6.2 Example of complex Strength Reduction transformations Fig. 6.2 Example of complex Strength Reduction transformations
.DE .DE

View file

@ -64,12 +64,15 @@ The assignment must match one of the EM patterns below.
('x' is the candidate. 'ws' is the word size of the target machine. ('x' is the candidate. 'ws' is the word size of the target machine.
'n' is any number.) 'n' is any number.)
.DS .DS
.TS
l l.
\fIpattern\fR \fIstep size\fR \fIpattern\fR \fIstep size\fR
INL x | +1 INL x | +1
DEL x | -1 DEL x | -1
LOL x ; (INC | DEC) ; STL x | +1 | -1 LOL x ; (INC | DEC) ; STL x | +1 | -1
LOL x ; LOC n ; (ADI ws | SBI ws) ; STL x | +n | -n LOL x ; LOC n ; (ADI ws | SBI ws) ; STL x | +n | -n
LOC n ; LOL x ; ADI ws ; STL x. +n LOC n ; LOL x ; ADI ws ; STL x +n
.TE
.DE .DE
From the patterns the step size of the induction variable From the patterns the step size of the induction variable
can also be determined. can also be determined.
@ -95,6 +98,8 @@ code in front of it.
If an expression is to be optimized, it must If an expression is to be optimized, it must
be generated by the following syntax rules. be generated by the following syntax rules.
.DS .DS
.TS
l l.
optimizable_expr: optimizable_expr:
iv_expr const mult | iv_expr const mult |
const iv_expr mult | const iv_expr mult |
@ -108,6 +113,7 @@ be generated by the following syntax rules.
AAR ws ; AAR ws ;
const: const:
LOC n ; LOC n ;
.TE
.DE .DE
An 'address' is an EM instruction that loads an An 'address' is an EM instruction that loads an
address on the stack. address on the stack.
@ -120,6 +126,8 @@ instructions like LDL are an 'address'.
denote resp. the array address and the denote resp. the array address and the
array descriptor address). array descriptor address).
.DS .DS
.TS
l l.
address: address:
LAE | LAE |
LAL | LAL |
@ -128,9 +136,12 @@ array descriptor address).
LIL ,, | LIL ,, |
LDL if ps=2*ws | LDL if ps=2*ws |
LDE ,, ; LDE ,, ;
.TE
.DE .DE
The notion of an iv-expression was introduced earlier. The notion of an iv-expression was introduced earlier.
.DS .DS
.TS
l l.
iv_expr: iv_expr:
iv_expr unair_op | iv_expr unair_op |
iv_expr iv_expr binary_op | iv_expr iv_expr binary_op |
@ -150,6 +161,7 @@ The notion of an iv-expression was introduced earlier.
LOL x if x is not changed in loop ; LOL x if x is not changed in loop ;
iv: iv:
LOL x if x is an induction variable ; LOL x if x is an induction variable ;
.TE
.DE .DE
An iv_expression must satisfy one additional constraint: An iv_expression must satisfy one additional constraint:
it must use exactly one operand that is an induction it must use exactly one operand that is an induction