use of de.mirkosertic.bytecoder.ssa.ExpressionList in project Bytecoder by mirkosertic.
the class InlineGotoOptimizerTest method testIf.
@Test
public void testIf() {
Program theProgram = new Program();
ControlFlowGraph theGraph = theProgram.getControlFlowGraph();
RegionNode theNode = theGraph.createAt(BytecodeOpcodeAddress.START_AT_ZERO, RegionNode.BlockType.NORMAL);
RegionNode theNode1 = theGraph.createAt(new BytecodeOpcodeAddress(20), RegionNode.BlockType.NORMAL);
RegionNode theNode2 = theGraph.createAt(new BytecodeOpcodeAddress(40), RegionNode.BlockType.NORMAL);
RegionNode theNode3 = theGraph.createAt(new BytecodeOpcodeAddress(60), RegionNode.BlockType.NORMAL);
theNode.addSuccessor(theNode1);
theNode.addSuccessor(theNode2);
ExpressionList theTrueClause = new ExpressionList();
theTrueClause.add(new GotoExpression(new BytecodeOpcodeAddress(20)));
IFExpression theIF = new IFExpression(new BytecodeOpcodeAddress(0), new BytecodeOpcodeAddress(20), new IntegerValue(10), theTrueClause);
theNode.getExpressions().add(theIF);
theNode.getExpressions().add(new GotoExpression(new BytecodeOpcodeAddress(40)));
theNode1.addSuccessor(theNode3);
theNode1.getExpressions().add(new GotoExpression(new BytecodeOpcodeAddress(60)));
theNode2.addSuccessor(theNode3);
theNode2.getExpressions().add(new GotoExpression(new BytecodeOpcodeAddress(60)));
theNode3.getExpressions().add(new ReturnExpression());
theGraph.calculateReachabilityAndMarkBackEdges();
InlineGotoOptimizer theOptimizer = new InlineGotoOptimizer();
theOptimizer.optimize(theGraph, null);
System.out.println(theGraph.toDOT());
}
use of de.mirkosertic.bytecoder.ssa.ExpressionList in project Bytecoder by mirkosertic.
the class Relooper method replaceGotosIn.
private void replaceGotosIn(Stack<Block> aTraversalStack, SimpleBlock aCurrent, RegionNode aLabel, ExpressionList aList) {
for (Expression theExpression : aList.toList()) {
if (theExpression instanceof ExpressionListContainer) {
ExpressionListContainer theContainer = (ExpressionListContainer) theExpression;
for (ExpressionList theList : theContainer.getExpressionLists()) {
replaceGotosIn(aTraversalStack, aCurrent, aLabel, theList);
}
}
if (theExpression instanceof GotoExpression) {
GotoExpression theGoto = (GotoExpression) theExpression;
boolean theGotoFound = false;
// We search the successor edge
for (Map.Entry<RegionNode.Edge, RegionNode> theSuc : aLabel.getSuccessors().entrySet()) {
if (Objects.equals(theSuc.getValue().getStartAddress(), theGoto.getJumpTarget())) {
theGotoFound = true;
RegionNode theTarget = theSuc.getValue();
// We found the matching edge
if (theSuc.getKey().getType() == RegionNode.EdgeType.NORMAL) {
// We can only branch to the next block
// We search the whole hiararchy to find the right block to break out
boolean theSomethingFound = false;
for (int i = aTraversalStack.size() - 1; i >= 0; i--) {
Block theNestingBlock = aTraversalStack.get(i);
if (theNestingBlock.next() != null && theNestingBlock.next().entries().contains(theTarget)) {
theNestingBlock.requireLabel();
BreakExpression theBreak = new BreakExpression(theNestingBlock.label(), theTarget.getStartAddress());
aList.replace(theGoto, theBreak);
if (theNestingBlock.next() instanceof SimpleBlock && theNestingBlock.next().entries().size() == 1) {
theBreak.noSetRequired();
}
theSomethingFound = true;
break;
} else if (theNestingBlock.entries().contains(theTarget)) {
theNestingBlock.requireLabel();
ContinueExpression theContinue = new ContinueExpression(theNestingBlock.label(), theTarget.getStartAddress());
aList.replace(theGoto, theContinue);
theSomethingFound = true;
break;
}
}
if (!theSomethingFound) {
throw new IllegalStateException("Failed to jump to " + theTarget.getStartAddress().getAddress() + " from " + aCurrent.label().name() + " : no matching entry found!");
}
} else {
// We can only branch back into the known stack of nested blocks
boolean theSomethingFound = false;
for (Block theNestingBlock : aTraversalStack) {
if (theNestingBlock.entries().contains(theTarget)) {
theSomethingFound = true;
// We can return to the target in the hierarchy
theNestingBlock.requireLabel();
ContinueExpression theContinue = new ContinueExpression(theNestingBlock.label(), theTarget.getStartAddress());
aList.replace(theGoto, theContinue);
break;
}
}
if (!theSomethingFound) {
throw new IllegalStateException("No back edge target found for " + theTarget.getStartAddress().getAddress());
}
}
}
}
if (!theGotoFound) {
throw new IllegalStateException("No GOTO possible for " + theGoto.getJumpTarget().getAddress() + " in label " + aCurrent.label().name());
}
}
}
}
use of de.mirkosertic.bytecoder.ssa.ExpressionList in project Bytecoder by mirkosertic.
the class OpenCLWriter method writeExpressions.
private void writeExpressions(ExpressionList aList) {
for (Expression theExpression : aList.toList()) {
if (options.isDebugOutput()) {
String theComment = theExpression.getComment();
if (theComment != null && !theComment.isEmpty()) {
print("// ");
println(theComment);
}
}
if (theExpression instanceof VariableAssignmentExpression) {
VariableAssignmentExpression theInit = (VariableAssignmentExpression) theExpression;
Variable theVariable = theInit.getVariable();
Value theValue = theInit.getValue();
if (theVariable.resolveType().isObject() && theValue instanceof InvocationExpression) {
print(toType(theVariable.resolveType(), false));
print(" ");
print(theVariable.getName());
print("_temp = ");
printValue(theValue);
println(";");
print(theVariable.getName());
print(" = &");
print(theVariable.getName());
println("_temp;");
} else {
print(theVariable.getName());
print(" = ");
printValue(theValue);
println(";");
}
} else if (theExpression instanceof ArrayStoreExpression) {
ArrayStoreExpression theStore = (ArrayStoreExpression) theExpression;
List<Value> theIncomingData = theStore.incomingDataFlows();
Value theArray = theIncomingData.get(0);
Value theIndex = theIncomingData.get(1);
Value theValue = theIncomingData.get(2);
printValue(theArray);
print("[");
printValue(theIndex);
print("] = ");
printValue(theValue);
println(";");
} else if (theExpression instanceof IFExpression) {
IFExpression theE = (IFExpression) theExpression;
print("if ");
printValue(theE.incomingDataFlows().get(0));
println(" {");
withDeeperIndent().writeExpressions(theE.getExpressions());
println("}");
} else if (theExpression instanceof BreakExpression) {
BreakExpression theBreak = (BreakExpression) theExpression;
if (theBreak.isSetLabelRequired()) {
print("$__label__ = ");
print(theBreak.jumpTarget().getAddress());
println(";");
}
if (!theBreak.isSilent()) {
print("goto $");
print(theBreak.blockToBreak().name());
println("_next;");
}
} else if (theExpression instanceof ContinueExpression) {
ContinueExpression theContinue = (ContinueExpression) theExpression;
print("$__label__ = ");
print(theContinue.jumpTarget().getAddress());
println(";");
print("goto $");
print(theContinue.labelToReturnTo().name());
println(";");
} else if (theExpression instanceof ReturnExpression) {
println("return;");
} else if (theExpression instanceof PutFieldExpression) {
PutFieldExpression thePutField = (PutFieldExpression) theExpression;
List<Value> theIncomingData = thePutField.incomingDataFlows();
Value theTarget = theIncomingData.get(0);
BytecodeFieldRefConstant theField = thePutField.getField();
Value thevalue = theIncomingData.get(1);
printValue(theTarget);
printInstanceFieldReference(theField);
print(" = ");
printValue(thevalue);
println(";");
} else if (theExpression instanceof ReturnValueExpression) {
ReturnValueExpression theReturn = (ReturnValueExpression) theExpression;
List<Value> theIncomingData = theReturn.incomingDataFlows();
print("return ");
printValue(theIncomingData.get(0));
println(";");
} else {
throw new IllegalArgumentException("Not supported. " + theExpression);
}
}
}
use of de.mirkosertic.bytecoder.ssa.ExpressionList in project Bytecoder by mirkosertic.
the class WASMSSAWriter method writeTableSwitchExpression.
private void writeTableSwitchExpression(TableSwitchExpression aExpression) {
println("(block $tableswitch");
Value theValue = aExpression.incomingDataFlows().get(0);
WASMSSAWriter theChild1 = withDeeperIndent();
theChild1.println("(block $label$0");
WASMSSAWriter theChild2 = theChild1.withDeeperIndent();
theChild2.println("(block $label$1");
WASMSSAWriter theChild3 = theChild2.withDeeperIndent();
theChild3.print("(br_if $label$1 (i32.lt_s ");
theChild3.writeValue(theValue);
theChild3.print(" (i32.const ");
theChild3.print(aExpression.getLowValue());
theChild3.println(")))");
theChild3.print("(br_if $label$0 (i32.le_s ");
theChild3.writeValue(theValue);
theChild3.print(" (i32.const ");
theChild3.print(aExpression.getHighValue());
theChild3.println(")))");
theChild3.writeExpressionList(aExpression.getDefaultExpressions());
theChild3.println();
theChild3.println("(br $tableswitch)");
theChild2.println(")");
theChild1.println(")");
WASMSSAWriter theChild4 = withDeeperIndent();
// For each statement
for (Map.Entry<Long, ExpressionList> theEntry : aExpression.getOffsets().entrySet()) {
theChild4.print("(block $switch_");
theChild4.print(theEntry.getKey());
theChild4.println();
WASMSSAWriter theChild5 = theChild4.withDeeperIndent();
theChild5.print("(br_if $switch_");
theChild5.print(theEntry.getKey());
theChild5.print(" (i32.ne (i32.const ");
theChild5.print(theEntry.getKey());
theChild5.print(") (i32.sub ");
theChild5.writeValue(theValue);
theChild5.print(" (i32.const ");
theChild5.print(aExpression.getLowValue());
theChild5.print("))))");
theChild5.println();
theChild5.writeExpressionList(theEntry.getValue());
theChild5.println();
theChild4.println(")");
}
println(")");
println("(unreachable)");
}
use of de.mirkosertic.bytecoder.ssa.ExpressionList in project Bytecoder by mirkosertic.
the class WASMSSAWriter method writeLookupSwitchExpression.
private void writeLookupSwitchExpression(LookupSwitchExpression aExpression) {
println("(block $outer");
Value theValue = aExpression.incomingDataFlows().get(0);
WASMSSAWriter theChild2 = withDeeperIndent();
// For each statement
for (Map.Entry<Long, ExpressionList> theEntry : aExpression.getPairs().entrySet()) {
theChild2.print("(block $switch_");
theChild2.print(theEntry.getKey());
theChild2.println();
WASMSSAWriter theChild3 = theChild2.withDeeperIndent();
theChild3.print("(br_if $switch_");
theChild3.print(theEntry.getKey());
theChild3.print(" (i32.ne (i32.const ");
theChild3.print(theEntry.getKey());
theChild3.print(") ");
theChild3.writeValue(theValue);
theChild3.print("))");
theChild3.println();
theChild3.writeExpressionList(theEntry.getValue());
theChild3.println();
theChild3.writeExpressionList(theEntry.getValue());
theChild3.println("(br $outer)");
theChild2.println(")");
}
writeExpressionList(aExpression.getDefaultExpressions());
println(")");
}
Aggregations