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
This commit is contained in:
Daniel Jasper 2015-01-20 08:57:44 +00:00
parent 06df574f20
commit a68dc11261
2 changed files with 26 additions and 21 deletions

View File

@ -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<ConstantInt>(C)->getValue() ==
(cast<ConstantInt>(CR.GE)->getValue() + 1LL)) {
(cast<ConstantInt>(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<ConstantInt>(RHSR.first->Low)->getValue() ==
(cast<ConstantInt>(CR.LT)->getValue() - 1LL)) {
(cast<ConstantInt>(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

View File

@ -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,