summaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/CanonicalizeFreezeInLoops.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Transforms/Utils/CanonicalizeFreezeInLoops.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/CanonicalizeFreezeInLoops.cpp60
1 files changed, 44 insertions, 16 deletions
diff --git a/llvm/lib/Transforms/Utils/CanonicalizeFreezeInLoops.cpp b/llvm/lib/Transforms/Utils/CanonicalizeFreezeInLoops.cpp
index fb4d82885377..282c44563466 100644
--- a/llvm/lib/Transforms/Utils/CanonicalizeFreezeInLoops.cpp
+++ b/llvm/lib/Transforms/Utils/CanonicalizeFreezeInLoops.cpp
@@ -29,9 +29,10 @@
//===----------------------------------------------------------------------===//
#include "llvm/Transforms/Utils/CanonicalizeFreezeInLoops.h"
+#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallSet.h"
-#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/IVDescriptors.h"
#include "llvm/Analysis/LoopAnalysisManager.h"
#include "llvm/Analysis/LoopInfo.h"
@@ -66,19 +67,6 @@ class CanonicalizeFreezeInLoopsImpl {
ScalarEvolution &SE;
DominatorTree &DT;
- struct FrozenIndPHIInfo {
- // A freeze instruction that uses an induction phi
- FreezeInst *FI = nullptr;
- // The induction phi, step instruction, the operand idx of StepInst which is
- // a step value
- PHINode *PHI;
- BinaryOperator *StepInst;
- unsigned StepValIdx = 0;
-
- FrozenIndPHIInfo(PHINode *PHI, BinaryOperator *StepInst)
- : PHI(PHI), StepInst(StepInst) {}
- };
-
// Can freeze instruction be pushed into operands of I?
// In order to do this, I should not create a poison after I's flags are
// stripped.
@@ -99,6 +87,46 @@ public:
} // anonymous namespace
+namespace llvm {
+
+struct FrozenIndPHIInfo {
+ // A freeze instruction that uses an induction phi
+ FreezeInst *FI = nullptr;
+ // The induction phi, step instruction, the operand idx of StepInst which is
+ // a step value
+ PHINode *PHI;
+ BinaryOperator *StepInst;
+ unsigned StepValIdx = 0;
+
+ FrozenIndPHIInfo(PHINode *PHI, BinaryOperator *StepInst)
+ : PHI(PHI), StepInst(StepInst) {}
+
+ bool operator==(const FrozenIndPHIInfo &Other) { return FI == Other.FI; }
+};
+
+template <> struct DenseMapInfo<FrozenIndPHIInfo> {
+ static inline FrozenIndPHIInfo getEmptyKey() {
+ return FrozenIndPHIInfo(DenseMapInfo<PHINode *>::getEmptyKey(),
+ DenseMapInfo<BinaryOperator *>::getEmptyKey());
+ }
+
+ static inline FrozenIndPHIInfo getTombstoneKey() {
+ return FrozenIndPHIInfo(DenseMapInfo<PHINode *>::getTombstoneKey(),
+ DenseMapInfo<BinaryOperator *>::getTombstoneKey());
+ }
+
+ static unsigned getHashValue(const FrozenIndPHIInfo &Val) {
+ return DenseMapInfo<FreezeInst *>::getHashValue(Val.FI);
+ };
+
+ static bool isEqual(const FrozenIndPHIInfo &LHS,
+ const FrozenIndPHIInfo &RHS) {
+ return LHS.FI == RHS.FI;
+ };
+};
+
+} // end namespace llvm
+
// Given U = (value, user), replace value with freeze(value), and let
// SCEV forget user. The inserted freeze is placed in the preheader.
void CanonicalizeFreezeInLoopsImpl::InsertFreezeAndForgetFromSCEV(Use &U) {
@@ -126,7 +154,7 @@ bool CanonicalizeFreezeInLoopsImpl::run() {
if (!L->isLoopSimplifyForm())
return false;
- SmallVector<FrozenIndPHIInfo, 4> Candidates;
+ SmallSetVector<FrozenIndPHIInfo, 4> Candidates;
for (auto &PHI : L->getHeader()->phis()) {
InductionDescriptor ID;
@@ -155,7 +183,7 @@ bool CanonicalizeFreezeInLoopsImpl::run() {
if (auto *FI = dyn_cast<FreezeInst>(U)) {
LLVM_DEBUG(dbgs() << "canonfr: found: " << *FI << "\n");
Info.FI = FI;
- Candidates.push_back(Info);
+ Candidates.insert(Info);
}
};
for_each(PHI.users(), Visit);