From: Daniel Jasper Date: Tue, 20 Jan 2015 08:57:44 +0000 (+0000) Subject: Factor out a splitSwitchCase() function so that it can be reused. X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=a68dc112616e1c318e10b0d0336cf68bcea371e1;p=oota-llvm.git Factor out a splitSwitchCase() function so that it can be reused. This is in preparation for a fix to llvm.org/PR22262. One of the ideas here is to first find a good jump table range first and then split before and after it. Thereby, we don't need to use the split-based-on-density heuristic at all, which can make the "binary tree" deteriorate in various cases. Also some minor cleanups. No functional changes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@226551 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index a8db35c3a98..2ee276fccbe 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -2397,17 +2397,8 @@ bool SelectionDAGBuilder::handleBTSplitSwitchCase(CaseRec& CR, CaseRecVector& WorkList, const Value* SV, MachineBasicBlock* SwitchBB) { - // Get the MachineFunction which holds the current MBB. This is used when - // inserting any additional MBBs necessary to represent the switch. - MachineFunction *CurMF = FuncInfo.MF; - - // Figure out which block is immediately after the current one. - MachineFunction::iterator BBI = CR.CaseBB; - ++BBI; - Case& FrontCase = *CR.Range.first; Case& BackCase = *(CR.Range.second-1); - const BasicBlock *LLVMBB = CR.CaseBB->getBasicBlock(); // Size is the number of Cases represented by this range. unsigned Size = CR.Range.second - CR.Range.first; @@ -2439,12 +2430,10 @@ bool SelectionDAGBuilder::handleBTSplitSwitchCase(CaseRec& CR, // Use volatile double here to avoid excess precision issues on some hosts, // e.g. that use 80-bit X87 registers. volatile double LDensity = - (double)LSize.roundToDouble() / - (LEnd - First + 1ULL).roundToDouble(); + LSize.roundToDouble() / (LEnd - First + 1ULL).roundToDouble(); volatile double RDensity = - (double)RSize.roundToDouble() / - (Last - RBegin + 1ULL).roundToDouble(); - volatile double Metric = Range.logBase2()*(LDensity+RDensity); + RSize.roundToDouble() / (Last - RBegin + 1ULL).roundToDouble(); + volatile double Metric = Range.logBase2() * (LDensity + RDensity); // Should always split in some non-trivial place DEBUG(dbgs() <<"=>Step\n" << "LEnd: " << LEnd << ", RBegin: " << RBegin << '\n' @@ -2468,6 +2457,23 @@ bool SelectionDAGBuilder::handleBTSplitSwitchCase(CaseRec& CR, } else { Pivot = CR.Range.first + Size/2; } + splitSwitchCase(CR, Pivot, WorkList, SV, SwitchBB); + return true; +} + +void SelectionDAGBuilder::splitSwitchCase(CaseRec &CR, CaseItr Pivot, + CaseRecVector &WorkList, + const Value *SV, + MachineBasicBlock *SwitchBB) { + // Get the MachineFunction which holds the current MBB. This is used when + // inserting any additional MBBs necessary to represent the switch. + MachineFunction *CurMF = FuncInfo.MF; + + // Figure out which block is immediately after the current one. + MachineFunction::iterator BBI = CR.CaseBB; + ++BBI; + + const BasicBlock *LLVMBB = CR.CaseBB->getBasicBlock(); CaseRange LHSR(CR.Range.first, Pivot); CaseRange RHSR(Pivot, CR.Range.second); @@ -2480,10 +2486,9 @@ bool SelectionDAGBuilder::handleBTSplitSwitchCase(CaseRec& CR, // LHS's Case Value, and that Case Value is exactly one less than the // Pivot's Value, then we can branch directly to the LHS's Target, // rather than creating a leaf node for it. - if ((LHSR.second - LHSR.first) == 1 && - LHSR.first->High == CR.GE && + if ((LHSR.second - LHSR.first) == 1 && LHSR.first->High == CR.GE && cast(C)->getValue() == - (cast(CR.GE)->getValue() + 1LL)) { + (cast(CR.GE)->getValue() + 1LL)) { TrueBB = LHSR.first->BB; } else { TrueBB = CurMF->CreateMachineBasicBlock(LLVMBB); @@ -2500,12 +2505,12 @@ bool SelectionDAGBuilder::handleBTSplitSwitchCase(CaseRec& CR, // the current Case Value, rather than emitting a RHS leaf node for it. if ((RHSR.second - RHSR.first) == 1 && CR.LT && cast(RHSR.first->Low)->getValue() == - (cast(CR.LT)->getValue() - 1LL)) { + (cast(CR.LT)->getValue() - 1LL)) { FalseBB = RHSR.first->BB; } else { FalseBB = CurMF->CreateMachineBasicBlock(LLVMBB); CurMF->insert(BBI, FalseBB); - WorkList.push_back(CaseRec(FalseBB,CR.LT,C,RHSR)); + WorkList.push_back(CaseRec(FalseBB, CR.LT, C, RHSR)); // Put SV in a virtual register to make it available from the new blocks. ExportFromCurrentBlock(SV); @@ -2520,8 +2525,6 @@ bool SelectionDAGBuilder::handleBTSplitSwitchCase(CaseRec& CR, visitSwitchCase(CB, SwitchBB); else SwitchCases.push_back(CB); - - return true; } /// handleBitTestsSwitchCase - if current case range has few destination and diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h index eba98b8086b..30cc125b38f 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h @@ -687,6 +687,8 @@ private: CaseRecVector& WorkList, const Value* SV, MachineBasicBlock *SwitchBB); + void splitSwitchCase(CaseRec &CR, CaseItr Pivot, CaseRecVector &WorkList, + const Value *SV, MachineBasicBlock *SwitchBB); bool handleBitTestsSwitchCase(CaseRec& CR, CaseRecVector& WorkList, const Value* SV,