Package org.jruby.compiler.ir.instructions

Examples of org.jruby.compiler.ir.instructions.CallInstr


        for (Instr i : _bb.getInstrs()) {
            if (i.operation == Operation.BINDING_LOAD) continue;

            // Process calls specially -- these are the sites of binding stores!
            if (i instanceof CallInstr) {
                CallInstr call = (CallInstr) i;
                Operand o = call.getClosureArg();
                if ((o != null) && (o instanceof MetaObject)) {
                    // At this call site, a binding will get allocated if it has not been already!
                    bindingAllocated = true;

                    IRClosure cl = (IRClosure) ((MetaObject) o).scope;
                    CFG cl_cfg = cl.getCFG();
                    BindingStorePlacementProblem cl_bsp = new BindingStorePlacementProblem();
                    cl_bsp.setup(cl_cfg);
                    cl_bsp.compute_MOP_Solution();
                    cl_cfg.setDataFlowSolution(cl_bsp.getName(), cl_bsp);

                    // If the call is an eval, or if the callee can capture this method's binding, we have to spill all variables.
                    boolean spillAllVars = call.canBeEval() || call.canCaptureCallersBinding();

                    // - If all variables have to be spilled, then those variables will no longer be dirty after the call site
                    // - If a variable is used in the closure (FIXME: Strictly only those vars that are live at the call site --
                    //   but we dont have this info!), it has to be spilt. So, these variables are no longer dirty after the call site.
                    // - If a variable is (re)defined in the closure, it will be saved inside the closure.  So, these variables
                    //   won't be dirty after the call site either!
                    Set<Variable> newDirtyVars = new HashSet<Variable>(dirtyVars);
                    for (Variable v : dirtyVars) {
                        if (spillAllVars || cl_bsp.scopeUsesVariable(v) || cl_bsp.scopeDefinesVariable(v)) {
                            newDirtyVars.remove(v);
                        }
                    }
                    dirtyVars = newDirtyVars;
                } // Call has no closure && it requires stores
                else if (call.requiresBinding()) {
                    dirtyVars.clear();
                    bindingAllocated = true;
                }
            }
View Full Code Here


        while (instrs.hasNext()) {
            Instr i = instrs.next();
            if (i.operation == Operation.BINDING_LOAD) continue;

            if (i instanceof CallInstr) {
                CallInstr call = (CallInstr) i;
                Operand o = call.getClosureArg();
                if ((o != null) && (o instanceof MetaObject)) {
                    CFG cl_cfg = ((IRClosure) ((MetaObject) o).scope).getCFG();
                    BindingStorePlacementProblem cl_bsp = (BindingStorePlacementProblem) cl_cfg.getDataFlowSolution(bsp.getName());

                    // Add a binding allocation instruction, if necessary
                    instrs.previous();
                    if (!bindingAllocated) {
                        instrs.add(new AllocateBindingInstr(s));
                        bindingAllocated = true;
                    }

                    // If the call is an eval, or if the callee can capture this method's binding,
                    // we have to spill all variables.
                    boolean spillAllVars = call.canBeEval() || call.canCaptureCallersBinding();

                    // Unless we have to spill everything, spill only those dirty variables that are:
                    // - used in the closure (FIXME: Strictly only those vars that are live at the call site -- but we dont have this info!)
                    Set<Variable> newDirtyVars = new HashSet<Variable>(dirtyVars);
                    for (Variable v : dirtyVars) {
                        if (spillAllVars || cl_bsp.scopeUsesVariable(v)) {
                            // FIXME: This may not need check for local variable if it is guaranteed to only be local variables.
                            instrs.add(new StoreToBindingInstr(s, v.getName(), v));
                            newDirtyVars.remove(v);
                        } // These variables will be spilt inside the closure -- so they will no longer be dirty after the call site!
                        else if (cl_bsp.scopeDefinesVariable(v)) {
                            newDirtyVars.remove(v);
                        }
                    }
                    dirtyVars = newDirtyVars;
                    instrs.next();

                    // add stores in the closure
                    ((BindingStorePlacementProblem) cl_cfg.getDataFlowSolution(bsp.getName())).addStoreAndBindingAllocInstructions();
                } // Call has no closure && it requires stores
                else if (call.requiresBinding()) {
                    instrs.previous();
                    if (!bindingAllocated) {
                        instrs.add(new AllocateBindingInstr(s));
                        bindingAllocated = true;
                    }
View Full Code Here

            }

            // Check if 'i' is a call and uses a closure!
            // If so, we need to process the closure for live variable info.
            if (i instanceof CallInstr) {
                CallInstr c = (CallInstr) i;
                // SSS FIXME: This relies on the local opt. pass having run already
                // so that the built closure from the previous instr. is propagated to the call site here.
                // Formalize this dependency somewhere?
                Operand o = c.getClosureArg();
//                   System.out.println("Processing closure: " + o + "-------");
                if ((o != null) && (o instanceof MetaObject)) {
                    IRClosure cl = (IRClosure)((MetaObject)o).scope;
                    if (c.isLVADataflowBarrier()) {
                        processClosure(cl, lvp.getAllVars());

                        // Mark all variables live if 'c' is a dataflow barrier!
//                        System.out.println(".. call is a data flow barrier ..");
                        for (int j = 0; j < _setSize; j++)
                            _tmp.set(j);
                    }
                    else {
                        // Propagate current LVA state through the closure
                        // SSS FIXME: Think through this .. Is there any way out of having
                        // to recompute the entire lva for the closure each time through?

                        // 1. Collect variables live at this point.
                        List<Variable> liveVars = new ArrayList<Variable>();
                        for (int j = 0; j < _tmp.size(); j++) {
                            if (_tmp.get(j) == true) {
//                                System.out.println(lvp.getVariable(j) + " is live on exit of closure!");
                                liveVars.add(lvp.getVariable(j));
                            }
                        }
//                        System.out.println(" .. collected live on exit ..");

                        // 2. Run LVA on the closure
                        LiveVariablesProblem xlvp = processClosure(cl, liveVars);

//                        System.out.println("------- done with closure" + o);

                        // 3. Collect variables live on entry of the closure and merge that info into the current problem.
                        for (Variable y: xlvp.getVarsLiveOnEntry()) {
                            DataFlowVar dv = lvp.getDFVar(y);
                            // This can be null for vars used, but not defined!  Yes, the source program is buggy ..
                            if (dv != null) {
//                                System.out.println(y + " is live on entry of the closure!");
                                _tmp.set(dv._id);
                            }
                        }
                    }
                }
                else if (c.isLVADataflowBarrier()) {
                    // Mark all variables live if 'c' is a dataflow barrier!
//                    System.out.println(".. call is a data flow barrier ..");
                    for (int j = 0; j < _setSize; j++)
                        _tmp.set(j);
                }
View Full Code Here

            else {
//                System.out.println("IGNORING! No result!");
            }

            if (i instanceof CallInstr) {
                CallInstr c = (CallInstr) i;
                if (c.isLVADataflowBarrier()) {
                    // Mark all variables live if 'c' is a dataflow barrier!
                    for (int j = 0; j < _setSize; j++)
                        _tmp.set(j);
                }
                else {
                    Operand o = c.getClosureArg();
                    if ((o != null) && (o instanceof MetaObject)) {
                        // 2. Run LVA on the closure
                        IRClosure cl = (IRClosure)((MetaObject)o).scope;
                        CFG x = cl.getCFG();
                        LiveVariablesProblem xlvp = (LiveVariablesProblem)x.getDataFlowSolution(lvp.getName());
View Full Code Here

            if (r != null) reqdLoads.remove(r);

            // Process calls specially -- these are the sites of binding loads!
            if (i instanceof CallInstr) {
                CallInstr call = (CallInstr) i;
                Operand o = call.getClosureArg();
                if ((o != null) && (o instanceof MetaObject)) {
                    IRClosure cl = (IRClosure) ((MetaObject) o).scope;
                    CFG cl_cfg = cl.getCFG();
                    BindingLoadPlacementProblem cl_blp = new BindingLoadPlacementProblem();
                    cl_blp.initLoadsOnScopeExit(reqdLoads);
                    cl_blp.setup(cl_cfg);
                    cl_blp.compute_MOP_Solution();
                    cl_cfg.setDataFlowSolution(cl_blp.getName(), cl_blp);
                    if (call.requiresBinding()) {
                        reqdLoads.clear();
                    }

                    // Variables defined in the closure do not need to be loaded anymore at
                    // program points before the call.
                    Set<Variable> newReqdLoads = new HashSet<Variable>(reqdLoads);
                    for (Variable v : reqdLoads) {
                        if (cl_blp.scopeDefinesVariable(v)) newReqdLoads.remove(v);
                    }
                    reqdLoads = newReqdLoads;
                }
                // In this case, we are going to blindly load everything -- so, at the call site, pending loads dont carry over!
                else if (call.requiresBinding()) {
                    reqdLoads.clear();
                }
            }

            // The variables used as arguments will need to be loaded
View Full Code Here

            Variable r = i.getResult();

            if (r != null) reqdLoads.remove(r);

            if (i instanceof CallInstr) {
                CallInstr call = (CallInstr) i;
                Operand o = call.getClosureArg();
                if ((o != null) && (o instanceof MetaObject)) {
                    CFG cl_cfg = ((IRClosure) ((MetaObject) o).scope).getCFG();
                    BindingLoadPlacementProblem cl_blp = (BindingLoadPlacementProblem) cl_cfg.getDataFlowSolution(blp.getName());

                    // Only those variables that are defined in the closure, and are in the required loads set
                    // will need to be loaded from the binding after the call!
                    Set<Variable> newReqdLoads = new HashSet<Variable>(reqdLoads);
                    it.next();
                    for (Variable v : reqdLoads) {
                        if (cl_blp.scopeDefinesVariable(v)) {
                            it.add(new LoadFromBindingInstr(v, s, v.getName()));
                            it.previous();
                            newReqdLoads.remove(v);
                        }
                    }
                    it.previous();
                    reqdLoads = newReqdLoads;

                    // add loads in the closure
                    ((BindingLoadPlacementProblem) cl_cfg.getDataFlowSolution(blp.getName())).addLoads();
                } else if (call.requiresBinding()) {
                    it.next();
                    for (Variable v : reqdLoads) {
                        it.add(new LoadFromBindingInstr(v, s, v.getName()));
                        it.previous();
                    }
View Full Code Here

        // to preserve expected code execution order
        Operand       receiver     = build(receiverNode, s);
        List<Operand> args         = setupCallArgs(callArgsNode, s);
        Operand       block        = setupCallClosure(callNode.getIterNode(), s);
        Variable      callResult   = s.getNewTemporaryVariable();
        Instr      callInstr    = new CallInstr(callResult, new MethAddr(callNode.getName()), receiver, args.toArray(new Operand[args.size()]), block);
        s.addInstr(callInstr);
        return callResult;
    }
View Full Code Here

        } else if (iVisited instanceof Colon2MethodNode) {
            Colon2MethodNode c2mNode = (Colon2MethodNode)iVisited;
            List<Operand> args       = setupCallArgs(null, s);
            Operand       block      = setupCallClosure(null, s);
            Variable      callResult = s.getNewTemporaryVariable();
            Instr      callInstr  = new CallInstr(callResult, new MethAddr(c2mNode.getName()),
                    null, args.toArray(new Operand[args.size()]), block);
            s.addInstr(callInstr);
            return callResult;
        }
        else { throw new NotCompilableException("Not compilable: " + iVisited); }
View Full Code Here

    public Operand buildFCall(FCallNode fcallNode, IRScope s) {
        Node          callArgsNode = fcallNode.getArgsNode();
        List<Operand> args         = setupCallArgs(callArgsNode, s);
        Operand       block        = setupCallClosure(fcallNode.getIterNode(), s);
        Variable      callResult   = s.getNewTemporaryVariable();
        Instr         callInstr    = new CallInstr(callResult, new MethAddr(fcallNode.getName()), getSelf(s), args.toArray(new Operand[args.size()]), block);
        s.addInstr(callInstr);
        return callResult;
    }
View Full Code Here

        }
       
        // get attr
        Operand  v1 = build(opAsgnNode.getReceiverNode(), s);
        Variable      getResult   = s.getNewTemporaryVariable();
        Instr callInstr = new CallInstr(getResult, new MethAddr(opAsgnNode.getVariableName()), v1,
                NO_ARGS, null);
        s.addInstr(callInstr);

        // call operator
        Operand  v2 = build(opAsgnNode.getValueNode(), s);
        Variable      setValue   = s.getNewTemporaryVariable();
        callInstr = new CallInstr(setValue, new MethAddr(opAsgnNode.getOperatorName()), getResult,
                new Operand[]{v2}, null);
        s.addInstr(callInstr);

        // set attr
        Variable      setResult   = s.getNewTemporaryVariable();
        callInstr    = new CallInstr(setResult, new MethAddr(opAsgnNode.getVariableNameAsgn()),
                v1, new Operand[] {setValue}, null);
        s.addInstr(callInstr);

        return setResult;
    }
View Full Code Here

TOP

Related Classes of org.jruby.compiler.ir.instructions.CallInstr

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.