diff options
Diffstat (limited to 'contrib/llvm/lib/Transforms/Utils/InlineFunction.cpp')
| -rw-r--r-- | contrib/llvm/lib/Transforms/Utils/InlineFunction.cpp | 178 | 
1 files changed, 157 insertions, 21 deletions
| diff --git a/contrib/llvm/lib/Transforms/Utils/InlineFunction.cpp b/contrib/llvm/lib/Transforms/Utils/InlineFunction.cpp index d5b382e55e5c..5464dbc4a830 100644 --- a/contrib/llvm/lib/Transforms/Utils/InlineFunction.cpp +++ b/contrib/llvm/lib/Transforms/Utils/InlineFunction.cpp @@ -45,6 +45,9 @@ bool llvm::InlineFunction(InvokeInst *II, InlineFunctionInfo &IFI) {    return InlineFunction(CallSite(II), IFI);  } +// FIXME: New EH - Remove the functions marked [LIBUNWIND] when new EH is +// turned on. +  /// [LIBUNWIND] Look for an llvm.eh.exception call in the given block.  static EHExceptionInst *findExceptionInBlock(BasicBlock *bb) {    for (BasicBlock::iterator i = bb->begin(), e = bb->end(); i != e; i++) { @@ -250,20 +253,32 @@ namespace {      PHINode *InnerSelectorPHI;      SmallVector<Value*, 8> UnwindDestPHIValues; +    // FIXME: New EH - These will replace the analogous ones above. +    BasicBlock *OuterResumeDest; //< Destination of the invoke's unwind. +    BasicBlock *InnerResumeDest; //< Destination for the callee's resume. +    LandingPadInst *CallerLPad;  //< LandingPadInst associated with the invoke. +    PHINode *InnerEHValuesPHI;   //< PHI for EH values from landingpad insts. +    public: -    InvokeInliningInfo(InvokeInst *II) : -      OuterUnwindDest(II->getUnwindDest()), OuterSelector(0), -      InnerUnwindDest(0), InnerExceptionPHI(0), InnerSelectorPHI(0) { - -      // If there are PHI nodes in the unwind destination block, we -      // need to keep track of which values came into them from the -      // invoke before removing the edge from this block. -      llvm::BasicBlock *invokeBB = II->getParent(); -      for (BasicBlock::iterator I = OuterUnwindDest->begin(); -             isa<PHINode>(I); ++I) { +    InvokeInliningInfo(InvokeInst *II) +      : OuterUnwindDest(II->getUnwindDest()), OuterSelector(0), +        InnerUnwindDest(0), InnerExceptionPHI(0), InnerSelectorPHI(0), +        OuterResumeDest(II->getUnwindDest()), InnerResumeDest(0), +        CallerLPad(0), InnerEHValuesPHI(0) { +      // If there are PHI nodes in the unwind destination block, we need to keep +      // track of which values came into them from the invoke before removing +      // the edge from this block. +      llvm::BasicBlock *InvokeBB = II->getParent(); +      BasicBlock::iterator I = OuterUnwindDest->begin(); +      for (; isa<PHINode>(I); ++I) {          // Save the value to use for this edge. -        PHINode *phi = cast<PHINode>(I); -        UnwindDestPHIValues.push_back(phi->getIncomingValueForBlock(invokeBB)); +        PHINode *PHI = cast<PHINode>(I); +        UnwindDestPHIValues.push_back(PHI->getIncomingValueForBlock(InvokeBB)); +      } + +      // FIXME: With the new EH, this if/dyn_cast should be a 'cast'. +      if (LandingPadInst *LPI = dyn_cast<LandingPadInst>(I)) { +        CallerLPad = LPI;        }      } @@ -281,11 +296,23 @@ namespace {      BasicBlock *getInnerUnwindDest(); +    // FIXME: New EH - Rename when new EH is turned on. +    BasicBlock *getInnerUnwindDestNewEH(); + +    LandingPadInst *getLandingPadInst() const { return CallerLPad; } +      bool forwardEHResume(CallInst *call, BasicBlock *src); -    /// Add incoming-PHI values to the unwind destination block for -    /// the given basic block, using the values for the original -    /// invoke's source block. +    /// forwardResume - Forward the 'resume' instruction to the caller's landing +    /// pad block. When the landing pad block has only one predecessor, this is +    /// a simple branch. When there is more than one predecessor, we need to +    /// split the landing pad block after the landingpad instruction and jump +    /// to there. +    void forwardResume(ResumeInst *RI); + +    /// addIncomingPHIValuesFor - Add incoming-PHI values to the unwind +    /// destination block for the given basic block, using the values for the +    /// original invoke's source block.      void addIncomingPHIValuesFor(BasicBlock *BB) const {        addIncomingPHIValuesForInto(BB, OuterUnwindDest);      } @@ -300,7 +327,7 @@ namespace {    };  } -/// Get or create a target for the branch out of rewritten calls to +/// [LIBUNWIND] Get or create a target for the branch out of rewritten calls to  /// llvm.eh.resume.  BasicBlock *InvokeInliningInfo::getInnerUnwindDest() {    if (InnerUnwindDest) return InnerUnwindDest; @@ -404,6 +431,60 @@ bool InvokeInliningInfo::forwardEHResume(CallInst *call, BasicBlock *src) {    return true;  } +/// Get or create a target for the branch from ResumeInsts. +BasicBlock *InvokeInliningInfo::getInnerUnwindDestNewEH() { +  // FIXME: New EH - rename this function when new EH is turned on. +  if (InnerResumeDest) return InnerResumeDest; + +  // Split the landing pad. +  BasicBlock::iterator SplitPoint = CallerLPad; ++SplitPoint; +  InnerResumeDest = +    OuterResumeDest->splitBasicBlock(SplitPoint, +                                     OuterResumeDest->getName() + ".body"); + +  // The number of incoming edges we expect to the inner landing pad. +  const unsigned PHICapacity = 2; + +  // Create corresponding new PHIs for all the PHIs in the outer landing pad. +  BasicBlock::iterator InsertPoint = InnerResumeDest->begin(); +  BasicBlock::iterator I = OuterResumeDest->begin(); +  for (unsigned i = 0, e = UnwindDestPHIValues.size(); i != e; ++i, ++I) { +    PHINode *OuterPHI = cast<PHINode>(I); +    PHINode *InnerPHI = PHINode::Create(OuterPHI->getType(), PHICapacity, +                                        OuterPHI->getName() + ".lpad-body", +                                        InsertPoint); +    OuterPHI->replaceAllUsesWith(InnerPHI); +    InnerPHI->addIncoming(OuterPHI, OuterResumeDest); +  } + +  // Create a PHI for the exception values. +  InnerEHValuesPHI = PHINode::Create(CallerLPad->getType(), PHICapacity, +                                     "eh.lpad-body", InsertPoint); +  CallerLPad->replaceAllUsesWith(InnerEHValuesPHI); +  InnerEHValuesPHI->addIncoming(CallerLPad, OuterResumeDest); + +  // All done. +  return InnerResumeDest; +} + +/// forwardResume - Forward the 'resume' instruction to the caller's landing pad +/// block. When the landing pad block has only one predecessor, this is a simple +/// branch. When there is more than one predecessor, we need to split the +/// landing pad block after the landingpad instruction and jump to there. +void InvokeInliningInfo::forwardResume(ResumeInst *RI) { +  BasicBlock *Dest = getInnerUnwindDestNewEH(); +  BasicBlock *Src = RI->getParent(); + +  BranchInst::Create(Dest, Src); + +  // Update the PHIs in the destination. They were inserted in an order which +  // makes this work. +  addIncomingPHIValuesForInto(Src, Dest); + +  InnerEHValuesPHI->addIncoming(RI->getOperand(0), Src); +  RI->eraseFromParent(); +} +  /// [LIBUNWIND] Check whether this selector is "only cleanups":  ///   call i32 @llvm.eh.selector(blah, blah, i32 0)  static bool isCleanupOnlySelector(EHSelectorInst *selector) { @@ -421,9 +502,19 @@ static bool isCleanupOnlySelector(EHSelectorInst *selector) {  /// Returns true to indicate that the next block should be skipped.  static bool HandleCallsInBlockInlinedThroughInvoke(BasicBlock *BB,                                                     InvokeInliningInfo &Invoke) { +  LandingPadInst *LPI = Invoke.getLandingPadInst(); +    for (BasicBlock::iterator BBI = BB->begin(), E = BB->end(); BBI != E; ) {      Instruction *I = BBI++; -     + +    if (LPI) // FIXME: New EH - This won't be NULL in the new EH. +      if (LandingPadInst *L = dyn_cast<LandingPadInst>(I)) { +        unsigned NumClauses = LPI->getNumClauses(); +        L->reserveClauses(NumClauses); +        for (unsigned i = 0; i != NumClauses; ++i) +          L->addClause(LPI->getClause(i)); +      } +      // We only need to check for function calls: inlined invoke      // instructions require no special handling.      CallInst *CI = dyn_cast<CallInst>(I); @@ -557,6 +648,10 @@ static void HandleInlinedInvoke(InvokeInst *II, BasicBlock *FirstNewBlock,        // there is now a new entry in them.        Invoke.addIncomingPHIValuesFor(BB);      } + +    if (ResumeInst *RI = dyn_cast<ResumeInst>(BB->getTerminator())) { +      Invoke.forwardResume(RI); +    }    }    // Now that everything is happy, we have one final detail.  The PHI nodes in @@ -636,7 +731,7 @@ static Value *HandleByValArgument(Value *Arg, Instruction *TheCall,                                    const Function *CalledFunc,                                    InlineFunctionInfo &IFI,                                    unsigned ByValAlignment) { -  const Type *AggTy = cast<PointerType>(Arg->getType())->getElementType(); +  Type *AggTy = cast<PointerType>(Arg->getType())->getElementType();    // If the called function is readonly, then it could not mutate the caller's    // copy of the byval'd memory.  In this case, it is safe to elide the copy and @@ -726,7 +821,7 @@ static bool isUsedByLifetimeMarker(Value *V) {  // hasLifetimeMarkers - Check whether the given alloca already has  // lifetime.start or lifetime.end intrinsics.  static bool hasLifetimeMarkers(AllocaInst *AI) { -  const Type *Int8PtrTy = Type::getInt8PtrTy(AI->getType()->getContext()); +  Type *Int8PtrTy = Type::getInt8PtrTy(AI->getType()->getContext());    if (AI->getType() == Int8PtrTy)      return isUsedByLifetimeMarker(AI); @@ -770,8 +865,15 @@ static void fixupLineNumbers(Function *Fn, Function::iterator FI,      for (BasicBlock::iterator BI = FI->begin(), BE = FI->end();           BI != BE; ++BI) {        DebugLoc DL = BI->getDebugLoc(); -      if (!DL.isUnknown()) +      if (!DL.isUnknown()) {          BI->setDebugLoc(updateInlinedAtInfo(DL, TheCallDL, BI->getContext())); +        if (DbgValueInst *DVI = dyn_cast<DbgValueInst>(BI)) { +          LLVMContext &Ctx = BI->getContext(); +          MDNode *InlinedAt = BI->getDebugLoc().getInlinedAt(Ctx); +          DVI->setOperand(2, createInlinedVariable(DVI->getVariable(),  +                                                   InlinedAt, Ctx)); +        } +      }      }    }  } @@ -822,6 +924,40 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI) {        return false;    } +  // Find the personality function used by the landing pads of the caller. If it +  // exists, then check to see that it matches the personality function used in +  // the callee. +  for (Function::const_iterator +         I = Caller->begin(), E = Caller->end(); I != E; ++I) +    if (const InvokeInst *II = dyn_cast<InvokeInst>(I->getTerminator())) { +      const BasicBlock *BB = II->getUnwindDest(); +      // FIXME: This 'isa' here should become go away once the new EH system is +      // in place. +      if (!isa<LandingPadInst>(BB->getFirstNonPHI())) +        continue; +      const LandingPadInst *LP = cast<LandingPadInst>(BB->getFirstNonPHI()); +      const Value *CallerPersFn = LP->getPersonalityFn(); + +      // If the personality functions match, then we can perform the +      // inlining. Otherwise, we can't inline. +      // TODO: This isn't 100% true. Some personality functions are proper +      //       supersets of others and can be used in place of the other. +      for (Function::const_iterator +             I = CalledFunc->begin(), E = CalledFunc->end(); I != E; ++I) +        if (const InvokeInst *II = dyn_cast<InvokeInst>(I->getTerminator())) { +          const BasicBlock *BB = II->getUnwindDest(); +          // FIXME: This 'if/dyn_cast' here should become a normal 'cast' once +          // the new EH system is in place. +          if (const LandingPadInst *LP = +              dyn_cast<LandingPadInst>(BB->getFirstNonPHI())) +            if (CallerPersFn != LP->getPersonalityFn()) +              return false; +          break; +        } + +      break; +    } +    // Get an iterator to the last basic block in the function, which will have    // the new function inlined after it.    // @@ -1090,7 +1226,7 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI) {    // Handle all of the return instructions that we just cloned in, and eliminate    // any users of the original call/invoke instruction. -  const Type *RTy = CalledFunc->getReturnType(); +  Type *RTy = CalledFunc->getReturnType();    PHINode *PHI = 0;    if (Returns.size() > 1) { | 
