Package org.jruby.ir.representations

Examples of org.jruby.ir.representations.BasicBlock


        boolean scopeHasLocalVarStores      = false;
        boolean scopeHasUnrescuedExceptions = false;

        CFG        cfg = scope.cfg();
        BasicBlock geb = cfg.getGlobalEnsureBB();

        if (slvpp != null) {
            scopeHasLocalVarStores      = slvpp.scopeHasLocalVarStores();
            scopeHasUnrescuedExceptions = slvpp.scopeHasUnrescuedExceptions();
        } else {
            // We dont require local-var load/stores to have been run.
            // If it is not run, we go conservative and add push/pop binding instrs. everywhere
            scopeHasLocalVarStores      = true;
            scopeHasUnrescuedExceptions = false;
            for (BasicBlock bb: cfg.getBasicBlocks()) {
                // SSS FIXME: This is highly conservative.  If the bb has an exception raising instr.
                // and if we dont have a rescuer, only then do we have unrescued exceptions.
                if (cfg.getRescuerBBFor(bb) == null) {
                    scopeHasUnrescuedExceptions = true;
                    break;
                }
            }
        }

        BasicBlock entryBB = cfg.getEntryBB();

        // SSS FIXME: Right now, we always add push/pop frame instrs -- in the future, we may skip them
        // for certain scopes.
        //
        // Add explicit frame and binding push/pop instrs ONLY for methods -- we cannot handle this in closures and evals yet
        // If the scope uses $_ or $~ family of vars, has local load/stores, or if its binding has escaped, we have
        // to allocate a dynamic scope for it and add binding push/pop instructions.
        if ((scope instanceof IRMethod) || (scope instanceof IRScriptBody) || (scope instanceof IRModuleBody)) {
            if (scope.bindingHasEscaped() || scope.usesBackrefOrLastline() || scopeHasLocalVarStores || scopeHasUnrescuedExceptions) {
                // Push
                entryBB.addInstr(new PushFrameInstr());
                entryBB.addInstr(new PushBindingInstr(scope));

                // Allocate GEB if necessary for popping binding
                if (geb == null && (scopeHasLocalVarStores || scopeHasUnrescuedExceptions)) {
                    Variable exc = scope.getNewTemporaryVariable();
                    geb = new BasicBlock(cfg, new Label("_GLOBAL_ENSURE_BLOCK"));
                    geb.addInstr(new ReceiveExceptionInstr(exc, false)); // No need to check type since it is not used before rethrowing
                    geb.addInstr(new ThrowExceptionInstr(exc));
                    cfg.addGlobalEnsureBB(geb);
                }

                // Pop on all scope-exit paths
                BasicBlock exitBB = cfg.getExitBB();
                for (BasicBlock bb: cfg.getBasicBlocks()) {
                    ListIterator<Instr> instrs = bb.getInstrs().listIterator();
                    while (instrs.hasNext()) {
                        Instr i = instrs.next();
                        if ((bb != exitBB) && (i instanceof ReturnBase) || (i instanceof BreakInstr)) {
View Full Code Here


        // Compute meet over all "sources" and compute "destination" basic blocks that should then be processed.
        // sources & targets depends on direction of the data flow problem
        initSolnForNode();
        if (problem.getFlowDirection() == DataFlowProblem.DF_Direction.FORWARD) {
            for (Edge e: problem.getScope().cfg().getIncomingEdges(basicBlock)) {
                BasicBlock b = (BasicBlock)e.getSource().getData();
                compute_MEET(e, b, problem.getFlowGraphNode(b));
            }
        } else if (problem.getFlowDirection() == DataFlowProblem.DF_Direction.BACKWARD) {
            for (Edge e: problem.getScope().cfg().getOutgoingEdges(basicBlock)) {
                BasicBlock b = (BasicBlock)e.getDestination().getData();
                compute_MEET(e, b, problem.getFlowGraphNode(b));
            }
        } else {
            throw new RuntimeException("Bidirectional data flow computation not implemented yet!");
        }
View Full Code Here

            scopeHasUnrescuedExceptions = scopeHasUnrescuedExceptions || bbHasUnrescuedExceptions;
            scopeHasLocalVarStores      = scopeHasLocalVarStores || bbAddedStores;
        }

        // Allocate global-ensure block, if necessary
        BasicBlock geb = null;
        if ((mightRequireGlobalEnsureBlock == true) && !dirtyVars.isEmpty()) {
            Variable exc = cfgScope.getNewTemporaryVariable();
            geb = new BasicBlock(cfg, new Label("_GLOBAL_ENSURE_BLOCK"));
            geb.addInstr(new ReceiveExceptionInstr(exc, false)); // No need to check type since it is not used before rethrowing
            for (LocalVariable v : dirtyVars) {
                Operand value = varRenameMap.get(v);
                if (value == null) {
                    value = cfgScope.getNewTemporaryVariable("%t_" + v.getName());
                    varRenameMap.put(v, value);
                }
                geb.addInstr(new StoreLocalVarInstr(value, (IRClosure) cfgScope, v));
            }
            geb.addInstr(new ThrowExceptionInstr(exc));
            cfg.addGlobalEnsureBB(geb);
        }
    }
View Full Code Here

        Integer[] bbToPoNumbers = new Integer[maxNodeId + 1]; // Set up a map of bbid -> post order numbering
        BasicBlock[] poNumbersToBB = new BasicBlock[maxNodeId + 1];
        int n = 0;
        ListIterator<BasicBlock> it = postOrderList.listIterator();
        while (it.hasNext()) {
            BasicBlock b = it.next();
            bbToPoNumbers[b.getID()] = n;
            poNumbersToBB[n] = b;
            n++;
        }

        // Construct the dominator sets using the fast dominance algorithm by
        // Keith D. Cooper, Timothy J. Harvey, and Ken Kennedy.
        // http://www.cs.rice.edu/~keith/EMBED/dom.pdf (tip courtesy Slava Pestov)
        //
        // Faster than the standard iterative data-flow algorithm
        //
        // This maps a bb's post-order number to the bb's idom post-order number.
        // We convert this po-number -> po-number map to a bb -> bb map later on!
        Integer[] idoms = new Integer[maxNodeId + 1];

        BasicBlock root = cfg.getEntryBB();
        Integer rootPoNumber = bbToPoNumbers[root.getID()];
        idoms[rootPoNumber] = rootPoNumber;

        boolean changed = true;
        while (changed) {
            changed = false;
            it = postOrderList.listIterator(cfg.size());
            while (it.hasPrevious()) {
                BasicBlock b = it.previous();
                if (b == root) continue;

                // Non-root -- process it
                Integer bPoNumber = bbToPoNumbers[b.getID()];
                Integer oldBIdom = idoms[bPoNumber];
                Integer newBIdom = null;

                // newBIdom is initialized to be some (first-encountered, for ex.) processed predecessor of 'b'.
                for (BasicBlock src : cfg.getIncomingSources(b)) {
View Full Code Here

            //
            // Note that Throwable also catches IRReturnJump and IRBreakJump.  There is
            // nothing special to do for IRReturnJump.  But, break-jumps have extra
            // logic.  So, all handlers need to check if the handler is a IRBreakJump
            // and take action accordingly.
            BasicBlock rBB = cfg().getRescuerBBFor(b);
            BasicBlock eBB = cfg().getEnsurerBBFor(b);
            if ((eBB != null) && (rBB == eBB || rBB == null)) {
                // 1. same rescue and ensure handler ==> just spit out one entry with a Throwable class
                // 2. only ensure handler            ==> just spit out one entry with a Throwable class
                //
                // The rescue handler knows whether to unwrap or not.  But for now, the rescue handler
                // has to process its recv_exception instruction as
                //    e = (e instanceof RaiseException) ? unwrap(e) : e;

                etEntries.add(new Object[] {b.getLabel(), eBB.getLabel(), Throwable.class});
            } else if (rBB != null) {
                // Unrescuable comes before Throwable
                if (eBB != null) etEntries.add(new Object[] {b.getLabel(), eBB.getLabel(), Unrescuable.class});
                etEntries.add(new Object[] {b.getLabel(), rBB.getLabel(), Throwable.class});
            }
        }

        // SSS FIXME: This could be optimized by compressing entries for adjacent BBs that have identical handlers
View Full Code Here

        depends(cfg());
       
        for (BasicBlock b : linearizedBBList) {
            for (Instr i : b.getInstrs()) {
                if (i == excInstr) {
                    BasicBlock rescuerBB = cfg().getRescuerBBFor(b);
                    return (rescuerBB == null) ? -1 : rescuerBB.getLabel().getTargetPC();
                }
            }
        }

        // SSS FIXME: Cannot happen! Throw runtime exception
View Full Code Here

        depends(cfg());
       
        for (BasicBlock b : linearizedBBList) {
            for (Instr i : b.getInstrs()) {
                if (i == excInstr) {
                    BasicBlock ensurerBB = cfg.getEnsurerBBFor(b);
                    return (ensurerBB == null) ? -1 : ensurerBB.getLabel().getTargetPC();
                }
            }
        }

        // SSS FIXME: Cannot happen! Throw runtime exception
View Full Code Here

        if (addedGEBForUncaughtBreaks) {
            return false;
        }

        CFG        cfg = cfg();
        BasicBlock geb = cfg.getGlobalEnsureBB();
        if (geb == null) {
            geb = new BasicBlock(cfg, new Label("_GLOBAL_ENSURE_BLOCK"));
            Variable exc = getNewTemporaryVariable();
            geb.addInstr(new ReceiveExceptionInstr(exc, false)); // No need to check type since it is not used before rethrowing
            // Handle uncaught break using runtime helper
            // --> IRRuntimeHelpers.catchUncaughtBreakInLambdas(context, scope, bj, blockType)
            geb.addInstr(new RuntimeHelperCall(null, "catchUncaughtBreakInLambdas", new Operand[]{exc} ));
            cfg.addGlobalEnsureBB(geb);
        } else {
            // SSS FIXME: Assumptions:
            //
            // First instr is a 'ReceiveExceptionInstr'
            // Last instr is a 'ThrowExceptionInstr'

            List<Instr> instrs = geb.getInstrs();
            Variable exc = ((ReceiveExceptionInstr)instrs.get(0)).getResult();
            instrs.set(instrs.size(), new RuntimeHelperCall(null, "catchUncaughtBreakInLambdas", new Operand[]{exc} ));
        }

        // Update scope
View Full Code Here

    public BasicBlock getRenamedBB(BasicBlock bb) {
        return bbRenameMap.get(bb);
    }

    public BasicBlock getOrCreateRenamedBB(BasicBlock bb) {
        BasicBlock renamedBB = getRenamedBB(bb);
        if (renamedBB == null) {
            renamedBB =  new BasicBlock(this.callerCFG, getRenamedLabel(bb.getLabel()));
            if (bb.isRescueEntry()) renamedBB.markRescueEntryBB();
            bbRenameMap.put(bb, renamedBB);
        }
        return renamedBB;
    }
View Full Code Here

    private CFG cloneSelf(InlinerInfo ii) {
        CFG selfClone = new CFG(cfg.getScope());

        // clone bbs
        BasicBlock entry = cfg.getEntryBB();
        BasicBlock exit = cfg.getExitBB();
        for (BasicBlock b : cfg.getBasicBlocks()) {
            if ((b != entry) && (b != exit)) {
                selfClone.addBasicBlock(b.cloneForInlinedMethod(ii));
            }
        }

        // clone edges
        for (BasicBlock b: cfg.getBasicBlocks()) {
            if ((b != entry) && (b != exit)) {
                BasicBlock rb = ii.getRenamedBB(b);
                for (Edge<BasicBlock> e : cfg.getOutgoingEdges(b)) {
                    BasicBlock destination = e.getDestination().getData();
                    if (destination != exit) selfClone.addEdge(rb, ii.getRenamedBB(destination), e.getType());
                }
            }
        }
View Full Code Here

TOP

Related Classes of org.jruby.ir.representations.BasicBlock

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.