@@ -58,6 +58,11 @@ static cl::opt<unsigned>
58
58
CPMaxIteration (" arm-constant-island-max-iteration" , cl::Hidden, cl::init(30 ),
59
59
cl::desc(" The max number of iteration for converge" ));
60
60
61
+ static cl::opt<bool > SynthesizeThumb1TBB (
62
+ " arm-synthesize-thumb-1-tbb" , cl::Hidden, cl::init(true ),
63
+ cl::desc(" Use compressed jump tables in Thumb-1 by synthesizing an "
64
+ " equivalent to the TBB/TBH instructions" ));
65
+
61
66
namespace {
62
67
// / ARMConstantIslands - Due to limited PC-relative displacements, ARM
63
68
// / requires constant pool entries to be scattered among the instructions
@@ -189,6 +194,7 @@ namespace {
189
194
bool isThumb;
190
195
bool isThumb1;
191
196
bool isThumb2;
197
+ bool isPositionIndependentOrROPI;
192
198
public:
193
199
static char ID;
194
200
ARMConstantIslands () : MachineFunctionPass(ID) {}
@@ -319,13 +325,16 @@ bool ARMConstantIslands::runOnMachineFunction(MachineFunction &mf) {
319
325
320
326
STI = &static_cast <const ARMSubtarget &>(MF->getSubtarget ());
321
327
TII = STI->getInstrInfo ();
328
+ isPositionIndependentOrROPI =
329
+ STI->getTargetLowering ()->isPositionIndependent () || STI->isROPI ();
322
330
AFI = MF->getInfo <ARMFunctionInfo>();
323
331
324
332
isThumb = AFI->isThumbFunction ();
325
333
isThumb1 = AFI->isThumb1OnlyFunction ();
326
334
isThumb2 = AFI->isThumb2Function ();
327
335
328
336
HasFarJump = false ;
337
+ bool GenerateTBB = isThumb2 || (isThumb1 && SynthesizeThumb1TBB);
329
338
330
339
// This pass invalidates liveness information when it splits basic blocks.
331
340
MF->getRegInfo ().invalidateLiveness ();
@@ -337,7 +346,7 @@ bool ARMConstantIslands::runOnMachineFunction(MachineFunction &mf) {
337
346
// Try to reorder and otherwise adjust the block layout to make good use
338
347
// of the TB[BH] instructions.
339
348
bool MadeChange = false ;
340
- if (isThumb2 && AdjustJumpTableBlocks) {
349
+ if (GenerateTBB && AdjustJumpTableBlocks) {
341
350
scanFunctionJumpTables ();
342
351
MadeChange |= reorderThumb2JumpTables ();
343
352
// Data is out of date, so clear it. It'll be re-computed later.
@@ -414,7 +423,7 @@ bool ARMConstantIslands::runOnMachineFunction(MachineFunction &mf) {
414
423
MadeChange |= optimizeThumb2Branches ();
415
424
416
425
// Optimize jump tables using TBB / TBH.
417
- if (isThumb2 )
426
+ if (GenerateTBB )
418
427
MadeChange |= optimizeThumb2JumpTables ();
419
428
420
429
// After a while, this might be made debug-only, but it is not expensive.
@@ -540,9 +549,11 @@ void ARMConstantIslands::doInitialJumpTablePlacement(
540
549
case ARM::t2BR_JT:
541
550
JTOpcode = ARM::JUMPTABLE_INSTS;
542
551
break ;
552
+ case ARM::tTBB_JT:
543
553
case ARM::t2TBB_JT:
544
554
JTOpcode = ARM::JUMPTABLE_TBB;
545
555
break ;
556
+ case ARM::tTBH_JT:
546
557
case ARM::t2TBH_JT:
547
558
JTOpcode = ARM::JUMPTABLE_TBH;
548
559
break ;
@@ -615,8 +626,9 @@ unsigned ARMConstantIslands::getCPELogAlign(const MachineInstr *CPEMI) {
615
626
case ARM::CONSTPOOL_ENTRY:
616
627
break ;
617
628
case ARM::JUMPTABLE_TBB:
618
- return 0 ;
629
+ return isThumb1 ? 2 : 0 ;
619
630
case ARM::JUMPTABLE_TBH:
631
+ return isThumb1 ? 2 : 1 ;
620
632
case ARM::JUMPTABLE_INSTS:
621
633
return 1 ;
622
634
case ARM::JUMPTABLE_ADDRS:
@@ -638,7 +650,8 @@ unsigned ARMConstantIslands::getCPELogAlign(const MachineInstr *CPEMI) {
638
650
void ARMConstantIslands::scanFunctionJumpTables () {
639
651
for (MachineBasicBlock &MBB : *MF) {
640
652
for (MachineInstr &I : MBB)
641
- if (I.isBranch () && I.getOpcode () == ARM::t2BR_JT)
653
+ if (I.isBranch () &&
654
+ (I.getOpcode () == ARM::t2BR_JT || I.getOpcode () == ARM::tBR_JTr))
642
655
T2JumpTables.push_back (&I);
643
656
}
644
657
}
@@ -679,6 +692,7 @@ initializeFunctionInfo(const std::vector<MachineInstr*> &CPEMIs) {
679
692
default :
680
693
continue ; // Ignore other JT branches
681
694
case ARM::t2BR_JT:
695
+ case ARM::tBR_JTr:
682
696
T2JumpTables.push_back (&I);
683
697
continue ; // Does not get an entry in ImmBranches
684
698
case ARM::Bcc:
@@ -1943,7 +1957,7 @@ bool ARMConstantIslands::preserveBaseRegister(MachineInstr *JumpMI,
1943
1957
1944
1958
if (RemovableAdd) {
1945
1959
RemovableAdd->eraseFromParent ();
1946
- DeadSize += 4 ;
1960
+ DeadSize += isThumb2 ? 4 : 2 ;
1947
1961
} else if (BaseReg == EntryReg) {
1948
1962
// The add wasn't removable, but clobbered the base for the TBB. So we can't
1949
1963
// preserve it.
@@ -2010,25 +2024,82 @@ bool ARMConstantIslands::optimizeThumb2JumpTables() {
2010
2024
if (!ByteOk && !HalfWordOk)
2011
2025
continue ;
2012
2026
2027
+ CPUser &User = CPUsers[JumpTableUserIndices[JTI]];
2013
2028
MachineBasicBlock *MBB = MI->getParent ();
2014
2029
if (!MI->getOperand (0 ).isKill ()) // FIXME: needed now?
2015
2030
continue ;
2016
- unsigned IdxReg = MI->getOperand (1 ).getReg ();
2017
- bool IdxRegKill = MI->getOperand (1 ).isKill ();
2018
2031
2019
- CPUser &User = CPUsers[JumpTableUserIndices[JTI]];
2020
2032
unsigned DeadSize = 0 ;
2021
2033
bool CanDeleteLEA = false ;
2022
2034
bool BaseRegKill = false ;
2023
- bool PreservedBaseReg =
2035
+
2036
+ unsigned IdxReg = ~0U ;
2037
+ bool IdxRegKill = true ;
2038
+ if (isThumb2) {
2039
+ IdxReg = MI->getOperand (1 ).getReg ();
2040
+ IdxRegKill = MI->getOperand (1 ).isKill ();
2041
+
2042
+ bool PreservedBaseReg =
2024
2043
preserveBaseRegister (MI, User.MI , DeadSize, CanDeleteLEA, BaseRegKill);
2044
+ if (!jumpTableFollowsTB (MI, User.CPEMI ) && !PreservedBaseReg)
2045
+ continue ;
2046
+ } else {
2047
+ // We're in thumb-1 mode, so we must have something like:
2048
+ // %idx = tLSLri %idx, 2
2049
+ // %base = tLEApcrelJT
2050
+ // %t = tLDRr %idx, %base
2051
+ unsigned BaseReg = User.MI ->getOperand (0 ).getReg ();
2052
+
2053
+ if (User.MI ->getIterator () == User.MI ->getParent ()->begin ())
2054
+ continue ;
2055
+ MachineInstr *Shift = User.MI ->getPrevNode ();
2056
+ if (Shift->getOpcode () != ARM::tLSLri ||
2057
+ Shift->getOperand (3 ).getImm () != 2 ||
2058
+ !Shift->getOperand (2 ).isKill ())
2059
+ continue ;
2060
+ IdxReg = Shift->getOperand (2 ).getReg ();
2061
+ unsigned ShiftedIdxReg = Shift->getOperand (0 ).getReg ();
2025
2062
2026
- if (!jumpTableFollowsTB (MI, User.CPEMI ) && !PreservedBaseReg)
2027
- continue ;
2063
+ MachineInstr *Load = User.MI ->getNextNode ();
2064
+ if (Load->getOpcode () != ARM::tLDRr)
2065
+ continue ;
2066
+ if (Load->getOperand (1 ).getReg () != ShiftedIdxReg ||
2067
+ Load->getOperand (2 ).getReg () != BaseReg ||
2068
+ !Load->getOperand (1 ).isKill ())
2069
+ continue ;
2028
2070
2071
+ // If we're in PIC mode, there should be another ADD following.
2072
+ if (isPositionIndependentOrROPI) {
2073
+ MachineInstr *Add = Load->getNextNode ();
2074
+ if (Add->getOpcode () != ARM::tADDrr ||
2075
+ Add->getOperand (2 ).getReg () != Load->getOperand (0 ).getReg () ||
2076
+ Add->getOperand (3 ).getReg () != BaseReg ||
2077
+ !Add->getOperand (2 ).isKill ())
2078
+ continue ;
2079
+ if (Add->getOperand (0 ).getReg () != MI->getOperand (0 ).getReg ())
2080
+ continue ;
2081
+
2082
+ Add->eraseFromParent ();
2083
+ DeadSize += 2 ;
2084
+ } else {
2085
+ if (Load->getOperand (0 ).getReg () != MI->getOperand (0 ).getReg ())
2086
+ continue ;
2087
+ }
2088
+
2089
+
2090
+ // Now safe to delete the load and lsl. The LEA will be removed later.
2091
+ CanDeleteLEA = true ;
2092
+ Shift->eraseFromParent ();
2093
+ Load->eraseFromParent ();
2094
+ DeadSize += 4 ;
2095
+ }
2096
+
2029
2097
DEBUG (dbgs () << " Shrink JT: " << *MI);
2030
2098
MachineInstr *CPEMI = User.CPEMI ;
2031
2099
unsigned Opc = ByteOk ? ARM::t2TBB_JT : ARM::t2TBH_JT;
2100
+ if (!isThumb2)
2101
+ Opc = ByteOk ? ARM::tTBB_JT : ARM::tTBH_JT;
2102
+
2032
2103
MachineBasicBlock::iterator MI_JT = MI;
2033
2104
MachineInstr *NewJTMI =
2034
2105
BuildMI (*MBB, MI_JT, MI->getDebugLoc (), TII->get (Opc))
@@ -2048,7 +2119,7 @@ bool ARMConstantIslands::optimizeThumb2JumpTables() {
2048
2119
2049
2120
if (CanDeleteLEA) {
2050
2121
User.MI ->eraseFromParent ();
2051
- DeadSize += 4 ;
2122
+ DeadSize += isThumb2 ? 4 : 2 ;
2052
2123
2053
2124
// The LEA was eliminated, the TBB instruction becomes the only new user
2054
2125
// of the jump table.
@@ -2164,9 +2235,16 @@ adjustJTTargetBlockForward(MachineBasicBlock *BB, MachineBasicBlock *JTBB) {
2164
2235
// Add an unconditional branch from NewBB to BB.
2165
2236
// There doesn't seem to be meaningful DebugInfo available; this doesn't
2166
2237
// correspond directly to anything in the source.
2167
- assert (isThumb2 && " Adjusting for TB[BH] but not in Thumb2?" );
2168
- BuildMI (NewBB, DebugLoc (), TII->get (ARM::t2B)).addMBB (BB)
2169
- .addImm (ARMCC::AL).addReg (0 );
2238
+ if (isThumb2)
2239
+ BuildMI (NewBB, DebugLoc (), TII->get (ARM::t2B))
2240
+ .addMBB (BB)
2241
+ .addImm (ARMCC::AL)
2242
+ .addReg (0 );
2243
+ else
2244
+ BuildMI (NewBB, DebugLoc (), TII->get (ARM::tB))
2245
+ .addMBB (BB)
2246
+ .addImm (ARMCC::AL)
2247
+ .addReg (0 );
2170
2248
2171
2249
// Update internal data structures to account for the newly inserted MBB.
2172
2250
MF->RenumberBlocks (NewBB);
0 commit comments