Package org.jruby.compiler.ir.instructions

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


        }
       
        // 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);
View Full Code Here


    }

    public Operand buildVCall(VCallNode node, IRScope s) {
        List<Operand> args       = new ArrayList<Operand>(); args.add(getSelf(s));
        Variable      callResult = s.getNewTemporaryVariable();
        Instr         callInstr  = new CallInstr(callResult, new MethAddr(node.getName()), getSelf(s), NO_ARGS, null);
        s.addInstr(callInstr);
        return callResult;
    }
View Full Code Here

        Map<Operand,Operand> valueMap = new HashMap<Operand,Operand>();
        Map<Variable,List<Variable>> simplificationMap = new HashMap<Variable,List<Variable>>();
        Map<String,CodeVersion> versionMap = new HashMap<String,CodeVersion>();
        ListIterator<Instr> instrs = s.getInstrs().listIterator();
        while (instrs.hasNext()) {
            Instr i = instrs.next();
            Operation iop = i.operation;
            if (iop.startsBasicBlock()) {
                valueMap = new HashMap<Operand,Operand>();
                simplificationMap = new HashMap<Variable,List<Variable>>();
                versionMap = new HashMap<String, CodeVersion>();
            }

            // Simplify instruction and record mapping between target variable and simplified value
//            System.out.println("BEFORE: " + i);
            Operand  val = i.simplifyAndGetResult(valueMap);
            Variable res = i.getResult();
//            System.out.println("For " + i + "; dst = " + res + "; val = " + val);
//            System.out.println("AFTER: " + i);
            if (val != null && res != null && res != val) {
                recordSimplification(res, val, valueMap, simplificationMap);

                if (val instanceof BreakResult) {
                    BreakResult br = (BreakResult)val;
                    i.markDead();
                    instrs.add(new CopyInstr(res, br._result));
                    instrs.add(new JumpInstr(br._jumpTarget));
                }
            }
            // Optimize some core class method calls for constant values
            else if (iop.isCall()) {
                val = null;
                CallInstr call = (CallInstr) i;
                Operand    r    = call.getReceiver();
                // SSS FIXME: r can be null for ruby/jruby internal call instructions!
                // Cannot optimize them as of now.
                if (r != null) {
                    // If 'r' is not a constant, it could actually be a compound value!
                    // Look in our value map to see if we have a simplified value for the receiver.
                    if (!r.isConstant()) {
                        Operand v = valueMap.get(r);
                        if (v != null)
                            r = v;
                    }

                    // Check if we can optimize this call based on the receiving method and receiver type
                    // Use the simplified receiver!
                    IRMethod rm = call.getTargetMethodWithReceiver(r);
                    if (rm != null) {
                        IRModule rc = rm.getDefiningIRModule();
                        if (rc != null) { // TODO: I am fairly sure I am wallpapering
                            if (rc.isCoreClass("Fixnum")) {
                                Operand[] args = call.getOperands();
                                if (args[2].isConstant()) {
                                    addMethodGuard(rm, deoptLabel, versionMap, instrs);
                                    val = ((Fixnum) r).computeValue(rm.getName(), (Constant) args[2]);
                                }
                            } else if (rc.isCoreClass("Float")) {
                                Operand[] args = call.getOperands();
                                if (args[2].isConstant()) {
                                    addMethodGuard(rm, deoptLabel, versionMap, instrs);
                                    val = ((Float) r).computeValue(rm.getName(), (Constant) args[2]);
                                }
                            } else if (rc.isCoreClass("Array")) {
                                Operand[] args = call.getOperands();
                                if (args[2] instanceof Fixnum && (rm.getName() == "[]")) {
                                    addMethodGuard(rm, deoptLabel, versionMap, instrs);
                                    val = ((Array) r).fetchCompileTimeArrayElement(((Fixnum) args[2]).value.intValue(), false);
                                }
                            }
                        }

                        // If we got a simplified value, mark the call dead and insert a copy in its place!
                        if (val != null) {
                            i.markDead();
                            instrs.add(new CopyInstr(res, val));
                            recordSimplification(res, val, valueMap, simplificationMap);
                        }
                    }
                }
            }

            // Purge all entries in valueMap that have 'res' as their simplified value to take care of RAW scenarios (because we aren't in SSA form yet!)
            if (res != null) {
                List<Variable> simplifiedVars = simplificationMap.get(res);
                if (simplifiedVars != null) {
                    for (Variable v: simplifiedVars)
                        valueMap.remove(v);
                    simplificationMap.remove(res);
                }
            }

            // If the call has been optimized away in the previous step, it is no longer a hard boundary for opts!
            if (iop.endsBasicBlock() || (iop.isCall() && !i.isDead())) {
                valueMap = new HashMap<Operand,Operand>();
                simplificationMap = new HashMap<Variable,List<Variable>>();
                versionMap = new HashMap<String, CodeVersion>();
            }
        }
View Full Code Here

        Map<Variable, Integer> ends = new HashMap<Variable, Integer>();
        Map<Variable, Integer> starts = new HashMap<Variable, Integer>();
        SortedSet<Variable> variables = new TreeSet<Variable>();
       
        for (int i = instructions.size() - 1; i >= 0; i--) {
            Instr instr = instructions.get(i);
            Variable var = instr.result;

            if (var != null) {
                variables.add(var);
                starts.put(var, i);
            }

            for (Operand operand : instr.getOperands()) {
                if (operand != null && operand instanceof Variable && ends.get((Variable)operand) == null) {
                    ends.put((Variable)operand, i);
                    variables.add((Variable)operand);
                }
            }
View Full Code Here

        Map<LocalVariable, Integer> ends = new HashMap<LocalVariable, Integer>();
        Map<LocalVariable, Integer> starts = new HashMap<LocalVariable, Integer>();
        Set<LocalVariable> variables = new TreeSet<LocalVariable>();

        for (int i = instructions.size() - 1; i >= 0; i--) {
            Instr instr = instructions.get(i);

            // TODO: Instruction encode whether arguments are optional/required/block
            // TODO: PErhaps this should be part of allocate and not have a generic
            //    getLiveLocalVariables...perhaps we just need this to setup static scope

            Variable variable = instr.result;

            if (variable != null && variable instanceof LocalVariable) {
                variables.add((LocalVariable) variable);
                starts.put((LocalVariable) variable, i);
            }

            for (Operand operand : instr.getOperands()) {
                if (!(operand instanceof LocalVariable)) continue;

                variable = (LocalVariable) operand;

                if (ends.get((LocalVariable) variable) == null) {
View Full Code Here

    }

    @Interp
    public void calculateParameterCounts() {
        for (int i = instructions.size() - 1; i >= 0; i--) {
            Instr instr = instructions.get(i);
        }
    }
View Full Code Here

            if (b == _exitBB) {
                assert stack.empty();
            }
            else {
                // Find the basic block that is the target of the 'taken' branch
                Instr lastInstr = b.getLastInstr();
                if (lastInstr == null) {
                    // Only possible for the root block with 2 edges + blocks with just 1 target with no instructions
                    BasicBlock b1 = null, b2 = null;
                    for (CFG_Edge e: _cfg.outgoingEdgesOf(b)) {
                        if (b1 == null)
                            b1 = e._dst;
                        else if (b2 == null)
                            b2 = e._dst;
                        else
                            throw new RuntimeException("Encountered bb: " + b.getID() + " with no instrs. and more than 2 targets!!");
                    }

                    assert (b1 != null);

                    // Process lower number target first!
                    if (b2 == null) {
                        pushBBOnStack(stack, bbSet, b1);
                    }
                    else if (b1.getID() < b2.getID()) {
                        pushBBOnStack(stack, bbSet, b2);
                        pushBBOnStack(stack, bbSet, b1);
                    }
                    else {
                        pushBBOnStack(stack, bbSet, b1);
                        pushBBOnStack(stack, bbSet, b2);
                    }
                }
                else {
//                   System.out.println("last instr is: " + lastInstr);
                   BasicBlock blockToIgnore = null;
                   if (lastInstr instanceof JumpInstr) {
                       blockToIgnore = _bbMap.get(((JumpInstr)lastInstr).target);

                       // Check if all of blockToIgnore's predecessors get to it with a jump!
                       // This can happen because of exceptions and rescue handlers
                       // If so, dont ignore it.  Process it right away (because everyone will end up ignoring this block!)
                       boolean allJumps = true;
                       for (CFG_Edge e: _cfg.incomingEdgesOf(blockToIgnore)) {
                           if (! (e._src.getLastInstr() instanceof JumpInstr))
                               allJumps = false;
                       }

                       if (allJumps)
                           blockToIgnore = null;
                   }
                   else if (lastInstr instanceof BranchInstr) {
                       // Push the taken block onto the stack first so that it gets processed last!
                       BasicBlock takenBlock = _bbMap.get(((BranchInstr)lastInstr).getJumpTarget());
                       pushBBOnStack(stack, bbSet, takenBlock);
                       blockToIgnore = takenBlock;
                   }

                   // Push everything else
                   for (CFG_Edge e: _cfg.outgoingEdgesOf(b)) {
                       BasicBlock x = e._dst;
                       if (x != blockToIgnore)
                           pushBBOnStack(stack, bbSet, x);
                   }
                }
                assert !stack.empty();
            }
        }

        // Verify that all bbs have been laid out!
        for (BasicBlock b: getNodes()) {
            if (!bbSet.get(b.getID()))
                throw new RuntimeException("Bad CFG linearization: BB " + b.getID() + " has been missed!");
        }

        // Fixup (add/remove) jumps where appropriate
        int n = _linearizedBBList.size();
        for (int i = 0; i < n; i++) {
            BasicBlock curr = _linearizedBBList.get(i);
            Instr   li   = curr.getLastInstr();
            if ((i+1) < n) {
                BasicBlock next = _linearizedBBList.get(i+1);

                // If curr ends in a jump to next, remove the jump!
                if (li instanceof JumpInstr) {
View Full Code Here

    }

    public BasicBlock cloneForInlining(InlinerInfo ii) {
        BasicBlock clonedBB = ii.getOrCreateRenamedBB(this);
        for (Instr i: getInstrs()) {
        Instr clonedInstr = i.cloneForInlining(ii);
            clonedBB.addInstr(clonedInstr);
            if (clonedInstr instanceof YieldInstr)
                ii.recordYieldSite(clonedBB, (YieldInstr)clonedInstr);
        }
View Full Code Here

    public void processClosureArgAndReturnInstrs(InlinerInfo ii, YieldInstr yi) {
        Variable  yieldResult = ii.getRenamedVariable(yi.result);
        Operand[] yieldArgs   = yi.getOperands();

        for (ListIterator<Instr> it = ((ArrayList<Instr>)_instrs).listIterator(); it.hasNext(); ) {
            Instr i = it.next();
            if (i instanceof ClosureReturnInstr) {
                // Replace the closure return receive with a simple copy
                it.set(new CopyInstr(yieldResult, ((ClosureReturnInstr)i).getArg()));
            }
            else if (i instanceof ReceiveClosureArgInstr) {
View Full Code Here

TOP

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

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.