diff options
| author | Chris Lattner <sabre@nondot.org> | 2010-08-29 06:43:52 +0000 | 
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2010-08-29 06:43:52 +0000 | 
| commit | 1dc98b47b5052aa25eae67c738d499e8c7671479 (patch) | |
| tree | 68c2c7a0f391445d1b98fd52d4eb738b981fa2ae /llvm/lib/Transforms | |
| parent | d0c054886c4241c0e0982ad8a5e77348758cf285 (diff) | |
| download | bcm5719-llvm-1dc98b47b5052aa25eae67c738d499e8c7671479.tar.gz bcm5719-llvm-1dc98b47b5052aa25eae67c738d499e8c7671479.zip | |
completely rewrite the memory promotion algorithm in LICM.
Among other things, this uses SSAUpdater instead of 
PromoteMemToReg.
llvm-svn: 112417
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/LICM.cpp | 415 | 
1 files changed, 215 insertions, 200 deletions
| diff --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp index a1868af12fd..2c0579bb3ba 100644 --- a/llvm/lib/Transforms/Scalar/LICM.cpp +++ b/llvm/lib/Transforms/Scalar/LICM.cpp @@ -26,8 +26,7 @@  //          pointer.  There are no calls in the loop which mod/ref the pointer.  //     If these conditions are true, we can promote the loads and stores in the  //     loop of the pointer to use a temporary alloca'd variable.  We then use -//     the mem2reg functionality to construct the appropriate SSA form for the -//     variable. +//     the SSAUpdater to construct the appropriate SSA form for the value.  //  //===----------------------------------------------------------------------===// @@ -44,7 +43,6 @@  #include "llvm/Analysis/AliasSetTracker.h"  #include "llvm/Analysis/Dominators.h"  #include "llvm/Analysis/ScalarEvolution.h" -#include "llvm/Transforms/Utils/PromoteMemToReg.h"  #include "llvm/Transforms/Utils/SSAUpdater.h"  #include "llvm/Support/CFG.h"  #include "llvm/Support/CommandLine.h" @@ -205,20 +203,7 @@ namespace {      bool isLoopInvariantInst(Instruction &I);      bool isNotUsedInLoop(Instruction &I); -    /// PromoteValuesInLoop - Look at the stores in the loop and promote as many -    /// to scalars as we can. -    /// -    void PromoteValuesInLoop(); - -    /// FindPromotableValuesInLoop - Check the current loop for stores to -    /// definite pointers, which are not loaded and stored through may aliases. -    /// If these are found, create an alloca for the value, add it to the -    /// PromotedValues list, and keep track of the mapping from value to -    /// alloca... -    /// -    void FindPromotableValuesInLoop( -                   std::vector<std::pair<AllocaInst*, Value*> > &PromotedValues, -                                    DenseMap<Value*, AllocaInst*> &Val2AlMap); +    void PromoteAliasSet(AliasSet &AS);    };  } @@ -284,10 +269,14 @@ bool LICM::runOnLoop(Loop *L, LPPassManager &LPM) {      HoistRegion(DT->getNode(L->getHeader()));    // Now that all loop invariants have been removed from the loop, promote any -  // memory references to scalars that we can... -  if (!DisablePromotion && Preheader && L->hasDedicatedExits()) -    PromoteValuesInLoop(); - +  // memory references to scalars that we can. +  if (!DisablePromotion && Preheader && L->hasDedicatedExits()) { +    // Loop over all of the alias sets in the tracker object. +    for (AliasSetTracker::iterator I = CurAST->begin(), E = CurAST->end(); +         I != E; ++I) +      PromoteAliasSet(*I); +  } +      // Clear out loops state information for the next iteration    CurLoop = 0;    Preheader = 0; @@ -622,212 +611,238 @@ bool LICM::isSafeToExecuteUnconditionally(Instruction &Inst) {    return true;  } - -/// PromoteValuesInLoop - Try to promote memory values to scalars by sinking +/// PromoteAliasSet - Try to promote memory values to scalars by sinking  /// stores out of the loop and moving loads to before the loop.  We do this by  /// looping over the stores in the loop, looking for stores to Must pointers -/// which are loop invariant.  We promote these memory locations to use allocas -/// instead.  These allocas can easily be raised to register values by the -/// PromoteMem2Reg functionality. +/// which are loop invariant.  /// -void LICM::PromoteValuesInLoop() { -  // PromotedValues - List of values that are promoted out of the loop.  Each -  // value has an alloca instruction for it, and a canonical version of the -  // pointer. -  std::vector<std::pair<AllocaInst*, Value*> > PromotedValues; -  DenseMap<Value*, AllocaInst*> ValueToAllocaMap; // Map of ptr to alloca - -  FindPromotableValuesInLoop(PromotedValues, ValueToAllocaMap); -  if (ValueToAllocaMap.empty()) return;   // If there are values to promote. - -  Changed = true; -  NumPromoted += PromotedValues.size(); - -  std::vector<Value*> PointerValueNumbers; - -  // Emit a copy from the value into the alloca'd value in the loop preheader -  TerminatorInst *LoopPredInst = Preheader->getTerminator(); -  for (unsigned i = 0, e = PromotedValues.size(); i != e; ++i) { -    Value *Ptr = PromotedValues[i].second; - -    // If we are promoting a pointer value, update alias information for the -    // inserted load. -    Value *LoadValue = 0; -    if (cast<PointerType>(Ptr->getType())->getElementType()->isPointerTy()) { -      // Locate a load or store through the pointer, and assign the same value -      // to LI as we are loading or storing.  Since we know that the value is -      // stored in this loop, this will always succeed. -      for (Value::use_iterator UI = Ptr->use_begin(), E = Ptr->use_end(); -           UI != E; ++UI) { -        User *U = *UI; -        if (LoadInst *LI = dyn_cast<LoadInst>(U)) { -          LoadValue = LI; -          break; -        } else if (StoreInst *SI = dyn_cast<StoreInst>(U)) { -          if (SI->getOperand(1) == Ptr) { -            LoadValue = SI->getOperand(0); -            break; -          } -        } -      } -      assert(LoadValue && "No store through the pointer found!"); -      PointerValueNumbers.push_back(LoadValue);  // Remember this for later. -    } - -    // Load from the memory we are promoting. -    LoadInst *LI = new LoadInst(Ptr, Ptr->getName()+".promoted", LoopPredInst); - -    if (LoadValue) CurAST->copyValue(LoadValue, LI); - -    // Store into the temporary alloca. -    new StoreInst(LI, PromotedValues[i].first, LoopPredInst); -  } +void LICM::PromoteAliasSet(AliasSet &AS) { +  // We can promote this alias set if it has a store, if it is a "Must" alias +  // set, if the pointer is loop invariant, and if we are not eliminating any +  // volatile loads or stores. +  if (AS.isForwardingAliasSet() || !AS.isMod() || !AS.isMustAlias() || +      AS.isVolatile() || !CurLoop->isLoopInvariant(AS.begin()->getValue())) +    return; +   +  assert(!AS.empty() && +         "Must alias set should have at least one pointer element in it!"); +  Value *SomePtr = AS.begin()->getValue(); -  // Scan the basic blocks in the loop, replacing uses of our pointers with -  // uses of the allocas in question. +  // It isn't safe to promote a load/store from the loop if the load/store is +  // conditional.  For example, turning:    // -  for (Loop::block_iterator I = CurLoop->block_begin(), -         E = CurLoop->block_end(); I != E; ++I) { -    BasicBlock *BB = *I; -    // Rewrite all loads and stores in the block of the pointer... -    for (BasicBlock::iterator II = BB->begin(), E = BB->end(); II != E; ++II) { -      if (LoadInst *L = dyn_cast<LoadInst>(II)) { -        DenseMap<Value*, AllocaInst*>::iterator -          I = ValueToAllocaMap.find(L->getOperand(0)); -        if (I != ValueToAllocaMap.end()) -          L->setOperand(0, I->second);    // Rewrite load instruction... -      } else if (StoreInst *S = dyn_cast<StoreInst>(II)) { -        DenseMap<Value*, AllocaInst*>::iterator -          I = ValueToAllocaMap.find(S->getOperand(1)); -        if (I != ValueToAllocaMap.end()) -          S->setOperand(1, I->second);    // Rewrite store instruction... -      } -    } -  } - -  // Now that the body of the loop uses the allocas instead of the original -  // memory locations, insert code to copy the alloca value back into the -  // original memory location on all exits from the loop. -  SmallVector<BasicBlock*, 8> ExitBlocks; -  CurLoop->getUniqueExitBlocks(ExitBlocks); -  for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i) { -    // Copy all of the allocas into their memory locations. -    BasicBlock::iterator BI = ExitBlocks[i]->getFirstNonPHI(); -    Instruction *InsertPos = BI; -    unsigned PVN = 0; -    for (unsigned i = 0, e = PromotedValues.size(); i != e; ++i) { -      // Load from the alloca. -      LoadInst *LI = new LoadInst(PromotedValues[i].first, "", InsertPos); - -      // If this is a pointer type, update alias info appropriately. -      if (LI->getType()->isPointerTy()) -        CurAST->copyValue(PointerValueNumbers[PVN++], LI); - -      // Store into the memory we promoted. -      new StoreInst(LI, PromotedValues[i].second, InsertPos); -    } -  } - -  // Now that we have done the deed, use the mem2reg functionality to promote -  // all of the new allocas we just created into real SSA registers. +  //    for () { if (c) *P += 1; }    // -  std::vector<AllocaInst*> PromotedAllocas; -  PromotedAllocas.reserve(PromotedValues.size()); -  for (unsigned i = 0, e = PromotedValues.size(); i != e; ++i) -    PromotedAllocas.push_back(PromotedValues[i].first); -  PromoteMemToReg(PromotedAllocas, *DT, *DF, CurAST); -} - -/// FindPromotableValuesInLoop - Check the current loop for stores to definite -/// pointers, which are not loaded and stored through may aliases and are safe -/// for promotion.  If these are found, create an alloca for the value, add it  -/// to the PromotedValues list, and keep track of the mapping from value to  -/// alloca.  -void LICM::FindPromotableValuesInLoop( -                   std::vector<std::pair<AllocaInst*, Value*> > &PromotedValues, -                             DenseMap<Value*, AllocaInst*> &ValueToAllocaMap) { -  Instruction *FnStart = CurLoop->getHeader()->getParent()->begin()->begin(); - -  // Loop over all of the alias sets in the tracker object. -  for (AliasSetTracker::iterator I = CurAST->begin(), E = CurAST->end(); -       I != E; ++I) { -    AliasSet &AS = *I; -    // We can promote this alias set if it has a store, if it is a "Must" alias -    // set, if the pointer is loop invariant, and if we are not eliminating any -    // volatile loads or stores. -    if (AS.isForwardingAliasSet() || !AS.isMod() || !AS.isMustAlias() || -        AS.isVolatile() || !CurLoop->isLoopInvariant(AS.begin()->getValue())) -      continue; +  // into: +  // +  //    tmp = *P;  for () { if (c) tmp +=1; } *P = tmp; +  // +  // is not safe, because *P may only be valid to access if 'c' is true. +  //  +  // It is safe to promote P if all uses are direct load/stores and if at +  // least one is guaranteed to be executed. +  bool GuaranteedToExecute = false; +   +  SmallVector<Instruction*, 64> LoopUses; +  SmallPtrSet<Value*, 4> PointerMustAliases; + +  // Check that all of the pointers in the alias set have the same type.  We +  // cannot (yet) promote a memory location that is loaded and stored in +  // different sizes. +  for (AliasSet::iterator ASI = AS.begin(), E = AS.end(); ASI != E; ++ASI) { +    Value *ASIV = ASI->getValue(); +    PointerMustAliases.insert(ASIV); -    assert(!AS.empty() && -           "Must alias set should have at least one pointer element in it!"); -    Value *V = AS.begin()->getValue(); -      // Check that all of the pointers in the alias set have the same type.  We      // cannot (yet) promote a memory location that is loaded and stored in      // different sizes. -    { -      bool PointerOk = true; -      for (AliasSet::iterator I = AS.begin(), E = AS.end(); I != E; ++I) -        if (V->getType() != I->getValue()->getType()) { -          PointerOk = false; -          break; -        } -      if (!PointerOk) -        continue; -    } - -    // It isn't safe to promote a load/store from the loop if the load/store is -    // conditional.  For example, turning: -    // -    //    for () { if (c) *P += 1; } -    // -    // into: -    // -    //    tmp = *P;  for () { if (c) tmp +=1; } *P = tmp; -    // -    // is not safe, because *P may only be valid to access if 'c' is true. -    //  -    // It is safe to promote P if all uses are direct load/stores and if at -    // least one is guaranteed to be executed. -    bool GuaranteedToExecute = false; -    bool InvalidInst = false; -    for (Value::use_iterator UI = V->use_begin(), UE = V->use_end(); +    if (SomePtr->getType() != ASIV->getType()) +      return; +     +    for (Value::use_iterator UI = ASIV->use_begin(), UE = ASIV->use_end();           UI != UE; ++UI) { -      // Ignore instructions not in this loop. +      // Ignore instructions that are outside the loop.        Instruction *Use = dyn_cast<Instruction>(*UI);        if (!Use || !CurLoop->contains(Use))          continue; - -      if (!isa<LoadInst>(Use) && !isa<StoreInst>(Use)) { -        InvalidInst = true; -        break; -      } +       +      // If there is an non-load/store instruction in the loop, we can't promote +      // it. +      if (isa<LoadInst>(Use)) +        assert(!cast<LoadInst>(Use)->isVolatile() && "AST broken"); +      else if (isa<StoreInst>(Use)) +        assert(!cast<StoreInst>(Use)->isVolatile() &&  +               Use->getOperand(0) != ASIV && "AST broken"); +      else +        return; // Not a load or store.        if (!GuaranteedToExecute)          GuaranteedToExecute = isSafeToExecuteUnconditionally(*Use); +       +      LoopUses.push_back(Use);      } +  } +   +  // If there isn't a guaranteed-to-execute instruction, we can't promote. +  if (!GuaranteedToExecute) +    return; +   +  // Otherwise, this is safe to promote, lets do it! +  DEBUG(dbgs() << "LICM: Promoting value stored to in loop: " <<*SomePtr<<'\n');   +  Changed = true; +  ++NumPromoted; -    // If there is an non-load/store instruction in the loop, we can't promote -    // it.  If there isn't a guaranteed-to-execute instruction, we can't -    // promote. -    if (InvalidInst || !GuaranteedToExecute) +  // We use the SSAUpdater interface to insert phi nodes as required. +  SmallVector<PHINode*, 16> NewPHIs; +  SSAUpdater SSA(&NewPHIs); +   +  // It wants to know some value of the same type as what we'll be inserting. +  Value *SomeValue; +  if (isa<LoadInst>(LoopUses[0])) +    SomeValue = LoopUses[0]; +  else +    SomeValue = cast<StoreInst>(LoopUses[0])->getOperand(0); +  SSA.Initialize(SomeValue); + +  // First step: bucket up uses of the pointers by the block they occur in. +  // This is important because we have to handle multiple defs/uses in a block +  // ourselves: SSAUpdater is purely for cross-block references. +  // FIXME: Want a TinyVector<Instruction*> since there is usually 0/1 element. +  DenseMap<BasicBlock*, std::vector<Instruction*> > UsesByBlock; +  for (unsigned i = 0, e = LoopUses.size(); i != e; ++i) { +    Instruction *User = LoopUses[i]; +    UsesByBlock[User->getParent()].push_back(User); +  } +   +  // Okay, now we can iterate over all the blocks in the loop with uses, +  // processing them.  Keep track of which loads are loading a live-in value. +  SmallVector<LoadInst*, 32> LiveInLoads; +   +  for (unsigned LoopUse = 0, e = LoopUses.size(); LoopUse != e; ++LoopUse) { +    Instruction *User = LoopUses[LoopUse]; +    std::vector<Instruction*> &BlockUses = UsesByBlock[User->getParent()]; +     +    // If this block has already been processed, ignore this repeat use. +    if (BlockUses.empty()) continue; +     +    // Okay, this is the first use in the block.  If this block just has a +    // single user in it, we can rewrite it trivially. +    if (BlockUses.size() == 1) { +      // If it is a store, it is a trivial def of the value in the block. +      if (isa<StoreInst>(User)) { +        SSA.AddAvailableValue(User->getParent(), +                              cast<StoreInst>(User)->getOperand(0)); +      } else { +        // Otherwise it is a load, queue it to rewrite as a live-in load. +        LiveInLoads.push_back(cast<LoadInst>(User)); +      } +      BlockUses.clear();        continue; +    } +     +    // Otherwise, check to see if this block is all loads.  If so, we can queue +    // them all as live in loads. +    bool HasStore = false; +    for (unsigned i = 0, e = BlockUses.size(); i != e; ++i) { +      if (isa<StoreInst>(BlockUses[i])) { +        HasStore = true; +        break; +      } +    } -    const Type *Ty = cast<PointerType>(V->getType())->getElementType(); -    AllocaInst *AI = new AllocaInst(Ty, 0, V->getName()+".tmp", FnStart); -    PromotedValues.push_back(std::make_pair(AI, V)); +    if (!HasStore) { +      for (unsigned i = 0, e = BlockUses.size(); i != e; ++i) +        LiveInLoads.push_back(cast<LoadInst>(BlockUses[i])); +      BlockUses.clear(); +      continue; +    } + +    // Otherwise, we have mixed loads and stores (or just a bunch of stores). +    // Since SSAUpdater is purely for cross-block values, we need to determine +    // the order of these instructions in the block.  If the first use in the +    // block is a load, then it uses the live in value.  The last store defines +    // the live out value.  We handle this by doing a linear scan of the block. +    BasicBlock *BB = User->getParent(); +    Value *StoredValue = 0; +    for (BasicBlock::iterator II = BB->begin(), E = BB->end(); II != E; ++II) { +      if (LoadInst *L = dyn_cast<LoadInst>(II)) { +        // If this is a load to an unrelated pointer, ignore it. +        if (!PointerMustAliases.count(L->getOperand(0))) continue; + +        // If we haven't seen a store yet, this is a live in use, otherwise +        // use the stored value. +        if (StoredValue) +          L->replaceAllUsesWith(StoredValue); +        else +          LiveInLoads.push_back(L); +        continue; +      } +       +      if (StoreInst *S = dyn_cast<StoreInst>(II)) { +        // If this is a load to an unrelated pointer, ignore it. +        if (!PointerMustAliases.count(S->getOperand(1))) continue; -    // Update the AST and alias analysis. -    CurAST->copyValue(V, AI); +        // Remember that this is the active value in the block. +        StoredValue = S->getOperand(0); +      } +    } +     +    // The last stored value that happened is the live-out for the block. +    assert(StoredValue && "Already checked that there is a store in block"); +    SSA.AddAvailableValue(BB, StoredValue); +    BlockUses.clear(); +  } +   +  // Now that all the intra-loop values are classified, set up the preheader. +  // It gets a load of the pointer we're promoting, and it is the live-out value +  // from the preheader. +  LoadInst *PreheaderLoad = new LoadInst(SomePtr,SomePtr->getName()+".promoted", +                                         Preheader->getTerminator()); +  SSA.AddAvailableValue(Preheader, PreheaderLoad); + +  // Now that the preheader is good to go, set up the exit blocks.  Each exit +  // block gets a store of the live-out values that feed them.  Since we've +  // already told the SSA updater about the defs in the loop and the preheader +  // definition, it is all set and we can start using it. +  SmallVector<BasicBlock*, 8> ExitBlocks; +  CurLoop->getUniqueExitBlocks(ExitBlocks); +  for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i) { +    BasicBlock *ExitBlock = ExitBlocks[i]; +    Value *LiveInValue = SSA.GetValueInMiddleOfBlock(ExitBlock); +    Instruction *InsertPos = ExitBlock->getFirstNonPHI(); +    new StoreInst(LiveInValue, SomePtr, InsertPos); +  } -    for (AliasSet::iterator I = AS.begin(), E = AS.end(); I != E; ++I) -      ValueToAllocaMap[I->getValue()] = AI; +  // Okay, now we rewrite all loads that use live-in values in the loop, +  // inserting PHI nodes as necessary. +  for (unsigned i = 0, e = LiveInLoads.size(); i != e; ++i) { +    LoadInst *ALoad = LiveInLoads[i]; +    ALoad->replaceAllUsesWith(SSA.GetValueInMiddleOfBlock(ALoad->getParent())); +  } +   +  // Now that everything is rewritten, delete the old instructions from the body +  // of the loop.  They should all be dead now. +  for (unsigned i = 0, e = LoopUses.size(); i != e; ++i) { +    Instruction *User = LoopUses[i]; +    CurAST->deleteValue(User); +    User->eraseFromParent(); +  } +   +  // If the preheader load is itself a pointer, we need to tell alias analysis +  // about the new pointer we created in the preheader block and about any PHI +  // nodes that just got inserted. +  if (PreheaderLoad->getType()->isPointerTy()) { +    // Copy any value stored to or loaded from a must-alias of the pointer. +    CurAST->copyValue(SomeValue, PreheaderLoad); -    DEBUG(dbgs() << "LICM: Promoting value: " << *V << "\n"); +    for (unsigned i = 0, e = NewPHIs.size(); i != e; ++i) +      CurAST->copyValue(SomeValue, NewPHIs[i]);    } +   +  // fwew, we're done!  } +  /// cloneBasicBlockAnalysis - Simple Analysis hook. Clone alias set info.  void LICM::cloneBasicBlockAnalysis(BasicBlock *From, BasicBlock *To, Loop *L) {    AliasSetTracker *AST = LoopToAliasMap[L]; | 

