Lower jumptable to BR_JT. The legalizer can lower it to a BRIND or let the target custom lower it.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@31293 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng 2006-10-30 08:00:44 +00:00
parent c41cd9c391
commit 3d4ce11085
2 changed files with 55 additions and 28 deletions

View File

@ -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.

View File

@ -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<ConstantIntegral>(Cases.front().first)->getZExtValue();
uint64_t Last = cast<ConstantIntegral>(Cases.back().first)->getZExtValue();