From 9de1934099f4eedaeb2f3a023411b2cd3e0e1eae Mon Sep 17 00:00:00 2001 From: Anton Korobeynikov Date: Wed, 14 Nov 2007 09:18:41 +0000 Subject: [PATCH] Fix PIC jump table codegen on x86-32/linux. In fact, such thing should be applied to all targets uses GOT-relative offsets for PIC (Alpha?) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44108 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/AsmPrinter.h | 5 ++- lib/CodeGen/AsmPrinter.cpp | 69 +++++++++++++++++------------ lib/Target/X86/X86ATTAsmPrinter.cpp | 29 +++++++++++- lib/Target/X86/X86ATTAsmPrinter.h | 6 +++ test/CodeGen/X86/test-pic-jtbl.ll | 4 +- 5 files changed, 81 insertions(+), 32 deletions(-) diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h index 937e9ed0f0d..ceff9b5bd7c 100644 --- a/include/llvm/CodeGen/AsmPrinter.h +++ b/include/llvm/CodeGen/AsmPrinter.h @@ -311,7 +311,10 @@ namespace llvm { const MachineBasicBlock *MBB) const; virtual void printPICJumpTableSetLabel(unsigned uid, unsigned uid2, const MachineBasicBlock *MBB) const; - + virtual void printPICJumpTableEntry(const MachineJumpTableInfo *MJTI, + const MachineBasicBlock *MBB, + unsigned uid) const; + /// printDataDirective - This method prints the asm directive for the /// specified type. void printDataDirective(const Type *type); diff --git a/lib/CodeGen/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter.cpp index ed51e10d220..ce89337f36f 100644 --- a/lib/CodeGen/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter.cpp @@ -245,17 +245,9 @@ void AsmPrinter::EmitJumpTableInfo(MachineJumpTableInfo *MJTI, MachineFunction &MF) { const std::vector &JT = MJTI->getJumpTables(); if (JT.empty()) return; + bool IsPic = TM.getRelocationModel() == Reloc::PIC_; - // Use JumpTableDirective otherwise honor the entry size from the jump table - // info. - const char *JTEntryDirective = TAI->getJumpTableDirective(); - bool HadJTEntryDirective = JTEntryDirective != NULL; - if (!HadJTEntryDirective) { - JTEntryDirective = MJTI->getEntrySize() == 4 ? - TAI->getData32bitsDirective() : TAI->getData64bitsDirective(); - } - // Pick the directive to use to print the jump table entries, and switch to // the appropriate section. TargetLowering *LoweringInfo = TM.getTargetLowering(); @@ -300,30 +292,51 @@ void AsmPrinter::EmitJumpTableInfo(MachineJumpTableInfo *MJTI, << '_' << i << ":\n"; for (unsigned ii = 0, ee = JTBBs.size(); ii != ee; ++ii) { - O << JTEntryDirective << ' '; - // If we have emitted set directives for the jump table entries, print - // them rather than the entries themselves. If we're emitting PIC, then - // emit the table entries as differences between two text section labels. - // If we're emitting non-PIC code, then emit the entries as direct - // references to the target basic blocks. - if (!EmittedSets.empty()) { - O << TAI->getPrivateGlobalPrefix() << getFunctionNumber() - << '_' << i << "_set_" << JTBBs[ii]->getNumber(); - } else if (IsPic) { - printBasicBlockLabel(JTBBs[ii], false, false); - // If the arch uses custom Jump Table directives, don't calc relative to - // JT - if (!HadJTEntryDirective) - O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" - << getFunctionNumber() << '_' << i; - } else { - printBasicBlockLabel(JTBBs[ii], false, false); - } + printPICJumpTableEntry(MJTI, JTBBs[ii], i); O << '\n'; } } } +void AsmPrinter::printPICJumpTableEntry(const MachineJumpTableInfo *MJTI, + const MachineBasicBlock *MBB, + unsigned uid) const { + bool IsPic = TM.getRelocationModel() == Reloc::PIC_; + + // Use JumpTableDirective otherwise honor the entry size from the jump table + // info. + const char *JTEntryDirective = TAI->getJumpTableDirective(); + bool HadJTEntryDirective = JTEntryDirective != NULL; + if (!HadJTEntryDirective) { + JTEntryDirective = MJTI->getEntrySize() == 4 ? + TAI->getData32bitsDirective() : TAI->getData64bitsDirective(); + } + + O << JTEntryDirective << ' '; + + // If we have emitted set directives for the jump table entries, print + // them rather than the entries themselves. If we're emitting PIC, then + // emit the table entries as differences between two text section labels. + // If we're emitting non-PIC code, then emit the entries as direct + // references to the target basic blocks. + if (IsPic) { + if (TAI->getSetDirective()) { + O << TAI->getPrivateGlobalPrefix() << getFunctionNumber() + << '_' << uid << "_set_" << MBB->getNumber(); + } else { + printBasicBlockLabel(MBB, false, false); + // If the arch uses custom Jump Table directives, don't calc relative to + // JT + if (!HadJTEntryDirective) + O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" + << getFunctionNumber() << '_' << uid; + } + } else { + printBasicBlockLabel(MBB, false, false); + } +} + + /// EmitSpecialLLVMGlobal - Check to see if the specified global is a /// special global used by LLVM. If so, emit it and return true, otherwise /// do nothing and return false. diff --git a/lib/Target/X86/X86ATTAsmPrinter.cpp b/lib/Target/X86/X86ATTAsmPrinter.cpp index f46ebb840c2..44040977fed 100644 --- a/lib/Target/X86/X86ATTAsmPrinter.cpp +++ b/lib/Target/X86/X86ATTAsmPrinter.cpp @@ -22,6 +22,7 @@ #include "X86TargetAsmInfo.h" #include "llvm/ADT/StringExtras.h" #include "llvm/CallingConv.h" +#include "llvm/CodeGen/MachineJumpTableInfo.h" #include "llvm/Module.h" #include "llvm/Support/Mangler.h" #include "llvm/Target/TargetAsmInfo.h" @@ -502,7 +503,11 @@ void X86ATTAsmPrinter::printPICJumpTableSetLabel(unsigned uid, const MachineBasicBlock *MBB) const { if (!TAI->getSetDirective()) return; - + + // We don't need .set machinery if we have GOT-style relocations + if (Subtarget->isPICStyleGOT()) + return; + O << TAI->getSetDirective() << ' ' << TAI->getPrivateGlobalPrefix() << getFunctionNumber() << '_' << uid << "_set_" << MBB->getNumber() << ','; printBasicBlockLabel(MBB, false, false); @@ -519,6 +524,28 @@ void X86ATTAsmPrinter::printPICLabel(const MachineInstr *MI, unsigned Op) { } +void X86ATTAsmPrinter::printPICJumpTableEntry(const MachineJumpTableInfo *MJTI, + const MachineBasicBlock *MBB, + unsigned uid) const +{ + const char *JTEntryDirective = MJTI->getEntrySize() == 4 ? + TAI->getData32bitsDirective() : TAI->getData64bitsDirective(); + + O << JTEntryDirective << ' '; + + if (TM.getRelocationModel() == Reloc::PIC_) { + if (Subtarget->isPICStyleRIPRel() || Subtarget->isPICStyleStub()) { + O << TAI->getPrivateGlobalPrefix() << getFunctionNumber() + << '_' << uid << "_set_" << MBB->getNumber(); + } else if (Subtarget->isPICStyleGOT()) { + printBasicBlockLabel(MBB, false, false); + O << "@GOTOFF"; + } else + assert(0 && "Don't know how to print MBB label for this PIC mode"); + } else + printBasicBlockLabel(MBB, false, false); +} + bool X86ATTAsmPrinter::printAsmMRegister(const MachineOperand &MO, const char Mode) { const MRegisterInfo &RI = *TM.getRegisterInfo(); diff --git a/lib/Target/X86/X86ATTAsmPrinter.h b/lib/Target/X86/X86ATTAsmPrinter.h index d1e036edd63..225a71389f7 100644 --- a/lib/Target/X86/X86ATTAsmPrinter.h +++ b/lib/Target/X86/X86ATTAsmPrinter.h @@ -19,6 +19,8 @@ namespace llvm { +struct MachineJumpTableInfo; + struct VISIBILITY_HIDDEN X86ATTAsmPrinter : public X86SharedAsmPrinter { X86ATTAsmPrinter(std::ostream &O, X86TargetMachine &TM, const TargetAsmInfo *T) : X86SharedAsmPrinter(O, TM, T) { } @@ -83,6 +85,10 @@ struct VISIBILITY_HIDDEN X86ATTAsmPrinter : public X86SharedAsmPrinter { const MachineBasicBlock *MBB) const { AsmPrinter::printPICJumpTableSetLabel(uid, uid2, MBB); } + void printPICJumpTableEntry(const MachineJumpTableInfo *MJTI, + const MachineBasicBlock *MBB, + unsigned uid) const; + void printPICLabel(const MachineInstr *MI, unsigned Op); bool runOnMachineFunction(MachineFunction &F); diff --git a/test/CodeGen/X86/test-pic-jtbl.ll b/test/CodeGen/X86/test-pic-jtbl.ll index 516a20bfb5c..e23f7c1a9fc 100644 --- a/test/CodeGen/X86/test-pic-jtbl.ll +++ b/test/CodeGen/X86/test-pic-jtbl.ll @@ -1,9 +1,9 @@ ; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux-gnu -relocation-model=pic \ ; RUN: -o %t -f ; RUN: grep _GLOBAL_OFFSET_TABLE_ %t -; RUN: grep piclabel %t | count 9 +; RUN: grep piclabel %t | count 3 ; RUN: grep PLT %t | count 6 -; RUN: grep GOTOFF %t | count 1 +; RUN: grep GOTOFF %t | count 14 ; RUN: grep JTI %t | count 2 define void @bar(i32 %n.u) { -- 2.34.1