@@ -104,6 +104,12 @@ static cl::opt<bool> PHICSEDebugHash(
104
104
cl::desc (" Perform extra assertion checking to verify that PHINodes's hash "
105
105
" function is well-behaved w.r.t. its isEqual predicate" ));
106
106
107
+ static cl::opt<unsigned > PHICSENumPHISmallSize (
108
+ " phicse-num-phi-smallsize" , cl::init(32 ), cl::Hidden,
109
+ cl::desc(
110
+ " When the basic block contains not more than this number of PHI nodes, "
111
+ " perform a (faster!) exhaustive search instead of set-driven one." ));
112
+
107
113
// Max recursion depth for collectBitParts used when detecting bswap and
108
114
// bitreverse idioms
109
115
static const unsigned BitPartRecursionMaxDepth = 64 ;
@@ -1132,9 +1138,39 @@ bool llvm::TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB,
1132
1138
return true ;
1133
1139
}
1134
1140
1135
- // WARNING: this logic must be kept in sync with
1136
- // Instruction::isIdenticalToWhenDefined()!
1137
- bool llvm::EliminateDuplicatePHINodes (BasicBlock *BB) {
1141
+ static bool EliminateDuplicatePHINodesNaiveImpl (BasicBlock *BB) {
1142
+ // This implementation doesn't currently consider undef operands
1143
+ // specially. Theoretically, two phis which are identical except for
1144
+ // one having an undef where the other doesn't could be collapsed.
1145
+
1146
+ bool Changed = false ;
1147
+
1148
+ // Examine each PHI.
1149
+ // Note that increment of I must *NOT* be in the iteration_expression, since
1150
+ // we don't want to immediately advance when we restart from the beginning.
1151
+ for (auto I = BB->begin (); PHINode *PN = dyn_cast<PHINode>(I);) {
1152
+ ++I;
1153
+ // Is there an identical PHI node in this basic block?
1154
+ // Note that we only look in the upper square's triangle,
1155
+ // we already checked that the lower triangle PHI's aren't identical.
1156
+ for (auto J = I; PHINode *DuplicatePN = dyn_cast<PHINode>(J); ++J) {
1157
+ if (!DuplicatePN->isIdenticalToWhenDefined (PN))
1158
+ continue ;
1159
+ // A duplicate. Replace this PHI with the base PHI.
1160
+ ++NumPHICSEs;
1161
+ DuplicatePN->replaceAllUsesWith (PN);
1162
+ DuplicatePN->eraseFromParent ();
1163
+ Changed = true ;
1164
+
1165
+ // The RAUW can change PHIs that we already visited.
1166
+ I = BB->begin ();
1167
+ break ; // Start over from the beginning.
1168
+ }
1169
+ }
1170
+ return Changed;
1171
+ }
1172
+
1173
+ static bool EliminateDuplicatePHINodesSetBasedImpl (BasicBlock *BB) {
1138
1174
// This implementation doesn't currently consider undef operands
1139
1175
// specially. Theoretically, two phis which are identical except for
1140
1176
// one having an undef where the other doesn't could be collapsed.
@@ -1152,6 +1188,8 @@ bool llvm::EliminateDuplicatePHINodes(BasicBlock *BB) {
1152
1188
return PN == getEmptyKey () || PN == getTombstoneKey ();
1153
1189
}
1154
1190
1191
+ // WARNING: this logic must be kept in sync with
1192
+ // Instruction::isIdenticalToWhenDefined()!
1155
1193
static unsigned getHashValueImpl (PHINode *PN) {
1156
1194
// Compute a hash value on the operands. Instcombine will likely have
1157
1195
// sorted them, which helps expose duplicates, but we have to check all
@@ -1191,6 +1229,7 @@ bool llvm::EliminateDuplicatePHINodes(BasicBlock *BB) {
1191
1229
1192
1230
// Set of unique PHINodes.
1193
1231
DenseSet<PHINode *, PHIDenseMapInfo> PHISet;
1232
+ PHISet.reserve (4 * PHICSENumPHISmallSize);
1194
1233
1195
1234
// Examine each PHI.
1196
1235
bool Changed = false ;
@@ -1213,6 +1252,16 @@ bool llvm::EliminateDuplicatePHINodes(BasicBlock *BB) {
1213
1252
return Changed;
1214
1253
}
1215
1254
1255
+ bool llvm::EliminateDuplicatePHINodes (BasicBlock *BB) {
1256
+ if (
1257
+ #ifndef NDEBUG
1258
+ !PHICSEDebugHash &&
1259
+ #endif
1260
+ hasNItemsOrLess (BB->phis (), PHICSENumPHISmallSize))
1261
+ return EliminateDuplicatePHINodesNaiveImpl (BB);
1262
+ return EliminateDuplicatePHINodesSetBasedImpl (BB);
1263
+ }
1264
+
1216
1265
// / enforceKnownAlignment - If the specified pointer points to an object that
1217
1266
// / we control, modify the object's alignment to PrefAlign. This isn't
1218
1267
// / often possible though. If alignment is important, a more reliable approach
0 commit comments