Skip to content

Commit 6ae04de

Browse files
#57 WIP sequence parallel copies
1 parent b54ee29 commit 6ae04de

File tree

1 file changed

+53
-91
lines changed
  • optvm/src/main/java/com/compilerprogramming/ezlang/compiler

1 file changed

+53
-91
lines changed

optvm/src/main/java/com/compilerprogramming/ezlang/compiler/ExitSSA2.java

Lines changed: 53 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -133,111 +133,73 @@ private void replaceInstruction(BasicBlock block, Instruction.ParallelCopyInstru
133133
block.replaceInstruction(pcopy, instructions);
134134
}
135135

136-
static final class Copy {
137-
Operand src;
138-
Operand dest;
139-
boolean removed = false;
136+
private boolean isEqual(Operand op1, Operand op2) {
137+
if (op1 instanceof Operand.RegisterOperand reg1 && op2 instanceof Operand.RegisterOperand reg2)
138+
return reg1.reg.id == reg2.reg.id;
139+
return false;
140+
}
140141

141-
public Copy(Operand src, Operand dest) {
142-
this.src = src;
143-
this.dest = dest;
144-
}
142+
// The parallel move algo below is from
143+
// https://xavierleroy.org/publi/parallel-move.pdf
144+
// Tilting at windmills with Coq:
145+
// formal verification of a compilation algorithm
146+
// for parallel moves
147+
// Laurence Rideau, Bernard Paul Serpette, Xavier Leroy
148+
enum MoveStatus {
149+
TO_MOVE, BEING_MOVED, MOVED
145150
}
146151

147-
List<Copy> getCopies(Instruction.ParallelCopyInstruction pcopy) {
148-
List<Copy> copies = new ArrayList<>();
149-
for (int i = 0; i < pcopy.sourceOperands.size(); i++) {
150-
var src = pcopy.sourceOperands.get(i);
151-
var dest = pcopy.destOperands.get(i);
152-
if (src instanceof Operand.RegisterOperand srcR && dest instanceof Operand.RegisterOperand destR) {
153-
if (srcR.reg.id == destR.reg.id)
154-
continue;
155-
}
156-
copies.add(new Copy(src,dest));
152+
static final class MoveCtx {
153+
Operand[] src;
154+
Operand[] dst;
155+
MoveStatus[] status;
156+
ArrayList<Instruction> copyInstructions;
157+
158+
MoveCtx(Instruction.ParallelCopyInstruction pcopy) {
159+
src = pcopy.sourceOperands.toArray(new Operand[0]);
160+
dst = pcopy.destOperands.toArray(new Operand[0]);
161+
copyInstructions = new ArrayList<Instruction>();
162+
status = new MoveStatus[src.length];
163+
Arrays.fill(status, MoveStatus.TO_MOVE);
157164
}
158-
return copies;
159165
}
160166

161-
private void sequenceParallelCopy(BasicBlock block, Instruction.ParallelCopyInstruction pcopy) {
162-
var copyInstructions = new ArrayList<Instruction>();
163-
var copies = getCopies(pcopy);
164-
165-
while (copies.size() > 0) {
166-
boolean progress = false;
167-
168-
for (var copy: copies) {
169-
boolean cycle = false;
170-
for (int i = 0; i < copies.size(); i++) {
171-
if (copy.removed == true)
172-
continue;
173-
if (copy.src.equals(copies.get(i).dest)) {
174-
cycle = true;
175-
break;
167+
private void moveOne(MoveCtx ctx, int i) {
168+
Operand[] src = ctx.src;
169+
Operand[] dst = ctx.dst;
170+
if (!isEqual(src[i], dst[i])) {
171+
ctx.status[i] = MoveStatus.BEING_MOVED;
172+
for (int j = 0; j < src.length; j++) {
173+
if (isEqual(src[j],dst[i])) {
174+
// cycle found
175+
switch (ctx.status[j]) {
176+
case TO_MOVE:
177+
moveOne(ctx, j);
178+
break;
179+
case BEING_MOVED:
180+
var temp = new Operand.RegisterOperand(function.registerPool.newTempReg(src[j].type));
181+
ctx.copyInstructions.add(new Instruction.Move(src[j], temp));
182+
src[j] = temp;
183+
break;
184+
case MOVED:
185+
break;
176186
}
177187
}
178-
if (!cycle) {
179-
copyInstructions.add(new Instruction.Move(copy.src,copy.dest));
180-
copy.removed = true;
181-
progress = true;
182-
}
183188
}
184-
185-
copies.removeIf(c->c.removed);
186-
if (progress)
187-
continue;
188-
189-
var copy = copies.removeFirst();
190-
var temp = new Operand.RegisterOperand(function.registerPool.newTempReg(copy.src.type));
191-
copyInstructions.add(new Instruction.Move(copy.src,temp));
192-
copies.add(new Copy(copy.dest,temp));
189+
ctx.copyInstructions.add(new Instruction.Move(src[i], dst[i]));
190+
ctx.status[i] = MoveStatus.MOVED;
193191
}
194-
replaceInstruction(block,pcopy,copyInstructions);
195192
}
196193

197-
private void sequenceParallelCopyX(BasicBlock block, Instruction.ParallelCopyInstruction pcopy) {
198-
var copyInstructions = new ArrayList<Instruction>();
199-
var ready = new ArrayList<Operand>();
200-
var toDo = new ArrayList<Operand>();
201-
var directPred = new HashMap<Operand,Operand>();
202-
var loc = new HashMap<Operand,Operand>();
203-
for (int i = 0; i <pcopy.sourceOperands.size(); i++) {
204-
var a = pcopy.sourceOperands.get(i);
205-
var b = pcopy.destOperands.get(i);
206-
if (a.equals(b))
207-
continue;
208-
loc.put(a,a);
209-
directPred.put(b,a);
210-
toDo.add(b);
211-
}
212-
for (int i = 0; i <pcopy.sourceOperands.size(); i++) {
213-
var a = pcopy.sourceOperands.get(i);
214-
var b = pcopy.destOperands.get(i);
215-
if (a == b)
216-
continue;
217-
if (loc.get(b) == null)
218-
ready.add(b);
219-
}
220-
while (!toDo.isEmpty()) {
221-
while (!ready.isEmpty()) {
222-
var b = ready.removeLast();
223-
var a = directPred.get(b);
224-
var c = loc.get(a);
225-
copyInstructions.add(new Instruction.Move(c,b));
226-
loc.put(a,b);
227-
if (a == c && directPred.get(a) != null)
228-
ready.add(a);
229-
}
230-
var b = toDo.removeLast();
231-
if (b == loc.get(directPred.get(b))) {
232-
var n = new Operand.RegisterOperand(function.registerPool.newTempReg(b.type));
233-
copyInstructions.add(new Instruction.Move(b,n));
234-
loc.put(b,n);
235-
ready.add(b);
236-
}
237-
}
238-
replaceInstruction(block,pcopy,copyInstructions);
194+
private void sequenceParallelCopy(BasicBlock block, Instruction.ParallelCopyInstruction parallelCopyInstruction) {
195+
var ctx = new MoveCtx(parallelCopyInstruction);
196+
for (int i = 0; i < ctx.src.length; i++)
197+
if (ctx.status[i] == MoveStatus.TO_MOVE)
198+
moveOne(ctx,i);
199+
replaceInstruction(block,parallelCopyInstruction,ctx.copyInstructions);
239200
}
240201

202+
241203
static final class PCopy {
242204
BasicBlock block;
243205
/**

0 commit comments

Comments
 (0)