@@ -751,16 +751,91 @@ bool IRTranslator::translateSwitch(const User &U, MachineIRBuilder &MIB) {
751
751
auto DefaultProb = getEdgeProbability (SwitchMBB, DefaultMBB);
752
752
WorkList.push_back ({SwitchMBB, First, Last, nullptr , nullptr , DefaultProb});
753
753
754
- // FIXME: At the moment we don't do any splitting optimizations here like
755
- // SelectionDAG does, so this worklist only has one entry.
756
754
while (!WorkList.empty ()) {
757
755
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
+
758
766
if (!lowerSwitchWorkItem (W, SI.getCondition (), SwitchMBB, DefaultMBB, MIB))
759
767
return false ;
760
768
}
761
769
return true ;
762
770
}
763
771
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
+
764
839
void IRTranslator::emitJumpTable (SwitchCG::JumpTable &JT,
765
840
MachineBasicBlock *MBB) {
766
841
// Emit the code for the jump table
0 commit comments