+ Reloc::Model Relocs = TLI.getTargetMachine().getRelocationModel();
+
+ // If the switch has more than 3 blocks, and is 100% dense, then emit a jump
+ // table rather than lowering the switch to a binary tree of conditional
+ // branches.
+ // FIXME: Make this work with 64 bit targets someday, possibly by always
+ // doing differences there so that entries stay 32 bits.
+ // FIXME: Make this work with PIC code
+ if (TLI.isOperationLegal(ISD::BRIND, TLI.getPointerTy()) &&
+ TLI.getPointerTy() == MVT::i32 &&
+ (Relocs == Reloc::Static || Relocs == Reloc::DynamicNoPIC) &&
+ Cases.size() > 3) {
+ uint64_t First = cast<ConstantIntegral>(Cases.front().first)->getRawValue();
+ uint64_t Last = cast<ConstantIntegral>(Cases.back().first)->getRawValue();
+
+ // Determine density
+ // FIXME: support sub-100% density
+ if (((Last - First) + 1ULL) == (uint64_t)Cases.size()) {
+ // 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);
+ 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)));
+
+ // Build a sorted vector of destination BBs, corresponding to each target
+ // of the switch.
+ // FIXME: need to insert DefaultMBB for each "hole" in the jump table,
+ // when we support jump tables with < 100% density.
+ std::set<MachineBasicBlock*> UniqueBBs;
+ std::vector<MachineBasicBlock*> DestBBs;
+ for (CaseItr ii = Cases.begin(), ee = Cases.end(); ii != ee; ++ii) {
+ DestBBs.push_back(ii->second);
+ UniqueBBs.insert(ii->second);
+ }
+ 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.SuccMBBs = UniqueBBs;
+ return;
+ }
+ }