diff options
author | Evan Cheng <evan.cheng@apple.com> | 2007-11-09 01:32:10 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2007-11-09 01:32:10 +0000 |
commit | 6fb0676d69697f38712be6843073618583d3a3f8 (patch) | |
tree | efeac53c6dd2e713a156d7a62ccc9fc748890d7e | |
parent | d5d2f0295f4abd084348d8a047836ef65433406a (diff) | |
download | external_llvm-6fb0676d69697f38712be6843073618583d3a3f8.zip external_llvm-6fb0676d69697f38712be6843073618583d3a3f8.tar.gz external_llvm-6fb0676d69697f38712be6843073618583d3a3f8.tar.bz2 |
Much improved pic jumptable codegen:
Then:
call "L1$pb"
"L1$pb":
popl %eax
...
LBB1_1: # entry
imull $4, %ecx, %ecx
leal LJTI1_0-"L1$pb"(%eax), %edx
addl LJTI1_0-"L1$pb"(%ecx,%eax), %edx
jmpl *%edx
.align 2
.set L1_0_set_3,LBB1_3-LJTI1_0
.set L1_0_set_2,LBB1_2-LJTI1_0
.set L1_0_set_5,LBB1_5-LJTI1_0
.set L1_0_set_4,LBB1_4-LJTI1_0
LJTI1_0:
.long L1_0_set_3
.long L1_0_set_2
Now:
call "L1$pb"
"L1$pb":
popl %eax
...
LBB1_1: # entry
addl LJTI1_0-"L1$pb"(%eax,%ecx,4), %eax
jmpl *%eax
.align 2
.set L1_0_set_3,LBB1_3-"L1$pb"
.set L1_0_set_2,LBB1_2-"L1$pb"
.set L1_0_set_5,LBB1_5-"L1$pb"
.set L1_0_set_4,LBB1_4-"L1$pb"
LJTI1_0:
.long L1_0_set_3
.long L1_0_set_2
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@43924 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/llvm/CodeGen/AsmPrinter.h | 11 | ||||
-rw-r--r-- | include/llvm/Target/TargetLowering.h | 7 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter.cpp | 19 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 18 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/TargetLowering.cpp | 7 | ||||
-rw-r--r-- | lib/Target/ARM/ARMAsmPrinter.cpp | 2 | ||||
-rw-r--r-- | lib/Target/X86/X86ATTAsmPrinter.cpp | 11 | ||||
-rw-r--r-- | lib/Target/X86/X86ATTAsmPrinter.h | 6 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelLowering.cpp | 11 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelLowering.h | 5 | ||||
-rw-r--r-- | lib/Target/X86/X86IntelAsmPrinter.cpp | 11 | ||||
-rw-r--r-- | lib/Target/X86/X86IntelAsmPrinter.h | 6 |
12 files changed, 87 insertions, 27 deletions
diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h index 607aa70..937e9ed 100644 --- a/include/llvm/CodeGen/AsmPrinter.h +++ b/include/llvm/CodeGen/AsmPrinter.h @@ -305,11 +305,12 @@ namespace llvm { bool printColon = false, bool printComment = true) const; - /// printSetLabel - This method prints a set label for the specified - /// MachineBasicBlock - void printSetLabel(unsigned uid, const MachineBasicBlock *MBB) const; - void printSetLabel(unsigned uid, unsigned uid2, - const MachineBasicBlock *MBB) const; + /// printPICJumpTableSetLabel - This method prints a set label for the + /// specified MachineBasicBlock for a jumptable entry. + virtual void printPICJumpTableSetLabel(unsigned uid, + const MachineBasicBlock *MBB) const; + virtual void printPICJumpTableSetLabel(unsigned uid, unsigned uid2, + const MachineBasicBlock *MBB) const; /// printDataDirective - This method prints the asm directive for the /// specified type. diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 79af960..ee26579 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -93,7 +93,7 @@ public: /// usesGlobalOffsetTable - Return true if this target uses a GOT for PIC /// codegen. bool usesGlobalOffsetTable() const { return UsesGlobalOffsetTable; } - + /// isSelectExpensive - Return true if the select operation is expensive for /// this target. bool isSelectExpensive() const { return SelectIsExpensive; } @@ -543,6 +543,11 @@ public: return false; } + /// getPICJumpTableRelocaBase - Returns relocation base for the given PIC + /// jumptable. + virtual SDOperand getPICJumpTableRelocBase(SDOperand Table, + SelectionDAG &DAG) const; + //===--------------------------------------------------------------------===// // TargetLowering Optimization Methods // diff --git a/lib/CodeGen/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter.cpp index 3500d12..ed51e10 100644 --- a/lib/CodeGen/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter.cpp @@ -26,6 +26,7 @@ #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetLowering.h" #include "llvm/Target/TargetMachine.h" +#include "llvm/ADT/SmallPtrSet.h" #include <cerrno> using namespace llvm; @@ -282,11 +283,11 @@ void AsmPrinter::EmitJumpTableInfo(MachineJumpTableInfo *MJTI, // For PIC codegen, if possible we want to use the SetDirective to reduce // the number of relocations the assembler will generate for the jump table. // Set directives are all printed before the jump table itself. - std::set<MachineBasicBlock*> EmittedSets; + SmallPtrSet<MachineBasicBlock*, 16> EmittedSets; if (TAI->getSetDirective() && IsPic) for (unsigned ii = 0, ee = JTBBs.size(); ii != ee; ++ii) - if (EmittedSets.insert(JTBBs[ii]).second) - printSetLabel(i, JTBBs[ii]); + if (EmittedSets.insert(JTBBs[ii])) + printPICJumpTableSetLabel(i, JTBBs[ii]); // On some targets (e.g. darwin) we want to emit two consequtive labels // before each jump table. The first label is never referenced, but tells @@ -1256,10 +1257,10 @@ void AsmPrinter::printBasicBlockLabel(const MachineBasicBlock *MBB, << MBB->getBasicBlock()->getName(); } -/// printSetLabel - This method prints a set label for the specified -/// MachineBasicBlock -void AsmPrinter::printSetLabel(unsigned uid, - const MachineBasicBlock *MBB) const { +/// printPICJumpTableSetLabel - This method prints a set label for the +/// specified MachineBasicBlock for a jumptable entry. +void AsmPrinter::printPICJumpTableSetLabel(unsigned uid, + const MachineBasicBlock *MBB) const { if (!TAI->getSetDirective()) return; @@ -1270,8 +1271,8 @@ void AsmPrinter::printSetLabel(unsigned uid, << '_' << uid << '\n'; } -void AsmPrinter::printSetLabel(unsigned uid, unsigned uid2, - const MachineBasicBlock *MBB) const { +void AsmPrinter::printPICJumpTableSetLabel(unsigned uid, unsigned uid2, + const MachineBasicBlock *MBB) const { if (!TAI->getSetDirective()) return; diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 6e58631..0731299 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -1599,21 +1599,17 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { case 8: LD = DAG.getLoad(MVT::i64, Chain, Addr, NULL, 0); break; } + Addr = LD; if (TLI.getTargetMachine().getRelocationModel() == Reloc::PIC_) { // 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) : LD; - 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); + // RelocBase can be JumpTable, GOT or some sort of global base. + if (PTy != MVT::i32) + Addr = DAG.getNode(ISD::SIGN_EXTEND, PTy, Addr); + Addr = DAG.getNode(ISD::ADD, PTy, Addr, + TLI.getPICJumpTableRelocBase(Table, DAG)); } + Result = DAG.getNode(ISD::BRIND, MVT::Other, LD.getValue(1), Addr); } } break; diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 3708b1c..eadfa1f 100644 --- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -393,6 +393,13 @@ unsigned TargetLowering::getVectorTypeBreakdown(MVT::ValueType VT, return 1; } +SDOperand TargetLowering::getPICJumpTableRelocBase(SDOperand Table, + SelectionDAG &DAG) const { + if (usesGlobalOffsetTable()) + return DAG.getNode(ISD::GLOBAL_OFFSET_TABLE, getPointerTy()); + return Table; +} + //===----------------------------------------------------------------------===// // Optimization Methods //===----------------------------------------------------------------------===// diff --git a/lib/Target/ARM/ARMAsmPrinter.cpp b/lib/Target/ARM/ARMAsmPrinter.cpp index 5f46b07..76e9c5d 100644 --- a/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/lib/Target/ARM/ARMAsmPrinter.cpp @@ -693,7 +693,7 @@ void ARMAsmPrinter::printJTBlockOperand(const MachineInstr *MI, int OpNo) { for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) { MachineBasicBlock *MBB = JTBBs[i]; if (UseSet && JTSets.insert(MBB).second) - printSetLabel(JTI, MO2.getImmedValue(), MBB); + printPICJumpTableSetLabel(JTI, MO2.getImmedValue(), MBB); O << JTEntryDirective << ' '; if (UseSet) diff --git a/lib/Target/X86/X86ATTAsmPrinter.cpp b/lib/Target/X86/X86ATTAsmPrinter.cpp index d8046ed..0716211 100644 --- a/lib/Target/X86/X86ATTAsmPrinter.cpp +++ b/lib/Target/X86/X86ATTAsmPrinter.cpp @@ -498,6 +498,17 @@ void X86ATTAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op, } } +void X86ATTAsmPrinter::printPICJumpTableSetLabel(unsigned uid, + const MachineBasicBlock *MBB) const { + if (!TAI->getSetDirective()) + return; + + O << TAI->getSetDirective() << ' ' << TAI->getPrivateGlobalPrefix() + << getFunctionNumber() << '_' << uid << "_set_" << MBB->getNumber() << ','; + printBasicBlockLabel(MBB, false, false); + O << '-' << computePICLabel(getFunctionNumber(), TAI, Subtarget) << '\n'; +} + void X86ATTAsmPrinter::printPICLabel(const MachineInstr *MI, unsigned Op) { std::string label = computePICLabel(getFunctionNumber(), TAI, Subtarget); O << label << "\n" << label << ":"; diff --git a/lib/Target/X86/X86ATTAsmPrinter.h b/lib/Target/X86/X86ATTAsmPrinter.h index 4244cee..d1e036e 100644 --- a/lib/Target/X86/X86ATTAsmPrinter.h +++ b/lib/Target/X86/X86ATTAsmPrinter.h @@ -77,6 +77,12 @@ struct VISIBILITY_HIDDEN X86ATTAsmPrinter : public X86SharedAsmPrinter { void printSSECC(const MachineInstr *MI, unsigned Op); void printMemReference(const MachineInstr *MI, unsigned Op, const char *Modifier=NULL); + void printPICJumpTableSetLabel(unsigned uid, + const MachineBasicBlock *MBB) const; + void printPICJumpTableSetLabel(unsigned uid, unsigned uid2, + const MachineBasicBlock *MBB) const { + AsmPrinter::printPICJumpTableSetLabel(uid, uid2, MBB); + } void printPICLabel(const MachineInstr *MI, unsigned Op); bool runOnMachineFunction(MachineFunction &F); diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index e9df3f5..8c40b3c 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -650,6 +650,17 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM) } +/// getPICJumpTableRelocaBase - Returns relocation base for the given PIC +/// jumptable. +SDOperand X86TargetLowering::getPICJumpTableRelocBase(SDOperand Table, + SelectionDAG &DAG) const { + if (usesGlobalOffsetTable()) + return DAG.getNode(ISD::GLOBAL_OFFSET_TABLE, getPointerTy()); + if (!Subtarget->isPICStyleRIPRel()) + return DAG.getNode(X86ISD::GlobalBaseReg, getPointerTy()); + return Table; +} + //===----------------------------------------------------------------------===// // Return Value Calling Convention Implementation //===----------------------------------------------------------------------===// diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h index 4f422a9..2921f7b 100644 --- a/lib/Target/X86/X86ISelLowering.h +++ b/lib/Target/X86/X86ISelLowering.h @@ -296,6 +296,11 @@ namespace llvm { public: explicit X86TargetLowering(TargetMachine &TM); + /// getPICJumpTableRelocaBase - Returns relocation base for the given PIC + /// jumptable. + SDOperand getPICJumpTableRelocBase(SDOperand Table, + SelectionDAG &DAG) const; + // Return the number of bytes that a function should pop when it returns (in // addition to the space used by the return address). // diff --git a/lib/Target/X86/X86IntelAsmPrinter.cpp b/lib/Target/X86/X86IntelAsmPrinter.cpp index bd8886c..3ddc5cc 100644 --- a/lib/Target/X86/X86IntelAsmPrinter.cpp +++ b/lib/Target/X86/X86IntelAsmPrinter.cpp @@ -235,6 +235,17 @@ void X86IntelAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op, O << "]"; } +void X86IntelAsmPrinter::printPICJumpTableSetLabel(unsigned uid, + const MachineBasicBlock *MBB) const { + if (!TAI->getSetDirective()) + return; + + O << TAI->getSetDirective() << ' ' << TAI->getPrivateGlobalPrefix() + << getFunctionNumber() << '_' << uid << "_set_" << MBB->getNumber() << ','; + printBasicBlockLabel(MBB, false, false); + O << '-' << "\"L" << getFunctionNumber() << "$pb\"'\n"; +} + void X86IntelAsmPrinter::printPICLabel(const MachineInstr *MI, unsigned Op) { O << "\"L" << getFunctionNumber() << "$pb\"\n"; O << "\"L" << getFunctionNumber() << "$pb\":"; diff --git a/lib/Target/X86/X86IntelAsmPrinter.h b/lib/Target/X86/X86IntelAsmPrinter.h index 903803d..e3a37aa 100644 --- a/lib/Target/X86/X86IntelAsmPrinter.h +++ b/lib/Target/X86/X86IntelAsmPrinter.h @@ -99,6 +99,12 @@ struct VISIBILITY_HIDDEN X86IntelAsmPrinter : public X86SharedAsmPrinter { void printSSECC(const MachineInstr *MI, unsigned Op); void printMemReference(const MachineInstr *MI, unsigned Op, const char *Modifier=NULL); + void printPICJumpTableSetLabel(unsigned uid, + const MachineBasicBlock *MBB) const; + void printPICJumpTableSetLabel(unsigned uid, unsigned uid2, + const MachineBasicBlock *MBB) const { + AsmPrinter::printPICJumpTableSetLabel(uid, uid2, MBB); + } void printPICLabel(const MachineInstr *MI, unsigned Op); bool runOnMachineFunction(MachineFunction &F); bool doInitialization(Module &M); |