inlinedSomething = true;
  private boolean maybeInlineMethod(OPT_InlineDecision inlDec,                                     OPT_Instruction callSite) {    if (inlDec.isNO()) {      return false;    }    //-#if RVM_WITH_OSR    // Insert OsrBarrier point before the callsite which is going to be    // inlined, attach the OsrBarrier instruction to callsite's scratch    // object, then the callee can find this barrier        // verify it    if (this.osrGuardedInline) {      if (VM.VerifyAssertions) VM._assert(lastOsrBarrier != null);      callSite.scratchObject = lastOsrBarrier;    }    //-#endif    // Execute the inline decision.    // NOTE: It is tempting to wrap the call to OPT_Inliner.execute in     // a try/catch block that suppresses MagicNotImplemented failures    // by "backing out" the attempted inlining of a method that contained    // an unimplemented magic.  Unfortunately, this is somewhat hard to do    // cleanly, since exceptional control flow can inject control flow graph    // edges from inlinedContext to blocks in the enclosing caller CFG.    // These are not easy to find and remove because inlinedContext is not    // well-formed (the exception was thrown while generating the IR, in     // particular before calling finalPass, therefore the inlined CFG    // is not formed and finding all of its member blocks is somewhat awkward).    // We could write code to deal with this, but since in practice the    // opt compiler implements all but a few fringe magics, it is just fine    // to completely give up rather than take heroic measures here.    // In a few cases we do care about, we use NoInlinePragma to    // prevent the opt compiler from inlining a method that contains an    // unimplemented magic.    OPT_GenerationContext inlinedContext =       OPT_Inliner.execute(inlDec, gc,                           currentBBLE.block.exceptionHandlers, callSite);        // TODO: We're currently not keeping track if any of the     // enclosing exception handlers are actually reachable from     // this inlined callee.      // Therefore we simply force all of them to be generated wrt    // the state of the local variables in currentBBLE.    // This can result in generating unreachable handlers     // (if no PEI can reach them) and in generating suboptimal     // catch blocks (by merging in currentBBLE's local state    // into catch blocks that can't actually be reached from the inlined CFG).    // I strongly suspect it's not worth worrying about this.....    // dead code elimination should zap the unreachable handlers,     // and we shouldn't care too  much about the    // optimization possibilities lost by the extra local rectification.    // Especially since the odds of currentBBLE actually having     // unreachable handler blocks is darn close to zero. --dave 9/21/99.    // NOTE: No need to add CFG edges (they were added as needed     // during generation of the callee)    if (currentBBLE.handlers != null) {      for (int i = 0; i < currentBBLE.handlers.length; i++) {        blocks.rectifyLocals(_localState, currentBBLE.handlers[i]);      }    }    if (inlinedContext.epilogue != null) {      // Wrap a synthetic BBLE around OPT_GenerationContext.epilogue and      // pass it as from to getOrCreateBlock.      // This causes any compensation code inserted by getOrCreateBlock      // into the epilogue of the inlined method (see inlineTest7)      BasicBlockLE epilogueBBLE = new BasicBlockLE();      epilogueBBLE.block = inlinedContext.epilogue;      if (inlinedContext.result != null) {        // If the call has a result, _callHelper allocated a new         // temp for it and pushed it onto the expression stack.        // But, since we successfully inlined the call and         // inlinedContext.epilogue != null,        // we can use inlinedContext.result to obtain better         // downstream information about the inlined callee's return value.        // Therefore we'll pop the old callSite.result off the stack         // and push result instead.        // NOTE: It's critical that we pop callSite.result         // _before_ we copy the stack state into epilogueBBLE!        // Otherwise we'll end up with bogus code in the inlined         // method's prologue due to stack saving!!!!        VM_TypeReference resultType = Call.getResult(callSite).type;        pop(resultType);        // throw away callSite.result      }      blocks.rectifyStacks(currentBBLE.block, stack, epilogueBBLE);      if (inlinedContext.result != null) {        VM_TypeReference resultType = Call.getResult(callSite).type;        push(inlinedContext.result, resultType);      }      epilogueBBLE.copyIntoLocalState(_localState);      BasicBlockLE afterBBLE =         blocks.getOrCreateBlock(bcodes.index(), epilogueBBLE, stack, _localState);      // Create the InliningBlockLE and initialize fallThrough links.      InliningBlockLE inlinedCallee = new InliningBlockLE(inlinedContext);      currentBBLE.fallThrough = inlinedCallee;      currentBBLE.block.insertOut(inlinedCallee.gc.cfg.firstInCodeOrder());      inlinedCallee.epilogueBBLE = epilogueBBLE;      epilogueBBLE.fallThrough = afterBBLE;      epilogueBBLE.block.insertOut(epilogueBBLE.fallThrough.block);    } else {      // All exits from the callee were via throws.      // Therefore the next basic block is unreachable (unless      // there is a branch to it from somewhere else in the current method,      // which will naturally be handled when we generate the branch).      InliningBlockLE inlinedCallee = new InliningBlockLE(inlinedContext);      currentBBLE.fallThrough = inlinedCallee;      currentBBLE.block.insertOut(inlinedCallee.gc.cfg.firstInCodeOrder());    }    endOfBasicBlock = true;    return true;  }