diff options
| author | Juergen Ributzka <juergen@apple.com> | 2014-03-21 06:04:39 +0000 |
|---|---|---|
| committer | Juergen Ributzka <juergen@apple.com> | 2014-03-21 06:04:39 +0000 |
| commit | 500abd48d17772ad8c1505995b6619bedebc5403 (patch) | |
| tree | caa532d7aedc2204981318beef182be4eae2ab9b /llvm/lib/Transforms/Scalar | |
| parent | 5429c06b90874fb9d444fa411782afd8163b69ad (diff) | |
| download | bcm5719-llvm-500abd48d17772ad8c1505995b6619bedebc5403.tar.gz bcm5719-llvm-500abd48d17772ad8c1505995b6619bedebc5403.zip | |
[Constant Hoisting] Lazily compute the idom and cache the result.
Related to <rdar://problem/16381500>
llvm-svn: 204434
Diffstat (limited to 'llvm/lib/Transforms/Scalar')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/ConstantHoisting.cpp | 47 |
1 files changed, 43 insertions, 4 deletions
diff --git a/llvm/lib/Transforms/Scalar/ConstantHoisting.cpp b/llvm/lib/Transforms/Scalar/ConstantHoisting.cpp index 25fef5f500f..89df2b496f3 100644 --- a/llvm/lib/Transforms/Scalar/ConstantHoisting.cpp +++ b/llvm/lib/Transforms/Scalar/ConstantHoisting.cpp @@ -87,9 +87,10 @@ struct ConstantCandidate { struct RebasedConstantInfo { ConstantUseListType Uses; Constant *Offset; + mutable BasicBlock *IDom; RebasedConstantInfo(ConstantUseListType &&Uses, Constant *Offset) - : Uses(Uses), Offset(Offset) { } + : Uses(Uses), Offset(Offset), IDom(nullptr) { } }; /// \brief A base constant and all its rebased constants. @@ -152,6 +153,17 @@ private: Entry = nullptr; } + /// \brief Find the common dominator of all uses and cache the result for + /// future lookup. + BasicBlock *getIDom(const RebasedConstantInfo &RCI) const { + if (RCI.IDom) + return RCI.IDom; + RCI.IDom = findIDomOfAllUses(RCI.Uses); + assert(RCI.IDom && "Invalid IDom."); + return RCI.IDom; + } + + BasicBlock *findIDomOfAllUses(const ConstantUseListType &Uses) const; Instruction *findMatInsertPt(Instruction *Inst, unsigned Idx = ~0U) const; Instruction *findConstantInsertionPoint(const ConstantInfo &ConstInfo) const; void collectConstantCandidates(Instruction *Inst, unsigned Idx, @@ -202,6 +214,32 @@ bool ConstantHoisting::runOnFunction(Function &Fn) { return MadeChange; } +/// \brief Find nearest common dominator of all uses. +/// FIXME: Replace this with NearestCommonDominator once it is in common code. +BasicBlock * +ConstantHoisting::findIDomOfAllUses(const ConstantUseListType &Uses) const { + // Collect all basic blocks. + SmallPtrSet<BasicBlock *, 8> BBs; + for (auto const &U : Uses) + BBs.insert(findMatInsertPt(U.Inst, U.OpndIdx)->getParent()); + + if (BBs.count(Entry)) + return Entry; + + while (BBs.size() >= 2) { + BasicBlock *BB, *BB1, *BB2; + BB1 = *BBs.begin(); + BB2 = *std::next(BBs.begin()); + BB = DT->findNearestCommonDominator(BB1, BB2); + if (BB == Entry) + return Entry; + BBs.erase(BB1); + BBs.erase(BB2); + BBs.insert(BB); + } + assert((BBs.size() == 1) && "Expected only one element."); + return *BBs.begin(); +} /// \brief Find the constant materialization insertion point. Instruction *ConstantHoisting::findMatInsertPt(Instruction *Inst, @@ -224,11 +262,12 @@ Instruction *ConstantHoisting::findMatInsertPt(Instruction *Inst, Instruction *ConstantHoisting:: findConstantInsertionPoint(const ConstantInfo &ConstInfo) const { assert(!ConstInfo.RebasedConstants.empty() && "Invalid constant info entry."); - // Collect all basic blocks. + // Collect all IDoms. SmallPtrSet<BasicBlock *, 8> BBs; for (auto const &RCI : ConstInfo.RebasedConstants) - for (auto const &U : RCI.Uses) - BBs.insert(U.Inst->getParent()); + BBs.insert(getIDom(RCI)); + + assert(!BBs.empty() && "No dominators!?"); if (BBs.count(Entry)) return &Entry->front(); |

