diff options
author | Evan Cheng <evan.cheng@apple.com> | 2009-07-25 00:33:29 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2009-07-25 00:33:29 +0000 |
commit | f3a1fce8ae411ea7135bc48495e09538d492929e (patch) | |
tree | 04b6da3b544e2edbe87580c4d28fc0e898bdc455 /llvm/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp | |
parent | bcf2ae6aa56af3668906e1aed9687a3228d55188 (diff) | |
download | bcm5719-llvm-f3a1fce8ae411ea7135bc48495e09538d492929e.tar.gz bcm5719-llvm-f3a1fce8ae411ea7135bc48495e09538d492929e.zip |
Change Thumb2 jumptable codegen to one that uses two level jumps:
Before:
adr r12, #LJTI3_0_0
ldr pc, [r12, +r0, lsl #2]
LJTI3_0_0:
.long LBB3_24
.long LBB3_30
.long LBB3_31
.long LBB3_32
After:
adr r12, #LJTI3_0_0
add pc, r12, +r0, lsl #2
LJTI3_0_0:
b.w LBB3_24
b.w LBB3_30
b.w LBB3_31
b.w LBB3_32
This has several advantages.
1. This will make it easier to optimize this to a TBB / TBH instruction +
(smaller) table.
2. This eliminate the need for ugly asm printer hack to force the address
into thumb addresses (bit 0 is one).
3. Same codegen for pic and non-pic.
4. This eliminate the need to align the table so constantpool island pass
won't have to over-estimate the size.
Based on my calculation, the later is probably slightly faster as well since
ldr pc with shifter address is very slow. That is, it should be a win as long
as the HW implementation can do a reasonable job of branch predict the second
branch.
llvm-svn: 77024
Diffstat (limited to 'llvm/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp')
-rw-r--r-- | llvm/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp | 47 |
1 files changed, 27 insertions, 20 deletions
diff --git a/llvm/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp b/llvm/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp index 4d21d5cfd90..cffbecd764b 100644 --- a/llvm/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp +++ b/llvm/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp @@ -160,6 +160,7 @@ namespace { void printCPInstOperand(const MachineInstr *MI, int OpNum, const char *Modifier); void printJTBlockOperand(const MachineInstr *MI, int OpNum); + void printJT2BlockOperand(const MachineInstr *MI, int OpNum); virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, unsigned AsmVariant, const char *ExtraCode); @@ -907,6 +908,8 @@ void ARMAsmPrinter::printCPInstOperand(const MachineInstr *MI, int OpNum, } void ARMAsmPrinter::printJTBlockOperand(const MachineInstr *MI, int OpNum) { + assert(!Subtarget->isThumb2() && "Thumb2 should use double-jump jumptables!"); + const MachineOperand &MO1 = MI->getOperand(OpNum); const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id unsigned JTI = MO1.getIndex(); @@ -922,23 +925,13 @@ void ARMAsmPrinter::printJTBlockOperand(const MachineInstr *MI, int OpNum) { const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs; bool UseSet= TAI->getSetDirective() && TM.getRelocationModel() == Reloc::PIC_; - bool NeedBit0 = Subtarget->isTargetDarwin() && Subtarget->isThumb2(); SmallPtrSet<MachineBasicBlock*, 8> JTSets; for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) { MachineBasicBlock *MBB = JTBBs[i]; - if (UseSet && JTSets.insert(MBB)) { - // FIXME: Temporary workaround for an assembler bug. The assembler isn't - // setting the bit zero to 1 even though it is a thumb address. - if (NeedBit0) { - O << TAI->getSetDirective() << ' ' << TAI->getPrivateGlobalPrefix() - << getFunctionNumber() << '_' << JTI << '_' << MO2.getImm() - << "_set_" << MBB->getNumber() << ",("; - printBasicBlockLabel(MBB, false, false, false); - O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() - << '_' << JTI << '_' << MO2.getImm() << "+1)\n"; - } else - printPICJumpTableSetLabel(JTI, MO2.getImm(), MBB); - } + bool isNew = JTSets.insert(MBB); + + if (UseSet && isNew) + printPICJumpTableSetLabel(JTI, MO2.getImm(), MBB); O << JTEntryDirective << ' '; if (UseSet) @@ -952,19 +945,33 @@ void ARMAsmPrinter::printJTBlockOperand(const MachineInstr *MI, int OpNum) { O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << '_' << JTI << '_' << MO2.getImm(); } else { - // FIXME: Temporary workaround for an assembler bug. The assembler isn't - // setting the bit zero to 1 even though it is a thumb address. - if (NeedBit0) - O << '('; printBasicBlockLabel(MBB, false, false, false); - if (NeedBit0) - O << "+1)"; } if (i != e-1) O << '\n'; } } +void ARMAsmPrinter::printJT2BlockOperand(const MachineInstr *MI, int OpNum) { + const MachineOperand &MO1 = MI->getOperand(OpNum); + const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id + unsigned JTI = MO1.getIndex(); + O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() + << '_' << JTI << '_' << MO2.getImm() << ":\n"; + + const MachineFunction *MF = MI->getParent()->getParent(); + const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); + const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); + const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs; + for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) { + MachineBasicBlock *MBB = JTBBs[i]; + O << "\tb.w "; + printBasicBlockLabel(MBB, false, false, false); + if (i != e-1) + O << '\n'; + } +} + bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, unsigned AsmVariant, const char *ExtraCode){ |