[llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
Chris Lattner
sabre at nondot.org
Sun Oct 22 14:37:08 PDT 2006
Changes in directory llvm/lib/CodeGen/SelectionDAG:
SelectionDAGISel.cpp updated: 1.291 -> 1.292
---
Log message:
Implement PR964: http://llvm.org/PR964 and Regression/CodeGen/Generic/SwitchLowering.ll
---
Diffs of the changes: (+44 -5)
SelectionDAGISel.cpp | 49 ++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 44 insertions(+), 5 deletions(-)
Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.291 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.292
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.291 Fri Oct 20 02:07:24 2006
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Sun Oct 22 16:36:53 2006
@@ -889,18 +889,19 @@
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
// next basic block. Otherwise, just fall through.
if (I.getNumOperands() == 2) {
// Update machine-CFG edges.
- MachineBasicBlock *DefaultMBB = FuncInfo.MBBMap[I.getDefaultDest()];
// If this is not a fall-through branch, emit the branch.
- if (DefaultMBB != NextBlock)
+ if (Default != NextBlock)
DAG.setRoot(DAG.getNode(ISD::BR, MVT::Other, getRoot(),
- DAG.getBasicBlock(DefaultMBB)));
+ DAG.getBasicBlock(Default)));
- CurMBB->addSuccessor(DefaultMBB);
+ CurMBB->addSuccessor(Default);
return;
}
@@ -920,13 +921,51 @@
// inserted into CaseBlock records, representing basic blocks in the binary
// search tree.
Value *SV = I.getOperand(0);
- MachineBasicBlock *Default = FuncInfo.MBBMap[I.getDefaultDest()];
// 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)"
+
+ // 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;
+ }
+
+ SelectionDAGISel::CaseBlock CB(ISD::SETEQ, SV, Cases[i].first,
+ Cases[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);
+
+ 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
More information about the llvm-commits
mailing list