From 972f4697226098a80872c6456d102b592325ca44 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Mon, 30 Oct 2006 08:00:44 +0000 Subject: [PATCH] Lower jumptable to BR_JT. The legalizer can lower it to a BRIND or let the target custom lower it. llvm-svn: 31293 --- lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 48 +++++++++++++++++++ lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 35 +++----------- 2 files changed, 55 insertions(+), 28 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 125e46c0cad..bb4280b5c80 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -16,6 +16,7 @@ #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/Target/TargetLowering.h" #include "llvm/Target/TargetData.h" +#include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" #include "llvm/CallingConv.h" #include "llvm/Constants.h" @@ -1240,6 +1241,53 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { } Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2); break; + case ISD::BR_JT: + Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. + // Ensure that libcalls are emitted before a branch. + Tmp1 = DAG.getNode(ISD::TokenFactor, MVT::Other, Tmp1, LastCALLSEQ_END); + Tmp1 = LegalizeOp(Tmp1); + LastCALLSEQ_END = DAG.getEntryNode(); + + Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the jumptable node. + Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Node->getOperand(2)); + + switch (TLI.getOperationAction(ISD::BR_JT, MVT::Other)) { + default: assert(0 && "This action is not supported yet!"); + case TargetLowering::Legal: break; + case TargetLowering::Custom: + Tmp1 = TLI.LowerOperation(Result, DAG); + if (Tmp1.Val) Result = Tmp1; + break; + case TargetLowering::Expand: { + SDOperand Chain = Result.getOperand(0); + SDOperand Table = Result.getOperand(1); + SDOperand Index = Result.getOperand(2); + + MVT::ValueType PTy = TLI.getPointerTy(); + bool isPIC = TLI.getTargetMachine().getRelocationModel() == Reloc::PIC_; + // PIC jump table entries are 32-bit values. + unsigned EntrySize = isPIC ? 4 : MVT::getSizeInBits(PTy)/8; + Index= DAG.getNode(ISD::MUL, PTy, Index, DAG.getConstant(EntrySize, PTy)); + SDOperand Addr = DAG.getNode(ISD::ADD, PTy, Index, Table); + SDOperand LD = DAG.getLoad(isPIC ? MVT::i32 : PTy, Chain, Addr, NULL, 0); + if (isPIC) { + // For PIC, the sequence is: + // BRIND(load(Jumptable + index) + RelocBase) + // RelocBase is the JumpTable on PPC and X86, GOT on Alpha + SDOperand Reloc; + if (TLI.usesGlobalOffsetTable()) + Reloc = DAG.getNode(ISD::GLOBAL_OFFSET_TABLE, PTy); + else + Reloc = Table; + Addr= (PTy != MVT::i32) ? DAG.getNode(ISD::SIGN_EXTEND, PTy, LD) : Addr; + Addr = DAG.getNode(ISD::ADD, PTy, Addr, Reloc); + Result = DAG.getNode(ISD::BRIND, MVT::Other, LD.getValue(1), Addr); + } else { + Result = DAG.getNode(ISD::BRIND, MVT::Other, LD.getValue(1), LD); + } + } + } + break; case ISD::BRCOND: Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. // Ensure that libcalls are emitted before a return. diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 9794af17719..6a2a8e79c1b 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -1070,33 +1070,11 @@ void SelectionDAGLowering::visitSwitchCase(SelectionDAGISel::CaseBlock &CB) { void SelectionDAGLowering::visitJumpTable(SelectionDAGISel::JumpTable &JT) { // Emit the code for the jump table MVT::ValueType PTy = TLI.getPointerTy(); - assert((PTy == MVT::i32 || PTy == MVT::i64) && - "Jump table entries are 32-bit values"); - bool isPIC = TLI.getTargetMachine().getRelocationModel() == Reloc::PIC_; - // PIC jump table entries are 32-bit values. - unsigned EntrySize = isPIC ? 4 : MVT::getSizeInBits(PTy)/8; - SDOperand Copy = DAG.getCopyFromReg(getRoot(), JT.Reg, PTy); - SDOperand IDX = DAG.getNode(ISD::MUL, PTy, Copy, - DAG.getConstant(EntrySize, PTy)); - SDOperand TAB = DAG.getJumpTable(JT.JTI,PTy); - SDOperand ADD = DAG.getNode(ISD::ADD, PTy, IDX, TAB); - SDOperand LD = DAG.getLoad(isPIC ? MVT::i32 : PTy, Copy.getValue(1), ADD, - NULL, 0); - if (isPIC) { - // For Pic, the sequence is: - // BRIND(load(Jumptable + index) + RelocBase) - // RelocBase is the JumpTable on PPC and X86, GOT on Alpha - SDOperand Reloc; - if (TLI.usesGlobalOffsetTable()) - Reloc = DAG.getNode(ISD::GLOBAL_OFFSET_TABLE, PTy); - else - Reloc = TAB; - ADD = (PTy != MVT::i32) ? DAG.getNode(ISD::SIGN_EXTEND, PTy, LD) : LD; - ADD = DAG.getNode(ISD::ADD, PTy, ADD, Reloc); - DAG.setRoot(DAG.getNode(ISD::BRIND, MVT::Other, LD.getValue(1), ADD)); - } else { - DAG.setRoot(DAG.getNode(ISD::BRIND, MVT::Other, LD.getValue(1), LD)); - } + SDOperand Index = DAG.getCopyFromReg(getRoot(), JT.Reg, PTy); + SDOperand Table = DAG.getJumpTable(JT.JTI, PTy); + DAG.setRoot(DAG.getNode(ISD::BR_JT, MVT::Other, Index.getValue(1), + Table, Index)); + return; } void SelectionDAGLowering::visitSwitch(SwitchInst &I) { @@ -1200,7 +1178,8 @@ void SelectionDAGLowering::visitSwitch(SwitchInst &I) { // 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::BRIND, TLI.getPointerTy()) && + if ((TLI.isOperationLegal(ISD::BR_JT, MVT::Other) || + TLI.isOperationLegal(ISD::BRIND, MVT::Other)) && Cases.size() > 5) { uint64_t First =cast(Cases.front().first)->getZExtValue(); uint64_t Last = cast(Cases.back().first)->getZExtValue();