public void inlineMethod(IRScope method, RubyModule implClass, int classToken, BasicBlock basicBlock, CallBase call) { // Inline depends(cfg()); new CFGInliner(cfg).inlineMethod(method, implClass, classToken, basicBlock, call); // Reset state resetState(); // Re-run opts for (CompilerPass pass: getManager().getInliningCompilerPasses(this)) { pass.run(this); } }
public void inlineMethod(IRScope method, RubyModule implClass, int classToken, BasicBlock basicBlock, CallBase call) { // Inline depends(cfg()); new CFGInliner(cfg).inlineMethod(method, implClass, classToken, basicBlock, call); // Reset state resetState(); // Re-run opts for (CompilerPass pass: getManager().getInliningCompilerPasses(this)) { pass.run(this); } }
private FullInterpreterContext inlineMethodCommon(IRMethod methodToInline, long callsiteId, int classToken, boolean cloneHost) { alreadyHasInline = true; // FIXME: Tried prepareFullBuild here and for methodToInline and a couple of missing callsiteid errors happened in spec:ruby:fast if (getFullInterpreterContext() == null) return inlineFailed("inline into startup interpreter scope"); // FIXME: So a potential problem is closures contain local variables in the method being inlined then we will nuke // those scoped variables and the closure cannot see them. One idea is since for deoptimization we will need to // create a scope restore table we will have a list of all lvars -> temps. Since this will be a map we depend on // for restoring scope we can probably make an temp variable which will look for values from this table. Even in // that solution we need access to the temp table from the closure so I am unsure that will work. // // Another solution is to force inline those closures but that only works if the methods they are calling through // are IR methods (or are native but can be substituted with IR methods). // // Note: we can look for scoped methods and make this less conservative. if (!methodToInline.getClosures().isEmpty()) return inlineFailed("inline a method which contains nested closures"); FullInterpreterContext newContext = getFullInterpreterContext().duplicate(); BasicBlock basicBlock = newContext.findBasicBlockOf(callsiteId); CallBase call = (CallBase) basicBlock.siteOf(callsiteId); // we know it is callBase and not a yield RubyModule implClass = compilable.getImplementationClass(); String error = new CFGInliner(newContext).inlineMethod(methodToInline, implClass, classToken, basicBlock, call, cloneHost); return error == null ? newContext : inlineFailed(error); }
private FullInterpreterContext inlineMethodCommon(IRMethod methodToInline, long callsiteId, int classToken, boolean cloneHost) { alreadyHasInline = true; // FIXME: Tried prepareFullBuild here and for methodToInline and a couple of missing callsiteid errors happened in spec:ruby:fast if (getFullInterpreterContext() == null) return inlineFailed("inline into startup interpreter scope"); // FIXME: So a potential problem is closures contain local variables in the method being inlined then we will nuke // those scoped variables and the closure cannot see them. One idea is since for deoptimization we will need to // create a scope restore table we will have a list of all lvars -> temps. Since this will be a map we depend on // for restoring scope we can probably make an temp variable which will look for values from this table. Even in // that solution we need access to the temp table from the closure so I am unsure that will work. // // Another solution is to force inline those closures but that only works if the methods they are calling through // are IR methods (or are native but can be substituted with IR methods). // // Note: we can look for scoped methods and make this less conservative. if (!methodToInline.getClosures().isEmpty()) return inlineFailed("inline a method which contains nested closures"); FullInterpreterContext newContext = getFullInterpreterContext().duplicate(); BasicBlock basicBlock = newContext.findBasicBlockOf(callsiteId); CallBase call = (CallBase) basicBlock.siteOf(callsiteId); // we know it is callBase and not a yield RubyModule implClass = compilable.getImplementationClass(); String error = new CFGInliner(newContext).inlineMethod(methodToInline, implClass, classToken, basicBlock, call, cloneHost); return error == null ? newContext : inlineFailed(error); }