llvm.org GIT mirror llvm / 071c62f
Rearrange handling of jump tables. Highlights: 1. MachineJumpTableInfo is now created lazily for a function the first time it actually makes a jump table instead of for every function. 2. The encoding of jump table entries is now described by the MachineJumpTableInfo::JTEntryKind enum. This enum is determined by the TLI::getJumpTableEncoding() hook, instead of by lots of code scattered throughout the compiler that "knows" that jump table entries are always 32-bits in pic mode (for example). 3. The size and alignment of jump table entries is now calculated based on their kind, instead of at machinefunction creation time. Future work includes using the EntryKind in more places in the compiler, eliminating other logic that "knows" the layout of jump tables in various situations. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@94470 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 10 years ago
11 changed file(s) with 206 addition(s) and 103 deletion(s). Raw diff Collapse all Expand all
142142 const MachineFrameInfo *getFrameInfo() const { return FrameInfo; }
143143
144144 /// getJumpTableInfo - Return the jump table info object for the current
145 /// function. This object contains information about jump tables for switch
146 /// instructions in the current function.
147 ///
145 /// function. This object contains information about jump tables in the
146 /// current function. If the current function has no jump tables, this will
147 /// return null.
148 const MachineJumpTableInfo *getJumpTableInfo() const { return JumpTableInfo; }
148149 MachineJumpTableInfo *getJumpTableInfo() { return JumpTableInfo; }
149 const MachineJumpTableInfo *getJumpTableInfo() const { return JumpTableInfo; }
150
151 /// getOrCreateJumpTableInfo - Get the JumpTableInfo for this function, if it
152 /// does already exist, allocate one.
153 MachineJumpTableInfo *getOrCreateJumpTableInfo(unsigned JTEntryKind);
154
150155
151156 /// getConstantPool - Return the constant pool object for the current
152157 /// function.
3939 };
4040
4141 class MachineJumpTableInfo {
42 unsigned EntrySize;
43 unsigned Alignment;
42 public:
43 /// JTEntryKind - This enum indicates how each entry of the jump table is
44 /// represented and emitted.
45 enum JTEntryKind {
46 /// EK_BlockAddress - Each entry is a plain address of block, e.g.:
47 /// .word LBB123
48 EK_BlockAddress,
49
50 /// EK_GPRel32BlockAddress - Each entry is an address of block, encoded
51 /// with a relocation as gp-relative, e.g.:
52 /// .gprel32 LBB123
53 EK_GPRel32BlockAddress,
54
55 /// EK_LabelDifference32 - Each entry is the address of the block minus
56 /// the address of the jump table. This is used for PIC jump tables where
57 /// gprel32 is not supported. e.g.:
58 /// .word LBB123 - LJTI1_2
59 /// If the .set directive is supported, this is emitted as:
60 /// .set L4_5_set_123, LBB123 - LJTI1_2
61 /// .word L4_5_set_123
62 EK_LabelDifference32
63 };
64 private:
65 JTEntryKind EntryKind;
4466 std::vector JumpTables;
4567 public:
46 MachineJumpTableInfo(unsigned Size, unsigned Align)
47 : EntrySize(Size), Alignment(Align) {}
68 MachineJumpTableInfo(JTEntryKind Kind): EntryKind(Kind) {}
4869
70 JTEntryKind getEntryKind() const { return EntryKind; }
71
72 /// getEntrySize - Return the size of each entry in the jump table.
73 unsigned getEntrySize(const TargetData &TD) const;
74 /// getEntryAlignment - Return the alignment of each entry in the jump table.
75 unsigned getEntryAlignment(const TargetData &TD) const;
76
4977 /// getJumpTableIndex - Create a new jump table or return an existing one.
5078 ///
5179 unsigned getJumpTableIndex(const std::vector &DestBBs);
5886 return JumpTables;
5987 }
6088
61 /// RemoveJumpTable - Mark the specific index as being dead. This will cause
62 /// it to not be emitted.
89 /// RemoveJumpTable - Mark the specific index as being dead. This will
90 /// prevent it from being emitted.
6391 void RemoveJumpTable(unsigned Idx) {
6492 JumpTables[Idx].MBBs.clear();
6593 }
73101 bool ReplaceMBBInJumpTable(unsigned Idx, MachineBasicBlock *Old,
74102 MachineBasicBlock *New);
75103
76 /// getEntrySize - Returns the size of an individual field in a jump table.
77 ///
78 unsigned getEntrySize() const { return EntrySize; }
79
80 /// getAlignment - returns the target's preferred alignment for jump tables
81 unsigned getAlignment() const { return Alignment; }
82
83104 /// print - Used by the MachineFunction printer to print information about
84105 /// jump tables. Implemented in MachineFunction.cpp
85106 ///
751751 return false;
752752 }
753753
754 /// getJumpTableEncoding - Return the entry encoding for a jump table in the
755 /// current function. The returned value is a member of the
756 /// MachineJumpTableInfo::JTEntryKind enum.
757 virtual unsigned getJumpTableEncoding() const;
758
754759 /// getPICJumpTableRelocaBase - Returns relocation base for the given PIC
755760 /// jumptable.
756761 virtual SDValue getPICJumpTableRelocBase(SDValue Table,
497497 OutStreamer.SwitchSection(ReadOnlySection);
498498 JTInDiffSection = true;
499499 }
500
501 EmitAlignment(Log2_32(MJTI->getAlignment()));
500
501 unsigned EntrySize = MJTI->getEntrySize(*TM.getTargetData());
502 EmitAlignment(Log2_32(MJTI->getEntryAlignment(*TM.getTargetData())));
502503
503504 for (unsigned i = 0, e = JT.size(); i != e; ++i) {
504505 const std::vector &JTBBs = JT[i].MBBs;
527528 if (!IsPic) {
528529 // In non-pic mode, the entries in the jump table are direct references
529530 // to the basic blocks.
530 unsigned EntrySize = MJTI->getEntrySize();
531531 for (unsigned ii = 0, ee = JTBBs.size(); ii != ee; ++ii) {
532532 MCSymbol *MBBSym = GetMBBSymbol(JTBBs[ii]->getNumber());
533533 OutStreamer.EmitValue(MCSymbolRefExpr::Create(MBBSym, OutContext),
565565 Val = MCBinaryExpr::CreateSub(Val, JTI, OutContext);
566566 }
567567
568 OutStreamer.EmitValue(Val, MJTI->getEntrySize(), /*addrspace*/0);
568 unsigned EntrySize = MJTI->getEntrySize(*TM.getTargetData());
569 OutStreamer.EmitValue(Val, EntrySize, /*addrspace*/0);
569570 }
570571
571572
205205 // See if any jump tables have become mergable or dead as the code generator
206206 // did its thing.
207207 MachineJumpTableInfo *JTI = MF.getJumpTableInfo();
208 if (JTI == 0) {
209 delete RS;
210 return MadeChange;
211 }
212
208213 const std::vector &JTs = JTI->getJumpTables();
209 if (!JTs.empty()) {
210 // Figure out how these jump tables should be merged.
211 std::vector JTMapping;
212 JTMapping.reserve(JTs.size());
213
214 // We always keep the 0th jump table.
215 JTMapping.push_back(0);
216
217 // Scan the jump tables, seeing if there are any duplicates. Note that this
218 // is N^2, which should be fixed someday.
219 for (unsigned i = 1, e = JTs.size(); i != e; ++i) {
220 if (JTs[i].MBBs.empty())
221 JTMapping.push_back(i);
222 else
223 JTMapping.push_back(JTI->getJumpTableIndex(JTs[i].MBBs));
224 }
225
226 // If a jump table was merge with another one, walk the function rewriting
227 // references to jump tables to reference the new JT ID's. Keep track of
228 // whether we see a jump table idx, if not, we can delete the JT.
229 BitVector JTIsLive(JTs.size());
230 for (MachineFunction::iterator BB = MF.begin(), E = MF.end();
231 BB != E; ++BB) {
232 for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end();
233 I != E; ++I)
234 for (unsigned op = 0, e = I->getNumOperands(); op != e; ++op) {
235 MachineOperand &Op = I->getOperand(op);
236 if (!Op.isJTI()) continue;
237 unsigned NewIdx = JTMapping[Op.getIndex()];
238 Op.setIndex(NewIdx);
239
240 // Remember that this JT is live.
241 JTIsLive.set(NewIdx);
242 }
243 }
244
245 // Finally, remove dead jump tables. This happens either because the
246 // indirect jump was unreachable (and thus deleted) or because the jump
247 // table was merged with some other one.
248 for (unsigned i = 0, e = JTIsLive.size(); i != e; ++i)
249 if (!JTIsLive.test(i)) {
250 JTI->RemoveJumpTable(i);
251 MadeChange = true;
214 // Figure out how these jump tables should be merged.
215 std::vector JTMapping;
216 JTMapping.reserve(JTs.size());
217
218 // We always keep the 0th jump table.
219 JTMapping.push_back(0);
220
221 // Scan the jump tables, seeing if there are any duplicates. Note that this
222 // is N^2, which should be fixed someday.
223 for (unsigned i = 1, e = JTs.size(); i != e; ++i) {
224 if (JTs[i].MBBs.empty())
225 JTMapping.push_back(i);
226 else
227 JTMapping.push_back(JTI->getJumpTableIndex(JTs[i].MBBs));
228 }
229
230 // If a jump table was merge with another one, walk the function rewriting
231 // references to jump tables to reference the new JT ID's. Keep track of
232 // whether we see a jump table idx, if not, we can delete the JT.
233 BitVector JTIsLive(JTs.size());
234 for (MachineFunction::iterator BB = MF.begin(), E = MF.end();
235 BB != E; ++BB) {
236 for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end();
237 I != E; ++I)
238 for (unsigned op = 0, e = I->getNumOperands(); op != e; ++op) {
239 MachineOperand &Op = I->getOperand(op);
240 if (!Op.isJTI()) continue;
241 unsigned NewIdx = JTMapping[Op.getIndex()];
242 Op.setIndex(NewIdx);
243
244 // Remember that this JT is live.
245 JTIsLive.set(NewIdx);
252246 }
253247 }
248
249 // Finally, remove dead jump tables. This happens either because the
250 // indirect jump was unreachable (and thus deleted) or because the jump
251 // table was merged with some other one.
252 for (unsigned i = 0, e = JTIsLive.size(); i != e; ++i)
253 if (!JTIsLive.test(i)) {
254 JTI->RemoveJumpTable(i);
255 MadeChange = true;
256 }
254257
255258 delete RS;
256259 return MadeChange;
956959 }
957960 // If MBB was the target of a jump table, update jump tables to go to the
958961 // fallthrough instead.
959 MF.getJumpTableInfo()->ReplaceMBBInJumpTables(MBB, FallThrough);
962 if (MachineJumpTableInfo *MJTI = MF.getJumpTableInfo())
963 MJTI->ReplaceMBBInJumpTables(MBB, FallThrough);
960964 MadeChange = true;
961965 }
962966 return MadeChange;
11901194 }
11911195
11921196 // Change any jumptables to go to the new MBB.
1193 MF.getJumpTableInfo()->ReplaceMBBInJumpTables(MBB, CurTBB);
1197 if (MachineJumpTableInfo *MJTI = MF.getJumpTableInfo())
1198 MJTI->ReplaceMBBInJumpTables(MBB, CurTBB);
11941199 if (DidChange) {
11951200 ++NumBranchOpts;
11961201 MadeChange = true;
9595 MachineConstantPool(TM.getTargetData());
9696 Alignment = TM.getTargetLowering()->getFunctionAlignment(F);
9797
98 // Set up jump table.
99 const TargetData &TD = *TM.getTargetData();
100 bool IsPic = TM.getRelocationModel() == Reloc::PIC_;
101 unsigned EntrySize = IsPic ? 4 : TD.getPointerSize();
102 unsigned TyAlignment = IsPic ?
103 TD.getABITypeAlignment(Type::getInt32Ty(F->getContext()))
104 : TD.getPointerABIAlignment();
105 JumpTableInfo = new (Allocator.Allocate())
106 MachineJumpTableInfo(EntrySize, TyAlignment);
98 JumpTableInfo = 0;
10799 }
108100
109101 MachineFunction::~MachineFunction() {
120112 }
121113 FrameInfo->~MachineFrameInfo(); Allocator.Deallocate(FrameInfo);
122114 ConstantPool->~MachineConstantPool(); Allocator.Deallocate(ConstantPool);
123 JumpTableInfo->~MachineJumpTableInfo(); Allocator.Deallocate(JumpTableInfo);
124 }
125
115
116 if (JumpTableInfo) {
117 JumpTableInfo->~MachineJumpTableInfo();
118 Allocator.Deallocate(JumpTableInfo);
119 }
120 }
121
122 /// getOrCreateJumpTableInfo - Get the JumpTableInfo for this function, if it
123 /// does already exist, allocate one.
124 MachineJumpTableInfo *MachineFunction::
125 getOrCreateJumpTableInfo(unsigned EntryKind) {
126 if (JumpTableInfo) return JumpTableInfo;
127
128 JumpTableInfo = new (Allocator.Allocate())
129 MachineJumpTableInfo((MachineJumpTableInfo::JTEntryKind)EntryKind);
130 return JumpTableInfo;
131 }
126132
127133 /// RenumberBlocks - This discards all of the MachineBasicBlock numbers and
128134 /// recomputes them. This guarantees that the MBB numbers are sequential,
310316 FrameInfo->print(*this, OS);
311317
312318 // Print JumpTable Information
313 JumpTableInfo->print(OS);
319 if (JumpTableInfo)
320 JumpTableInfo->print(OS);
314321
315322 // Print Constant Pool
316323 ConstantPool->print(OS);
526533 //===----------------------------------------------------------------------===//
527534 // MachineJumpTableInfo implementation
528535 //===----------------------------------------------------------------------===//
536
537 /// getEntrySize - Return the size of each entry in the jump table.
538 unsigned MachineJumpTableInfo::getEntrySize(const TargetData &TD) const {
539 // The size of a jump table entry is 4 bytes unless the entry is just the
540 // address of a block, in which case it is the pointer size.
541 switch (getEntryKind()) {
542 case MachineJumpTableInfo::EK_BlockAddress:
543 return TD.getPointerSize();
544 case MachineJumpTableInfo::EK_GPRel32BlockAddress:
545 case MachineJumpTableInfo::EK_LabelDifference32:
546 return 4;
547 }
548 assert(0 && "Unknown jump table encoding!");
549 return ~0;
550 }
551
552 /// getEntryAlignment - Return the alignment of each entry in the jump table.
553 unsigned MachineJumpTableInfo::getEntryAlignment(const TargetData &TD) const {
554 // The alignment of a jump table entry is the alignment of int32 unless the
555 // entry is just the address of a block, in which case it is the pointer
556 // alignment.
557 switch (getEntryKind()) {
558 case MachineJumpTableInfo::EK_BlockAddress:
559 return TD.getPointerABIAlignment();
560 case MachineJumpTableInfo::EK_GPRel32BlockAddress:
561 case MachineJumpTableInfo::EK_LabelDifference32:
562 return TD.getABIIntegerTypeAlignment(32);
563 }
564 assert(0 && "Unknown jump table encoding!");
565 return ~0;
566 }
529567
530568 /// getJumpTableIndex - Create a new jump table entry in the jump table info
531569 /// or return an existing one.
28152815 SDValue Index = Node->getOperand(2);
28162816
28172817 EVT PTy = TLI.getPointerTy();
2818 MachineFunction &MF = DAG.getMachineFunction();
2819 unsigned EntrySize = MF.getJumpTableInfo()->getEntrySize();
2820 Index= DAG.getNode(ISD::MUL, dl, PTy,
2818
2819 const TargetData &TD = *TLI.getTargetData();
2820 unsigned EntrySize =
2821 DAG.getMachineFunction().getJumpTableInfo()->getEntrySize(TD);
2822
2823 Index = DAG.getNode(ISD::MUL, dl, PTy,
28212824 Index, DAG.getConstant(EntrySize, PTy));
28222825 SDValue Addr = DAG.getNode(ISD::ADD, dl, PTy, Index, Table);
28232826
17321732 std::vector DestBBs;
17331733 APInt TEI = First;
17341734 for (CaseItr I = CR.Range.first, E = CR.Range.second; I != E; ++TEI) {
1735 const APInt& Low = cast(I->Low)->getValue();
1736 const APInt& High = cast(I->High)->getValue();
1735 const APInt &Low = cast(I->Low)->getValue();
1736 const APInt &High = cast(I->High)->getValue();
17371737
17381738 if (Low.sle(TEI) && TEI.sle(High)) {
17391739 DestBBs.push_back(I->BB);
17561756
17571757 // Create a jump table index for this jump table, or return an existing
17581758 // one.
1759 unsigned JTI = CurMF->getJumpTableInfo()->getJumpTableIndex(DestBBs);
1759 unsigned JTEncoding = TLI.getJumpTableEncoding();
1760 unsigned JTI = CurMF->getOrCreateJumpTableInfo(JTEncoding)
1761 ->getJumpTableIndex(DestBBs);
17601762
17611763 // Set the jump table information so that we can codegen it as a second
17621764 // MachineBasicBlock
2020 #include "llvm/GlobalVariable.h"
2121 #include "llvm/DerivedTypes.h"
2222 #include "llvm/CodeGen/MachineFrameInfo.h"
23 #include "llvm/CodeGen/MachineJumpTableInfo.h"
2324 #include "llvm/CodeGen/SelectionDAG.h"
2425 #include "llvm/ADT/STLExtras.h"
2526 #include "llvm/Support/ErrorHandling.h"
792793 return TD->getCallFrameTypeAlignment(Ty);
793794 }
794795
796 /// getJumpTableEncoding - Return the entry encoding for a jump table in the
797 /// current function. The returned value is a member of the
798 /// MachineJumpTableInfo::JTEntryKind enum.
799 unsigned TargetLowering::getJumpTableEncoding() const {
800 // In non-pic modes, just use the address of a block.
801 if (getTargetMachine().getRelocationModel() != Reloc::PIC_)
802 return MachineJumpTableInfo::EK_BlockAddress;
803
804 // In PIC mode, if the target supports a GPRel32 directive, use it.
805 if (getTargetMachine().getMCAsmInfo()->getGPRel32Directive() != 0)
806 return MachineJumpTableInfo::EK_GPRel32BlockAddress;
807
808 // Otherwise, use a label difference.
809 return MachineJumpTableInfo::EK_LabelDifference32;
810 }
811
795812 SDValue TargetLowering::getPICJumpTableRelocBase(SDValue Table,
796813 SelectionDAG &DAG) const {
797814 if (usesGlobalOffsetTable())
846846 for (unsigned i = 0, e = JT.size(); i != e; ++i)
847847 NumEntries += JT[i].MBBs.size();
848848
849 unsigned EntrySize = MJTI->getEntrySize();
850
851 return NumEntries * EntrySize;
849 return NumEntries * MJTI->getEntrySize(*TheJIT->getTargetData());
852850 }
853851
854852 static uintptr_t RoundUpToAlign(uintptr_t Size, unsigned Alignment) {
10161014 if (MemMgr->NeedsExactSize()) {
10171015 DEBUG(dbgs() << "JIT: ExactSize\n");
10181016 const TargetInstrInfo* TII = F.getTarget().getInstrInfo();
1019 MachineJumpTableInfo *MJTI = F.getJumpTableInfo();
10201017 MachineConstantPool *MCP = F.getConstantPool();
10211018
10221019 // Ensure the constant pool/jump table info is at least 4-byte aligned.
10281025 // Add the constant pool size
10291026 ActualSize += GetConstantPoolSizeInBytes(MCP, TheJIT->getTargetData());
10301027
1031 // Add the aligment of the jump table info
1032 ActualSize = RoundUpToAlign(ActualSize, MJTI->getAlignment());
1033
1034 // Add the jump table size
1035 ActualSize += GetJumpTableSizeInBytes(MJTI);
1028 if (MachineJumpTableInfo *MJTI = F.getJumpTableInfo()) {
1029 // Add the aligment of the jump table info
1030 ActualSize = RoundUpToAlign(ActualSize,
1031 MJTI->getEntryAlignment(*TheJIT->getTargetData()));
1032
1033 // Add the jump table size
1034 ActualSize += GetJumpTableSizeInBytes(MJTI);
1035 }
10361036
10371037 // Add the alignment for the function
10381038 ActualSize = RoundUpToAlign(ActualSize,
10611061 emitAlignment(16);
10621062
10631063 emitConstantPool(F.getConstantPool());
1064 initJumpTableInfo(F.getJumpTableInfo());
1064 if (MachineJumpTableInfo *MJTI = F.getJumpTableInfo())
1065 initJumpTableInfo(MJTI);
10651066
10661067 // About to start emitting the machine code for the function.
10671068 emitAlignment(std::max(F.getFunction()->getAlignment(), 8U));
10831084 return true;
10841085 }
10851086
1086 emitJumpTableInfo(F.getJumpTableInfo());
1087 if (MachineJumpTableInfo *MJTI = F.getJumpTableInfo())
1088 emitJumpTableInfo(MJTI);
10871089
10881090 // FnStart is the start of the text, not the start of the constant pool and
10891091 // other per-function data.
14031405 for (unsigned i = 0, e = JT.size(); i != e; ++i)
14041406 NumEntries += JT[i].MBBs.size();
14051407
1406 unsigned EntrySize = MJTI->getEntrySize();
1408 unsigned EntrySize = MJTI->getEntrySize(*TheJIT->getTargetData());
14071409
14081410 // Just allocate space for all the jump tables now. We will fix up the actual
14091411 // MBB entries in the tables after we emit the code for each block, since then
14101412 // we will know the final locations of the MBBs in memory.
14111413 JumpTable = MJTI;
1412 JumpTableBase = allocateSpace(NumEntries * EntrySize, MJTI->getAlignment());
1414 JumpTableBase = allocateSpace(NumEntries * EntrySize,
1415 MJTI->getEntryAlignment(*TheJIT->getTargetData()));
14131416 }
14141417
14151418 void JITEmitter::emitJumpTableInfo(MachineJumpTableInfo *MJTI) {
14191422 const std::vector &JT = MJTI->getJumpTables();
14201423 if (JT.empty() || JumpTableBase == 0) return;
14211424
1425 // FIXME: This should use MachineJumpTableInfo::getEntryKind() instead of
1426 // checking for PIC etc.
14221427 if (TargetMachine::getRelocationModel() == Reloc::PIC_) {
1423 assert(MJTI->getEntrySize() == 4 && "Cross JIT'ing?");
1428 assert(MJTI->getEntrySize(*TheJIT->getTargetData()) == 4&&"Cross JIT'ing?");
14241429 // For each jump table, place the offset from the beginning of the table
14251430 // to the target address.
14261431 int *SlotPtr = (int*)JumpTableBase;
14361441 }
14371442 }
14381443 } else {
1439 assert(MJTI->getEntrySize() == sizeof(void*) && "Cross JIT'ing?");
1444 assert(MJTI->getEntrySize(*TheJIT->getTargetData()) == sizeof(void*) &&
1445 "Cross JIT'ing?");
14401446
14411447 // For each jump table, map each target in the jump table to the address of
14421448 // an emitted MachineBasicBlock.
15041510 const std::vector &JT = JumpTable->getJumpTables();
15051511 assert(Index < JT.size() && "Invalid jump table index!");
15061512
1513 unsigned EntrySize = JumpTable->getEntrySize(*TheJIT->getTargetData());
1514
15071515 unsigned Offset = 0;
1508 unsigned EntrySize = JumpTable->getEntrySize();
1509
15101516 for (unsigned i = 0; i < Index; ++i)
15111517 Offset += JT[i].MBBs.size();
15121518
487487 void X86AsmPrinter::printPICJumpTableEntry(const MachineJumpTableInfo *MJTI,
488488 const MachineBasicBlock *MBB,
489489 unsigned uid) const {
490 const char *JTEntryDirective = MJTI->getEntrySize() == 4 ?
490 const char *JTEntryDirective = MJTI->getEntrySize(*TM.getTargetData()) == 4 ?
491491 MAI->getData32bitsDirective() : MAI->getData64bitsDirective();
492492
493493 O << JTEntryDirective << ' ';