From 2f1ae88445c696a9b9d61e14747ba721190cdc99 Mon Sep 17 00:00:00 2001 From: Nate Begeman Date: Thu, 27 Jul 2006 01:13:04 +0000 Subject: [PATCH] Support jump tables when in PIC relocation model git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29318 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/AsmPrinter.h | 12 +++++-- lib/CodeGen/AsmPrinter.cpp | 34 ++++++++++--------- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 14 +++++--- lib/Target/PowerPC/PPCAsmPrinter.cpp | 4 +-- lib/Target/X86/X86ATTAsmPrinter.cpp | 4 ++- lib/Target/X86/X86AsmPrinter.cpp | 2 +- 6 files changed, 43 insertions(+), 27 deletions(-) diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h index c90a3eedaef..802fe6db445 100644 --- a/include/llvm/CodeGen/AsmPrinter.h +++ b/include/llvm/CodeGen/AsmPrinter.h @@ -156,9 +156,15 @@ namespace llvm { /// before emitting the constant pool for a function. const char *ConstantPoolSection; // Defaults to "\t.section .rodata\n" - /// JumpTableSection - This is the section that we SwitchToSection right - /// before emitting the jump tables for a function. - const char *JumpTableSection; // Defaults to "\t.section .rodata\n" + /// JumpTableDataSection - This is the section that we SwitchToSection right + /// before emitting the jump tables for a function when the relocation model + /// is not PIC. + const char *JumpTableDataSection; // Defaults to "\t.section .rodata\n" + + /// JumpTableTextSection - This is the section that we SwitchToSection right + /// before emitting the jump tables for a function when the relocation model + /// is PIC. + const char *JumpTableTextSection; // Defaults to "\t.text\n" /// StaticCtorsSection - This is the directive that is emitted to switch to /// a section to emit the static constructor list. diff --git a/lib/CodeGen/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter.cpp index 6e5dab7851f..a0f377c63fc 100644 --- a/lib/CodeGen/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter.cpp @@ -52,7 +52,8 @@ AsmPrinter::AsmPrinter(std::ostream &o, TargetMachine &tm) DataSectionStartSuffix(""), SectionEndDirectiveSuffix(0), ConstantPoolSection("\t.section .rodata\n"), - JumpTableSection("\t.section .rodata\n"), + JumpTableDataSection("\t.section .rodata\n"), + JumpTableTextSection("\t.text\n"), StaticCtorsSection("\t.section .ctors,\"aw\",@progbits"), StaticDtorsSection("\t.section .dtors,\"aw\",@progbits"), FourByteConstantSection(0), @@ -89,7 +90,7 @@ void AsmPrinter::SwitchToTextSection(const char *NewSection, O << CurrentSection << TextSectionStartSuffix << '\n'; } -/// SwitchToTextSection - Switch to the specified text section of the executable +/// SwitchToDataSection - Switch to the specified data section of the executable /// if we are not already in it! /// void AsmPrinter::SwitchToDataSection(const char *NewSection, @@ -209,29 +210,30 @@ void AsmPrinter::EmitJumpTableInfo(MachineJumpTableInfo *MJTI) { const std::vector &JT = MJTI->getJumpTables(); if (JT.empty()) return; const TargetData *TD = TM.getTargetData(); + const char *PtrDataDirective = Data32bitsDirective; - // FIXME: someday we need to handle PIC jump tables - assert((TM.getRelocationModel() == Reloc::Static || - TM.getRelocationModel() == Reloc::DynamicNoPIC) && - "Unhandled relocation model emitting jump table information!"); - - SwitchToDataSection(JumpTableSection, 0); + // Pick the directive to use to print the jump table entries, and switch to + // the appropriate section. + if (TM.getRelocationModel() == Reloc::PIC_) { + SwitchToTextSection(JumpTableTextSection, 0); + } else { + SwitchToDataSection(JumpTableDataSection, 0); + if (TD->getPointerSize() == 8) + PtrDataDirective = Data64bitsDirective; + } EmitAlignment(Log2_32(TD->getPointerAlignment())); - // Pick the directive to use based on the pointer size. FIXME: when we support - // PIC jumptables, this should always use the 32-bit directive for label - // differences. - const char *PtrDataDirective = Data32bitsDirective; - if (TD->getPointerSize() == 8) - PtrDataDirective = Data64bitsDirective; - for (unsigned i = 0, e = JT.size(); i != e; ++i) { O << PrivateGlobalPrefix << "JTI" << getFunctionNumber() << '_' << i << ":\n"; const std::vector &JTBBs = JT[i].MBBs; for (unsigned ii = 0, ee = JTBBs.size(); ii != ee; ++ii) { O << PtrDataDirective << ' '; - printBasicBlockLabel(JTBBs[ii]); + printBasicBlockLabel(JTBBs[ii], false, false); + if (TM.getRelocationModel() == Reloc::PIC_) { + O << '-' << PrivateGlobalPrefix << "JTI" << getFunctionNumber() + << '_' << i; + } O << '\n'; } } diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index e8e7a4701fd..76510f36c4b 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -850,9 +850,15 @@ void SelectionDAGLowering::visitJumpTable(SelectionDAGISel::JumpTable &JT) { SDOperand Copy = DAG.getCopyFromReg(getRoot(), JT.Reg, PTy); SDOperand IDX = DAG.getNode(ISD::MUL, PTy, Copy, DAG.getConstant(PTyBytes, PTy)); - SDOperand ADD = DAG.getNode(ISD::ADD, PTy, IDX, DAG.getJumpTable(JT.JTI,PTy)); + SDOperand TAB = DAG.getJumpTable(JT.JTI,PTy); + SDOperand ADD = DAG.getNode(ISD::ADD, PTy, IDX, TAB); SDOperand LD = DAG.getLoad(PTy, Copy.getValue(1), ADD, DAG.getSrcValue(0)); - DAG.setRoot(DAG.getNode(ISD::BRIND, MVT::Other, LD.getValue(1), LD)); + if (TLI.getTargetMachine().getRelocationModel() == Reloc::PIC_) { + ADD = DAG.getNode(ISD::ADD, PTy, LD.getValue(0), TAB); + 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)); + } } void SelectionDAGLowering::visitSwitch(SwitchInst &I) { @@ -896,20 +902,20 @@ void SelectionDAGLowering::visitSwitch(SwitchInst &I) { // to represent the switch. MachineFunction *CurMF = CurMBB->getParent(); const BasicBlock *LLVMBB = CurMBB->getBasicBlock(); - Reloc::Model Relocs = TLI.getTargetMachine().getRelocationModel(); // 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. // FIXME: Make this work with PIC code if (TLI.isOperationLegal(ISD::BRIND, TLI.getPointerTy()) && - (Relocs == Reloc::Static || Relocs == Reloc::DynamicNoPIC) && Cases.size() > 5) { uint64_t First = cast(Cases.front().first)->getRawValue(); uint64_t Last = cast(Cases.back().first)->getRawValue(); double Density = (double)Cases.size() / (double)((Last - First) + 1ULL); if (Density >= 0.3125) { + Reloc::Model Relocs = TLI.getTargetMachine().getRelocationModel(); + // 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 diff --git a/lib/Target/PowerPC/PPCAsmPrinter.cpp b/lib/Target/PowerPC/PPCAsmPrinter.cpp index 6e75f3ceb7f..bf9c608d515 100644 --- a/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ b/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -282,8 +282,8 @@ namespace { Data64bitsDirective = 0; // we can't emit a 64-bit unit AlignmentIsInBytes = false; // Alignment is by power of 2. ConstantPoolSection = "\t.const\t"; - // FIXME: Conditionalize jump table section based on PIC - JumpTableSection = ".const"; + JumpTableDataSection = ".const"; + JumpTableTextSection = "\t.text"; LCOMMDirective = "\t.lcomm\t"; StaticCtorsSection = ".mod_init_func"; StaticDtorsSection = ".mod_term_func"; diff --git a/lib/Target/X86/X86ATTAsmPrinter.cpp b/lib/Target/X86/X86ATTAsmPrinter.cpp index 769aa73b417..712f34a3cbe 100755 --- a/lib/Target/X86/X86ATTAsmPrinter.cpp +++ b/lib/Target/X86/X86ATTAsmPrinter.cpp @@ -143,7 +143,9 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, if (!isMemOp) O << '$'; O << PrivateGlobalPrefix << "JTI" << getFunctionNumber() << "_" << MO.getJumpTableIndex(); - // FIXME: PIC relocation model + if (Subtarget->TargetType == X86Subtarget::isDarwin && + TM.getRelocationModel() == Reloc::PIC_) + O << "-\"L" << getFunctionNumber() << "$pb\""; return; } case MachineOperand::MO_ConstantPoolIndex: { diff --git a/lib/Target/X86/X86AsmPrinter.cpp b/lib/Target/X86/X86AsmPrinter.cpp index 069b04751a8..2c4b1107b00 100644 --- a/lib/Target/X86/X86AsmPrinter.cpp +++ b/lib/Target/X86/X86AsmPrinter.cpp @@ -62,7 +62,7 @@ bool X86SharedAsmPrinter::doInitialization(Module &M) { ZeroDirective = "\t.space\t"; // ".space N" emits N zeros. PrivateGlobalPrefix = "L"; // Marker for constant pool idxs ConstantPoolSection = "\t.const\n"; - JumpTableSection = "\t.const\n"; // FIXME: depends on PIC mode + JumpTableDataSection = "\t.const\n"; // FIXME: depends on PIC mode FourByteConstantSection = "\t.literal4\n"; EightByteConstantSection = "\t.literal8\n"; LCOMMDirective = "\t.lcomm\t";