@@ -751,16 +751,91 @@ bool IRTranslator::translateSwitch(const User &U, MachineIRBuilder &MIB) {
751751 auto DefaultProb = getEdgeProbability (SwitchMBB, DefaultMBB);
752752 WorkList.push_back ({SwitchMBB, First, Last, nullptr , nullptr , DefaultProb});
753753
754- // FIXME: At the moment we don't do any splitting optimizations here like
755- // SelectionDAG does, so this worklist only has one entry.
756754 while (!WorkList.empty ()) {
757755 SwitchWorkListItem W = WorkList.pop_back_val ();
756+
757+ unsigned NumClusters = W.LastCluster - W.FirstCluster + 1 ;
758+ // For optimized builds, lower large range as a balanced binary tree.
759+ if (NumClusters > 3 &&
760+ MF->getTarget ().getOptLevel () != CodeGenOptLevel::None &&
761+ !DefaultMBB->getParent ()->getFunction ().hasMinSize ()) {
762+ splitWorkItem (WorkList, W, SI.getCondition (), SwitchMBB, MIB);
763+ continue ;
764+ }
765+
758766 if (!lowerSwitchWorkItem (W, SI.getCondition (), SwitchMBB, DefaultMBB, MIB))
759767 return false ;
760768 }
761769 return true ;
762770}
763771
772+ void IRTranslator::splitWorkItem (SwitchCG::SwitchWorkList &WorkList,
773+ const SwitchCG::SwitchWorkListItem &W,
774+ Value *Cond, MachineBasicBlock *SwitchMBB,
775+ MachineIRBuilder &MIB) {
776+ using namespace SwitchCG ;
777+ assert (W.FirstCluster ->Low ->getValue ().slt (W.LastCluster ->Low ->getValue ()) &&
778+ " Clusters not sorted?" );
779+ assert (W.LastCluster - W.FirstCluster + 1 >= 2 && " Too small to split!" );
780+
781+ auto [LastLeft, FirstRight, LeftProb, RightProb] =
782+ SL->computeSplitWorkItemInfo (W);
783+
784+ // Use the first element on the right as pivot since we will make less-than
785+ // comparisons against it.
786+ CaseClusterIt PivotCluster = FirstRight;
787+ assert (PivotCluster > W.FirstCluster );
788+ assert (PivotCluster <= W.LastCluster );
789+
790+ CaseClusterIt FirstLeft = W.FirstCluster ;
791+ CaseClusterIt LastRight = W.LastCluster ;
792+
793+ const ConstantInt *Pivot = PivotCluster->Low ;
794+
795+ // New blocks will be inserted immediately after the current one.
796+ MachineFunction::iterator BBI (W.MBB );
797+ ++BBI;
798+
799+ // We will branch to the LHS if Value < Pivot. If LHS is a single cluster,
800+ // we can branch to its destination directly if it's squeezed exactly in
801+ // between the known lower bound and Pivot - 1.
802+ MachineBasicBlock *LeftMBB;
803+ if (FirstLeft == LastLeft && FirstLeft->Kind == CC_Range &&
804+ FirstLeft->Low == W.GE &&
805+ (FirstLeft->High ->getValue () + 1LL ) == Pivot->getValue ()) {
806+ LeftMBB = FirstLeft->MBB ;
807+ } else {
808+ LeftMBB = FuncInfo.MF ->CreateMachineBasicBlock (W.MBB ->getBasicBlock ());
809+ FuncInfo.MF ->insert (BBI, LeftMBB);
810+ WorkList.push_back (
811+ {LeftMBB, FirstLeft, LastLeft, W.GE , Pivot, W.DefaultProb / 2 });
812+ }
813+
814+ // Similarly, we will branch to the RHS if Value >= Pivot. If RHS is a
815+ // single cluster, RHS.Low == Pivot, and we can branch to its destination
816+ // directly if RHS.High equals the current upper bound.
817+ MachineBasicBlock *RightMBB;
818+ if (FirstRight == LastRight && FirstRight->Kind == CC_Range && W.LT &&
819+ (FirstRight->High ->getValue () + 1ULL ) == W.LT ->getValue ()) {
820+ RightMBB = FirstRight->MBB ;
821+ } else {
822+ RightMBB = FuncInfo.MF ->CreateMachineBasicBlock (W.MBB ->getBasicBlock ());
823+ FuncInfo.MF ->insert (BBI, RightMBB);
824+ WorkList.push_back (
825+ {RightMBB, FirstRight, LastRight, Pivot, W.LT , W.DefaultProb / 2 });
826+ }
827+
828+ // Create the CaseBlock record that will be used to lower the branch.
829+ CaseBlock CB (ICmpInst::Predicate::ICMP_SLT, false , Cond, Pivot, nullptr ,
830+ LeftMBB, RightMBB, W.MBB , MIB.getDebugLoc (), LeftProb,
831+ RightProb);
832+
833+ if (W.MBB == SwitchMBB)
834+ emitSwitchCase (CB, SwitchMBB, MIB);
835+ else
836+ SL->SwitchCases .push_back (CB);
837+ }
838+
764839void IRTranslator::emitJumpTable (SwitchCG::JumpTable &JT,
765840 MachineBasicBlock *MBB) {
766841 // Emit the code for the jump table
0 commit comments