diff options
Diffstat (limited to 'contrib/llvm/lib/CodeGen/GCRootLowering.cpp')
| -rw-r--r-- | contrib/llvm/lib/CodeGen/GCRootLowering.cpp | 133 | 
1 files changed, 56 insertions, 77 deletions
diff --git a/contrib/llvm/lib/CodeGen/GCRootLowering.cpp b/contrib/llvm/lib/CodeGen/GCRootLowering.cpp index 31ddeadbd97a..e8ccd84b0b93 100644 --- a/contrib/llvm/lib/CodeGen/GCRootLowering.cpp +++ b/contrib/llvm/lib/CodeGen/GCRootLowering.cpp @@ -38,7 +38,7 @@ namespace {  /// directed by the GCStrategy. It also performs automatic root initialization  /// and custom intrinsic lowering.  class LowerIntrinsics : public FunctionPass { -  bool PerformDefaultLowering(Function &F, GCStrategy &S); +  bool DoLowering(Function &F, GCStrategy &S);  public:    static char ID; @@ -102,13 +102,6 @@ void LowerIntrinsics::getAnalysisUsage(AnalysisUsage &AU) const {    AU.addPreserved<DominatorTreeWrapperPass>();  } -static bool NeedsDefaultLoweringPass(const GCStrategy &C) { -  // Default lowering is necessary only if read or write barriers have a default -  // action. The default for roots is no action. -  return !C.customWriteBarrier() || !C.customReadBarrier() || -         C.initializeRoots(); -} -  /// doInitialization - If this module uses the GC intrinsics, find them now.  bool LowerIntrinsics::doInitialization(Module &M) {    GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>(); @@ -148,8 +141,7 @@ static bool CouldBecomeSafePoint(Instruction *I) {    return true;  } -static bool InsertRootInitializers(Function &F, AllocaInst **Roots, -                                   unsigned Count) { +static bool InsertRootInitializers(Function &F, ArrayRef<AllocaInst *> Roots) {    // Scroll past alloca instructions.    BasicBlock::iterator IP = F.getEntryBlock().begin();    while (isa<AllocaInst>(IP)) @@ -166,12 +158,12 @@ static bool InsertRootInitializers(Function &F, AllocaInst **Roots,    // Add root initializers.    bool MadeChange = false; -  for (AllocaInst **I = Roots, **E = Roots + Count; I != E; ++I) -    if (!InitedRoots.count(*I)) { +  for (AllocaInst *Root : Roots) +    if (!InitedRoots.count(Root)) {        StoreInst *SI = new StoreInst( -          ConstantPointerNull::get(cast<PointerType>((*I)->getAllocatedType())), -          *I); -      SI->insertAfter(*I); +          ConstantPointerNull::get(cast<PointerType>(Root->getAllocatedType())), +          Root); +      SI->insertAfter(Root);        MadeChange = true;      } @@ -188,64 +180,59 @@ bool LowerIntrinsics::runOnFunction(Function &F) {    GCFunctionInfo &FI = getAnalysis<GCModuleInfo>().getFunctionInfo(F);    GCStrategy &S = FI.getStrategy(); -  bool MadeChange = false; - -  if (NeedsDefaultLoweringPass(S)) -    MadeChange |= PerformDefaultLowering(F, S); - -  return MadeChange; +  return DoLowering(F, S);  } -bool LowerIntrinsics::PerformDefaultLowering(Function &F, GCStrategy &S) { -  bool LowerWr = !S.customWriteBarrier(); -  bool LowerRd = !S.customReadBarrier(); -  bool InitRoots = S.initializeRoots(); - +/// Lower barriers out of existance (if the associated GCStrategy hasn't +/// already done so...), and insert initializing stores to roots as a defensive +/// measure.  Given we're going to report all roots live at all safepoints, we +/// need to be able to ensure each root has been initialized by the point the +/// first safepoint is reached.  This really should have been done by the +/// frontend, but the old API made this non-obvious, so we do a potentially +/// redundant store just in case.   +bool LowerIntrinsics::DoLowering(Function &F, GCStrategy &S) {    SmallVector<AllocaInst *, 32> Roots;    bool MadeChange = false; -  for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) { -    for (BasicBlock::iterator II = BB->begin(), E = BB->end(); II != E;) { -      if (IntrinsicInst *CI = dyn_cast<IntrinsicInst>(II++)) { -        Function *F = CI->getCalledFunction(); -        switch (F->getIntrinsicID()) { -        case Intrinsic::gcwrite: -          if (LowerWr) { -            // Replace a write barrier with a simple store. -            Value *St = -                new StoreInst(CI->getArgOperand(0), CI->getArgOperand(2), CI); -            CI->replaceAllUsesWith(St); -            CI->eraseFromParent(); -          } -          break; -        case Intrinsic::gcread: -          if (LowerRd) { -            // Replace a read barrier with a simple load. -            Value *Ld = new LoadInst(CI->getArgOperand(1), "", CI); -            Ld->takeName(CI); -            CI->replaceAllUsesWith(Ld); -            CI->eraseFromParent(); -          } -          break; -        case Intrinsic::gcroot: -          if (InitRoots) { -            // Initialize the GC root, but do not delete the intrinsic. The -            // backend needs the intrinsic to flag the stack slot. -            Roots.push_back( -                cast<AllocaInst>(CI->getArgOperand(0)->stripPointerCasts())); -          } -          break; -        default: -          continue; -        } - +  for (BasicBlock &BB : F)  +    for (BasicBlock::iterator II = BB.begin(), E = BB.end(); II != E;) { +      IntrinsicInst *CI = dyn_cast<IntrinsicInst>(II++); +      if (!CI) +        continue; + +      Function *F = CI->getCalledFunction(); +      switch (F->getIntrinsicID()) { +      default: break; +      case Intrinsic::gcwrite: { +        // Replace a write barrier with a simple store. +        Value *St = new StoreInst(CI->getArgOperand(0), +                                  CI->getArgOperand(2), CI); +        CI->replaceAllUsesWith(St); +        CI->eraseFromParent();          MadeChange = true; +        break; +      } +      case Intrinsic::gcread: { +        // Replace a read barrier with a simple load. +        Value *Ld = new LoadInst(CI->getArgOperand(1), "", CI); +        Ld->takeName(CI); +        CI->replaceAllUsesWith(Ld); +        CI->eraseFromParent(); +        MadeChange = true; +        break; +      } +      case Intrinsic::gcroot: { +        // Initialize the GC root, but do not delete the intrinsic. The +        // backend needs the intrinsic to flag the stack slot. +        Roots.push_back( +            cast<AllocaInst>(CI->getArgOperand(0)->stripPointerCasts())); +        break; +      }        }      } -  }    if (Roots.size()) -    MadeChange |= InsertRootInitializers(F, Roots.begin(), Roots.size()); +    MadeChange |= InsertRootInitializers(F, Roots);    return MadeChange;  } @@ -276,26 +263,18 @@ MCSymbol *GCMachineCodeAnalysis::InsertLabel(MachineBasicBlock &MBB,  }  void GCMachineCodeAnalysis::VisitCallPoint(MachineBasicBlock::iterator CI) { -  // Find the return address (next instruction), too, so as to bracket the call -  // instruction. +  // Find the return address (next instruction), since that's what will be on +  // the stack when the call is suspended and we need to inspect the stack.    MachineBasicBlock::iterator RAI = CI;    ++RAI; -  if (FI->getStrategy().needsSafePoint(GC::PreCall)) { -    MCSymbol *Label = InsertLabel(*CI->getParent(), CI, CI->getDebugLoc()); -    FI->addSafePoint(GC::PreCall, Label, CI->getDebugLoc()); -  } - -  if (FI->getStrategy().needsSafePoint(GC::PostCall)) { -    MCSymbol *Label = InsertLabel(*CI->getParent(), RAI, CI->getDebugLoc()); -    FI->addSafePoint(GC::PostCall, Label, CI->getDebugLoc()); -  } +  MCSymbol *Label = InsertLabel(*CI->getParent(), RAI, CI->getDebugLoc()); +  FI->addSafePoint(Label, CI->getDebugLoc());  }  void GCMachineCodeAnalysis::FindSafePoints(MachineFunction &MF) { -  for (MachineFunction::iterator BBI = MF.begin(), BBE = MF.end(); BBI != BBE; -       ++BBI) -    for (MachineBasicBlock::iterator MI = BBI->begin(), ME = BBI->end(); +  for (MachineBasicBlock &MBB : MF) +    for (MachineBasicBlock::iterator MI = MBB.begin(), ME = MBB.end();           MI != ME; ++MI)        if (MI->isCall()) {          // Do not treat tail or sibling call sites as safe points.  This is  | 
