use of de.mirkosertic.bytecoder.ssa.GotoExpression in project Bytecoder by mirkosertic.
the class WASMSSAWriter method writeExpression.
private void writeExpression(Expression aExpression) {
if (options.isDebugOutput()) {
String theComment = aExpression.getComment();
if (theComment != null && !theComment.isEmpty()) {
print(";; ");
println(theComment);
}
}
if (aExpression instanceof CheckCastExpression) {
return;
}
if (aExpression instanceof ReturnExpression) {
writeReturnExpression((ReturnExpression) aExpression);
return;
}
if (aExpression instanceof VariableAssignmentExpression) {
writeInitVariableExpression((VariableAssignmentExpression) aExpression);
return;
}
if (aExpression instanceof DirectInvokeMethodExpression) {
writeDirectMethodInvokeExpression((DirectInvokeMethodExpression) aExpression);
return;
}
if (aExpression instanceof IFExpression) {
writeIFExpression((IFExpression) aExpression);
return;
}
if (aExpression instanceof GotoExpression) {
writeGotoExpression((GotoExpression) aExpression);
return;
}
if (aExpression instanceof ReturnValueExpression) {
writeReturnExpression((ReturnValueExpression) aExpression);
return;
}
if (aExpression instanceof PutFieldExpression) {
writePutFieldExpression((PutFieldExpression) aExpression);
return;
}
if (aExpression instanceof SetMemoryLocationExpression) {
writeSetMemoryLocationExpression((SetMemoryLocationExpression) aExpression);
return;
}
if (aExpression instanceof PutStaticExpression) {
writePutStaticExpression((PutStaticExpression) aExpression);
return;
}
if (aExpression instanceof InvokeStaticMethodExpression) {
writeInvokeStaticExpression((InvokeStaticMethodExpression) aExpression);
return;
}
if (aExpression instanceof ThrowExpression) {
writeThrowExpression((ThrowExpression) aExpression);
return;
}
if (aExpression instanceof ArrayStoreExpression) {
writeArrayStoreExpression((ArrayStoreExpression) aExpression);
return;
}
if (aExpression instanceof InvokeVirtualMethodExpression) {
writeInvokeVirtualExpression((InvokeVirtualMethodExpression) aExpression);
return;
}
if (aExpression instanceof TableSwitchExpression) {
writeTableSwitchExpression((TableSwitchExpression) aExpression);
return;
}
if (aExpression instanceof LookupSwitchExpression) {
writeLookupSwitchExpression((LookupSwitchExpression) aExpression);
return;
}
if (aExpression instanceof UnreachableExpression) {
writeUnreachable((UnreachableExpression) aExpression);
return;
}
if (aExpression instanceof BreakExpression) {
BreakExpression theBreak = (BreakExpression) aExpression;
if (theBreak.isSetLabelRequired()) {
print("(set_local $__label__ (i32.const ");
print(theBreak.jumpTarget().getAddress());
println("))");
}
if (!theBreak.isSilent()) {
print("(br $");
print(theBreak.blockToBreak().name());
println(")");
}
return;
}
if (aExpression instanceof ContinueExpression) {
ContinueExpression theContinue = (ContinueExpression) aExpression;
print("(set_local $__label__ (i32.const ");
print(theContinue.jumpTarget().getAddress());
println("))");
print("(br $");
print(theContinue.labelToReturnTo().name());
println("_inner)");
return;
}
throw new IllegalStateException("Not supported : " + aExpression);
}
use of de.mirkosertic.bytecoder.ssa.GotoExpression in project Bytecoder by mirkosertic.
the class InlineFinalNodesOptimizer method inline.
private void inline(Map<BytecodeOpcodeAddress, RegionNode> aFinalNodes, ExpressionList aList) {
for (Expression theExpression : aList.toList()) {
if (theExpression instanceof ExpressionListContainer) {
ExpressionListContainer theContainer = (ExpressionListContainer) theExpression;
for (ExpressionList theList : theContainer.getExpressionLists()) {
inline(aFinalNodes, theList);
}
}
if (theExpression instanceof GotoExpression) {
GotoExpression theGoto = (GotoExpression) theExpression;
RegionNode thePotentialFinal = aFinalNodes.get(theGoto.getJumpTarget());
if (thePotentialFinal != null) {
aList.replace(theExpression, thePotentialFinal.getExpressions());
}
}
}
}
use of de.mirkosertic.bytecoder.ssa.GotoExpression in project Bytecoder by mirkosertic.
the class InlineGotoOptimizer method performNodeInlining.
private boolean performNodeInlining(ControlFlowGraph aGraph, RegionNode aNode, ExpressionList aList, List<BytecodeOpcodeAddress> aJumpTargets) {
for (Expression theExpression : aList.toList()) {
if (theExpression instanceof ExpressionListContainer) {
ExpressionListContainer theContainer = (ExpressionListContainer) theExpression;
for (ExpressionList theList : theContainer.getExpressionLists()) {
if (performNodeInlining(aGraph, aNode, theList, aJumpTargets)) {
return true;
}
}
}
if (theExpression instanceof GotoExpression) {
GotoExpression theGOTO = (GotoExpression) theExpression;
RegionNode theTargetNode = aGraph.nodeStartingAt(theGOTO.getJumpTarget());
if (theTargetNode.isStrictlyDominatedBy(aNode)) {
BytecodeOpcodeAddress theJumpTarget = theGOTO.getJumpTarget();
int theCount = 0;
for (BytecodeOpcodeAddress theEntry : aJumpTargets) {
if (theEntry.equals(theJumpTarget)) {
theCount++;
}
}
if (theCount == 1) {
// Node can be inlined
aGraph.delete(theTargetNode);
aList.replace(theGOTO, theTargetNode.getExpressions());
aNode.inheritSuccessorsOf(theTargetNode);
for (RegionNode theNode : aGraph.getKnownNodes()) {
recomputeGotos(theNode.getExpressions(), theTargetNode.getStartAddress(), aNode.getStartAddress());
}
return true;
}
}
}
}
return false;
}
use of de.mirkosertic.bytecoder.ssa.GotoExpression in project Bytecoder by mirkosertic.
the class InlineGotoOptimizer method recomputeGotos.
private void recomputeGotos(ExpressionList aList, BytecodeOpcodeAddress aOriginal, BytecodeOpcodeAddress aNew) {
for (Expression theExpression : aList.toList()) {
if (theExpression instanceof ExpressionListContainer) {
ExpressionListContainer theContainer = (ExpressionListContainer) theExpression;
for (ExpressionList theList : theContainer.getExpressionLists()) {
recomputeGotos(theList, aOriginal, aNew);
}
}
if (theExpression instanceof GotoExpression) {
GotoExpression theGoto = (GotoExpression) theExpression;
if (Objects.equals(theGoto.getJumpTarget(), aOriginal)) {
GotoExpression theNewGoto = new GotoExpression(aNew);
aList.replace(theGoto, theNewGoto);
}
}
}
}
use of de.mirkosertic.bytecoder.ssa.GotoExpression in project Bytecoder by mirkosertic.
the class JSSSAWriter method writeExpressions.
private void writeExpressions(ExpressionList aExpressions) {
for (Expression theExpression : aExpressions.toList()) {
if (options.isDebugOutput()) {
String theComment = theExpression.getComment();
if (theComment != null && !theComment.isEmpty()) {
print("// ");
println(theComment);
}
}
if (theExpression instanceof ReturnExpression) {
ReturnExpression theE = (ReturnExpression) theExpression;
print("return");
println(";");
} else if (theExpression instanceof VariableAssignmentExpression) {
VariableAssignmentExpression theE = (VariableAssignmentExpression) theExpression;
Variable theVariable = theE.getVariable();
Value theValue = theE.getValue();
if (theValue instanceof ComputedMemoryLocationWriteExpression) {
continue;
}
if (!program.isGlobalVariable(theVariable)) {
print("var ");
}
print(theVariable.getName());
print(" = ");
print(theValue);
print("; // type is ");
println(theVariable.resolveType().resolve().name() + " value type is " + theValue.resolveType());
} else if (theExpression instanceof PutStaticExpression) {
PutStaticExpression theE = (PutStaticExpression) theExpression;
BytecodeFieldRefConstant theField = theE.getField();
Value theValue = theE.incomingDataFlows().get(0);
printStaticFieldReference(theField);
print(" = ");
print(theValue);
println(";");
} else if (theExpression instanceof ReturnValueExpression) {
ReturnValueExpression theE = (ReturnValueExpression) theExpression;
Value theValue = theE.incomingDataFlows().get(0);
print("return ");
print(theValue);
println(";");
} else if (theExpression instanceof ThrowExpression) {
ThrowExpression theE = (ThrowExpression) theExpression;
Value theValue = theE.incomingDataFlows().get(0);
print("throw ");
print(theValue);
println(";");
} else if (theExpression instanceof InvokeVirtualMethodExpression) {
InvokeVirtualMethodExpression theE = (InvokeVirtualMethodExpression) theExpression;
print(theE);
println(";");
} else if (theExpression instanceof DirectInvokeMethodExpression) {
DirectInvokeMethodExpression theE = (DirectInvokeMethodExpression) theExpression;
print(theE);
println(";");
} else if (theExpression instanceof InvokeStaticMethodExpression) {
InvokeStaticMethodExpression theE = (InvokeStaticMethodExpression) theExpression;
print(theE);
println(";");
} else if (theExpression instanceof PutFieldExpression) {
PutFieldExpression theE = (PutFieldExpression) theExpression;
List<Value> theIncomingData = theE.incomingDataFlows();
Value theTarget = theIncomingData.get(0);
BytecodeFieldRefConstant theField = theE.getField();
Value thevalue = theIncomingData.get(1);
print(theTarget);
printInstanceFieldReference(theField);
print(" = ");
print(thevalue);
println(";");
} else if (theExpression instanceof IFExpression) {
IFExpression theE = (IFExpression) theExpression;
print("if (");
print(theE.incomingDataFlows().get(0));
println(") {");
withDeeperIndent().writeExpressions(theE.getExpressions());
println("}");
} else if (theExpression instanceof GotoExpression) {
GotoExpression theE = (GotoExpression) theExpression;
println(generateJumpCodeFor(theE.getJumpTarget()));
} else if (theExpression instanceof ArrayStoreExpression) {
ArrayStoreExpression theE = (ArrayStoreExpression) theExpression;
List<Value> theIncomingData = theE.incomingDataFlows();
Value theArray = theIncomingData.get(0);
Value theIndex = theIncomingData.get(1);
Value theValue = theIncomingData.get(2);
print(theArray);
printArrayIndexReference(theIndex);
print(" = ");
print(theValue);
println(";");
} else if (theExpression instanceof CheckCastExpression) {
CheckCastExpression theE = (CheckCastExpression) theExpression;
// Completely ignored
} else if (theExpression instanceof TableSwitchExpression) {
TableSwitchExpression theE = (TableSwitchExpression) theExpression;
Value theValue = theE.incomingDataFlows().get(0);
print("if (");
print(theValue);
print(" < ");
print(theE.getLowValue());
print(" || ");
print(theValue);
print(" > ");
print(theE.getHighValue());
println(") {");
print(" ");
writeExpressions(theE.getDefaultExpressions());
println("}");
print("switch(");
print(theValue);
print(" - ");
print(theE.getLowValue());
println(") {");
for (Map.Entry<Long, ExpressionList> theEntry : theE.getOffsets().entrySet()) {
print(" case ");
print(theEntry.getKey());
println(":");
print(" ");
writeExpressions(theEntry.getValue());
}
println("}");
println("throw 'Illegal jump target!';");
} else if (theExpression instanceof LookupSwitchExpression) {
LookupSwitchExpression theE = (LookupSwitchExpression) theExpression;
print("switch(");
print(theE.incomingDataFlows().get(0));
println(") {");
for (Map.Entry<Long, ExpressionList> theEntry : theE.getPairs().entrySet()) {
print(" case ");
print(theEntry.getKey());
println(":");
print(" ");
writeExpressions(theEntry.getValue());
}
println("}");
writeExpressions(theE.getDefaultExpressions());
} else if (theExpression instanceof SetMemoryLocationExpression) {
SetMemoryLocationExpression theE = (SetMemoryLocationExpression) theExpression;
List<Value> theIncomingData = theE.incomingDataFlows();
print("bytecoderGlobalMemory[");
ComputedMemoryLocationWriteExpression theValue = (ComputedMemoryLocationWriteExpression) theIncomingData.get(0);
print(theValue);
print("] = ");
print(theIncomingData.get(1));
println(";");
} else if (theExpression instanceof UnreachableExpression) {
println("throw 'Unreachable';");
} else if (theExpression instanceof BreakExpression) {
BreakExpression theBreak = (BreakExpression) theExpression;
if (theBreak.isSetLabelRequired()) {
print("__label__ = ");
print(theBreak.jumpTarget().getAddress());
println(";");
}
if (!theBreak.isSilent()) {
print("break $");
print(theBreak.blockToBreak().name());
println(";");
}
} else if (theExpression instanceof ContinueExpression) {
ContinueExpression theContinue = (ContinueExpression) theExpression;
print("__label__ = ");
print(theContinue.jumpTarget().getAddress());
println(";");
print("continue $");
print(theContinue.labelToReturnTo().name());
println(";");
} else {
throw new IllegalStateException("Not implemented : " + theExpression);
}
}
}
Aggregations