Made to work with troff
This commit is contained in:
parent
97e131bc81
commit
39730420a2
25 changed files with 583 additions and 456 deletions
|
@ -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
|
||||||
|
|
101
doc/ego/bo/bo1
101
doc/ego/bo/bo1
|
@ -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
|
||||||
N * conditional branch (which fails N-1 times)
|
.TS
|
||||||
N-1 * unconditional branch
|
l l l.
|
||||||
N-1 * body of the loop
|
N * conditional branch (which fails N-1 times)
|
||||||
|
N-1 * unconditional branch
|
||||||
|
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
|
||||||
N * conditional branch (which succeeds N-1 times)
|
.TS
|
||||||
1 * unconditional branch
|
l l l.
|
||||||
N-1 * body of the loop
|
N * conditional branch (which succeeds N-1 times)
|
||||||
|
1 * unconditional branch
|
||||||
|
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
|
||||||
LAB1: S1 LAB1: S1
|
.TS
|
||||||
BRA LAB2 S2
|
l l l l l.
|
||||||
... --> BEQ LAB3
|
LAB1: S1 LAB1: S1
|
||||||
LAB2: S2 ...
|
BRA LAB2 S2
|
||||||
BEQ LAB3 S3
|
... --> BEQ LAB3
|
||||||
S3
|
LAB2: S2 ...
|
||||||
|
BEQ LAB3 S3
|
||||||
|
S3
|
||||||
|
.TE
|
||||||
|
|
||||||
Fig. 10.2 An illegal transformation of Branch Optimization
|
Fig. 10.2 An illegal transformation of Branch Optimization
|
||||||
.DE
|
.DE
|
||||||
|
@ -118,34 +127,36 @@ 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 |
|
||||||
____|____ | |
|
|-----<------| ----->-----|
|
||||||
| | | |-------| |
|
____|____ | |
|
||||||
| S1 | | | v |
|
| | | |-------| |
|
||||||
| Bcc | | | .... |
|
| S1 | | | v |
|
||||||
|--| | | | |
|
| Bcc | | | .... |
|
||||||
| --------- | | ----|---- |
|
|--| | | | |
|
||||||
| | | | | |
|
| --------- | | ----|---- |
|
||||||
| .... ^ | | S2 | |
|
| | | | | |
|
||||||
| | | | | |
|
| .... ^ | | S2 | |
|
||||||
| --------- | | | | |
|
| | | | | |
|
||||||
v | | | ^ --------- |
|
| --------- | | | | |
|
||||||
| | S2 | | | | |
|
v | | | ^ --------- |
|
||||||
| | BRA | | | |-----<-----
|
| | S2 | | | | |
|
||||||
| | | | | v
|
| | BRA | | | |-----<-----
|
||||||
| --------- | | ____|____
|
| | | | | v
|
||||||
| | | | | |
|
| --------- | | ____|____
|
||||||
| ------>------ | | S1 |
|
| | | | | |
|
||||||
| | | Bnn |
|
| ------>------ | | S1 |
|
||||||
|-------| | | |
|
| | | Bnn |
|
||||||
| | ----|----
|
|-------| | | |
|
||||||
v | |
|
| | ----|----
|
||||||
|----<--|
|
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
|
||||||
|
|
|
@ -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.
|
|
||||||
|
|
|
@ -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
|
||||||
A := 10; A:= 10;
|
.TS
|
||||||
P; -- procedure call --> P;
|
l l.
|
||||||
B := A + 2; B := 12;
|
A := 10; A:= 10;
|
||||||
|
P; -- procedure call --> P;
|
||||||
|
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
|
||||||
|
|
100
doc/ego/cj/cj1
100
doc/ego/cj/cj1
|
@ -27,16 +27,18 @@ else
|
||||||
S3
|
S3
|
||||||
|
|
||||||
(pseudo) EM:
|
(pseudo) EM:
|
||||||
|
.TS
|
||||||
TEST COND TEST COND
|
l l l.
|
||||||
BNE *1 BNE *1
|
TEST COND TEST COND
|
||||||
S1 S1
|
BNE *1 BNE *1
|
||||||
S3 ---> BRA *2
|
S1 S1
|
||||||
BRA *2 1:
|
S3 ---> BRA *2
|
||||||
1: S2
|
BRA *2 1:
|
||||||
S2 2:
|
1: S2
|
||||||
S3 S3
|
S2 2:
|
||||||
|
S3 S3
|
||||||
2:
|
2:
|
||||||
|
.TE
|
||||||
|
|
||||||
Fig. 9.1 An example of Cross Jumping
|
Fig. 9.1 An example of Cross Jumping
|
||||||
.DE
|
.DE
|
||||||
|
@ -54,20 +56,23 @@ as demonstrated by the Fig. 8.2.
|
||||||
.DS
|
.DS
|
||||||
Pascal:
|
Pascal:
|
||||||
|
|
||||||
if cond then
|
if cond then
|
||||||
x := f(4)
|
x := f(4)
|
||||||
else
|
else
|
||||||
x := g(5)
|
x := g(5)
|
||||||
|
|
||||||
|
|
||||||
EM:
|
EM:
|
||||||
|
|
||||||
... ...
|
.TS
|
||||||
LOC 4 LOC 5
|
l l.
|
||||||
CAL F CAL G
|
... ...
|
||||||
ASP 2 ASP 2
|
LOC 4 LOC 5
|
||||||
LFR 2 LFR 2
|
CAL F CAL G
|
||||||
STL X STL X
|
ASP 2 ASP 2
|
||||||
|
LFR 2 LFR 2
|
||||||
|
STL X STL X
|
||||||
|
.TE
|
||||||
|
|
||||||
Fig. 9.2 Effectiveness of Cross Jumping
|
Fig. 9.2 Effectiveness of Cross Jumping
|
||||||
.DE
|
.DE
|
||||||
|
@ -92,37 +97,40 @@ 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
|
||||||
|
|
||||||
-------- --------
|
-------- --------
|
||||||
| | | |
|
| | | |
|
||||||
| S1 | | S2 |
|
| S1 | | S2 |
|
||||||
| S3 | | S3 |
|
| S3 | | S3 |
|
||||||
| | | |
|
| | | |
|
||||||
-------- --------
|
-------- --------
|
||||||
| |
|
| |
|
||||||
|------------------|--------------------|
|
|------------------|--------------------|
|
||||||
|
|
|
|
||||||
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 |
|
||||||
| | | |
|
| | | |
|
||||||
-------- --------
|
-------- --------
|
||||||
| |
|
| |
|
||||||
|--------------------<------------------|
|
|--------------------<------------------|
|
||||||
v
|
v
|
||||||
--------
|
--------
|
||||||
| |
|
| |
|
||||||
| S3 |
|
| S3 |
|
||||||
| |
|
| |
|
||||||
--------
|
--------
|
||||||
|
|
|
|
||||||
v
|
v
|
||||||
|
.ft R
|
||||||
|
|
||||||
Fig. 9.4 CFG after optimization
|
Fig. 9.4 CFG after optimization
|
||||||
.DE
|
.DE
|
||||||
|
|
|
@ -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
|
||||||
x := a * b; TMP := a * b; x := a * b;
|
.TS
|
||||||
CODE; x := TMP; CODE
|
l l l.
|
||||||
y := c + a * b; CODE y := x;
|
x := a * b; TMP := a * b; x := a * b;
|
||||||
y := c + TMP;
|
CODE; x := TMP; CODE
|
||||||
|
y := c + a * b; CODE y := x;
|
||||||
|
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
|
||||||
|
|
|
@ -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
|
||||||
x := A[i]; TMP := &A[i];
|
.TS
|
||||||
. . . --> x := *TMP;
|
l l l.
|
||||||
A[i] := y; . . .
|
x := A[i]; TMP := &A[i];
|
||||||
*TMP := y;
|
. . . --> x := *TMP;
|
||||||
|
A[i] := y; . . .
|
||||||
|
*TMP := y;
|
||||||
|
.TE
|
||||||
|
|
||||||
Fig. 7.4 Elimination of an array address computation
|
Fig. 7.4 Elimination of an array address computation
|
||||||
.DE
|
.DE
|
||||||
|
|
|
@ -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
|
||||||
a := c; (1)
|
.TS
|
||||||
|
l l.
|
||||||
|
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.
|
||||||
|
|
|
@ -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
|
||||||
(1) the value number of the operand
|
.TS
|
||||||
(2) the size of the operand
|
l l.
|
||||||
(3) a pointer to the first line of EM-code
|
(1) the value number of the operand
|
||||||
that constitutes the operand
|
(2) the size of the operand
|
||||||
|
(3) a pointer to the first line of EM-code
|
||||||
|
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
|
||||||
(1) the value number of the result
|
.TS
|
||||||
(2) the size of the result
|
l l.
|
||||||
(3) a pointer to the first line of the expression
|
(1) the value number of the result
|
||||||
|
(2) the size of the result
|
||||||
|
(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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
229
doc/ego/ic/ic3
229
doc/ego/ic/ic3
|
@ -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
|
||||||
x a non-terminal symbol
|
.TS
|
||||||
A a terminal symbol (in capitals)
|
l l.
|
||||||
x: a b c; a grammar rule
|
x a non-terminal symbol
|
||||||
a | b a or b
|
A a terminal symbol (in capitals)
|
||||||
(a)+ 1 or more occurrences of a
|
x: a b c; a grammar rule
|
||||||
{a} 0 or more occurrences of a
|
a | b a or b
|
||||||
|
(a)+ 1 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,21 +73,24 @@ identifying number
|
||||||
(see previous section for their use).
|
(see previous section for their use).
|
||||||
.DS
|
.DS
|
||||||
.UL syntax
|
.UL syntax
|
||||||
object_table:
|
.TS
|
||||||
{datablock} ;
|
lw(1i) l l.
|
||||||
datablock:
|
object_table:
|
||||||
D_ID -- unique identifying number
|
{datablock} ;
|
||||||
PSEUDO -- one of ROM,CON,BSS,HOL,UNKNOWN
|
datablock:
|
||||||
SIZE -- # bytes declared
|
D_ID -- unique identifying number
|
||||||
FLAGS
|
PSEUDO -- one of ROM,CON,BSS,HOL,UNKNOWN
|
||||||
{value} -- contents of rom
|
SIZE -- # bytes declared
|
||||||
{object} ; -- objects of the datablock
|
FLAGS
|
||||||
object:
|
{value} -- contents of rom
|
||||||
O_ID -- unique identifying number
|
{object} ; -- objects of the datablock
|
||||||
OFFSET -- offset within the datablock
|
object:
|
||||||
SIZE ; -- size of the object in bytes
|
O_ID -- unique identifying number
|
||||||
value:
|
OFFSET -- offset within the datablock
|
||||||
argument ;
|
SIZE ; -- size of the object in bytes
|
||||||
|
value:
|
||||||
|
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,26 +108,29 @@ The table has one entry for
|
||||||
every procedure.
|
every procedure.
|
||||||
.DS
|
.DS
|
||||||
.UL syntax
|
.UL syntax
|
||||||
procedure_table:
|
.TS
|
||||||
{procedure}
|
lw(1i) l l.
|
||||||
procedure:
|
procedure_table:
|
||||||
P_ID -- unique identifying number
|
{procedure}
|
||||||
#LABELS -- number of instruction labels
|
procedure:
|
||||||
#LOCALS -- number of bytes for locals
|
P_ID -- unique identifying number
|
||||||
#FORMALS -- number of bytes for formals
|
#LABELS -- number of instruction labels
|
||||||
FLAGS -- flag bits
|
#LOCALS -- number of bytes for locals
|
||||||
calling -- procedures called by this one
|
#FORMALS -- number of bytes for formals
|
||||||
change -- info about global variables changed
|
FLAGS -- flag bits
|
||||||
use ; -- info about global variables used
|
calling -- procedures called by this one
|
||||||
calling:
|
change -- info about global variables changed
|
||||||
{P_ID} ; -- procedures called
|
use ; -- info about global variables used
|
||||||
change:
|
calling:
|
||||||
ext -- external variables changed
|
{P_ID} ; -- procedures called
|
||||||
FLAGS ;
|
change:
|
||||||
use:
|
ext -- external variables changed
|
||||||
FLAGS ;
|
FLAGS ;
|
||||||
ext:
|
use:
|
||||||
{O_ID} ; -- a set of objects
|
FLAGS ;
|
||||||
|
ext:
|
||||||
|
{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,38 +240,41 @@ of arguments), then the list is terminated by a special
|
||||||
argument of type CEND.
|
argument of type CEND.
|
||||||
.DS
|
.DS
|
||||||
.UL syntax
|
.UL syntax
|
||||||
em_text:
|
.TS
|
||||||
{line} ;
|
lw(1i) l l.
|
||||||
line:
|
em_text:
|
||||||
INSTR -- opcode
|
{line} ;
|
||||||
OPTYPE -- operand type
|
line:
|
||||||
operand ;
|
INSTR -- opcode
|
||||||
operand:
|
OPTYPE -- operand type
|
||||||
empty | -- OPTYPE = NO
|
operand ;
|
||||||
SHORT | -- OPTYPE = SHORT
|
operand:
|
||||||
OFFSET | -- OPTYPE = OFFSET
|
empty | -- OPTYPE = NO
|
||||||
LAB_ID | -- OPTYPE = INSTRLAB
|
SHORT | -- OPTYPE = SHORT
|
||||||
O_ID | -- OPTYPE = OBJECT
|
OFFSET | -- OPTYPE = OFFSET
|
||||||
P_ID | -- OPTYPE = PROCEDURE
|
LAB_ID | -- OPTYPE = INSTRLAB
|
||||||
{argument} ; -- OPTYPE = LIST
|
O_ID | -- OPTYPE = OBJECT
|
||||||
argument:
|
P_ID | -- OPTYPE = PROCEDURE
|
||||||
ARGTYPE
|
{argument} ; -- OPTYPE = LIST
|
||||||
arg ;
|
argument:
|
||||||
arg:
|
ARGTYPE
|
||||||
empty | -- ARGTYPE = CEND
|
arg ;
|
||||||
OFFSET |
|
arg:
|
||||||
LAB_ID |
|
empty | -- ARGTYPE = CEND
|
||||||
O_ID |
|
OFFSET |
|
||||||
P_ID |
|
LAB_ID |
|
||||||
string | -- ARGTYPE = STRING
|
O_ID |
|
||||||
const ; -- ARGTYPE = ICON,UCON or FCON
|
P_ID |
|
||||||
string:
|
string | -- ARGTYPE = STRING
|
||||||
LENGTH -- number of characters
|
const ; -- ARGTYPE = ICON,UCON or FCON
|
||||||
{CHARACTER} ;
|
string:
|
||||||
const:
|
LENGTH -- number of characters
|
||||||
SIZE -- number of bytes
|
{CHARACTER} ;
|
||||||
string ; -- string representation of (un)signed
|
const:
|
||||||
-- or floating point constant
|
SIZE -- number of bytes
|
||||||
|
string ; -- string representation of (un)signed
|
||||||
|
-- or floating point constant
|
||||||
|
.TE
|
||||||
.DE
|
.DE
|
||||||
.NH 3
|
.NH 3
|
||||||
The control flow graphs
|
The control flow graphs
|
||||||
|
@ -306,24 +318,27 @@ 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
|
||||||
control_flow_graph:
|
.TS
|
||||||
{basic_block} ;
|
lw(1i) l l.
|
||||||
basic_block:
|
control_flow_graph:
|
||||||
B_ID -- unique identifying number
|
{basic_block} ;
|
||||||
#INSTR -- number of EM instructions
|
basic_block:
|
||||||
succ
|
B_ID -- unique identifying number
|
||||||
pred
|
#INSTR -- number of EM instructions
|
||||||
idom -- immediate dominator
|
succ
|
||||||
loops -- set of loops
|
pred
|
||||||
FLAGS ; -- flag bits
|
idom -- immediate dominator
|
||||||
succ:
|
loops -- set of loops
|
||||||
{B_ID} ;
|
FLAGS ; -- flag bits
|
||||||
pred:
|
succ:
|
||||||
{B_ID} ;
|
{B_ID} ;
|
||||||
idom:
|
pred:
|
||||||
B_ID ;
|
{B_ID} ;
|
||||||
loops:
|
idom:
|
||||||
{LP_ID} ;
|
B_ID ;
|
||||||
|
loops:
|
||||||
|
{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,28 +402,30 @@ 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
|
||||||
looptable:
|
.TS
|
||||||
{loop} ;
|
lw(1i) l l.
|
||||||
loop:
|
looptable:
|
||||||
LP_ID -- unique identifying number
|
{loop} ;
|
||||||
LEVEL -- loop nesting level
|
loop:
|
||||||
entry -- loop entry block
|
LP_ID -- unique identifying number
|
||||||
end ;
|
LEVEL -- loop nesting level
|
||||||
entry:
|
entry -- loop entry block
|
||||||
B_ID ;
|
end ;
|
||||||
end:
|
entry:
|
||||||
B_ID ;
|
B_ID ;
|
||||||
|
end:
|
||||||
|
B_ID ;
|
||||||
|
.TE
|
||||||
.DE
|
.DE
|
||||||
|
|
|
@ -57,24 +57,27 @@ indicating which part of the EM text belongs
|
||||||
to that block.
|
to that block.
|
||||||
.DS
|
.DS
|
||||||
.UL syntax
|
.UL syntax
|
||||||
intermediate_code:
|
.TS
|
||||||
object_table_file
|
lw(1i) l l.
|
||||||
proctable_file
|
intermediate_code:
|
||||||
em_text_file
|
object_table_file
|
||||||
cfg_file ;
|
proctable_file
|
||||||
object_table_file:
|
em_text_file
|
||||||
LENGTH -- number of objects
|
cfg_file ;
|
||||||
object_table ;
|
object_table_file:
|
||||||
proctable_file:
|
LENGTH -- number of objects
|
||||||
LENGTH -- number of procedures
|
object_table ;
|
||||||
procedure_table ;
|
proctable_file:
|
||||||
em_text_file:
|
LENGTH -- number of procedures
|
||||||
em_text ;
|
procedure_table ;
|
||||||
cfg_file:
|
em_text_file:
|
||||||
{per_proc} ; -- one for every procedure
|
em_text ;
|
||||||
per_proc:
|
cfg_file:
|
||||||
BLENGTH -- number of basic blocks
|
{per_proc} ; -- one for every procedure
|
||||||
LLENGTH -- number of loops
|
per_proc:
|
||||||
control_flow_graph
|
BLENGTH -- number of basic blocks
|
||||||
looptable ;
|
LLENGTH -- number of loops
|
||||||
|
control_flow_graph
|
||||||
|
looptable ;
|
||||||
|
.TE
|
||||||
.DE
|
.DE
|
||||||
|
|
|
@ -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
|
||||||
LDE X+6 -- Load Double External
|
.TS
|
||||||
LAE X+20 -- Load Address External
|
l l.
|
||||||
|
LDE X+6 -- Load Double 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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -165,19 +165,25 @@ 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
|
||||||
|
|
||||||
procedure r is procedure r is
|
.TS
|
||||||
begin begin
|
lw(2.5i) l.
|
||||||
x(); x();
|
procedure r is procedure r is
|
||||||
p(); -- in line a(); -- nested call
|
begin begin
|
||||||
y(); b(); -- nested call
|
x(); x();
|
||||||
end; y();
|
p(); -- in line a(); -- nested call
|
||||||
end;
|
y(); b(); -- nested call
|
||||||
|
end; y();
|
||||||
|
end;
|
||||||
|
.TE
|
||||||
|
|
||||||
Fig. 5.1 Example of nested procedure calls
|
Fig. 5.1 Example of nested procedure calls
|
||||||
.DE
|
.DE
|
||||||
|
@ -224,11 +230,11 @@ All list traversals look like:
|
||||||
traverse(list)
|
traverse(list)
|
||||||
{
|
{
|
||||||
for (c = first(list); c != 0; c = CDR(c)) {
|
for (c = first(list); c != 0; c = CDR(c)) {
|
||||||
if (c is marked) {
|
if (c is marked) {
|
||||||
traverse(CAR(c));
|
traverse(CAR(c));
|
||||||
} else {
|
} else {
|
||||||
do something with c
|
do something with c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.DE
|
.DE
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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$
|
||||||
.]
|
.]
|
||||||
|
|
|
@ -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
|
||||||
LOL -4 -- push local variable B
|
.TS
|
||||||
LOC 3 -- push constant 3
|
l l.
|
||||||
ADI 2 -- add two 2-byte items on top of
|
LOL -4 -- push local variable B
|
||||||
-- the stack and push the result
|
LOC 3 -- push constant 3
|
||||||
STL -2 -- pop A
|
ADI 2 -- add two 2-byte items on top of
|
||||||
|
-- the stack and push the result
|
||||||
|
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
|
||||||
|
|
|
@ -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
|
||||||
net_bytes_saved = bytes_saved - init_cost
|
.TS
|
||||||
bytes_saved = #occurrences * gains_per_occ
|
l l.
|
||||||
init_cost = #initializations * costs_per_init
|
net_bytes_saved = bytes_saved - init_cost
|
||||||
|
bytes_saved = #occurrences * gains_per_occ
|
||||||
|
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
|
||||||
|
|
|
@ -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
|
||||||
Pascal: EM:
|
.TS
|
||||||
|
l l.
|
||||||
|
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,17 +38,20 @@ 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
|
||||||
Pascal: EM: optimized EM:
|
.TS
|
||||||
|
l l l.
|
||||||
|
Pascal: EM: optimized EM:
|
||||||
|
|
||||||
f(a,2) LOC 2 LOC 2
|
f(a,2) LOC 2 LOC 2
|
||||||
g(3,b,c) LOE A LOE A
|
g(3,b,c) LOE A LOE A
|
||||||
CAL F CAL F
|
CAL F CAL F
|
||||||
ASP 4 LOE C
|
ASP 4 LOE C
|
||||||
LOE C LOE B
|
LOE C LOE B
|
||||||
LOE B LOC 3
|
LOE B LOC 3
|
||||||
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,19 +91,23 @@ 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
|
||||||
Pascal: EM:
|
.TS
|
||||||
|
l l.
|
||||||
|
Pascal: EM:
|
||||||
|
|
||||||
|
5 + f(10) + g(30) LOC 5
|
||||||
|
LOC 10
|
||||||
|
CAL F
|
||||||
|
ASP 2 -- cannot be removed
|
||||||
|
LFR 2 -- push function result
|
||||||
|
ADI 2
|
||||||
|
LOC 30
|
||||||
|
CAL G
|
||||||
|
ASP 2
|
||||||
|
LFR 2
|
||||||
|
ADI 2
|
||||||
|
.TE
|
||||||
|
|
||||||
5 + f(10) + g(30) LOC 5
|
|
||||||
LOC 10
|
|
||||||
CAL F
|
|
||||||
ASP 2 -- cannot be removed
|
|
||||||
LFR 2 -- push function result
|
|
||||||
ADI 2
|
|
||||||
LOC 30
|
|
||||||
CAL G
|
|
||||||
ASP 2
|
|
||||||
LFR 2
|
|
||||||
ADI 2
|
|
||||||
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,19 +115,22 @@ 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
|
||||||
Pascal: EM:
|
.TS
|
||||||
|
l l.
|
||||||
|
Pascal: EM:
|
||||||
|
|
||||||
f(10) + 5 * g(30) LOC 10
|
f(10) + 5 * g(30) LOC 10
|
||||||
CAL F
|
CAL F
|
||||||
ASP 2
|
ASP 2
|
||||||
LFR 2
|
LFR 2
|
||||||
LOC 5
|
LOC 5
|
||||||
LOC 30
|
LOC 30
|
||||||
CAL G
|
CAL G
|
||||||
ASP 2
|
ASP 2
|
||||||
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
|
||||||
|
|
|
@ -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
|
||||||
i := 1; i := 1;
|
.TS
|
||||||
while i < 100 loop --> TMP := i * 118;
|
l l.
|
||||||
put(i * 118); while i < 100 loop
|
i := 1; i := 1;
|
||||||
i := i + 1; put(TMP);
|
while i < 100 loop\ \ \ \ \ \ \ --> TMP := i * 118;
|
||||||
end loop; i := i + 1;
|
put(i * 118); while i < 100 loop
|
||||||
TMP := TMP + 118;
|
i := i + 1; put(TMP);
|
||||||
end loop;
|
end loop; i := i + 1;
|
||||||
|
TMP := TMP + 118;
|
||||||
|
end loop;
|
||||||
|
.TE
|
||||||
|
|
||||||
Fig. 6.1 An example of Strenght Reduction
|
Fig. 6.1 An example of Strenght Reduction
|
||||||
.DE
|
.DE
|
||||||
|
|
|
@ -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
|
||||||
\fIform\fR \fIreplacement\fR
|
.TS
|
||||||
(3) A[iv-expr] := *TMP := (assign indirect)
|
l l l.
|
||||||
(4) A[iv-expr] *TMP (use indirect)
|
\fIform\fR \fIreplacement\fR
|
||||||
(5) &A[iv-expr] TMP
|
(3) A[iv-expr] := *TMP := (assign indirect)
|
||||||
|
(4) A[iv-expr] *TMP (use indirect)
|
||||||
|
(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
|
||||||
i := 100; i := 100;
|
.TS
|
||||||
while i > 1 loop TMP := (6-i) * 5;
|
l l.
|
||||||
X := (6-i) * 5 + 2; while i > 1 loop
|
i := 100; i := 100;
|
||||||
Y := (6-i) * 5 - 8; --> X := TMP + 2;
|
while i > 1 loop TMP := (6-i) * 5;
|
||||||
i := i - 3; Y := TMP - 8;
|
X := (6-i) * 5 + 2; while i > 1 loop
|
||||||
end loop; i := i - 3;
|
Y := (6-i) * 5 - 8;\ \ \ \ \ \ \ --> X := TMP + 2;
|
||||||
TMP := TMP + 15;
|
i := i - 3; Y := TMP - 8;
|
||||||
end loop;
|
end loop; i := i - 3;
|
||||||
|
TMP := TMP + 15;
|
||||||
|
end loop;
|
||||||
|
.TE
|
||||||
|
|
||||||
Fig. 6.2 Example of complex Strength Reduction transformations
|
Fig. 6.2 Example of complex Strength Reduction transformations
|
||||||
.DE
|
.DE
|
||||||
|
|
104
doc/ego/sr/sr3
104
doc/ego/sr/sr3
|
@ -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
|
||||||
\fIpattern\fR \fIstep size\fR
|
.TS
|
||||||
INL x | +1
|
l l.
|
||||||
DEL x | -1
|
\fIpattern\fR \fIstep size\fR
|
||||||
LOL x ; (INC | DEC) ; STL x | +1 | -1
|
INL x | +1
|
||||||
LOL x ; LOC n ; (ADI ws | SBI ws) ; STL x | +n | -n
|
DEL x | -1
|
||||||
LOC n ; LOL x ; ADI ws ; STL x. +n
|
LOL x ; (INC | DEC) ; STL x | +1 | -1
|
||||||
|
LOL x ; LOC n ; (ADI ws | SBI ws) ; STL x | +n | -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,19 +98,22 @@ 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
|
||||||
optimizable_expr:
|
.TS
|
||||||
iv_expr const mult |
|
l l.
|
||||||
const iv_expr mult |
|
optimizable_expr:
|
||||||
address iv_expr address array_instr;
|
iv_expr const mult |
|
||||||
mult:
|
const iv_expr mult |
|
||||||
MLI ws |
|
address iv_expr address array_instr;
|
||||||
MLU ws ;
|
mult:
|
||||||
array_instr:
|
MLI ws |
|
||||||
LAR ws |
|
MLU ws ;
|
||||||
SAR ws |
|
array_instr:
|
||||||
AAR ws ;
|
LAR ws |
|
||||||
const:
|
SAR ws |
|
||||||
LOC n ;
|
AAR ws ;
|
||||||
|
const:
|
||||||
|
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,36 +126,42 @@ 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
|
||||||
address:
|
.TS
|
||||||
LAE |
|
l l.
|
||||||
LAL |
|
address:
|
||||||
LOL if ps=ws |
|
LAE |
|
||||||
LOE ,, |
|
LAL |
|
||||||
LIL ,, |
|
LOL if ps=ws |
|
||||||
LDL if ps=2*ws |
|
LOE ,, |
|
||||||
LDE ,, ;
|
LIL ,, |
|
||||||
|
LDL if ps=2*ws |
|
||||||
|
LDE ,, ;
|
||||||
|
.TE
|
||||||
.DE
|
.DE
|
||||||
The notion of an iv-expression was introduced earlier.
|
The notion of an iv-expression was introduced earlier.
|
||||||
.DS
|
.DS
|
||||||
iv_expr:
|
.TS
|
||||||
iv_expr unair_op |
|
l l.
|
||||||
iv_expr iv_expr binary_op |
|
iv_expr:
|
||||||
loopconst |
|
iv_expr unair_op |
|
||||||
iv ;
|
iv_expr iv_expr binary_op |
|
||||||
unair_op:
|
loopconst |
|
||||||
NGI ws |
|
iv ;
|
||||||
INC |
|
unair_op:
|
||||||
DEC ;
|
NGI ws |
|
||||||
binary_op:
|
INC |
|
||||||
ADI ws |
|
DEC ;
|
||||||
ADU ws |
|
binary_op:
|
||||||
SBI ws |
|
ADI ws |
|
||||||
SBU ws ;
|
ADU ws |
|
||||||
loopconst:
|
SBI ws |
|
||||||
const |
|
SBU ws ;
|
||||||
LOL x if x is not changed in loop ;
|
loopconst:
|
||||||
iv:
|
const |
|
||||||
LOL x if x is an induction variable ;
|
LOL x if x is not changed in loop ;
|
||||||
|
iv:
|
||||||
|
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
|
||||||
|
|
Loading…
Add table
Reference in a new issue