Search in sources :

Example 11 with BasicBlock

use of org.jikesrvm.compilers.opt.ir.BasicBlock in project JikesRVM by JikesRVM.

the class Inliner method execute.

/**
 * Return a generation context that represents the
 * execution of inlDec in the context <code>&lt;parent,ebag&gt;</code> for
 * the call instruction callSite.
 * <p> PRECONDITION: inlDec.isYes()
 * <p> POSTCONDITIONS:
 * Let gc be the returned generation context.
 * <ul>
 *  <li> gc.cfg.firstInCodeOrder is the entry to the inlined context
 *  <li>gc.cfg.lastInCodeOrder is the exit from the inlined context
 *  <li> GenerationContext.transferState(parent, child) has been called.
 * </ul>
 *
 * @param inlDec the inlining decision to execute
 * @param parent the caller generation context
 * @param ebag exception handler scope for the caller
 * @param callSite the callsite to execute
 * @return a generation context that represents the execution of the
 *         inline decision in the given context
 */
public static GenerationContext execute(InlineDecision inlDec, GenerationContext parent, ExceptionHandlerBasicBlockBag ebag, Instruction callSite) {
    if (inlDec.needsGuard()) {
        // Step 1: create the synthetic generation context we'll
        // return to our caller.
        GenerationContext container = GenerationContext.createSynthetic(parent, ebag);
        container.getCfg().breakCodeOrder(container.getPrologue(), container.getEpilogue());
        // Step 2: (a) Print a message (optional)
        // (b) Generate the child GC for each target
        RVMMethod[] targets = inlDec.getTargets();
        byte[] guards = inlDec.getGuards();
        GenerationContext[] children = new GenerationContext[targets.length];
        for (int i = 0; i < targets.length; i++) {
            NormalMethod callee = (NormalMethod) targets[i];
            // (a)
            if (parent.getOptions().PRINT_INLINE_REPORT) {
                String guard = guards[i] == OptOptions.INLINE_GUARD_CLASS_TEST ? " (class test) " : " (method test) ";
                VM.sysWriteln("\tGuarded inline" + guard + " " + callee + " into " + callSite.position().getMethod() + " at bytecode " + callSite.getBytecodeIndex());
            }
            // (b)
            children[i] = parent.createChildContext(ebag, callee, callSite);
            BC2IR.generateHIR(children[i]);
            children[i].transferStateToParent();
        }
        // special purpose coding wrapping the calls to Operand.meet.
        if (Call.hasResult(callSite)) {
            Register reg = Call.getResult(callSite).getRegister();
            container.setResult(children[0].getResult());
            for (int i = 1; i < targets.length; i++) {
                if (children[i].getResult() != null) {
                    container.setResult((container.getResult() == null) ? children[i].getResult() : Operand.meet(container.getResult(), children[i].getResult(), reg));
                }
            }
            if (!inlDec.OSRTestFailed()) {
                // Account for the non-predicted case as well...
                RegisterOperand failureCaseResult = Call.getResult(callSite).copyRO();
                container.setResult((container.getResult() == null) ? failureCaseResult : Operand.meet(container.getResult(), failureCaseResult, reg));
            }
        }
        // Step 4: Create a block to contain a copy of the original call or an OSR_Yieldpoint
        // to cover the case that all predictions fail.
        BasicBlock testFailed = new BasicBlock(callSite.getBytecodeIndex(), callSite.position(), parent.getCfg());
        testFailed.setExceptionHandlers(ebag);
        if (COUNT_FAILED_GUARDS && Controller.options.INSERT_DEBUGGING_COUNTERS) {
            // Get a dynamic count of how many times guards fail at runtime.
            // Need a name for the event to count.  In this example, a
            // separate counter for each method by using the method name
            // as the event name.  You could also have used just the string
            // "Guarded inline failed" to keep only one counter.
            String eventName = "Guarded inline failed: " + callSite.position().getMethod().toString();
            // Create instruction that will increment the counter
            // corresponding to the named event.
            Instruction counterInst = AOSDatabase.debuggingCounterData.getCounterInstructionForEvent(eventName);
            testFailed.appendInstruction(counterInst);
        }
        if (inlDec.OSRTestFailed()) {
            // note where we're storing the osr barrier instruction
            Instruction lastOsrBarrier = parent.getOSRBarrierFromInst(callSite);
            Instruction s = BC2IR._osrHelper(lastOsrBarrier, parent);
            s.copyPosition(callSite);
            testFailed.appendInstruction(s);
            testFailed.insertOut(parent.getExit());
        } else {
            Instruction call = callSite.copyWithoutLinks();
            Call.getMethod(call).setIsGuardedInlineOffBranch(true);
            call.copyPosition(callSite);
            testFailed.appendInstruction(call);
            testFailed.insertOut(container.getEpilogue());
            // BC2IR.maybeInlineMethod).
            if (ebag != null) {
                for (Enumeration<BasicBlock> e = ebag.enumerator(); e.hasMoreElements(); ) {
                    BasicBlock handler = e.nextElement();
                    testFailed.insertOut(handler);
                }
            }
            testFailed.setCanThrowExceptions();
            testFailed.setMayThrowUncaughtException();
        }
        container.getCfg().linkInCodeOrder(testFailed, container.getEpilogue());
        testFailed.setInfrequent();
        // Step 5: Patch together all the callees by generating guard blocks
        BasicBlock firstIfBlock = testFailed;
        // Note: We know that receiver must be a register
        // operand (and not a string constant) because we are doing a
        // guarded inlining....if it was a string constant we'd have
        // been able to inline without a guard.
        Operand receiver = Call.getParam(callSite, 0);
        MethodOperand mo = Call.getMethod(callSite);
        boolean isInterface = mo.isInterface();
        if (isInterface) {
            if (VM.BuildForIMTInterfaceInvocation) {
                RVMType interfaceType = mo.getTarget().getDeclaringClass();
                TypeReference recTypeRef = receiver.getType();
                RVMClass recType = (RVMClass) recTypeRef.peekType();
                // Attempt to avoid inserting the check by seeing if the
                // known static type of the receiver implements the interface.
                boolean requiresImplementsTest = true;
                if (recType != null && recType.isResolved() && !recType.isInterface()) {
                    byte doesImplement = ClassLoaderProxy.includesType(interfaceType.getTypeRef(), recTypeRef);
                    requiresImplementsTest = doesImplement != YES;
                }
                if (requiresImplementsTest) {
                    RegisterOperand checkedReceiver = parent.getTemps().makeTemp(receiver);
                    Instruction dtc = TypeCheck.create(MUST_IMPLEMENT_INTERFACE, checkedReceiver, receiver.copy(), new TypeOperand(interfaceType), Call.getGuard(callSite).copy());
                    dtc.copyPosition(callSite);
                    checkedReceiver.refine(interfaceType.getTypeRef());
                    Call.setParam(callSite, 0, checkedReceiver.copyRO());
                    testFailed.prependInstruction(dtc);
                }
            }
        }
        // "logical" test and to share test insertion for interfaces/virtuals.
        for (int i = children.length - 1; i >= 0; i--, testFailed = firstIfBlock) {
            firstIfBlock = new BasicBlock(callSite.getBytecodeIndex(), callSite.position(), parent.getCfg());
            firstIfBlock.setExceptionHandlers(ebag);
            BasicBlock lastIfBlock = firstIfBlock;
            RVMMethod target = children[i].getMethod();
            Instruction tmp;
            if (isInterface) {
                RVMClass callDeclClass = mo.getTarget().getDeclaringClass();
                if (!callDeclClass.isInterface()) {
                    // the entire compilation.
                    throw new OptimizingCompilerException("Attempted guarded inline of invoke interface when decl class of target method may not be an interface");
                }
                // We potentially have to generate IR to perform two tests here:
                // (1) Does the receiver object implement callDeclClass?
                // (2) Given that it does, is target the method that would
                // be invoked for this receiver?
                // It is quite common to be able to answer (1) "YES" at compile
                // time, in which case we only have to generate IR to establish
                // (2) at runtime.
                byte doesImplement = ClassLoaderProxy.includesType(callDeclClass.getTypeRef(), target.getDeclaringClass().getTypeRef());
                if (doesImplement != YES) {
                    // implements the interface).
                    if (parent.getOptions().PRINT_INLINE_REPORT) {
                        VM.sysWriteln("\t\tRequired additional instanceof " + callDeclClass + " test");
                    }
                    firstIfBlock = new BasicBlock(callSite.getBytecodeIndex(), callSite.position(), parent.getCfg());
                    firstIfBlock.setExceptionHandlers(ebag);
                    RegisterOperand instanceOfResult = parent.getTemps().makeTempInt();
                    tmp = InstanceOf.create(INSTANCEOF_NOTNULL, instanceOfResult, new TypeOperand(callDeclClass), receiver.copy(), Call.getGuard(callSite));
                    tmp.copyPosition(callSite);
                    firstIfBlock.appendInstruction(tmp);
                    tmp = IfCmp.create(INT_IFCMP, parent.getTemps().makeTempValidation(), instanceOfResult.copyD2U(), new IntConstantOperand(0), ConditionOperand.EQUAL(), testFailed.makeJumpTarget(), BranchProfileOperand.unlikely());
                    tmp.copyPosition(callSite);
                    firstIfBlock.appendInstruction(tmp);
                    firstIfBlock.insertOut(testFailed);
                    firstIfBlock.insertOut(lastIfBlock);
                    container.getCfg().linkInCodeOrder(firstIfBlock, lastIfBlock);
                }
            }
            if (guards[i] == OptOptions.INLINE_GUARD_CLASS_TEST) {
                tmp = InlineGuard.create(IG_CLASS_TEST, receiver.copy(), Call.getGuard(callSite).copy(), new TypeOperand(target.getDeclaringClass()), testFailed.makeJumpTarget(), BranchProfileOperand.unlikely());
            } else if (guards[i] == OptOptions.INLINE_GUARD_METHOD_TEST) {
                // declaring class.
                if (isInterface) {
                    RegisterOperand t = parent.getTemps().makeTempInt();
                    Instruction test = InstanceOf.create(INSTANCEOF_NOTNULL, t, new TypeOperand(target.getDeclaringClass().getTypeRef()), receiver.copy());
                    test.copyPosition(callSite);
                    lastIfBlock.appendInstruction(test);
                    Instruction cmp = IfCmp.create(INT_IFCMP, parent.getTemps().makeTempValidation(), t.copyD2U(), new IntConstantOperand(0), ConditionOperand.EQUAL(), testFailed.makeJumpTarget(), BranchProfileOperand.unlikely());
                    cmp.copyPosition(callSite);
                    lastIfBlock.appendInstruction(cmp);
                    BasicBlock subclassTest = new BasicBlock(callSite.getBytecodeIndex(), callSite.position(), parent.getCfg());
                    lastIfBlock.insertOut(testFailed);
                    lastIfBlock.insertOut(subclassTest);
                    container.getCfg().linkInCodeOrder(lastIfBlock, subclassTest);
                    lastIfBlock = subclassTest;
                }
                tmp = InlineGuard.create(IG_METHOD_TEST, receiver.copy(), Call.getGuard(callSite).copy(), MethodOperand.VIRTUAL(target.getMemberRef().asMethodReference(), target), testFailed.makeJumpTarget(), BranchProfileOperand.unlikely());
            } else {
                tmp = InlineGuard.create(IG_PATCH_POINT, receiver.copy(), Call.getGuard(callSite).copy(), MethodOperand.VIRTUAL(target.getMemberRef().asMethodReference(), target), testFailed.makeJumpTarget(), inlDec.OSRTestFailed() ? BranchProfileOperand.never() : BranchProfileOperand.unlikely());
            }
            tmp.copyPosition(callSite);
            lastIfBlock.appendInstruction(tmp);
            lastIfBlock.insertOut(testFailed);
            lastIfBlock.insertOut(children[i].getPrologue());
            container.getCfg().linkInCodeOrder(lastIfBlock, children[i].getCfg().firstInCodeOrder());
            if (children[i].getEpilogue() != null) {
                children[i].getEpilogue().appendInstruction(container.getEpilogue().makeGOTO());
                children[i].getEpilogue().insertOut(container.getEpilogue());
            }
            container.getCfg().linkInCodeOrder(children[i].getCfg().lastInCodeOrder(), testFailed);
        }
        // Step 6: finish by linking container.prologue & testFailed
        container.getPrologue().insertOut(testFailed);
        container.getCfg().linkInCodeOrder(container.getPrologue(), testFailed);
        return container;
    } else {
        if (VM.VerifyAssertions)
            VM._assert(inlDec.getNumberOfTargets() == 1);
        NormalMethod callee = (NormalMethod) inlDec.getTargets()[0];
        if (parent.getOptions().PRINT_INLINE_REPORT) {
            VM.sysWriteln("\tInline " + callee + " into " + callSite.position().getMethod() + " at bytecode " + callSite.getBytecodeIndex());
        }
        GenerationContext child = parent.createChildContext(ebag, callee, callSite);
        BC2IR.generateHIR(child);
        child.transferStateToParent();
        return child;
    }
}
Also used : GenerationContext(org.jikesrvm.compilers.opt.bc2ir.GenerationContext) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand) TypeOperand(org.jikesrvm.compilers.opt.ir.operand.TypeOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ConditionOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) RVMType(org.jikesrvm.classloader.RVMType) ExceptionHandlerBasicBlock(org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand) RVMClass(org.jikesrvm.classloader.RVMClass) RVMMethod(org.jikesrvm.classloader.RVMMethod) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register) NormalMethod(org.jikesrvm.classloader.NormalMethod) TypeOperand(org.jikesrvm.compilers.opt.ir.operand.TypeOperand) TypeReference(org.jikesrvm.classloader.TypeReference) OptimizingCompilerException(org.jikesrvm.compilers.opt.OptimizingCompilerException)

Example 12 with BasicBlock

use of org.jikesrvm.compilers.opt.ir.BasicBlock in project JikesRVM by JikesRVM.

the class ReorderingPhase method exileInfrequentBlocks.

// ///////////////////////
// Code for trivial algorithm
// ///////////////////////
/**
 * Select a new basic block ordering via a simple heuristic
 * that moves all infrequent basic blocks to the end.
 * @param ir the IR object to reorder
 */
private void exileInfrequentBlocks(IR ir) {
    // (1) Look to see if there are infrequent blocks
    // Also count how many blocks there are.
    int numBlocks = 0;
    boolean foundSome = false;
    for (Enumeration<BasicBlock> e = ir.getBasicBlocks(); e.hasMoreElements(); ) {
        BasicBlock bb = e.nextElement();
        numBlocks++;
        foundSome |= bb.getInfrequent();
    }
    // Nothing to do
    if (!foundSome)
        return;
    // Reorder the blocks to exile the infrequent blocks.
    // Relative order within the set of frequent and infrequent is unchanged.
    BasicBlock[] newOrdering = new BasicBlock[numBlocks];
    int idx = 0;
    // First append frequent blocks to newOrdering
    for (BasicBlock bb = ir.cfg.firstInCodeOrder(); bb != null; bb = bb.nextBasicBlockInCodeOrder()) {
        if (!bb.getInfrequent()) {
            newOrdering[idx++] = bb;
        }
    }
    // Next append infrequent blocks to newOrdering
    for (BasicBlock bb = ir.cfg.firstInCodeOrder(); bb != null; bb = bb.nextBasicBlockInCodeOrder()) {
        if (bb.getInfrequent()) {
            newOrdering[idx++] = bb;
        }
    }
    // don't lose blocks!
    if (VM.VerifyAssertions)
        VM._assert(idx == numBlocks);
    if (VM.VerifyAssertions)
        VM._assert(ir.cfg.entry() == newOrdering[0]);
    // Add/remove unconditional goto's as needed.
    for (int i = 0; i < newOrdering.length; i++) {
        Instruction lastInstr = newOrdering[i].lastRealInstruction();
        // Append a GOTO if needed to maintain old fallthrough semantics.
        BasicBlock fallthroughBlock = newOrdering[i].getFallThroughBlock();
        if (fallthroughBlock != null) {
            if (i == newOrdering.length - 1 || fallthroughBlock != newOrdering[i + 1]) {
                // Add unconditional goto to preserve old fallthrough semantics
                newOrdering[i].appendInstruction(fallthroughBlock.makeGOTO());
            }
        }
        // (Only possible if newOrdering[i] is not the last basic block.)
        if (i < newOrdering.length - 1 && lastInstr != null && lastInstr.operator() == GOTO) {
            BranchOperand op = Goto.getTarget(lastInstr);
            if (op.target.getBasicBlock() == newOrdering[i + 1]) {
                // unconditional goto is redundant in new ordering
                lastInstr.remove();
            }
        }
    }
    // Re-insert all basic blocks according to new ordering
    ir.cfg.clearCodeOrder();
    for (BasicBlock bb : newOrdering) {
        ir.cfg.addLastInCodeOrder(bb);
    }
}
Also used : BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) BranchOperand(org.jikesrvm.compilers.opt.ir.operand.BranchOperand)

Example 13 with BasicBlock

use of org.jikesrvm.compilers.opt.ir.BasicBlock in project JikesRVM by JikesRVM.

the class ReorderingPhase method doPettisHansenAlgo2.

// ///////////////////////
// Code for P&H Algo2
// ///////////////////////
/**
 * Reorder code using Algo2 (Bottom-Up Positioning) from
 * Pettis and Hansen PLDI'90.
 * @param ir the IR to reorder.
 */
private void doPettisHansenAlgo2(IR ir) {
    // (1) Setup:
    // (a) Count the blocks
    // (b) Create a sorted set of CFG edges
    // (c) Create a set of blocks
    // (d) Make fallthroughs explict by adding GOTOs
    int numBlocks = 0;
    TreeSet<Edge> edges = new TreeSet<Edge>();
    LinkedHashSet<BasicBlock> chainHeads = new LinkedHashSet<BasicBlock>();
    HashMap<BasicBlock, BasicBlock> associatedChain = new HashMap<BasicBlock, BasicBlock>();
    BasicBlock entry = ir.cfg.entry();
    if (VM.VerifyAssertions)
        VM._assert(ir.cfg.entry() == ir.cfg.firstInCodeOrder());
    for (BasicBlock bb = entry; bb != null; bb = bb.nextBasicBlockInCodeOrder()) {
        numBlocks++;
        chainHeads.add(bb);
        associatedChain.put(bb, bb);
        BasicBlock ft = bb.getFallThroughBlock();
        if (ft != null) {
            bb.appendInstruction(Goto.create(GOTO, ft.makeJumpTarget()));
        }
        float bw = bb.getExecutionFrequency();
        for (WeightedBranchTargets wbt = new WeightedBranchTargets(bb); wbt.hasMoreElements(); wbt.advance()) {
            edges.add(new Edge(bb, wbt.curBlock(), wbt.curWeight() * bw));
        }
    }
    if (DEBUG)
        VM.sysWriteln("Edges = " + edges);
    // (2) Build chains
    ir.cfg.clearCodeOrder();
    for (Edge e : edges) {
        // then merge the chains.
        if (DEBUG)
            VM.sysWriteln("Processing edge " + e);
        if (e.target == entry) {
            if (DEBUG)
                VM.sysWriteln("\tCan't put entry block in interior of chain");
            continue;
        }
        if (e.source.nextBasicBlockInCodeOrder() != null) {
            if (DEBUG)
                VM.sysWriteln("\tSource is not at end of a chain");
            continue;
        }
        if (e.target.prevBasicBlockInCodeOrder() != null) {
            if (DEBUG)
                VM.sysWriteln("\tTarget is not at start of a chain");
            continue;
        }
        BasicBlock sourceChain = associatedChain.get(e.source);
        BasicBlock targetChain = associatedChain.get(e.target);
        if (sourceChain == targetChain) {
            if (DEBUG)
                VM.sysWriteln("\tSource and target are in same chain");
            continue;
        }
        if (DEBUG)
            VM.sysWriteln("\tMerging chains");
        chainHeads.remove(e.target);
        ir.cfg.linkInCodeOrder(e.source, e.target);
        // Yuck....we should really use near-linear time union find here
        // Doing this crappy thing makes us O(N^2) in the worst case.
        BasicBlock newChain = sourceChain;
        for (BasicBlock ptr = e.target; ptr != null; ptr = ptr.nextBasicBlockInCodeOrder()) {
            associatedChain.put(ptr, newChain);
        }
    }
    if (DEBUG)
        VM.sysWriteln("Chains constructed ");
    LinkedHashMap<BasicBlock, ChainInfo> chainInfo = new LinkedHashMap<BasicBlock, ChainInfo>();
    for (BasicBlock head : chainHeads) {
        if (DEBUG)
            dumpChain(head);
        chainInfo.put(head, new ChainInfo(head));
    }
    // (3) Summarize inter-chain edges.
    for (Edge e : edges) {
        BasicBlock sourceChain = associatedChain.get(e.source);
        BasicBlock targetChain = associatedChain.get(e.target);
        if (sourceChain != targetChain) {
            ChainInfo sourceInfo = chainInfo.get(sourceChain);
            ChainInfo targetInfo = chainInfo.get(targetChain);
            if (DEBUG)
                VM.sysWriteln("Inter-chain edge " + sourceChain + "->" + targetChain + " (" + e.weight + ")");
            Float value = sourceInfo.outWeights.get(targetInfo);
            float weight = e.weight;
            if (value != null) {
                weight += value;
            }
            sourceInfo.outWeights.put(targetInfo, weight);
            targetInfo.inWeight += e.weight;
            if (DEBUG)
                VM.sysWriteln("\t" + targetInfo + "," + sourceInfo.outWeights.get(targetInfo));
        }
    }
    if (DEBUG)
        VM.sysWriteln("Chain Info " + chainInfo);
    // (4) Construct a total order of the chains, guided by the interchain edge weights.
    // Constructing an optimal order is NP-Hard, so we apply the following heuristic.
    // The chain that starts with the entry node is placed first.
    // At each step, pick the chain with the maximal placedWeight (incoming edges from chains
    // that are already placed) and minimal inWeight (incoming edges from chains that are not
    // already placed). Prefer a node with non-zero placedWeight and inWeight to one that has
    // zeros for both. (A node with both zero placedWeight and zero inWeight is something that
    // the profile data predicts is not reachable via normal control flow from the entry node).
    BasicBlock lastNode = null;
    ChainInfo nextChoice = chainInfo.get(entry);
    int numPlaced = 0;
    ir.cfg.setFirstNode(entry);
    while (true) {
        if (DEBUG)
            VM.sysWriteln("Placing chain " + nextChoice);
        // Append nextChoice to the previous chain
        if (lastNode != null)
            ir.cfg.linkInCodeOrder(lastNode, nextChoice.head);
        for (BasicBlock ptr = nextChoice.head; ptr != null; ptr = ptr.nextBasicBlockInCodeOrder()) {
            numPlaced++;
            lastNode = ptr;
        }
        // update ChainInfo
        chainInfo.remove(nextChoice.head);
        // no chains left to place.
        if (chainInfo.isEmpty())
            break;
        for (ChainInfo target : nextChoice.outWeights.keySet()) {
            if (DEBUG)
                VM.sysWrite("\toutedge " + target);
            float weight = nextChoice.outWeights.get(target);
            if (DEBUG)
                VM.sysWriteln(" = " + weight);
            target.placedWeight += weight;
            target.inWeight -= weight;
        }
        if (DEBUG)
            VM.sysWriteln("Chain Info " + chainInfo);
        // Find the next chain to append.
        nextChoice = null;
        for (ChainInfo cand : chainInfo.values()) {
            if (cand.placedWeight > 0f) {
                if (nextChoice == null) {
                    if (DEBUG)
                        VM.sysWriteln("First reachable candidate " + cand);
                    nextChoice = cand;
                } else if (cand.inWeight > nextChoice.inWeight || (cand.inWeight == nextChoice.inWeight && cand.placedWeight > nextChoice.placedWeight)) {
                    if (DEBUG)
                        VM.sysWriteln(cand + " is a better choice than " + nextChoice);
                    nextChoice = cand;
                }
            }
        }
        if (nextChoice != null)
            continue;
        // Pick one with minimal inWeight and continue.
        for (ChainInfo cand : chainInfo.values()) {
            if (nextChoice == null) {
                if (DEBUG)
                    VM.sysWriteln("First candidate " + cand);
                nextChoice = cand;
            } else if (cand.inWeight < nextChoice.inWeight) {
                if (DEBUG)
                    VM.sysWriteln(cand + " is a better choice than " + nextChoice);
                nextChoice = cand;
            }
        }
    }
    // Don't lose blocks!!
    if (VM.VerifyAssertions)
        VM._assert(numPlaced == numBlocks);
    ir.cfg.setLastNode(lastNode);
}
Also used : LinkedHashSet(java.util.LinkedHashSet) WeightedBranchTargets(org.jikesrvm.compilers.opt.ir.WeightedBranchTargets) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) LinkedHashMap(java.util.LinkedHashMap) TreeSet(java.util.TreeSet)

Example 14 with BasicBlock

use of org.jikesrvm.compilers.opt.ir.BasicBlock in project JikesRVM by JikesRVM.

the class ReorderingPhase method dumpChain.

private void dumpChain(BasicBlock head) {
    VM.sysWrite("{" + head);
    for (BasicBlock next = head.nextBasicBlockInCodeOrder(); next != null; next = next.nextBasicBlockInCodeOrder()) {
        VM.sysWrite(", " + next);
    }
    VM.sysWriteln("}");
}
Also used : BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock)

Example 15 with BasicBlock

use of org.jikesrvm.compilers.opt.ir.BasicBlock in project JikesRVM by JikesRVM.

the class StaticSplitting method splitCandidate.

/**
 * Splits a node where we can safely not
 * replicate the on-branch in the cloned node.
 * @param ci description of the split candidate.
 * @param ir the governing IR
 */
private void splitCandidate(CandInfo ci, IR ir) {
    BasicBlock cand = ci.candBB;
    BasicBlock prev = ci.prevBB;
    BasicBlock succ = ci.succBB;
    BasicBlock clone = cand.copyWithoutLinks(ir);
    // Redirect clone to always stay on cold path.
    Instruction s = clone.lastRealInstruction();
    while (s.isBranch()) {
        s = s.remove();
    }
    clone.appendInstruction(Goto.create(GOTO, succ.makeJumpTarget()));
    // inject clone in code order;
    // force prev to go to clone instead of cand.
    prev.redirectOuts(cand, clone, ir);
    clone.recomputeNormalOut(ir);
    ir.cfg.addLastInCodeOrder(clone);
    clone.setInfrequent();
}
Also used : BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Aggregations

BasicBlock (org.jikesrvm.compilers.opt.ir.BasicBlock)219 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)117 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)93 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)66 ExceptionHandlerBasicBlock (org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock)52 Register (org.jikesrvm.compilers.opt.ir.Register)50 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)48 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)37 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)33 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)27 LocationOperand (org.jikesrvm.compilers.opt.ir.operand.LocationOperand)24 HeapOperand (org.jikesrvm.compilers.opt.ir.operand.HeapOperand)21 BasicBlockOperand (org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand)20 TrueGuardOperand (org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)19 TypeReference (org.jikesrvm.classloader.TypeReference)18 NullConstantOperand (org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand)18 Test (org.junit.Test)17 BranchOperand (org.jikesrvm.compilers.opt.ir.operand.BranchOperand)16 InlineSequence (org.jikesrvm.compilers.opt.inlining.InlineSequence)14 MemoryOperand (org.jikesrvm.compilers.opt.ir.operand.MemoryOperand)14