diff options
| author | Daniel Berlin <dberlin@dberlin.org> | 2017-02-20 22:26:03 +0000 | 
|---|---|---|
| committer | Daniel Berlin <dberlin@dberlin.org> | 2017-02-20 22:26:03 +0000 | 
| commit | 78cbd28102114115dde1d91dfe0d0a79341a642d (patch) | |
| tree | ac692a1106d2510bfb5c28337a5df3bf32e15bc3 /llvm/lib/Transforms | |
| parent | bb10c0f1ec60b4fd4572dd8cb87e21b74e3bc19b (diff) | |
| download | bcm5719-llvm-78cbd28102114115dde1d91dfe0d0a79341a642d.tar.gz bcm5719-llvm-78cbd28102114115dde1d91dfe0d0a79341a642d.zip | |
MemorySSA: Add support for renaming uses in the updater.
Summary:
This lets one add aliasing stores to the updater.
(i'm next going to move the creation/etc functions to the updater)
Reviewers: george.burgess.iv
Subscribers: llvm-commits, Prazek
Differential Revision: https://reviews.llvm.org/D30154
llvm-svn: 295677
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/Utils/MemorySSA.cpp | 73 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Utils/MemorySSAUpdater.cpp | 20 | 
2 files changed, 68 insertions, 25 deletions
| diff --git a/llvm/lib/Transforms/Utils/MemorySSA.cpp b/llvm/lib/Transforms/Utils/MemorySSA.cpp index 74deec41119..f8c3a4c06ab 100644 --- a/llvm/lib/Transforms/Utils/MemorySSA.cpp +++ b/llvm/lib/Transforms/Utils/MemorySSA.cpp @@ -1116,18 +1116,37 @@ public:    }  }; +void MemorySSA::renameSuccessorPhis(BasicBlock *BB, MemoryAccess *IncomingVal, +                                    bool RenameAllUses) { +  // Pass through values to our successors +  for (const BasicBlock *S : successors(BB)) { +    auto It = PerBlockAccesses.find(S); +    // Rename the phi nodes in our successor block +    if (It == PerBlockAccesses.end() || !isa<MemoryPhi>(It->second->front())) +      continue; +    AccessList *Accesses = It->second.get(); +    auto *Phi = cast<MemoryPhi>(&Accesses->front()); +    if (RenameAllUses) { +      int PhiIndex = Phi->getBasicBlockIndex(BB); +      assert(PhiIndex != -1 && "Incomplete phi during partial rename"); +      Phi->setIncomingValue(PhiIndex, IncomingVal); +    } else +      Phi->addIncoming(IncomingVal, BB); +  } +} +  /// \brief Rename a single basic block into MemorySSA form.  /// Uses the standard SSA renaming algorithm.  /// \returns The new incoming value. -MemoryAccess *MemorySSA::renameBlock(BasicBlock *BB, -                                     MemoryAccess *IncomingVal) { +MemoryAccess *MemorySSA::renameBlock(BasicBlock *BB, MemoryAccess *IncomingVal, +                                     bool RenameAllUses) {    auto It = PerBlockAccesses.find(BB);    // Skip most processing if the list is empty.    if (It != PerBlockAccesses.end()) {      AccessList *Accesses = It->second.get();      for (MemoryAccess &L : *Accesses) {        if (MemoryUseOrDef *MUD = dyn_cast<MemoryUseOrDef>(&L)) { -        if (MUD->getDefiningAccess() == nullptr) +        if (MUD->getDefiningAccess() == nullptr || RenameAllUses)            MUD->setDefiningAccess(IncomingVal);          if (isa<MemoryDef>(&L))            IncomingVal = &L; @@ -1136,18 +1155,6 @@ MemoryAccess *MemorySSA::renameBlock(BasicBlock *BB,        }      }    } - -  // Pass through values to our successors -  for (const BasicBlock *S : successors(BB)) { -    auto It = PerBlockAccesses.find(S); -    // Rename the phi nodes in our successor block -    if (It == PerBlockAccesses.end() || !isa<MemoryPhi>(It->second->front())) -      continue; -    AccessList *Accesses = It->second.get(); -    auto *Phi = cast<MemoryPhi>(&Accesses->front()); -    Phi->addIncoming(IncomingVal, BB); -  } -    return IncomingVal;  } @@ -1156,11 +1163,19 @@ MemoryAccess *MemorySSA::renameBlock(BasicBlock *BB,  /// We walk the dominator tree in preorder, renaming accesses, and then filling  /// in phi nodes in our successors.  void MemorySSA::renamePass(DomTreeNode *Root, MemoryAccess *IncomingVal, -                           SmallPtrSet<BasicBlock *, 16> &Visited) { +                           SmallPtrSetImpl<BasicBlock *> &Visited, +                           bool SkipVisited, bool RenameAllUses) {    SmallVector<RenamePassData, 32> WorkStack; -  IncomingVal = renameBlock(Root->getBlock(), IncomingVal); +  // Skip everything if we already renamed this block and we are skipping. +  // Note: You can't sink this into the if, because we need it to occur +  // regardless of whether we skip blocks or not. +  bool AlreadyVisited = !Visited.insert(Root->getBlock()).second; +  if (SkipVisited && AlreadyVisited) +    return; + +  IncomingVal = renameBlock(Root->getBlock(), IncomingVal, RenameAllUses); +  renameSuccessorPhis(Root->getBlock(), IncomingVal, RenameAllUses);    WorkStack.push_back({Root, Root->begin(), IncomingVal}); -  Visited.insert(Root->getBlock());    while (!WorkStack.empty()) {      DomTreeNode *Node = WorkStack.back().DTN; @@ -1173,8 +1188,20 @@ void MemorySSA::renamePass(DomTreeNode *Root, MemoryAccess *IncomingVal,        DomTreeNode *Child = *ChildIt;        ++WorkStack.back().ChildIt;        BasicBlock *BB = Child->getBlock(); -      Visited.insert(BB); -      IncomingVal = renameBlock(BB, IncomingVal); +      // Note: You can't sink this into the if, because we need it to occur +      // regardless of whether we skip blocks or not. +      AlreadyVisited = !Visited.insert(BB).second; +      if (SkipVisited && AlreadyVisited) { +        // We already visited this during our renaming, which can happen when +        // being asked to rename multiple blocks. Figure out the incoming val, +        // which is the last def. +        // Incoming value can only change if there is a block def, and in that +        // case, it's the last block def in the list. +        if (auto *BlockDefs = getWritableBlockDefs(BB)) +          IncomingVal = &*BlockDefs->rbegin(); +      } else +        IncomingVal = renameBlock(BB, IncomingVal, RenameAllUses); +      renameSuccessorPhis(BB, IncomingVal, RenameAllUses);        WorkStack.push_back({Child, Child->begin(), IncomingVal});      }    } @@ -1891,9 +1918,7 @@ void MemorySSA::print(raw_ostream &OS) const {  }  #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) -LLVM_DUMP_METHOD void MemorySSA::dump() const { -  print(dbgs()); -} +LLVM_DUMP_METHOD void MemorySSA::dump() const { print(dbgs()); }  #endif  void MemorySSA::verifyMemorySSA() const { @@ -2163,7 +2188,7 @@ void MemoryUse::print(raw_ostream &OS) const {  }  void MemoryAccess::dump() const { -  // Cannot completely remove virtual function even in release mode. +// Cannot completely remove virtual function even in release mode.  #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)    print(dbgs());    dbgs() << "\n"; diff --git a/llvm/lib/Transforms/Utils/MemorySSAUpdater.cpp b/llvm/lib/Transforms/Utils/MemorySSAUpdater.cpp index 21f286b8cde..3b90ab72f04 100644 --- a/llvm/lib/Transforms/Utils/MemorySSAUpdater.cpp +++ b/llvm/lib/Transforms/Utils/MemorySSAUpdater.cpp @@ -234,7 +234,7 @@ void setMemoryPhiValueForBlock(MemoryPhi *MP, const BasicBlock *BB,  // Then, we update the defs below us (and any new phi nodes) in the graph to  // point to the correct new defs, to ensure we only have one variable, and no  // disconnected stores. -void MemorySSAUpdater::insertDef(MemoryDef *MD) { +void MemorySSAUpdater::insertDef(MemoryDef *MD, bool RenameUses) {    InsertedPHIs.clear();    // See if we had a local def, and if not, go hunting. @@ -287,6 +287,24 @@ void MemorySSAUpdater::insertDef(MemoryDef *MD) {      // Put any new phis on the fixup list, and process them      FixupList.append(InsertedPHIs.end() - StartingPHISize, InsertedPHIs.end());    } +  // Now that all fixups are done, rename all uses if we are asked. +  if (RenameUses) { +    SmallPtrSet<BasicBlock *, 16> Visited; +    BasicBlock *StartBlock = MD->getBlock(); +    // We are guaranteed there is a def in the block, because we just got it +    // handed to us in this function. +    MemoryAccess *FirstDef = &*MSSA->getWritableBlockDefs(StartBlock)->begin(); +    // Convert to incoming value if it's a memorydef. A phi *is* already an +    // incoming value. +    if (auto *MD = dyn_cast<MemoryDef>(FirstDef)) +      FirstDef = MD->getDefiningAccess(); + +    MSSA->renamePass(MD->getBlock(), FirstDef, Visited); +    // We just inserted a phi into this block, so the incoming value will become +    // the phi anyway, so it does not matter what we pass. +    for (auto *MP : InsertedPHIs) +      MSSA->renamePass(MP->getBlock(), nullptr, Visited); +  }  }  void MemorySSAUpdater::fixupDefs(const SmallVectorImpl<MemoryAccess *> &Vars) { | 

