protected Label getRenamedLabelSimple(Label l) { return getHostScope().getNewLabel(); }
protected Label getRenamedLabelSimple(Label l) { return getHostScope().getNewLabel(); }
@Override public Instr clone(CloneInfo info) { if (info instanceof InlineCloneInfo) { InlineCloneInfo ii = (InlineCloneInfo) info; // lexical closure if (ii.getScopeBeingInlined().isScopeContainedBy(ii.getHostScope())) return NopInstr.NOP; } return this; }
protected Variable getRenamedVariableSimple(Variable v) { if (isClosure) { // when inlining a closure, // - local var depths are reduced by 1 (to move them to the host scope) // - tmp vars are reallocated in the host scope if (v instanceof LocalVariable) { LocalVariable lv = (LocalVariable) v; int depth = lv.getScopeDepth(); return getHostScope().getLocalVariable(lv.getName(), depth > 1 ? depth - 1 : 0); } return getHostScope().createTemporaryVariable(); } // METHOD_INLINE return getHostScope().getNewInlineVariable(inlineVarPrefix, v); }
protected Variable getRenamedVariableSimple(Variable v) { if (isClosure) { // when inlining a closure, // - local var depths are reduced by 1 (to move them to the host scope) // - tmp vars are reallocated in the host scope if (v instanceof LocalVariable) { LocalVariable lv = (LocalVariable) v; int depth = lv.getScopeDepth(); return getHostScope().getLocalVariable(lv.getName(), depth > 1 ? depth - 1 : 0); } return getHostScope().createTemporaryVariable(); } // METHOD_INLINE return getHostScope().getNewInlineVariable(inlineVarPrefix, v); }
@Override public Instr clone(CloneInfo info) { if (info instanceof InlineCloneInfo) { InlineCloneInfo ii = (InlineCloneInfo) info; // lexical closure if (ii.getScopeBeingInlined().isScopeContainedBy(ii.getHostScope())) return NopInstr.NOP; } return this; }
public Variable getRenamedSelfVariable(Variable self) { /* Note: evals make all this weird but our heuristics are such that we should not see the same callsite * make a monocall across an eval (within an eval is fine). If we ever cache pre-compiled evals we may * end up breaking here. * * There are two closure types we will see while inlinine. * 1. A closure attached to the call we are inlining or exists within host scope itself. ( .... inline_me { foo } * This will have same self as the host scope itself. * 2. A closure in the method we are inlining. * That will the same self as the inlined methods scope */ if (isClosure) { if (getScopeBeingInlined().getNearestTopLocalVariableScope() == getHostScope()) { return self; } else { return callReceiver; } } else { // method scope return callReceiver; } }
public Variable getRenamedSelfVariable(Variable self) { /* Note: evals make all this weird but our heuristics are such that we should not see the same callsite * make a monocall across an eval (within an eval is fine). If we ever cache pre-compiled evals we may * end up breaking here. * * There are two closure types we will see while inlinine. * 1. A closure attached to the call we are inlining or exists within host scope itself. ( .... inline_me { foo } * This will have same self as the host scope itself. * 2. A closure in the method we are inlining. * That will the same self as the inlined methods scope */ if (isClosure) { if (getScopeBeingInlined().getNearestTopLocalVariableScope() == getHostScope()) { return self; } else { return callReceiver; } } else { // method scope return callReceiver; } }
@Override public Operand cloneForInlining(CloneInfo ii) { if (ii instanceof InlineCloneInfo) { InlineCloneInfo iici = (InlineCloneInfo) ii; // inlined method lives somewhere else so we need to save that scope location. if (iici.getHostScope() != iici.getScopeBeingInlined()) { return new Scope(((InlineCloneInfo) ii).getScopeBeingInlined()); } } return this; }
@Override public Operand cloneForInlining(CloneInfo ii) { if (ii instanceof InlineCloneInfo) { InlineCloneInfo iici = (InlineCloneInfo) ii; // inlined method lives somewhere else so we need to save that scope location. if (iici.getHostScope() != iici.getScopeBeingInlined()) { return new Scope(((InlineCloneInfo) ii).getScopeBeingInlined()); } } return this; }
public InlineCloneInfo(CallBase call, CFG c, Variable callReceiver, IRScope scopeBeingInlined) { super( c.getScope()); this.isClosure = false; this.hostCFG = c; this.call = call; this.callArgs = call.getCallArgs(); this.callReceiver = callReceiver; this.canMapArgsStatically = !containsSplat(callArgs); this.argsArray = this.canMapArgsStatically ? null : getHostScope().createTemporaryVariable(); this.scopeBeingInlined = scopeBeingInlined; synchronized(globalInlineCount) { this.inlineVarPrefix = new ByteList(("%in" + globalInlineCount + "_").getBytes()); globalInlineCount++; } }
public InlineCloneInfo(CallBase call, CFG c, Variable callReceiver, IRScope scopeBeingInlined) { super( c.getScope()); this.isClosure = false; this.hostCFG = c; this.call = call; this.callArgs = call.getCallArgs(); this.callReceiver = callReceiver; this.canMapArgsStatically = !containsSplat(callArgs); this.argsArray = this.canMapArgsStatically ? null : getHostScope().createTemporaryVariable(); this.scopeBeingInlined = scopeBeingInlined; synchronized(globalInlineCount) { this.inlineVarPrefix = new ByteList(("%in" + globalInlineCount + "_").getBytes()); globalInlineCount++; } }
@Override public Instr clone(CloneInfo info) { if (info instanceof SimpleCloneInfo) return new NonlocalReturnInstr(getReturnValue().cloneForInlining(info), methodName); InlineCloneInfo ii = (InlineCloneInfo) info; if (ii.isClosure()) { if (ii.getHostScope() instanceof IRMethod) { // Lexically contained non-local returns can return directly if the live in the method they are inlining to. if (((InlineCloneInfo) info).getScopeBeingInlined().isScopeContainedBy(ii.getHostScope())) { return new ReturnInstr(getReturnValue().cloneForInlining(ii)); } // Treat like inlining of a regular method-return (note: a jump is added to exit so this copy // actually ends up being the methods return value). Variable v = ii.getCallResultVariable(); return v == null ? null : new CopyInstr(v, getReturnValue().cloneForInlining(ii)); } return new NonlocalReturnInstr(getReturnValue().cloneForInlining(ii), methodName); } else { throw new UnsupportedOperationException("Nonlocal returns shouldn't show up outside closures."); } }
@Override public Instr clone(CloneInfo info) { if (info instanceof SimpleCloneInfo) return new NonlocalReturnInstr(getReturnValue().cloneForInlining(info), methodName); InlineCloneInfo ii = (InlineCloneInfo) info; if (ii.isClosure()) { if (ii.getHostScope() instanceof IRMethod) { // Lexically contained non-local returns can return directly if the live in the method they are inlining to. if (((InlineCloneInfo) info).getScopeBeingInlined().isScopeContainedBy(ii.getHostScope())) { return new ReturnInstr(getReturnValue().cloneForInlining(ii)); } // Treat like inlining of a regular method-return (note: a jump is added to exit so this copy // actually ends up being the methods return value). Variable v = ii.getCallResultVariable(); return v == null ? null : new CopyInstr(v, getReturnValue().cloneForInlining(ii)); } return new NonlocalReturnInstr(getReturnValue().cloneForInlining(ii), methodName); } else { throw new UnsupportedOperationException("Nonlocal returns shouldn't show up outside closures."); } }
public void setupYieldArgsAndYieldResult(YieldInstr yi, BasicBlock yieldBB, int blockArityValue) { Operand yieldInstrArg = yi.getYieldArg(); if ((yieldInstrArg == UndefinedValue.UNDEFINED) || blockArityValue == 0) { yieldArg = new Array(); // Zero-elt array } else if (yieldInstrArg instanceof Array) { yieldArg = yieldInstrArg; // 1:1 arg match if (((Array) yieldInstrArg).size() == blockArityValue) canMapArgsStatically = true; } else if (blockArityValue == 1 && yi.unwrapArray == false) { yieldArg = yieldInstrArg; canMapArgsStatically = true; } else { // SSS FIXME: The code below is not entirely correct. We have to process 'yi.getYieldArg()' similar // to how InterpretedIRBlockBody (1.8 and 1.9 modes) processes it. We may need a special instruction // that takes care of aligning the stars and bringing good fortune to arg yielder and arg receiver. IRScope callerScope = getHostScope(); Variable yieldArgArray = callerScope.createTemporaryVariable(); yieldBB.addInstr(new ToAryInstr(yieldArgArray, yieldInstrArg)); yieldArg = yieldArgArray; } yieldResult = yi.getResult(); }
public void setupYieldArgsAndYieldResult(YieldInstr yi, BasicBlock yieldBB, int blockArityValue) { Operand yieldInstrArg = yi.getYieldArg(); if ((yieldInstrArg == UndefinedValue.UNDEFINED) || blockArityValue == 0) { yieldArg = new Array(); // Zero-elt array } else if (yieldInstrArg instanceof Array) { yieldArg = yieldInstrArg; // 1:1 arg match if (((Array) yieldInstrArg).size() == blockArityValue) canMapArgsStatically = true; } else if (blockArityValue == 1 && yi.unwrapArray == false) { yieldArg = yieldInstrArg; canMapArgsStatically = true; } else { // SSS FIXME: The code below is not entirely correct. We have to process 'yi.getYieldArg()' similar // to how InterpretedIRBlockBody (1.8 and 1.9 modes) processes it. We may need a special instruction // that takes care of aligning the stars and bringing good fortune to arg yielder and arg receiver. IRScope callerScope = getHostScope(); Variable yieldArgArray = callerScope.createTemporaryVariable(); yieldBB.addInstr(new ToAryInstr(yieldArgArray, yieldInstrArg)); yieldArg = yieldArgArray; } yieldResult = yi.getResult(); }
public BasicBlock cloneForInlining(InlineCloneInfo ii) { BasicBlock clonedBB = ii.getOrCreateRenamedBB(this); for (Instr i: getInstrs()) { Instr clonedInstr = i.clone(ii); if (clonedInstr != null) { clonedBB.addInstr(clonedInstr); if (clonedInstr instanceof YieldInstr) { ii.recordYieldSite(clonedBB, (YieldInstr)clonedInstr); } else if (i instanceof NonlocalReturnInstr && clonedInstr instanceof CopyInstr) { // non-local returns assign to method return variable but must jump to proper exit point clonedBB.addInstr(new JumpInstr(ii.getHostScope().getCFG().getExitBB().getLabel())); // FIXME: enebo...I see no guarantee that this copy will be part of a return? This behavior is // masked in any case I can see with optimization to not use a copy but convert non-local to local return. } } } return clonedBB; }
public BasicBlock cloneForInlining(InlineCloneInfo ii) { BasicBlock clonedBB = ii.getOrCreateRenamedBB(this); for (Instr i: getInstrs()) { Instr clonedInstr = i.clone(ii); if (clonedInstr != null) { clonedBB.addInstr(clonedInstr); if (clonedInstr instanceof YieldInstr) { ii.recordYieldSite(clonedBB, (YieldInstr)clonedInstr); } else if (i instanceof NonlocalReturnInstr && clonedInstr instanceof CopyInstr) { // non-local returns assign to method return variable but must jump to proper exit point clonedBB.addInstr(new JumpInstr(ii.getHostScope().getCFG().getExitBB().getLabel())); // FIXME: enebo...I see no guarantee that this copy will be part of a return? This behavior is // masked in any case I can see with optimization to not use a copy but convert non-local to local return. } } } return clonedBB; }
@Override public Instr clone(CloneInfo info) { if (info instanceof SimpleCloneInfo) { return new ReceivePostReqdArgInstr(info.getRenamedVariable(result), argIndex, preReqdArgsCount, optArgsCount, restArg, postReqdArgsCount); } InlineCloneInfo ii = (InlineCloneInfo) info; if (ii.canMapArgsStatically()) { int n = ii.getArgsCount(); int remaining = n - preReqdArgsCount; Operand argVal; if (remaining <= argIndex) { // SSS: FIXME: Argh! argVal = ii.getHostScope().getManager().getNil(); } else { argVal = (remaining > postReqdArgsCount) ? ii.getArg(n - postReqdArgsCount + argIndex) : ii.getArg(preReqdArgsCount + argIndex); } return new CopyInstr(ii.getRenamedVariable(result), argVal); } return new ReqdArgMultipleAsgnInstr(ii.getRenamedVariable(result), ii.getArgs(), preReqdArgsCount, postReqdArgsCount, argIndex); }
@Override public Instr clone(CloneInfo info) { if (info instanceof SimpleCloneInfo) { return new ReceivePostReqdArgInstr(info.getRenamedVariable(result), argIndex, preReqdArgsCount, optArgsCount, restArg, postReqdArgsCount); } InlineCloneInfo ii = (InlineCloneInfo) info; if (ii.canMapArgsStatically()) { int n = ii.getArgsCount(); int remaining = n - preReqdArgsCount; Operand argVal; if (remaining <= argIndex) { // SSS: FIXME: Argh! argVal = ii.getHostScope().getManager().getNil(); } else { argVal = (remaining > postReqdArgsCount) ? ii.getArg(n - postReqdArgsCount + argIndex) : ii.getArg(preReqdArgsCount + argIndex); } return new CopyInstr(ii.getRenamedVariable(result), argVal); } return new ReqdArgMultipleAsgnInstr(ii.getRenamedVariable(result), ii.getArgs(), preReqdArgsCount, postReqdArgsCount, argIndex); }