Adds phi instruction eliminator

This commit is contained in:
konsoletyper 2013-10-01 22:10:25 +04:00
parent 4e4d0cfe9e
commit 3d12aed446
2 changed files with 45 additions and 3 deletions

View File

@ -87,6 +87,7 @@ public class MethodDecompiler {
generator.program = program; generator.program = program;
generator.blockMap = blockMap; generator.blockMap = blockMap;
generator.indexer = indexer; generator.indexer = indexer;
generator.outgoings = getPhiOutgoings(program);
parentNode = codeTree.getRoot(); parentNode = codeTree.getRoot();
currentNode = parentNode.getFirstChild(); currentNode = parentNode.getFirstChild();
for (int i = 0; i < this.graph.size(); ++i) { for (int i = 0; i < this.graph.size(); ++i) {
@ -128,6 +129,26 @@ public class MethodDecompiler {
return renderable; return renderable;
} }
private Incoming[][] getPhiOutgoings(Program program) {
List<List<Incoming>> outgoings = new ArrayList<>();
for (int i = 0; i < program.basicBlockCount(); ++i) {
outgoings.add(new ArrayList<Incoming>());
}
for (int i = 0; i < program.basicBlockCount(); ++i) {
BasicBlock basicBlock = program.basicBlockAt(i);
for (Phi phi : basicBlock.getPhis()) {
for (Incoming incoming : phi.getIncomings()) {
outgoings.get(incoming.getSource().getIndex()).add(incoming);
}
}
}
Incoming[][] result = new Incoming[outgoings.size()][];
for (int i = 0; i < outgoings.size(); ++i) {
result[i] = outgoings.get(i).toArray(new Incoming[0]);
}
return result;
}
private List<Block> createBlocks(int start) { private List<Block> createBlocks(int start) {
List<Block> result = new ArrayList<>(); List<Block> result = new ArrayList<>();
while (currentNode != null && currentNode.getStart() == start) { while (currentNode != null && currentNode.getStart() == start) {

View File

@ -21,6 +21,7 @@ public class StatementGenerator implements InstructionVisitor {
MethodDecompiler.Block[] blockMap; MethodDecompiler.Block[] blockMap;
Program program; Program program;
ClassHolderSource classSource; ClassHolderSource classSource;
Incoming[][] outgoings;
@Override @Override
public void visit(EmptyInstruction insn) { public void visit(EmptyInstruction insn) {
@ -527,7 +528,7 @@ public class StatementGenerator implements InstructionVisitor {
assign(castToInteger(Expr.binary(op, Expr.var(first), Expr.var(second))), result); assign(castToInteger(Expr.binary(op, Expr.var(first), Expr.var(second))), result);
} }
private Statement generateJumpStatement(BasicBlock target) { private Statement generateJumpStatementWithoutPhis(BasicBlock target) {
if (nextBlock == target) { if (nextBlock == target) {
return null; return null;
} }
@ -543,8 +544,24 @@ public class StatementGenerator implements InstructionVisitor {
} }
} }
private Statement generateJumpStatement(SwitchStatement stmt, int target) { private Statement wrapWithPhis(Statement rawJump) {
Statement body = generateJumpStatement(program.basicBlockAt(target)); SequentialStatement seq = new SequentialStatement();
for (Incoming outgoing : outgoings[currentBlock.getIndex()]) {
seq.getSequence().add(Statement.assign(Expr.var(outgoing.getPhi().getReceiver().getIndex()),
Expr.var(outgoing.getValue().getIndex())));
}
if (rawJump != null) {
seq.getSequence().add(rawJump);
}
return !seq.getSequence().isEmpty() ? seq : null;
}
private Statement generateJumpStatement(BasicBlock target) {
return wrapWithPhis(generateJumpStatementWithoutPhis(target));
}
private Statement generateJumpStatementWithoutPhis(SwitchStatement stmt, int target) {
Statement body = generateJumpStatementWithoutPhis(program.basicBlockAt(target));
if (body == null) { if (body == null) {
BreakStatement breakStmt = new BreakStatement(); BreakStatement breakStmt = new BreakStatement();
breakStmt.setTarget(stmt); breakStmt.setTarget(stmt);
@ -553,6 +570,10 @@ public class StatementGenerator implements InstructionVisitor {
return body; return body;
} }
private Statement generateJumpStatement(SwitchStatement stmt, int target) {
return wrapWithPhis(generateJumpStatementWithoutPhis(stmt, target));
}
private void branch(Expr condition, BasicBlock consequentBlock, BasicBlock alternativeBlock) { private void branch(Expr condition, BasicBlock consequentBlock, BasicBlock alternativeBlock) {
Statement consequent = generateJumpStatement(consequentBlock); Statement consequent = generateJumpStatement(consequentBlock);
Statement alternative = generateJumpStatement(alternativeBlock); Statement alternative = generateJumpStatement(alternativeBlock);