[llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
Anton Korobeynikov
asl at math.spbu.ru
Sun Mar 25 08:07:45 PDT 2007
Changes in directory llvm/lib/CodeGen/SelectionDAG:
SelectionDAGISel.cpp updated: 1.393 -> 1.394
---
Log message:
First step of switch lowering refactoring: perform worklist-driven
strategy, emit JT's where possible.
---
Diffs of the changes: (+253 -180)
SelectionDAGISel.cpp | 433 +++++++++++++++++++++++++++++----------------------
1 files changed, 253 insertions(+), 180 deletions(-)
Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.393 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.394
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.393 Sun Mar 25 00:00:54 2007
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Sun Mar 25 10:07:15 2007
@@ -405,7 +405,9 @@
/// SwitchCases - Vector of CaseBlock structures used to communicate
/// SwitchInst code generation information.
std::vector<SelectionDAGISel::CaseBlock> SwitchCases;
- SelectionDAGISel::JumpTable JT;
+ /// JTCases - Vector of JumpTable structures used to communicate
+ /// SwitchInst code generation information.
+ std::vector<SelectionDAGISel::JumpTableBlock> JTCases;
/// FuncInfo - Information about the function as a whole.
///
@@ -414,7 +416,7 @@
SelectionDAGLowering(SelectionDAG &dag, TargetLowering &tli,
FunctionLoweringInfo &funcinfo)
: TLI(tli), DAG(dag), TD(DAG.getTarget().getTargetData()),
- JT(0,0,0,0), FuncInfo(funcinfo) {
+ FuncInfo(funcinfo) {
}
/// getRoot - Return the current virtual root of the Selection DAG.
@@ -497,6 +499,8 @@
// Helper for visitSwitch
void visitSwitchCase(SelectionDAGISel::CaseBlock &CB);
void visitJumpTable(SelectionDAGISel::JumpTable &JT);
+ void visitJumpTableHeader(SelectionDAGISel::JumpTable &JT,
+ SelectionDAGISel::JumpTableHeader &JTH);
// These all get lowered before this pass.
void visitInvoke(InvokeInst &I);
@@ -1065,7 +1069,7 @@
Cond = DAG.getNode(ISD::XOR, CondLHS.getValueType(), CondLHS, True);
} else
Cond = DAG.getSetCC(MVT::i1, CondLHS, getValue(CB.CmpRHS), CB.CC);
-
+
// Set NextBlock to be the MBB immediately after the current one, if any.
// This is used to avoid emitting unnecessary branches to the next block.
MachineBasicBlock *NextBlock = 0;
@@ -1092,8 +1096,10 @@
CurMBB->addSuccessor(CB.FalseBB);
}
+/// visitJumpTable - Emit JumpTable node in the current MBB
void SelectionDAGLowering::visitJumpTable(SelectionDAGISel::JumpTable &JT) {
// Emit the code for the jump table
+ assert(JT.Reg != -1UL && "Should lower JT Header first!");
MVT::ValueType PTy = TLI.getPointerTy();
SDOperand Index = DAG.getCopyFromReg(getRoot(), JT.Reg, PTy);
SDOperand Table = DAG.getJumpTable(JT.JTI, PTy);
@@ -1102,6 +1108,57 @@
return;
}
+/// visitJumpTableHeader - This function emits necessary code to produce index
+/// in the JumpTable from switch case.
+void SelectionDAGLowering::visitJumpTableHeader(SelectionDAGISel::JumpTable &JT,
+ SelectionDAGISel::JumpTableHeader &JTH) {
+ // Subtract the lowest switch case value from the value being switched on
+ // and conditional branch to default mbb if the result is greater than the
+ // difference between smallest and largest cases.
+ SDOperand SwitchOp = getValue(JTH.SValue);
+ MVT::ValueType VT = SwitchOp.getValueType();
+ SDOperand SUB = DAG.getNode(ISD::SUB, VT, SwitchOp,
+ DAG.getConstant(JTH.First, VT));
+
+ // The SDNode we just created, which holds the value being switched on
+ // minus the the smallest case value, needs to be copied to a virtual
+ // register so it can be used as an index into the jump table in a
+ // subsequent basic block. This value may be smaller or larger than the
+ // target's pointer type, and therefore require extension or truncating.
+ if (VT > TLI.getPointerTy())
+ SwitchOp = DAG.getNode(ISD::TRUNCATE, TLI.getPointerTy(), SUB);
+ else
+ SwitchOp = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(), SUB);
+
+ unsigned JumpTableReg = FuncInfo.MakeReg(TLI.getPointerTy());
+ SDOperand CopyTo = DAG.getCopyToReg(getRoot(), JumpTableReg, SwitchOp);
+ JT.Reg = JumpTableReg;
+
+ // Emit the range check for the jump table, and branch to the default
+ // block for the switch statement if the value being switched on exceeds
+ // the largest case in the switch.
+ SDOperand CMP = DAG.getSetCC(TLI.getSetCCResultTy(), SUB,
+ DAG.getConstant(JTH.Last-JTH.First,VT),
+ ISD::SETUGT);
+
+ // Set NextBlock to be the MBB immediately after the current one, if any.
+ // This is used to avoid emitting unnecessary branches to the next block.
+ MachineBasicBlock *NextBlock = 0;
+ MachineFunction::iterator BBI = CurMBB;
+ if (++BBI != CurMBB->getParent()->end())
+ NextBlock = BBI;
+
+ SDOperand BrCond = DAG.getNode(ISD::BRCOND, MVT::Other, CopyTo, CMP,
+ DAG.getBasicBlock(JT.Default));
+
+ if (JT.MBB == NextBlock)
+ DAG.setRoot(BrCond);
+ else
+ DAG.setRoot(DAG.getNode(ISD::BR, MVT::Other, BrCond,
+ DAG.getBasicBlock(JT.MBB)));
+}
+
+
void SelectionDAGLowering::visitInvoke(InvokeInst &I) {
assert(0 && "Should never be visited directly");
}
@@ -1151,14 +1208,11 @@
void SelectionDAGLowering::visitUnwind(UnwindInst &I) {
}
-void SelectionDAGLowering::visitSwitch(SwitchInst &I) {
+void SelectionDAGLowering::visitSwitch(SwitchInst &I) {
// Figure out which block is immediately after the current one.
MachineBasicBlock *NextBlock = 0;
MachineFunction::iterator BBI = CurMBB;
- if (++BBI != CurMBB->getParent()->end())
- NextBlock = BBI;
-
MachineBasicBlock *Default = FuncInfo.MBBMap[I.getDefaultDest()];
// If there is only the default destination, branch to it if it is not the
@@ -1184,7 +1238,6 @@
MachineBasicBlock *SMBB = FuncInfo.MBBMap[I.getSuccessor(i)];
Cases.push_back(Case(I.getSuccessorValue(i), SMBB));
}
-
std::sort(Cases.begin(), Cases.end(), CaseCmp());
// Get the Value to be switched on and default basic blocks, which will be
@@ -1195,174 +1248,161 @@
// Get the MachineFunction which holds the current MBB. This is used during
// emission of jump tables, and when inserting any additional MBBs necessary
// to represent the switch.
- MachineFunction *CurMF = CurMBB->getParent();
- const BasicBlock *LLVMBB = CurMBB->getBasicBlock();
-
- // If the switch has few cases (two or less) emit a series of specific
- // tests.
- if (Cases.size() < 3) {
- // TODO: If any two of the cases has the same destination, and if one value
- // is the same as the other, but has one bit unset that the other has set,
- // use bit manipulation to do two compares at once. For example:
- // "if (X == 6 || X == 4)" -> "if ((X|2) == 6)"
-
- // Rearrange the case blocks so that the last one falls through if possible.
- if (NextBlock && Default != NextBlock && Cases.back().second != NextBlock) {
- // The last case block won't fall through into 'NextBlock' if we emit the
- // branches in this order. See if rearranging a case value would help.
- for (unsigned i = 0, e = Cases.size()-1; i != e; ++i) {
- if (Cases[i].second == NextBlock) {
- std::swap(Cases[i], Cases.back());
- break;
+ MachineFunction *CurMF = CurMBB->getParent();
+
+ // Push the initial CaseRec onto the worklist
+ std::vector<CaseRec> WorkList;
+ WorkList.push_back(CaseRec(CurMBB,0,0,CaseRange(Cases.begin(),Cases.end())));
+
+ while (!WorkList.empty()) {
+ // Grab a record representing a case range to process off the worklist
+ CaseRec CR = WorkList.back();
+ WorkList.pop_back();
+ Case& FrontCase = *CR.Range.first;
+ Case& BackCase = *(CR.Range.second-1);
+ const BasicBlock *LLVMBB = CR.CaseBB->getBasicBlock();
+
+ // Figure out which block is immediately after the current one.
+ NextBlock = 0;
+ BBI = CR.CaseBB;
+
+ if (++BBI != CurMBB->getParent()->end())
+ NextBlock = BBI;
+
+ // Size is the number of Cases represented by this range.
+ unsigned Size = CR.Range.second - CR.Range.first;
+
+ // If the range has few cases (two or less) emit a series of specific
+ // tests.
+ if (Size < 3) {
+ // TODO: If any two of the cases has the same destination, and if one value
+ // is the same as the other, but has one bit unset that the other has set,
+ // use bit manipulation to do two compares at once. For example:
+ // "if (X == 6 || X == 4)" -> "if ((X|2) == 6)"
+
+ // Rearrange the case blocks so that the last one falls through if possible.
+ if (NextBlock && Default != NextBlock && BackCase.second != NextBlock) {
+ // The last case block won't fall through into 'NextBlock' if we emit the
+ // branches in this order. See if rearranging a case value would help.
+ for (CaseItr I = CR.Range.first, E = CR.Range.second-1; I != E; ++I) {
+ if (I->second == NextBlock) {
+ std::swap(*I, BackCase);
+ break;
+ }
}
}
- }
- // Create a CaseBlock record representing a conditional branch to
- // the Case's target mbb if the value being switched on SV is equal
- // to C.
- MachineBasicBlock *CurBlock = CurMBB;
- for (unsigned i = 0, e = Cases.size(); i != e; ++i) {
- MachineBasicBlock *FallThrough;
- if (i != e-1) {
- FallThrough = new MachineBasicBlock(CurMBB->getBasicBlock());
- CurMF->getBasicBlockList().insert(BBI, FallThrough);
- } else {
- // If the last case doesn't match, go to the default block.
- FallThrough = Default;
- }
+ // Create a CaseBlock record representing a conditional branch to
+ // the Case's target mbb if the value being switched on SV is equal
+ // to C.
+ MachineBasicBlock *CurBlock = CR.CaseBB;
+ for (CaseItr I = CR.Range.first, E = CR.Range.second; I != E; ++I) {
+ MachineBasicBlock *FallThrough;
+ if (I != E-1) {
+ FallThrough = new MachineBasicBlock(CurBlock->getBasicBlock());
+ CurMF->getBasicBlockList().insert(BBI, FallThrough);
+ } else {
+ // If the last case doesn't match, go to the default block.
+ FallThrough = Default;
+ }
- SelectionDAGISel::CaseBlock CB(ISD::SETEQ, SV, Cases[i].first,
- Cases[i].second, FallThrough, CurBlock);
+ SelectionDAGISel::CaseBlock CB(ISD::SETEQ, SV, I->first,
+ I->second, FallThrough, CurBlock);
- // If emitting the first comparison, just call visitSwitchCase to emit the
- // code into the current block. Otherwise, push the CaseBlock onto the
- // vector to be later processed by SDISel, and insert the node's MBB
- // before the next MBB.
- if (CurBlock == CurMBB)
- visitSwitchCase(CB);
- else
- SwitchCases.push_back(CB);
+ // If emitting the first comparison, just call visitSwitchCase to emit the
+ // code into the current block. Otherwise, push the CaseBlock onto the
+ // vector to be later processed by SDISel, and insert the node's MBB
+ // before the next MBB.
+ if (CurBlock == CurMBB)
+ visitSwitchCase(CB);
+ else
+ SwitchCases.push_back(CB);
- CurBlock = FallThrough;
- }
- return;
- }
-
- // If the switch has more than 5 blocks, and at least 31.25% dense, and the
- // target supports indirect branches, then emit a jump table rather than
- // lowering the switch to a binary tree of conditional branches.
- if ((TLI.isOperationLegal(ISD::BR_JT, MVT::Other) ||
- TLI.isOperationLegal(ISD::BRIND, MVT::Other)) &&
- Cases.size() > 5) {
- uint64_t First =cast<ConstantInt>(Cases.front().first)->getSExtValue();
- uint64_t Last = cast<ConstantInt>(Cases.back().first)->getSExtValue();
- double Density = (double)Cases.size() / (double)((Last - First) + 1ULL);
-
- if (Density >= 0.3125) {
- // Create a new basic block to hold the code for loading the address
- // of the jump table, and jumping to it. Update successor information;
- // we will either branch to the default case for the switch, or the jump
- // table.
- MachineBasicBlock *JumpTableBB = new MachineBasicBlock(LLVMBB);
- CurMF->getBasicBlockList().insert(BBI, JumpTableBB);
- CurMBB->addSuccessor(Default);
- CurMBB->addSuccessor(JumpTableBB);
-
- // Subtract the lowest switch case value from the value being switched on
- // and conditional branch to default mbb if the result is greater than the
- // difference between smallest and largest cases.
- SDOperand SwitchOp = getValue(SV);
- MVT::ValueType VT = SwitchOp.getValueType();
- SDOperand SUB = DAG.getNode(ISD::SUB, VT, SwitchOp,
- DAG.getConstant(First, VT));
-
- // The SDNode we just created, which holds the value being switched on
- // minus the the smallest case value, needs to be copied to a virtual
- // register so it can be used as an index into the jump table in a
- // subsequent basic block. This value may be smaller or larger than the
- // target's pointer type, and therefore require extension or truncating.
- if (VT > TLI.getPointerTy())
- SwitchOp = DAG.getNode(ISD::TRUNCATE, TLI.getPointerTy(), SUB);
- else
- SwitchOp = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(), SUB);
+ CurBlock = FallThrough;
+ }
- unsigned JumpTableReg = FuncInfo.MakeReg(TLI.getPointerTy());
- SDOperand CopyTo = DAG.getCopyToReg(getRoot(), JumpTableReg, SwitchOp);
-
- // Emit the range check for the jump table, and branch to the default
- // block for the switch statement if the value being switched on exceeds
- // the largest case in the switch.
- SDOperand CMP = DAG.getSetCC(TLI.getSetCCResultTy(), SUB,
- DAG.getConstant(Last-First,VT), ISD::SETUGT);
- DAG.setRoot(DAG.getNode(ISD::BRCOND, MVT::Other, CopyTo, CMP,
- DAG.getBasicBlock(Default)));
+ continue;
+ }
- // Build a vector of destination BBs, corresponding to each target
- // of the jump table. If the value of the jump table slot corresponds to
- // a case statement, push the case's BB onto the vector, otherwise, push
- // the default BB.
- std::vector<MachineBasicBlock*> DestBBs;
- int64_t TEI = First;
- for (CaseItr ii = Cases.begin(), ee = Cases.end(); ii != ee; ++TEI)
- if (cast<ConstantInt>(ii->first)->getSExtValue() == TEI) {
- DestBBs.push_back(ii->second);
- ++ii;
- } else {
- DestBBs.push_back(Default);
+ // If the switch has more than 5 blocks, and at least 31.25% dense, and the
+ // target supports indirect branches, then emit a jump table rather than
+ // lowering the switch to a binary tree of conditional branches.
+
+ if ((TLI.isOperationLegal(ISD::BR_JT, MVT::Other) ||
+ TLI.isOperationLegal(ISD::BRIND, MVT::Other)) &&
+ Size > 5) {
+ uint64_t First = cast<ConstantInt>(FrontCase.first)->getSExtValue();
+ uint64_t Last = cast<ConstantInt>(BackCase.first)->getSExtValue();
+ double Density = (double)Size / (double)((Last - First) + 1ULL);
+
+ if (Density >= 0.3125) {
+ // Create a new basic block to hold the code for loading the address
+ // of the jump table, and jumping to it. Update successor information;
+ // we will either branch to the default case for the switch, or the jump
+ // table.
+ MachineBasicBlock *JumpTableBB = new MachineBasicBlock(LLVMBB);
+ CurMF->getBasicBlockList().insert(BBI, JumpTableBB);
+ CR.CaseBB->addSuccessor(Default);
+ CR.CaseBB->addSuccessor(JumpTableBB);
+
+ // Build a vector of destination BBs, corresponding to each target
+ // of the jump table. If the value of the jump table slot corresponds to
+ // a case statement, push the case's BB onto the vector, otherwise, push
+ // the default BB.
+ std::vector<MachineBasicBlock*> DestBBs;
+ int64_t TEI = First;
+ for (CaseItr I = CR.Range.first, E = CR.Range.second; I != E; ++TEI)
+ if (cast<ConstantInt>(I->first)->getSExtValue() == TEI) {
+ DestBBs.push_back(I->second);
+ ++I;
+ } else {
+ DestBBs.push_back(Default);
+ }
+
+ // Update successor info. Add one edge to each unique successor.
+ // Vector bool would be better, but vector<bool> is really slow.
+ std::vector<unsigned char> SuccsHandled;
+ SuccsHandled.resize(CR.CaseBB->getParent()->getNumBlockIDs());
+
+ for (std::vector<MachineBasicBlock*>::iterator I = DestBBs.begin(),
+ E = DestBBs.end(); I != E; ++I) {
+ if (!SuccsHandled[(*I)->getNumber()]) {
+ SuccsHandled[(*I)->getNumber()] = true;
+ JumpTableBB->addSuccessor(*I);
+ }
}
- // Update successor info. Add one edge to each unique successor.
- // Vector bool would be better, but vector<bool> is really slow.
- std::vector<unsigned char> SuccsHandled;
- SuccsHandled.resize(CurMBB->getParent()->getNumBlockIDs());
-
- for (std::vector<MachineBasicBlock*>::iterator I = DestBBs.begin(),
- E = DestBBs.end(); I != E; ++I) {
- if (!SuccsHandled[(*I)->getNumber()]) {
- SuccsHandled[(*I)->getNumber()] = true;
- JumpTableBB->addSuccessor(*I);
- }
+ // Create a jump table index for this jump table, or return an existing
+ // one.
+ unsigned JTI = CurMF->getJumpTableInfo()->getJumpTableIndex(DestBBs);
+
+ // Set the jump table information so that we can codegen it as a second
+ // MachineBasicBlock
+ SelectionDAGISel::JumpTable JT(-1UL, JTI, JumpTableBB, Default);
+ SelectionDAGISel::JumpTableHeader JTH(First, Last, SV, CR.CaseBB,
+ (CR.CaseBB == CurMBB));
+ if (CR.CaseBB == CurMBB)
+ visitJumpTableHeader(JT, JTH);
+
+ JTCases.push_back(SelectionDAGISel::JumpTableBlock(JTH, JT));
+
+ continue;
}
-
- // Create a jump table index for this jump table, or return an existing
- // one.
- unsigned JTI = CurMF->getJumpTableInfo()->getJumpTableIndex(DestBBs);
-
- // Set the jump table information so that we can codegen it as a second
- // MachineBasicBlock
- JT.Reg = JumpTableReg;
- JT.JTI = JTI;
- JT.MBB = JumpTableBB;
- JT.Default = Default;
- return;
}
- }
-
- // Push the initial CaseRec onto the worklist
- std::vector<CaseRec> CaseVec;
- CaseVec.push_back(CaseRec(CurMBB,0,0,CaseRange(Cases.begin(),Cases.end())));
-
- while (!CaseVec.empty()) {
- // Grab a record representing a case range to process off the worklist
- CaseRec CR = CaseVec.back();
- CaseVec.pop_back();
-
- // Size is the number of Cases represented by this range. If Size is 1,
- // then we are processing a leaf of the binary search tree. Otherwise,
- // we need to pick a pivot, and push left and right ranges onto the
- // worklist.
- unsigned Size = CR.Range.second - CR.Range.first;
+
+ // Emit binary tree. If Size is 1, then we are processing a leaf of the
+ // binary search tree. Otherwise, we need to pick a pivot, and push left
+ // and right ranges onto the worklist.
- if (Size == 1) {
+ if (Size == 1) {
// Create a CaseBlock record representing a conditional branch to
// the Case's target mbb if the value being switched on SV is equal
// to C. Otherwise, branch to default.
- Constant *C = CR.Range.first->first;
- MachineBasicBlock *Target = CR.Range.first->second;
+ Constant *C = FrontCase.first;
+ MachineBasicBlock *Target = FrontCase.second;
SelectionDAGISel::CaseBlock CB(ISD::SETEQ, SV, C, Target, Default,
CR.CaseBB);
-
+
// If the MBB representing the leaf node is the current MBB, then just
// call visitSwitchCase to emit the code into the current block.
// Otherwise, push the CaseBlock onto the vector to be later processed
@@ -1372,13 +1412,32 @@
else
SwitchCases.push_back(CB);
} else {
- // split case range at pivot
- CaseItr Pivot = CR.Range.first + (Size / 2);
+ uint64_t First = cast<ConstantInt>(FrontCase.first)->getSExtValue();
+ uint64_t Last = cast<ConstantInt>(BackCase.first)->getSExtValue();
+ double Density = 0;
+ CaseItr Pivot;
+
+ // Select optimal pivot, maximizing sum density of LHS and RHS. This will
+ // (heuristically) allow us to emit JumpTable's later.
+ unsigned LSize = 1;
+ unsigned RSize = Size-1;
+ for (CaseItr I = CR.Range.first, J=I+1, E = CR.Range.second;
+ J!=E; ++I, ++J, ++LSize, --RSize) {
+ uint64_t LEnd = cast<ConstantInt>(I->first)->getSExtValue();
+ uint64_t RBegin = cast<ConstantInt>(J->first)->getSExtValue();
+ double LDensity = (double)LSize / (double)((LEnd - First) + 1ULL);
+ double RDensity = (double)RSize / (double)((Last - RBegin) + 1ULL);
+ if (Density < (LDensity + RDensity)) {
+ Pivot = J;
+ Density = LDensity + RDensity;
+ }
+ }
+
CaseRange LHSR(CR.Range.first, Pivot);
CaseRange RHSR(Pivot, CR.Range.second);
Constant *C = Pivot->first;
MachineBasicBlock *FalseBB = 0, *TrueBB = 0;
-
+
// We know that we branch to the LHS if the Value being switched on is
// less than the Pivot value, C. We use this to optimize our binary
// tree a bit, by recognizing that if SV is greater than or equal to the
@@ -1393,9 +1452,9 @@
} else {
TrueBB = new MachineBasicBlock(LLVMBB);
CurMF->getBasicBlockList().insert(BBI, TrueBB);
- CaseVec.push_back(CaseRec(TrueBB, C, CR.GE, LHSR));
+ WorkList.push_back(CaseRec(TrueBB, C, CR.GE, LHSR));
}
-
+
// Similar to the optimization above, if the Value being switched on is
// known to be less than the Constant CR.LT, and the current Case Value
// is CR.LT - 1, then we can branch directly to the target block for
@@ -1407,7 +1466,7 @@
} else {
FalseBB = new MachineBasicBlock(LLVMBB);
CurMF->getBasicBlockList().insert(BBI, FalseBB);
- CaseVec.push_back(CaseRec(FalseBB,CR.LT,C,RHSR));
+ WorkList.push_back(CaseRec(FalseBB,CR.LT,C,RHSR));
}
// Create a CaseBlock record representing a conditional branch to
@@ -1424,6 +1483,7 @@
}
}
+
void SelectionDAGLowering::visitSub(User &I) {
// -0.0 - X --> fneg
const Type *Ty = I.getType();
@@ -4477,7 +4537,8 @@
// lowering, as well as any jump table information.
SwitchCases.clear();
SwitchCases = SDL.SwitchCases;
- JT = SDL.JT;
+ JTCases.clear();
+ JTCases = SDL.JTCases;
// Make sure the root of the DAG is up-to-date.
DAG.setRoot(SDL.getRoot());
@@ -4530,7 +4591,7 @@
// Next, now that we know what the last MBB the LLVM BB expanded is, update
// PHI nodes in successors.
- if (SwitchCases.empty() && JT.Reg == 0) {
+ if (SwitchCases.empty() && JTCases.empty()) {
for (unsigned i = 0, e = PHINodesToUpdate.size(); i != e; ++i) {
MachineInstr *PHI = PHINodesToUpdate[i].first;
assert(PHI->getOpcode() == TargetInstrInfo::PHI &&
@@ -4544,35 +4605,47 @@
// If the JumpTable record is filled in, then we need to emit a jump table.
// Updating the PHI nodes is tricky in this case, since we need to determine
// whether the PHI is a successor of the range check MBB or the jump table MBB
- if (JT.Reg) {
- assert(SwitchCases.empty() && "Cannot have jump table and lowered switch");
- SelectionDAG SDAG(TLI, MF, getAnalysisToUpdate<MachineModuleInfo>());
- CurDAG = &SDAG;
- SelectionDAGLowering SDL(SDAG, TLI, FuncInfo);
- MachineBasicBlock *RangeBB = BB;
+ for (unsigned i = 0, e = JTCases.size(); i != e; ++i) {
+ // Lower header first, if it wasn't already lowered
+ if (!JTCases[i].first.Emitted) {
+ SelectionDAG HSDAG(TLI, MF, getAnalysisToUpdate<MachineModuleInfo>());
+ CurDAG = &HSDAG;
+ SelectionDAGLowering HSDL(HSDAG, TLI, FuncInfo);
+ // Set the current basic block to the mbb we wish to insert the code into
+ BB = JTCases[i].first.HeaderBB;
+ HSDL.setCurrentBasicBlock(BB);
+ // Emit the code
+ HSDL.visitJumpTableHeader(JTCases[i].second, JTCases[i].first);
+ HSDAG.setRoot(HSDL.getRoot());
+ CodeGenAndEmitDAG(HSDAG);
+ }
+
+ SelectionDAG JSDAG(TLI, MF, getAnalysisToUpdate<MachineModuleInfo>());
+ CurDAG = &JSDAG;
+ SelectionDAGLowering JSDL(JSDAG, TLI, FuncInfo);
// Set the current basic block to the mbb we wish to insert the code into
- BB = JT.MBB;
- SDL.setCurrentBasicBlock(BB);
+ BB = JTCases[i].second.MBB;
+ JSDL.setCurrentBasicBlock(BB);
// Emit the code
- SDL.visitJumpTable(JT);
- SDAG.setRoot(SDL.getRoot());
- CodeGenAndEmitDAG(SDAG);
+ JSDL.visitJumpTable(JTCases[i].second);
+ JSDAG.setRoot(JSDL.getRoot());
+ CodeGenAndEmitDAG(JSDAG);
+
// Update PHI Nodes
for (unsigned pi = 0, pe = PHINodesToUpdate.size(); pi != pe; ++pi) {
MachineInstr *PHI = PHINodesToUpdate[pi].first;
MachineBasicBlock *PHIBB = PHI->getParent();
assert(PHI->getOpcode() == TargetInstrInfo::PHI &&
"This is not a machine PHI node that we are updating!");
- if (PHIBB == JT.Default) {
+ if (PHIBB == JTCases[i].second.Default) {
PHI->addRegOperand(PHINodesToUpdate[pi].second, false);
- PHI->addMachineBasicBlockOperand(RangeBB);
+ PHI->addMachineBasicBlockOperand(JTCases[i].first.HeaderBB);
}
if (BB->succ_end() != std::find(BB->succ_begin(),BB->succ_end(), PHIBB)) {
PHI->addRegOperand(PHINodesToUpdate[pi].second, false);
PHI->addMachineBasicBlockOperand(BB);
}
}
- return;
}
// If the switch block involved a branch to one of the actual successors, we
More information about the llvm-commits
mailing list