29
29
// ===----------------------------------------------------------------------===//
30
30
31
31
#include " llvm/Transforms/Utils/CanonicalizeFreezeInLoops.h"
32
+ #include " llvm/ADT/DenseMapInfo.h"
32
33
#include " llvm/ADT/STLExtras.h"
34
+ #include " llvm/ADT/SetVector.h"
33
35
#include " llvm/ADT/SmallSet.h"
34
- #include " llvm/ADT/SmallVector.h"
35
36
#include " llvm/Analysis/IVDescriptors.h"
36
37
#include " llvm/Analysis/LoopAnalysisManager.h"
37
38
#include " llvm/Analysis/LoopInfo.h"
@@ -66,19 +67,6 @@ class CanonicalizeFreezeInLoopsImpl {
66
67
ScalarEvolution &SE;
67
68
DominatorTree &DT;
68
69
69
- struct FrozenIndPHIInfo {
70
- // A freeze instruction that uses an induction phi
71
- FreezeInst *FI = nullptr ;
72
- // The induction phi, step instruction, the operand idx of StepInst which is
73
- // a step value
74
- PHINode *PHI;
75
- BinaryOperator *StepInst;
76
- unsigned StepValIdx = 0 ;
77
-
78
- FrozenIndPHIInfo (PHINode *PHI, BinaryOperator *StepInst)
79
- : PHI(PHI), StepInst(StepInst) {}
80
- };
81
-
82
70
// Can freeze instruction be pushed into operands of I?
83
71
// In order to do this, I should not create a poison after I's flags are
84
72
// stripped.
@@ -99,6 +87,46 @@ class CanonicalizeFreezeInLoopsImpl {
99
87
100
88
} // anonymous namespace
101
89
90
+ namespace llvm {
91
+
92
+ struct FrozenIndPHIInfo {
93
+ // A freeze instruction that uses an induction phi
94
+ FreezeInst *FI = nullptr ;
95
+ // The induction phi, step instruction, the operand idx of StepInst which is
96
+ // a step value
97
+ PHINode *PHI;
98
+ BinaryOperator *StepInst;
99
+ unsigned StepValIdx = 0 ;
100
+
101
+ FrozenIndPHIInfo (PHINode *PHI, BinaryOperator *StepInst)
102
+ : PHI(PHI), StepInst(StepInst) {}
103
+
104
+ bool operator ==(const FrozenIndPHIInfo &Other) { return FI == Other.FI ; }
105
+ };
106
+
107
+ template <> struct DenseMapInfo <FrozenIndPHIInfo> {
108
+ static inline FrozenIndPHIInfo getEmptyKey () {
109
+ return FrozenIndPHIInfo (DenseMapInfo<PHINode *>::getEmptyKey (),
110
+ DenseMapInfo<BinaryOperator *>::getEmptyKey ());
111
+ }
112
+
113
+ static inline FrozenIndPHIInfo getTombstoneKey () {
114
+ return FrozenIndPHIInfo (DenseMapInfo<PHINode *>::getTombstoneKey (),
115
+ DenseMapInfo<BinaryOperator *>::getTombstoneKey ());
116
+ }
117
+
118
+ static unsigned getHashValue (const FrozenIndPHIInfo &Val) {
119
+ return DenseMapInfo<FreezeInst *>::getHashValue (Val.FI );
120
+ };
121
+
122
+ static bool isEqual (const FrozenIndPHIInfo &LHS,
123
+ const FrozenIndPHIInfo &RHS) {
124
+ return LHS.FI == RHS.FI ;
125
+ };
126
+ };
127
+
128
+ } // end namespace llvm
129
+
102
130
// Given U = (value, user), replace value with freeze(value), and let
103
131
// SCEV forget user. The inserted freeze is placed in the preheader.
104
132
void CanonicalizeFreezeInLoopsImpl::InsertFreezeAndForgetFromSCEV (Use &U) {
@@ -126,7 +154,7 @@ bool CanonicalizeFreezeInLoopsImpl::run() {
126
154
if (!L->isLoopSimplifyForm ())
127
155
return false ;
128
156
129
- SmallVector <FrozenIndPHIInfo, 4 > Candidates;
157
+ SmallSetVector <FrozenIndPHIInfo, 4 > Candidates;
130
158
131
159
for (auto &PHI : L->getHeader ()->phis ()) {
132
160
InductionDescriptor ID;
@@ -155,7 +183,7 @@ bool CanonicalizeFreezeInLoopsImpl::run() {
155
183
if (auto *FI = dyn_cast<FreezeInst>(U)) {
156
184
LLVM_DEBUG (dbgs () << " canonfr: found: " << *FI << " \n " );
157
185
Info.FI = FI;
158
- Candidates.push_back (Info);
186
+ Candidates.insert (Info);
159
187
}
160
188
};
161
189
for_each (PHI.users (), Visit);
0 commit comments