Search in sources :

Example 1 with ExpressionList

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());
}
Also used : ReturnExpression(de.mirkosertic.bytecoder.ssa.ReturnExpression) Program(de.mirkosertic.bytecoder.ssa.Program) GotoExpression(de.mirkosertic.bytecoder.ssa.GotoExpression) ControlFlowGraph(de.mirkosertic.bytecoder.ssa.ControlFlowGraph) IntegerValue(de.mirkosertic.bytecoder.ssa.IntegerValue) BytecodeOpcodeAddress(de.mirkosertic.bytecoder.core.BytecodeOpcodeAddress) IFExpression(de.mirkosertic.bytecoder.ssa.IFExpression) RegionNode(de.mirkosertic.bytecoder.ssa.RegionNode) ExpressionList(de.mirkosertic.bytecoder.ssa.ExpressionList) Test(org.junit.Test)

Example 2 with ExpressionList

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());
            }
        }
    }
}
Also used : BreakExpression(de.mirkosertic.bytecoder.ssa.BreakExpression) GotoExpression(de.mirkosertic.bytecoder.ssa.GotoExpression) ContinueExpression(de.mirkosertic.bytecoder.ssa.ContinueExpression) Expression(de.mirkosertic.bytecoder.ssa.Expression) GotoExpression(de.mirkosertic.bytecoder.ssa.GotoExpression) ReturnExpression(de.mirkosertic.bytecoder.ssa.ReturnExpression) BreakExpression(de.mirkosertic.bytecoder.ssa.BreakExpression) ContinueExpression(de.mirkosertic.bytecoder.ssa.ContinueExpression) ExpressionListContainer(de.mirkosertic.bytecoder.ssa.ExpressionListContainer) RegionNode(de.mirkosertic.bytecoder.ssa.RegionNode) ExpressionList(de.mirkosertic.bytecoder.ssa.ExpressionList) HashMap(java.util.HashMap) Map(java.util.Map)

Example 3 with ExpressionList

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);
        }
    }
}
Also used : Variable(de.mirkosertic.bytecoder.ssa.Variable) InvocationExpression(de.mirkosertic.bytecoder.ssa.InvocationExpression) IFExpression(de.mirkosertic.bytecoder.ssa.IFExpression) PutFieldExpression(de.mirkosertic.bytecoder.ssa.PutFieldExpression) BreakExpression(de.mirkosertic.bytecoder.ssa.BreakExpression) VariableAssignmentExpression(de.mirkosertic.bytecoder.ssa.VariableAssignmentExpression) ReturnValueExpression(de.mirkosertic.bytecoder.ssa.ReturnValueExpression) ReturnExpression(de.mirkosertic.bytecoder.ssa.ReturnExpression) ArrayStoreExpression(de.mirkosertic.bytecoder.ssa.ArrayStoreExpression) ContinueExpression(de.mirkosertic.bytecoder.ssa.ContinueExpression) InvokeVirtualMethodExpression(de.mirkosertic.bytecoder.ssa.InvokeVirtualMethodExpression) TypeConversionExpression(de.mirkosertic.bytecoder.ssa.TypeConversionExpression) CompareExpression(de.mirkosertic.bytecoder.ssa.CompareExpression) DirectInvokeMethodExpression(de.mirkosertic.bytecoder.ssa.DirectInvokeMethodExpression) InvocationExpression(de.mirkosertic.bytecoder.ssa.InvocationExpression) VariableAssignmentExpression(de.mirkosertic.bytecoder.ssa.VariableAssignmentExpression) InvokeStaticMethodExpression(de.mirkosertic.bytecoder.ssa.InvokeStaticMethodExpression) ReturnExpression(de.mirkosertic.bytecoder.ssa.ReturnExpression) ReturnValueExpression(de.mirkosertic.bytecoder.ssa.ReturnValueExpression) ArrayStoreExpression(de.mirkosertic.bytecoder.ssa.ArrayStoreExpression) BinaryExpression(de.mirkosertic.bytecoder.ssa.BinaryExpression) GetFieldExpression(de.mirkosertic.bytecoder.ssa.GetFieldExpression) ContinueExpression(de.mirkosertic.bytecoder.ssa.ContinueExpression) IFExpression(de.mirkosertic.bytecoder.ssa.IFExpression) ArrayEntryExpression(de.mirkosertic.bytecoder.ssa.ArrayEntryExpression) Expression(de.mirkosertic.bytecoder.ssa.Expression) PutFieldExpression(de.mirkosertic.bytecoder.ssa.PutFieldExpression) BreakExpression(de.mirkosertic.bytecoder.ssa.BreakExpression) DoubleValue(de.mirkosertic.bytecoder.ssa.DoubleValue) Value(de.mirkosertic.bytecoder.ssa.Value) IntegerValue(de.mirkosertic.bytecoder.ssa.IntegerValue) LongValue(de.mirkosertic.bytecoder.ssa.LongValue) FloatValue(de.mirkosertic.bytecoder.ssa.FloatValue) ExpressionList(de.mirkosertic.bytecoder.ssa.ExpressionList) List(java.util.List) BytecodeFieldRefConstant(de.mirkosertic.bytecoder.core.BytecodeFieldRefConstant)

Example 4 with ExpressionList

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)");
}
Also used : StringValue(de.mirkosertic.bytecoder.ssa.StringValue) ByteValue(de.mirkosertic.bytecoder.ssa.ByteValue) Value(de.mirkosertic.bytecoder.ssa.Value) ClassReferenceValue(de.mirkosertic.bytecoder.ssa.ClassReferenceValue) FloatValue(de.mirkosertic.bytecoder.ssa.FloatValue) NullValue(de.mirkosertic.bytecoder.ssa.NullValue) DoubleValue(de.mirkosertic.bytecoder.ssa.DoubleValue) IntegerValue(de.mirkosertic.bytecoder.ssa.IntegerValue) LongValue(de.mirkosertic.bytecoder.ssa.LongValue) ShortValue(de.mirkosertic.bytecoder.ssa.ShortValue) Map(java.util.Map) ExpressionList(de.mirkosertic.bytecoder.ssa.ExpressionList)

Example 5 with ExpressionList

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(")");
}
Also used : StringValue(de.mirkosertic.bytecoder.ssa.StringValue) ByteValue(de.mirkosertic.bytecoder.ssa.ByteValue) Value(de.mirkosertic.bytecoder.ssa.Value) ClassReferenceValue(de.mirkosertic.bytecoder.ssa.ClassReferenceValue) FloatValue(de.mirkosertic.bytecoder.ssa.FloatValue) NullValue(de.mirkosertic.bytecoder.ssa.NullValue) DoubleValue(de.mirkosertic.bytecoder.ssa.DoubleValue) IntegerValue(de.mirkosertic.bytecoder.ssa.IntegerValue) LongValue(de.mirkosertic.bytecoder.ssa.LongValue) ShortValue(de.mirkosertic.bytecoder.ssa.ShortValue) Map(java.util.Map) ExpressionList(de.mirkosertic.bytecoder.ssa.ExpressionList)

Aggregations

ExpressionList (de.mirkosertic.bytecoder.ssa.ExpressionList)10 Expression (de.mirkosertic.bytecoder.ssa.Expression)6 GotoExpression (de.mirkosertic.bytecoder.ssa.GotoExpression)6 IntegerValue (de.mirkosertic.bytecoder.ssa.IntegerValue)6 DoubleValue (de.mirkosertic.bytecoder.ssa.DoubleValue)4 ExpressionListContainer (de.mirkosertic.bytecoder.ssa.ExpressionListContainer)4 FloatValue (de.mirkosertic.bytecoder.ssa.FloatValue)4 LongValue (de.mirkosertic.bytecoder.ssa.LongValue)4 RegionNode (de.mirkosertic.bytecoder.ssa.RegionNode)4 BinaryExpression (de.mirkosertic.bytecoder.ssa.BinaryExpression)3 BreakExpression (de.mirkosertic.bytecoder.ssa.BreakExpression)3 ByteValue (de.mirkosertic.bytecoder.ssa.ByteValue)3 ClassReferenceValue (de.mirkosertic.bytecoder.ssa.ClassReferenceValue)3 ContinueExpression (de.mirkosertic.bytecoder.ssa.ContinueExpression)3 IFExpression (de.mirkosertic.bytecoder.ssa.IFExpression)3 ReturnExpression (de.mirkosertic.bytecoder.ssa.ReturnExpression)3 ReturnValueExpression (de.mirkosertic.bytecoder.ssa.ReturnValueExpression)3 Value (de.mirkosertic.bytecoder.ssa.Value)3 Variable (de.mirkosertic.bytecoder.ssa.Variable)3 VariableAssignmentExpression (de.mirkosertic.bytecoder.ssa.VariableAssignmentExpression)3