Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit b979315

Browse files
#57 Implement phase 1 of SSA Exit - make conventional SSA
1 parent 109fdc2 commit b979315

File tree

3 files changed

+195
-0
lines changed

3 files changed

+195
-0
lines changed

‎optvm/src/main/java/com/compilerprogramming/ezlang/compiler/BasicBlock.java‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,11 @@ public int whichPred(BasicBlock pred) {
158158
}
159159
throw new IllegalStateException();
160160
}
161+
public BasicBlock predecessor(int i) {
162+
if (i >= predecessors.size())
163+
return null;
164+
return predecessors.get(i);
165+
}
161166
public int whichSucc(BasicBlock succ) {
162167
int i = 0;
163168
for (BasicBlock s: successors) {
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
package com.compilerprogramming.ezlang.compiler;
2+
3+
import java.util.*;
4+
5+
/**
6+
* Implement method to exit SSA by converting to conventional SSA,
7+
* without coalescing. This is the basic form.
8+
*/
9+
public class ExitSSA2 {
10+
11+
CompiledFunction function;
12+
Map<BasicBlock,PCopy> parallelCopies = new HashMap<>();
13+
List<BasicBlock> allBlocks;
14+
15+
public ExitSSA2(CompiledFunction function, EnumSet<Options> options) {
16+
this.function = function;
17+
allBlocks = function.getBlocks();
18+
insertPCopiesForEachBlock();
19+
makeConventionalSSA();
20+
removePhis();
21+
sequentialzeParallelCopies();
22+
}
23+
24+
private void insertPCopiesForEachBlock() {
25+
// We do not actually insert pcopy instruction until needed
26+
// but we create an auxiliary data structure to help us track these
27+
for (BasicBlock block: allBlocks) {
28+
parallelCopies.put(block,new PCopy(block));
29+
}
30+
}
31+
private void insertAtEnd(BasicBlock bb, Instruction i) {
32+
assert bb.instructions.size() > 0;
33+
// Last instruction is a branch - so new instruction will
34+
// go before that
35+
int pos = bb.instructions.size()-1;
36+
bb.add(pos, i);
37+
}
38+
39+
private Instruction.ParallelCopyInstruction getParallelCopyAtEnd(BasicBlock block) {
40+
PCopy pcopy = parallelCopies.get(block);
41+
if (pcopy.pCopyEnd == null) {
42+
pcopy.pCopyEnd = new Instruction.ParallelCopyInstruction();
43+
insertAtEnd(block,pcopy.pCopyEnd);
44+
}
45+
return pcopy.pCopyEnd;
46+
}
47+
48+
private void insertAfterPhis(BasicBlock bb, Instruction newInst) {
49+
assert bb.instructions.size() > 0;
50+
int insertionPos = -1;
51+
for (int pos = 0; pos < bb.instructions.size(); pos++) {
52+
Instruction i = bb.instructions.get(pos);
53+
if (i instanceof Instruction.Phi) {
54+
insertionPos = pos+1; // After phi
55+
}
56+
else
57+
break;
58+
}
59+
if (insertionPos < 0) {
60+
throw new IllegalStateException();
61+
}
62+
bb.add(insertionPos, newInst);
63+
}
64+
65+
private Instruction.ParallelCopyInstruction getParallelCopyAtBegin(BasicBlock block) {
66+
PCopy pcopy = parallelCopies.get(block);
67+
if (pcopy.pCopyBegin == null) {
68+
pcopy.pCopyBegin = new Instruction.ParallelCopyInstruction();
69+
insertAfterPhis(block,pcopy.pCopyBegin);
70+
}
71+
return pcopy.pCopyBegin;
72+
}
73+
74+
/**
75+
* Isolate phi nodes to make SSA conventionalS
76+
* This is Phase 1 as described in Engineering a Compiler 3rd Edition, p490.
77+
*/
78+
private void makeConventionalSSA() {
79+
var blocks = function.getBlocks();
80+
for (BasicBlock block: blocks) {
81+
var phis = block.phis();
82+
if (phis.isEmpty())
83+
continue;
84+
for (var phi: phis) {
85+
for (int j = 0; j < phi.numInputs(); j++) {
86+
BasicBlock pred = block.predecessor(j);
87+
var pCopyBEnd = getParallelCopyAtEnd(pred);
88+
var oldInput = phi.input(j);
89+
var newInput = function.registerPool.newTempReg(oldInput.type);
90+
pCopyBEnd.addCopy(oldInput,new Operand.RegisterOperand(newInput));
91+
phi.replaceInput(j,newInput);
92+
}
93+
var oldPhiVar = phi.value();
94+
var newPhiVar = function.registerPool.newTempReg(oldPhiVar.type);
95+
phi.replaceValue(newPhiVar);
96+
var pCopyBBegin = getParallelCopyAtBegin(block);
97+
pCopyBBegin.addCopy(new Operand.RegisterOperand(newPhiVar),new Operand.RegisterOperand(oldPhiVar));
98+
}
99+
}
100+
}
101+
102+
private void removePhis() {
103+
104+
}
105+
106+
private void sequentialzeParallelCopies() {
107+
108+
}
109+
110+
static final class PCopy {
111+
BasicBlock block;
112+
/**
113+
* Parallel copy instruction after any Phi instructions
114+
* in the block, null if not present
115+
*/
116+
Instruction.ParallelCopyInstruction pCopyBegin = null;
117+
/**
118+
* Parallel copy instruction at the end of a block,
119+
* null if not present
120+
*/
121+
Instruction.ParallelCopyInstruction pCopyEnd = null;
122+
123+
public PCopy(BasicBlock block) {
124+
this.block = block;
125+
}
126+
}
127+
}

‎optvm/src/main/java/com/compilerprogramming/ezlang/compiler/Instruction.java‎

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ public abstract class Instruction {
2525
static final int I_ARRAY_LOAD = 13;
2626
static final int I_FIELD_GET = 14;
2727
static final int I_FIELD_SET = 15;
28+
static final int I_PARALLEL_COPY = 16;
2829

2930
public final int opcode;
3031
protected Operand.RegisterOperand def;
@@ -477,5 +478,67 @@ public StringBuilder toStr(StringBuilder sb) {
477478
}
478479
}
479480

481+
/**
482+
* The parallel copy instruction is only used temporarily to exit
483+
* SSA form. It represents the parallel copy semantics of phi instructions.
484+
*/
485+
public static class ParallelCopyInstruction extends Instruction {
486+
487+
List<Operand> sourceOperands = new ArrayList<>();
488+
List<Operand.RegisterOperand> destOperands = new ArrayList<>();
489+
490+
protected ParallelCopyInstruction() {
491+
super(I_PARALLEL_COPY);
492+
}
493+
494+
@Override
495+
public StringBuilder toStr(StringBuilder sb) {
496+
sb.append("(");
497+
for (int i = 0; i < destOperands.size(); i++) {
498+
if (i > 0)
499+
sb.append(",");
500+
sb.append(destOperands.get(i));
501+
}
502+
sb.append(") = (");
503+
for (int i = 0; i < sourceOperands.size(); i++) {
504+
if (i > 0)
505+
sb.append(",");
506+
sb.append(sourceOperands.get(i));
507+
}
508+
sb.append(")");
509+
return sb;
510+
}
511+
512+
public void addCopy(Operand sourceOperand, Operand.RegisterOperand destOperand) {
513+
sourceOperands.add(sourceOperand);
514+
destOperands.add(destOperand);
515+
}
516+
517+
@Override
518+
public Register def() {
519+
throw new UnsupportedOperationException();
520+
}
521+
@Override
522+
public void replaceDef(Register newDef) {
523+
throw new UnsupportedOperationException();
524+
}
525+
@Override
526+
public boolean definesVar() {
527+
return false;
528+
}
529+
@Override
530+
public List<Register> uses() {
531+
return Collections.emptyList();
532+
}
533+
@Override
534+
public void replaceUses(Register[] newUses) {
535+
throw new UnsupportedOperationException();
536+
}
537+
@Override
538+
public boolean replaceUse(Register source, Register target) {
539+
throw new UnsupportedOperationException();
540+
}
541+
}
542+
480543
public abstract StringBuilder toStr(StringBuilder sb);
481544
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /