@@ -84,59 +84,75 @@ static Instruction *getContextInstForUse(Use &U) {
84
84
85
85
namespace {
86
86
// / Represents either
87
- // / * a condition that holds on entry to a block (=conditional fact)
87
+ // / * a condition that holds on entry to a block (=condition fact)
88
88
// / * an assume (=assume fact)
89
89
// / * a use of a compare instruction to simplify.
90
90
// / It also tracks the Dominator DFS in and out numbers for each entry.
91
91
struct FactOrCheck {
92
+ enum class EntryTy {
93
+ ConditionFact, // / A condition that holds on entry to a block.
94
+ InstFact, // / A fact that holds after Inst executed (e.g. an assume or
95
+ // / min/mix intrinsic.
96
+ InstCheck, // / An instruction to simplify (e.g. an overflow math
97
+ // / intrinsics).
98
+ UseCheck // / An use of a compare instruction to simplify.
99
+ };
100
+
92
101
union {
93
102
Instruction *Inst;
94
103
Use *U;
95
104
};
105
+
96
106
unsigned NumIn;
97
107
unsigned NumOut;
98
- bool HasInst ;
108
+ EntryTy Ty ;
99
109
bool Not;
100
110
101
- FactOrCheck (DomTreeNode *DTN, Instruction *Inst, bool Not)
111
+ FactOrCheck (EntryTy Ty, DomTreeNode *DTN, Instruction *Inst, bool Not)
102
112
: Inst(Inst), NumIn(DTN->getDFSNumIn ()), NumOut(DTN->getDFSNumOut ()),
103
- HasInst( true ), Not(Not) {}
113
+ Ty(Ty ), Not(Not) {}
104
114
105
115
FactOrCheck (DomTreeNode *DTN, Use *U)
106
116
: U(U), NumIn(DTN->getDFSNumIn ()), NumOut(DTN->getDFSNumOut ()),
107
- HasInst(false ), Not(false ) {}
117
+ Ty(EntryTy::UseCheck), Not(false ) {}
118
+
119
+ static FactOrCheck getConditionFact (DomTreeNode *DTN, CmpInst *Inst,
120
+ bool Not = false ) {
121
+ return FactOrCheck (EntryTy::ConditionFact, DTN, Inst, Not);
122
+ }
108
123
109
- static FactOrCheck getFact (DomTreeNode *DTN, Instruction *Inst,
110
- bool Not = false ) {
111
- return FactOrCheck (DTN, Inst, Not);
124
+ static FactOrCheck getInstFact (DomTreeNode *DTN, Instruction *Inst,
125
+ bool Not = false ) {
126
+ return FactOrCheck (EntryTy::InstFact, DTN, Inst, Not);
112
127
}
113
128
114
129
static FactOrCheck getCheck (DomTreeNode *DTN, Use *U) {
115
130
return FactOrCheck (DTN, U);
116
131
}
117
132
118
133
static FactOrCheck getCheck (DomTreeNode *DTN, CallInst *CI) {
119
- return FactOrCheck (DTN, CI, false );
134
+ return FactOrCheck (EntryTy::InstCheck, DTN, CI, false );
120
135
}
121
136
122
137
bool isCheck () const {
123
- return !HasInst ||
124
- match (Inst, m_Intrinsic<Intrinsic::ssub_with_overflow>());
138
+ return Ty == EntryTy::InstCheck || Ty == EntryTy::UseCheck;
125
139
}
126
140
127
141
Instruction *getContextInst () const {
128
- if (HasInst )
129
- return Inst ;
130
- return getContextInstForUse (*U) ;
142
+ if (Ty == EntryTy::UseCheck )
143
+ return getContextInstForUse (*U) ;
144
+ return Inst ;
131
145
}
146
+
132
147
Instruction *getInstructionToSimplify () const {
133
148
assert (isCheck ());
134
- if (HasInst )
149
+ if (Ty == EntryTy::InstCheck )
135
150
return Inst;
136
151
// The use may have been simplified to a constant already.
137
152
return dyn_cast<Instruction>(*U);
138
153
}
139
- bool isConditionFact () const { return !isCheck () && isa<CmpInst>(Inst); }
154
+
155
+ bool isConditionFact () const { return Ty == EntryTy::ConditionFact; }
140
156
};
141
157
142
158
// / Keep state required to build worklist.
@@ -785,7 +801,7 @@ void State::addInfoFor(BasicBlock &BB) {
785
801
}
786
802
787
803
if (isa<MinMaxIntrinsic>(&I)) {
788
- WorkList.push_back (FactOrCheck::getFact (DT.getNode (&BB), &I));
804
+ WorkList.push_back (FactOrCheck::getInstFact (DT.getNode (&BB), &I));
789
805
continue ;
790
806
}
791
807
@@ -796,11 +812,11 @@ void State::addInfoFor(BasicBlock &BB) {
796
812
if (GuaranteedToExecute) {
797
813
// The assume is guaranteed to execute when BB is entered, hence Cond
798
814
// holds on entry to BB.
799
- WorkList.emplace_back (FactOrCheck::getFact (DT. getNode (I. getParent ()),
800
- cast<Instruction >(Cond)));
815
+ WorkList.emplace_back (FactOrCheck::getConditionFact (
816
+ DT. getNode (I. getParent ()), cast<CmpInst >(Cond)));
801
817
} else {
802
818
WorkList.emplace_back (
803
- FactOrCheck::getFact (DT.getNode (I.getParent ()), &I));
819
+ FactOrCheck::getInstFact (DT.getNode (I.getParent ()), &I));
804
820
}
805
821
}
806
822
GuaranteedToExecute &= isGuaranteedToTransferExecutionToSuccessor (&I);
@@ -838,7 +854,7 @@ void State::addInfoFor(BasicBlock &BB) {
838
854
Value *Cur = CondWorkList.pop_back_val ();
839
855
if (auto *Cmp = dyn_cast<ICmpInst>(Cur)) {
840
856
WorkList.emplace_back (
841
- FactOrCheck::getFact (DT.getNode (Successor), Cmp, IsOr));
857
+ FactOrCheck::getConditionFact (DT.getNode (Successor), Cmp, IsOr));
842
858
continue ;
843
859
}
844
860
if (IsOr && match (Cur, m_LogicalOr (m_Value (Op0), m_Value (Op1)))) {
@@ -861,10 +877,10 @@ void State::addInfoFor(BasicBlock &BB) {
861
877
return ;
862
878
if (canAddSuccessor (BB, Br->getSuccessor (0 )))
863
879
WorkList.emplace_back (
864
- FactOrCheck::getFact (DT.getNode (Br->getSuccessor (0 )), CmpI));
880
+ FactOrCheck::getConditionFact (DT.getNode (Br->getSuccessor (0 )), CmpI));
865
881
if (canAddSuccessor (BB, Br->getSuccessor (1 )))
866
- WorkList.emplace_back (
867
- FactOrCheck::getFact ( DT.getNode (Br->getSuccessor (1 )), CmpI, true ));
882
+ WorkList.emplace_back (FactOrCheck::getConditionFact (
883
+ DT.getNode (Br->getSuccessor (1 )), CmpI, true ));
868
884
}
869
885
870
886
namespace {
0 commit comments