1. Tidy up jump table info.

2. Allow the jit to handle PIC relocable jump tables.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@32581 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jim Laskey 2006-12-14 19:17:33 +00:00
parent 8897a7b02e
commit acd80ac7bb
5 changed files with 85 additions and 61 deletions

View File

@ -39,9 +39,11 @@ struct MachineJumpTableEntry {
class MachineJumpTableInfo { class MachineJumpTableInfo {
const TargetData *TD; const TargetData *TD;
unsigned EntrySize;
std::vector<MachineJumpTableEntry> JumpTables; std::vector<MachineJumpTableEntry> JumpTables;
public: 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. /// getJumpTableIndex - Create a new jump table or return an existing one.
/// ///
@ -77,8 +79,9 @@ public:
return MadeChange; return MadeChange;
} }
/// getEntrySize - returns the size of an individual field in a jump table /// getEntrySize - Returns the size of an individual field in a jump table.
unsigned getEntrySize() const; ///
unsigned getEntrySize() const { return EntrySize; }
/// getAlignment - returns the target's preferred alignment for jump tables /// getAlignment - returns the target's preferred alignment for jump tables
unsigned getAlignment() const; unsigned getAlignment() const;

View File

@ -188,36 +188,31 @@ void AsmPrinter::EmitJumpTableInfo(MachineJumpTableInfo *MJTI,
MachineFunction &MF) { MachineFunction &MF) {
const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
if (JT.empty()) return; 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, // Use JumpTableDirective otherwise honor the entry size from the jump table
// and 32 bits for PIC since PIC jump table entries are differences, not // info.
// pointers to blocks.
// Use the architecture specific relocation directive, if it is set
const char *JTEntryDirective = TAI->getJumpTableDirective(); const char *JTEntryDirective = TAI->getJumpTableDirective();
if (!JTEntryDirective) bool HadJTEntryDirective = JTEntryDirective != NULL;
JTEntryDirective = TAI->getData32bitsDirective(); if (!HadJTEntryDirective) {
JTEntryDirective = MJTI->getEntrySize() == 4 ?
TAI->getData32bitsDirective() : TAI->getData64bitsDirective();
}
// Pick the directive to use to print the jump table entries, and switch to // Pick the directive to use to print the jump table entries, and switch to
// the appropriate section. // the appropriate section.
if (TM.getRelocationModel() == Reloc::PIC_) { TargetLowering *LoweringInfo = TM.getTargetLowering();
TargetLowering *LoweringInfo = TM.getTargetLowering();
if (LoweringInfo && LoweringInfo->usesGlobalOffsetTable()) { if (IsPic && !(LoweringInfo && LoweringInfo->usesGlobalOffsetTable())) {
SwitchToDataSection(TAI->getJumpTableDataSection()); // In PIC mode, we need to emit the jump table to the same section as the
if (TD->getPointerSize() == 8 && !JTEntryDirective) // function body itself, otherwise the label differences won't make sense.
JTEntryDirective = TAI->getData64bitsDirective(); const Function *F = MF.getFunction();
} else { SwitchToTextSection(getSectionForFunction(*F).c_str(), F);
// 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 { } else {
SwitchToDataSection(TAI->getJumpTableDataSection()); 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) { for (unsigned i = 0, e = JT.size(); i != e; ++i) {
const std::vector<MachineBasicBlock*> &JTBBs = JT[i].MBBs; const std::vector<MachineBasicBlock*> &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. // the number of relocations the assembler will generate for the jump table.
// Set directives are all printed before the jump table itself. // Set directives are all printed before the jump table itself.
std::set<MachineBasicBlock*> EmittedSets; std::set<MachineBasicBlock*> EmittedSets;
if (TAI->getSetDirective() && TM.getRelocationModel() == Reloc::PIC_) if (TAI->getSetDirective() && IsPic)
for (unsigned ii = 0, ee = JTBBs.size(); ii != ee; ++ii) for (unsigned ii = 0, ee = JTBBs.size(); ii != ee; ++ii)
if (EmittedSets.insert(JTBBs[ii]).second) if (EmittedSets.insert(JTBBs[ii]).second)
printSetLabel(i, JTBBs[ii]); printSetLabel(i, JTBBs[ii]);
@ -247,12 +242,12 @@ void AsmPrinter::EmitJumpTableInfo(MachineJumpTableInfo *MJTI,
if (!EmittedSets.empty()) { if (!EmittedSets.empty()) {
O << TAI->getPrivateGlobalPrefix() << getFunctionNumber() O << TAI->getPrivateGlobalPrefix() << getFunctionNumber()
<< '_' << i << "_set_" << JTBBs[ii]->getNumber(); << '_' << i << "_set_" << JTBBs[ii]->getNumber();
} else if (TM.getRelocationModel() == Reloc::PIC_) { } else if (IsPic) {
printBasicBlockLabel(JTBBs[ii], false, false); printBasicBlockLabel(JTBBs[ii], false, false);
//If the arch uses custom Jump Table directives, don't calc relative to JT //If the arch uses custom Jump Table directives, don't calc relative to JT
if (!TAI->getJumpTableDirective()) if (!HadJTEntryDirective)
O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" O << '-' << TAI->getPrivateGlobalPrefix() << "JTI"
<< getFunctionNumber() << '_' << i; << getFunctionNumber() << '_' << i;
} else { } else {
printBasicBlockLabel(JTBBs[ii], false, false); printBasicBlockLabel(JTBBs[ii], false, false);
} }

View File

@ -21,6 +21,7 @@
#include "llvm/CodeGen/MachineJumpTableInfo.h" #include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/Passes.h"
#include "llvm/Target/TargetData.h" #include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetFrameInfo.h" #include "llvm/Target/TargetFrameInfo.h"
#include "llvm/Function.h" #include "llvm/Function.h"
@ -117,7 +118,14 @@ MachineFunction::MachineFunction(const Function *F,
MFInfo = 0; MFInfo = 0;
FrameInfo = new MachineFrameInfo(); FrameInfo = new MachineFrameInfo();
ConstantPool = new MachineConstantPool(TM.getTargetData()); 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; 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()); } void MachineJumpTableInfo::dump() const { print(*cerr.stream()); }

View File

@ -14,6 +14,7 @@
#include "llvm/CodeGen/SelectionDAG.h" #include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/Target/TargetLowering.h" #include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetData.h" #include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetMachine.h"
@ -1275,13 +1276,19 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
SDOperand Index = Result.getOperand(2); SDOperand Index = Result.getOperand(2);
MVT::ValueType PTy = TLI.getPointerTy(); MVT::ValueType PTy = TLI.getPointerTy();
bool isPIC = TLI.getTargetMachine().getRelocationModel() == Reloc::PIC_; MachineFunction &MF = DAG.getMachineFunction();
// PIC jump table entries are 32-bit values. unsigned EntrySize = MF.getJumpTableInfo()->getEntrySize();
unsigned EntrySize = isPIC ? 4 : MVT::getSizeInBits(PTy)/8;
Index= DAG.getNode(ISD::MUL, PTy, Index, DAG.getConstant(EntrySize, PTy)); Index= DAG.getNode(ISD::MUL, PTy, Index, DAG.getConstant(EntrySize, PTy));
SDOperand Addr = DAG.getNode(ISD::ADD, PTy, Index, Table); 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: // For PIC, the sequence is:
// BRIND(load(Jumptable + index) + RelocBase) // BRIND(load(Jumptable + index) + RelocBase)
// RelocBase is the JumpTable on PPC and X86, GOT on Alpha // RelocBase is the JumpTable on PPC and X86, GOT on Alpha

View File

@ -25,6 +25,7 @@
#include "llvm/ExecutionEngine/GenericValue.h" #include "llvm/ExecutionEngine/GenericValue.h"
#include "llvm/Target/TargetData.h" #include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetJITInfo.h" #include "llvm/Target/TargetJITInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/Debug.h" #include "llvm/Support/Debug.h"
#include "llvm/Support/MutexGuard.h" #include "llvm/Support/MutexGuard.h"
#include "llvm/ADT/Statistic.h" #include "llvm/ADT/Statistic.h"
@ -700,7 +701,7 @@ public:
void emitConstantPool(MachineConstantPool *MCP); void emitConstantPool(MachineConstantPool *MCP);
void initJumpTableInfo(MachineJumpTableInfo *MJTI); 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 startFunctionStub(unsigned StubSize, unsigned Alignment = 1);
virtual void* finishFunctionStub(const Function *F); virtual void* finishFunctionStub(const Function *F);
@ -791,7 +792,7 @@ bool JITEmitter::finishFunction(MachineFunction &F) {
abort(); 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 // FnStart is the start of the text, not the start of the constant pool and
// other per-function data. // other per-function data.
@ -821,7 +822,7 @@ bool JITEmitter::finishFunction(MachineFunction &F) {
MR.doesntNeedFunctionStub()); MR.doesntNeedFunctionStub());
} else if (MR.isBasicBlock()) { } else if (MR.isBasicBlock()) {
ResultPtr = (void*)getMachineBasicBlockAddress(MR.getBasicBlock()); ResultPtr = (void*)getMachineBasicBlockAddress(MR.getBasicBlock());
} else if (MR.isConstantPoolIndex()){ } else if (MR.isConstantPoolIndex()) {
ResultPtr=(void*)getConstantPoolEntryAddress(MR.getConstantPoolIndex()); ResultPtr=(void*)getConstantPoolEntryAddress(MR.getConstantPoolIndex());
} else { } else {
assert(MR.isJumpTableIndex()); assert(MR.isJumpTableIndex());
@ -914,22 +915,38 @@ void JITEmitter::initJumpTableInfo(MachineJumpTableInfo *MJTI) {
JumpTableBase = allocateSpace(NumEntries * EntrySize, MJTI->getAlignment()); JumpTableBase = allocateSpace(NumEntries * EntrySize, MJTI->getAlignment());
} }
void JITEmitter::emitJumpTableInfo(MachineJumpTableInfo *MJTI) { void JITEmitter::emitJumpTableInfo(MachineJumpTableInfo *MJTI, Reloc::Model RM){
const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
if (JT.empty() || JumpTableBase == 0) return; 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 if (RM == Reloc::PIC_) {
// an emitted MachineBasicBlock. assert(MJTI->getEntrySize() == 4 && "Cross JIT'ing?");
intptr_t *SlotPtr = (intptr_t*)JumpTableBase; // 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) { for (unsigned i = 0, e = JT.size(); i != e; ++i) {
const std::vector<MachineBasicBlock*> &MBBs = JT[i].MBBs; const std::vector<MachineBasicBlock*> &MBBs = JT[i].MBBs;
// Store the address of the basic block for this jump table slot in the // Store the offset of the basic block for this jump table slot in the
// memory we allocated for the jump table in 'initJumpTableInfo' // memory we allocated for the jump table in 'initJumpTableInfo'
for (unsigned mi = 0, me = MBBs.size(); mi != me; ++mi) intptr_t Base = (intptr_t)SlotPtr;
*SlotPtr++ = getMachineBasicBlockAddress(MBBs[mi]); 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<MachineBasicBlock*> &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(); unsigned EntrySize = JumpTable->getEntrySize();
for (unsigned i = 0; i < Index; ++i) 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); return (intptr_t)((char *)JumpTableBase + Offset);
} }