Search in sources :

Example 1 with ExpressionListContainer

use of de.mirkosertic.bytecoder.ssa.ExpressionListContainer 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 2 with ExpressionListContainer

use of de.mirkosertic.bytecoder.ssa.ExpressionListContainer 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());
            }
        }
    }
}
Also used : GotoExpression(de.mirkosertic.bytecoder.ssa.GotoExpression) Expression(de.mirkosertic.bytecoder.ssa.Expression) GotoExpression(de.mirkosertic.bytecoder.ssa.GotoExpression) ExpressionListContainer(de.mirkosertic.bytecoder.ssa.ExpressionListContainer) RegionNode(de.mirkosertic.bytecoder.ssa.RegionNode) ExpressionList(de.mirkosertic.bytecoder.ssa.ExpressionList)

Example 3 with ExpressionListContainer

use of de.mirkosertic.bytecoder.ssa.ExpressionListContainer 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;
}
Also used : GotoExpression(de.mirkosertic.bytecoder.ssa.GotoExpression) Expression(de.mirkosertic.bytecoder.ssa.Expression) GotoExpression(de.mirkosertic.bytecoder.ssa.GotoExpression) BytecodeOpcodeAddress(de.mirkosertic.bytecoder.core.BytecodeOpcodeAddress) ExpressionListContainer(de.mirkosertic.bytecoder.ssa.ExpressionListContainer) RegionNode(de.mirkosertic.bytecoder.ssa.RegionNode) ExpressionList(de.mirkosertic.bytecoder.ssa.ExpressionList)

Example 4 with ExpressionListContainer

use of de.mirkosertic.bytecoder.ssa.ExpressionListContainer 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);
            }
        }
    }
}
Also used : GotoExpression(de.mirkosertic.bytecoder.ssa.GotoExpression) Expression(de.mirkosertic.bytecoder.ssa.Expression) GotoExpression(de.mirkosertic.bytecoder.ssa.GotoExpression) ExpressionListContainer(de.mirkosertic.bytecoder.ssa.ExpressionListContainer) ExpressionList(de.mirkosertic.bytecoder.ssa.ExpressionList)

Aggregations

Expression (de.mirkosertic.bytecoder.ssa.Expression)4 ExpressionList (de.mirkosertic.bytecoder.ssa.ExpressionList)4 ExpressionListContainer (de.mirkosertic.bytecoder.ssa.ExpressionListContainer)4 GotoExpression (de.mirkosertic.bytecoder.ssa.GotoExpression)4 RegionNode (de.mirkosertic.bytecoder.ssa.RegionNode)3 BytecodeOpcodeAddress (de.mirkosertic.bytecoder.core.BytecodeOpcodeAddress)1 BreakExpression (de.mirkosertic.bytecoder.ssa.BreakExpression)1 ContinueExpression (de.mirkosertic.bytecoder.ssa.ContinueExpression)1 ReturnExpression (de.mirkosertic.bytecoder.ssa.ReturnExpression)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1