@@ -122,16 +122,22 @@ static cl::opt<unsigned>
122122 cl::desc (" Maximum cost accepted for the transformation" ),
123123 cl::Hidden, cl::init(50 ));
124124
125- extern cl::opt<bool > ProfcheckDisableMetadataFixes;
126-
127- } // namespace llvm
128-
129125static cl::opt<double > MaxClonedRate (
130126 " dfa-max-cloned-rate" ,
131127 cl::desc (
132128 " Maximum cloned instructions rate accepted for the transformation" ),
133129 cl::Hidden, cl::init(7.5 ));
134130
131+ static cl::opt<unsigned >
132+ MaxOuterUseBlocks (" dfa-max-out-use-blocks" ,
133+ cl::desc (" Maximum unduplicated blocks with outer uses "
134+ " accepted for the transformation" ),
135+ cl::Hidden, cl::init(40 ));
136+
137+ extern cl::opt<bool > ProfcheckDisableMetadataFixes;
138+
139+ } // namespace llvm
140+
135141namespace {
136142class SelectInstToUnfold {
137143 SelectInst *SI;
@@ -965,8 +971,16 @@ struct TransformDFA {
965971 // SLPVectorizer.
966972 // TODO: Thread the switch partially before reaching the threshold.
967973 uint64_t NumOrigInst = 0 ;
968- for (auto *BB : DuplicateMap.keys ())
974+ uint64_t NumOuterUseBlock = 0 ;
975+ for (auto *BB : DuplicateMap.keys ()) {
969976 NumOrigInst += BB->sizeWithoutDebug ();
977+ // Only unduplicated blocks with single predecessor require new phi
978+ // nodes.
979+ for (auto *Succ : successors (BB))
980+ if (!DuplicateMap.count (Succ) && Succ->getSinglePredecessor ())
981+ NumOuterUseBlock++;
982+ }
983+
970984 if (double (NumClonedInst) / double (NumOrigInst) > MaxClonedRate) {
971985 LLVM_DEBUG (dbgs () << " DFA Jump Threading: Not jump threading, too much "
972986 " instructions wll be cloned\n " );
@@ -977,6 +991,20 @@ struct TransformDFA {
977991 return false ;
978992 }
979993
994+ // Too much unduplicated blocks with outer uses may cause too much
995+ // insertions of phi nodes for duplicated definitions. TODO: Drop this
996+ // threshold if we come up with another way to reduce the number of inserted
997+ // phi nodes.
998+ if (NumOuterUseBlock > MaxOuterUseBlocks) {
999+ LLVM_DEBUG (dbgs () << " DFA Jump Threading: Not jump threading, too much "
1000+ " blocks with outer uses\n " );
1001+ ORE->emit ([&]() {
1002+ return OptimizationRemarkMissed (DEBUG_TYPE, " NotProfitable" , Switch)
1003+ << " Too much blocks with outer uses." ;
1004+ });
1005+ return false ;
1006+ }
1007+
9801008 InstructionCost DuplicationCost = 0 ;
9811009
9821010 unsigned JumpTableSize = 0 ;
0 commit comments