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 {
const TargetData *TD;
unsigned EntrySize;
std::vector<MachineJumpTableEntry> 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;

View File

@ -188,36 +188,31 @@ void AsmPrinter::EmitJumpTableInfo(MachineJumpTableInfo *MJTI,
MachineFunction &MF) {
const std::vector<MachineJumpTableEntry> &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<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.
// Set directives are all printed before the jump table itself.
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)
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);
}

View File

@ -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()); }

View File

@ -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

View File

@ -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<MachineJumpTableEntry> &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<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]);
for (unsigned i = 0, e = JT.size(); i != e; ++i) {
const std::vector<MachineBasicBlock*> &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<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();
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);
}