mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-09-26 09:18:56 +00:00
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:
@@ -2397,17 +2397,8 @@ bool SelectionDAGBuilder::handleBTSplitSwitchCase(CaseRec& CR,
|
|||||||
CaseRecVector& WorkList,
|
CaseRecVector& WorkList,
|
||||||
const Value* SV,
|
const Value* SV,
|
||||||
MachineBasicBlock* SwitchBB) {
|
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& FrontCase = *CR.Range.first;
|
||||||
Case& BackCase = *(CR.Range.second-1);
|
Case& BackCase = *(CR.Range.second-1);
|
||||||
const BasicBlock *LLVMBB = CR.CaseBB->getBasicBlock();
|
|
||||||
|
|
||||||
// Size is the number of Cases represented by this range.
|
// Size is the number of Cases represented by this range.
|
||||||
unsigned Size = CR.Range.second - CR.Range.first;
|
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,
|
// Use volatile double here to avoid excess precision issues on some hosts,
|
||||||
// e.g. that use 80-bit X87 registers.
|
// e.g. that use 80-bit X87 registers.
|
||||||
volatile double LDensity =
|
volatile double LDensity =
|
||||||
(double)LSize.roundToDouble() /
|
LSize.roundToDouble() / (LEnd - First + 1ULL).roundToDouble();
|
||||||
(LEnd - First + 1ULL).roundToDouble();
|
|
||||||
volatile double RDensity =
|
volatile double RDensity =
|
||||||
(double)RSize.roundToDouble() /
|
RSize.roundToDouble() / (Last - RBegin + 1ULL).roundToDouble();
|
||||||
(Last - RBegin + 1ULL).roundToDouble();
|
volatile double Metric = Range.logBase2() * (LDensity + RDensity);
|
||||||
volatile double Metric = Range.logBase2()*(LDensity+RDensity);
|
|
||||||
// Should always split in some non-trivial place
|
// Should always split in some non-trivial place
|
||||||
DEBUG(dbgs() <<"=>Step\n"
|
DEBUG(dbgs() <<"=>Step\n"
|
||||||
<< "LEnd: " << LEnd << ", RBegin: " << RBegin << '\n'
|
<< "LEnd: " << LEnd << ", RBegin: " << RBegin << '\n'
|
||||||
@@ -2468,6 +2457,23 @@ bool SelectionDAGBuilder::handleBTSplitSwitchCase(CaseRec& CR,
|
|||||||
} else {
|
} else {
|
||||||
Pivot = CR.Range.first + Size/2;
|
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 LHSR(CR.Range.first, Pivot);
|
||||||
CaseRange RHSR(Pivot, CR.Range.second);
|
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
|
// 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,
|
// Pivot's Value, then we can branch directly to the LHS's Target,
|
||||||
// rather than creating a leaf node for it.
|
// rather than creating a leaf node for it.
|
||||||
if ((LHSR.second - LHSR.first) == 1 &&
|
if ((LHSR.second - LHSR.first) == 1 && LHSR.first->High == CR.GE &&
|
||||||
LHSR.first->High == CR.GE &&
|
|
||||||
cast<ConstantInt>(C)->getValue() ==
|
cast<ConstantInt>(C)->getValue() ==
|
||||||
(cast<ConstantInt>(CR.GE)->getValue() + 1LL)) {
|
(cast<ConstantInt>(CR.GE)->getValue() + 1LL)) {
|
||||||
TrueBB = LHSR.first->BB;
|
TrueBB = LHSR.first->BB;
|
||||||
} else {
|
} else {
|
||||||
TrueBB = CurMF->CreateMachineBasicBlock(LLVMBB);
|
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.
|
// the current Case Value, rather than emitting a RHS leaf node for it.
|
||||||
if ((RHSR.second - RHSR.first) == 1 && CR.LT &&
|
if ((RHSR.second - RHSR.first) == 1 && CR.LT &&
|
||||||
cast<ConstantInt>(RHSR.first->Low)->getValue() ==
|
cast<ConstantInt>(RHSR.first->Low)->getValue() ==
|
||||||
(cast<ConstantInt>(CR.LT)->getValue() - 1LL)) {
|
(cast<ConstantInt>(CR.LT)->getValue() - 1LL)) {
|
||||||
FalseBB = RHSR.first->BB;
|
FalseBB = RHSR.first->BB;
|
||||||
} else {
|
} else {
|
||||||
FalseBB = CurMF->CreateMachineBasicBlock(LLVMBB);
|
FalseBB = CurMF->CreateMachineBasicBlock(LLVMBB);
|
||||||
CurMF->insert(BBI, FalseBB);
|
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.
|
// Put SV in a virtual register to make it available from the new blocks.
|
||||||
ExportFromCurrentBlock(SV);
|
ExportFromCurrentBlock(SV);
|
||||||
@@ -2520,8 +2525,6 @@ bool SelectionDAGBuilder::handleBTSplitSwitchCase(CaseRec& CR,
|
|||||||
visitSwitchCase(CB, SwitchBB);
|
visitSwitchCase(CB, SwitchBB);
|
||||||
else
|
else
|
||||||
SwitchCases.push_back(CB);
|
SwitchCases.push_back(CB);
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// handleBitTestsSwitchCase - if current case range has few destination and
|
/// handleBitTestsSwitchCase - if current case range has few destination and
|
||||||
|
@@ -687,6 +687,8 @@ private:
|
|||||||
CaseRecVector& WorkList,
|
CaseRecVector& WorkList,
|
||||||
const Value* SV,
|
const Value* SV,
|
||||||
MachineBasicBlock *SwitchBB);
|
MachineBasicBlock *SwitchBB);
|
||||||
|
void splitSwitchCase(CaseRec &CR, CaseItr Pivot, CaseRecVector &WorkList,
|
||||||
|
const Value *SV, MachineBasicBlock *SwitchBB);
|
||||||
bool handleBitTestsSwitchCase(CaseRec& CR,
|
bool handleBitTestsSwitchCase(CaseRec& CR,
|
||||||
CaseRecVector& WorkList,
|
CaseRecVector& WorkList,
|
||||||
const Value* SV,
|
const Value* SV,
|
||||||
|
Reference in New Issue
Block a user