diff --git a/include/llvm/CodeGen/MachineJumpTableInfo.h b/include/llvm/CodeGen/MachineJumpTableInfo.h index aa2981c4bbd..3da85ae21e8 100644 --- a/include/llvm/CodeGen/MachineJumpTableInfo.h +++ b/include/llvm/CodeGen/MachineJumpTableInfo.h @@ -39,9 +39,11 @@ struct MachineJumpTableEntry { class MachineJumpTableInfo { const TargetData *TD; + unsigned EntrySize; std::vector JumpTables; public: - MachineJumpTableInfo(const TargetData *td) : TD(td) {} + MachineJumpTableInfo(const TargetData *td, unsigned ES) + : TD(td), EntrySize(ES) {} /// getJumpTableIndex - Create a new jump table or return an existing one. /// @@ -77,8 +79,9 @@ public: return MadeChange; } - /// getEntrySize - returns the size of an individual field in a jump table - unsigned getEntrySize() const; + /// getEntrySize - Returns the size of an individual field in a jump table. + /// + unsigned getEntrySize() const { return EntrySize; } /// getAlignment - returns the target's preferred alignment for jump tables unsigned getAlignment() const; diff --git a/lib/CodeGen/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter.cpp index 72337e7e155..8757d303ec8 100644 --- a/lib/CodeGen/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter.cpp @@ -188,36 +188,31 @@ void AsmPrinter::EmitJumpTableInfo(MachineJumpTableInfo *MJTI, MachineFunction &MF) { const std::vector &JT = MJTI->getJumpTables(); if (JT.empty()) return; - const TargetData *TD = TM.getTargetData(); + bool IsPic = TM.getRelocationModel() == Reloc::PIC_; - // JTEntryDirective is a string to print sizeof(ptr) for non-PIC jump tables, - // and 32 bits for PIC since PIC jump table entries are differences, not - // pointers to blocks. - // Use the architecture specific relocation directive, if it is set + // Use JumpTableDirective otherwise honor the entry size from the jump table + // info. const char *JTEntryDirective = TAI->getJumpTableDirective(); - if (!JTEntryDirective) - JTEntryDirective = TAI->getData32bitsDirective(); + 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. - if (TM.getRelocationModel() == Reloc::PIC_) { - TargetLowering *LoweringInfo = TM.getTargetLowering(); - if (LoweringInfo && LoweringInfo->usesGlobalOffsetTable()) { - SwitchToDataSection(TAI->getJumpTableDataSection()); - if (TD->getPointerSize() == 8 && !JTEntryDirective) - JTEntryDirective = TAI->getData64bitsDirective(); - } else { - // In PIC mode, we need to emit the jump table to the same section as the - // function body itself, otherwise the label differences won't make sense. - const Function *F = MF.getFunction(); - SwitchToTextSection(getSectionForFunction(*F).c_str(), F); - } + TargetLowering *LoweringInfo = TM.getTargetLowering(); + + if (IsPic && !(LoweringInfo && LoweringInfo->usesGlobalOffsetTable())) { + // In PIC mode, we need to emit the jump table to the same section as the + // function body itself, otherwise the label differences won't make sense. + const Function *F = MF.getFunction(); + SwitchToTextSection(getSectionForFunction(*F).c_str(), F); } else { SwitchToDataSection(TAI->getJumpTableDataSection()); - if (TD->getPointerSize() == 8) - JTEntryDirective = TAI->getData64bitsDirective(); } - EmitAlignment(Log2_32(TD->getPointerAlignment())); + + EmitAlignment(Log2_32(MJTI->getAlignment())); for (unsigned i = 0, e = JT.size(); i != e; ++i) { const std::vector &JTBBs = JT[i].MBBs; @@ -229,7 +224,7 @@ void AsmPrinter::EmitJumpTableInfo(MachineJumpTableInfo *MJTI, // the number of relocations the assembler will generate for the jump table. // Set directives are all printed before the jump table itself. std::set EmittedSets; - if (TAI->getSetDirective() && TM.getRelocationModel() == Reloc::PIC_) + if (TAI->getSetDirective() && IsPic) for (unsigned ii = 0, ee = JTBBs.size(); ii != ee; ++ii) if (EmittedSets.insert(JTBBs[ii]).second) printSetLabel(i, JTBBs[ii]); @@ -247,12 +242,12 @@ void AsmPrinter::EmitJumpTableInfo(MachineJumpTableInfo *MJTI, if (!EmittedSets.empty()) { O << TAI->getPrivateGlobalPrefix() << getFunctionNumber() << '_' << i << "_set_" << JTBBs[ii]->getNumber(); - } else if (TM.getRelocationModel() == Reloc::PIC_) { + } else if (IsPic) { printBasicBlockLabel(JTBBs[ii], false, false); - //If the arch uses custom Jump Table directives, don't calc relative to JT - if (!TAI->getJumpTableDirective()) - O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" - << getFunctionNumber() << '_' << i; + //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); } diff --git a/lib/CodeGen/MachineFunction.cpp b/lib/CodeGen/MachineFunction.cpp index 5aaae6deb51..030e893f8f0 100644 --- a/lib/CodeGen/MachineFunction.cpp +++ b/lib/CodeGen/MachineFunction.cpp @@ -21,6 +21,7 @@ #include "llvm/CodeGen/MachineJumpTableInfo.h" #include "llvm/CodeGen/Passes.h" #include "llvm/Target/TargetData.h" +#include "llvm/Target/TargetLowering.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetFrameInfo.h" #include "llvm/Function.h" @@ -117,7 +118,14 @@ MachineFunction::MachineFunction(const Function *F, MFInfo = 0; FrameInfo = new MachineFrameInfo(); ConstantPool = new MachineConstantPool(TM.getTargetData()); - JumpTableInfo = new MachineJumpTableInfo(TM.getTargetData()); + + // Set up jump table. + const TargetData &TD = *TM.getTargetData(); + bool IsPic = TM.getRelocationModel() == Reloc::PIC_; + unsigned EntrySize = IsPic ? 4 : TD.getPointerSize(); + unsigned Alignment = IsPic ? TD.getIntAlignment() : TD.getPointerAlignment(); + JumpTableInfo = new MachineJumpTableInfo(EntrySize, Alignment); + BasicBlocks.Parent = this; } @@ -380,14 +388,6 @@ void MachineJumpTableInfo::print(std::ostream &OS) const { } } -unsigned MachineJumpTableInfo::getEntrySize() const { - return TD->getPointerSize(); -} - -unsigned MachineJumpTableInfo::getAlignment() const { - return TD->getPointerAlignment(); -} - void MachineJumpTableInfo::dump() const { print(*cerr.stream()); } diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index ed7c838122b..ac68486a2fe 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -14,6 +14,7 @@ #include "llvm/CodeGen/SelectionDAG.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineJumpTableInfo.h" #include "llvm/Target/TargetLowering.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetMachine.h" @@ -1275,13 +1276,19 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { 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; + MachineFunction &MF = DAG.getMachineFunction(); + unsigned EntrySize = MF.getJumpTableInfo()->getEntrySize(); 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) { + + SDOperand LD; + switch (EntrySize) { + default: assert(0 && "Size of jump table not supported yet."); break; + case 4: LD = DAG.getLoad(MVT::i32, Chain, Addr, NULL, 0); break; + case 8: LD = DAG.getLoad(MVT::i64, Chain, Addr, NULL, 0); break; + } + + 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 diff --git a/lib/ExecutionEngine/JIT/JITEmitter.cpp b/lib/ExecutionEngine/JIT/JITEmitter.cpp index 3c54b581cb3..bd1b895067c 100644 --- a/lib/ExecutionEngine/JIT/JITEmitter.cpp +++ b/lib/ExecutionEngine/JIT/JITEmitter.cpp @@ -25,6 +25,7 @@ #include "llvm/ExecutionEngine/GenericValue.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetJITInfo.h" +#include "llvm/Target/TargetMachine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/MutexGuard.h" #include "llvm/ADT/Statistic.h" @@ -700,7 +701,7 @@ public: void emitConstantPool(MachineConstantPool *MCP); void initJumpTableInfo(MachineJumpTableInfo *MJTI); - void emitJumpTableInfo(MachineJumpTableInfo *MJTI); + void emitJumpTableInfo(MachineJumpTableInfo *MJTI, Reloc::Model RM); virtual void startFunctionStub(unsigned StubSize, unsigned Alignment = 1); virtual void* finishFunctionStub(const Function *F); @@ -791,7 +792,7 @@ bool JITEmitter::finishFunction(MachineFunction &F) { abort(); } - emitJumpTableInfo(F.getJumpTableInfo()); + emitJumpTableInfo(F.getJumpTableInfo(), F.getTarget().getRelocationModel()); // FnStart is the start of the text, not the start of the constant pool and // other per-function data. @@ -821,7 +822,7 @@ bool JITEmitter::finishFunction(MachineFunction &F) { MR.doesntNeedFunctionStub()); } else if (MR.isBasicBlock()) { ResultPtr = (void*)getMachineBasicBlockAddress(MR.getBasicBlock()); - } else if (MR.isConstantPoolIndex()){ + } else if (MR.isConstantPoolIndex()) { ResultPtr=(void*)getConstantPoolEntryAddress(MR.getConstantPoolIndex()); } else { assert(MR.isJumpTableIndex()); @@ -914,22 +915,38 @@ void JITEmitter::initJumpTableInfo(MachineJumpTableInfo *MJTI) { JumpTableBase = allocateSpace(NumEntries * EntrySize, MJTI->getAlignment()); } -void JITEmitter::emitJumpTableInfo(MachineJumpTableInfo *MJTI) { +void JITEmitter::emitJumpTableInfo(MachineJumpTableInfo *MJTI, Reloc::Model RM){ const std::vector &JT = MJTI->getJumpTables(); if (JT.empty() || JumpTableBase == 0) return; - - assert(MJTI->getEntrySize() == sizeof(void*) && "Cross JIT'ing?"); - // For each jump table, map each target in the jump table to the address of - // an emitted MachineBasicBlock. - intptr_t *SlotPtr = (intptr_t*)JumpTableBase; + if (RM == Reloc::PIC_) { + assert(MJTI->getEntrySize() == 4 && "Cross JIT'ing?"); + // For each jump table, place the offset from the beginning of the table + // to the target address. + int *SlotPtr = (int*)JumpTableBase; - for (unsigned i = 0, e = JT.size(); i != e; ++i) { - const std::vector &MBBs = JT[i].MBBs; - // Store the address of the basic block for this jump table slot in the - // memory we allocated for the jump table in 'initJumpTableInfo' - for (unsigned mi = 0, me = MBBs.size(); mi != me; ++mi) - *SlotPtr++ = getMachineBasicBlockAddress(MBBs[mi]); + for (unsigned i = 0, e = JT.size(); i != e; ++i) { + const std::vector &MBBs = JT[i].MBBs; + // Store the offset of the basic block for this jump table slot in the + // memory we allocated for the jump table in 'initJumpTableInfo' + intptr_t Base = (intptr_t)SlotPtr; + for (unsigned mi = 0, me = MBBs.size(); mi != me; ++mi) + *SlotPtr++ = (intptr_t)getMachineBasicBlockAddress(MBBs[mi]) - Base; + } + } else { + assert(MJTI->getEntrySize() == sizeof(void*) && "Cross JIT'ing?"); + + // For each jump table, map each target in the jump table to the address of + // an emitted MachineBasicBlock. + intptr_t *SlotPtr = (intptr_t*)JumpTableBase; + + for (unsigned i = 0, e = JT.size(); i != e; ++i) { + const std::vector &MBBs = JT[i].MBBs; + // Store the address of the basic block for this jump table slot in the + // memory we allocated for the jump table in 'initJumpTableInfo' + for (unsigned mi = 0, me = MBBs.size(); mi != me; ++mi) + *SlotPtr++ = getMachineBasicBlockAddress(MBBs[mi]); + } } } @@ -972,7 +989,9 @@ intptr_t JITEmitter::getJumpTableEntryAddress(unsigned Index) const { unsigned EntrySize = JumpTable->getEntrySize(); for (unsigned i = 0; i < Index; ++i) - Offset += JT[i].MBBs.size() * EntrySize; + Offset += JT[i].MBBs.size(); + + Offset *= EntrySize; return (intptr_t)((char *)JumpTableBase + Offset); }