@@ -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 ;
@@ -638,7 +649,8 @@ unsigned ARMConstantIslands::getCPELogAlign(const MachineInstr *CPEMI) {
638
649
void ARMConstantIslands::scanFunctionJumpTables () {
639
650
for (MachineBasicBlock &MBB : *MF) {
640
651
for (MachineInstr &I : MBB)
641
- if (I.isBranch () && I.getOpcode () == ARM::t2BR_JT)
652
+ if (I.isBranch () &&
653
+ (I.getOpcode () == ARM::t2BR_JT || I.getOpcode () == ARM::tBR_JTr))
642
654
T2JumpTables.push_back (&I);
643
655
}
644
656
}
@@ -679,6 +691,7 @@ initializeFunctionInfo(const std::vector<MachineInstr*> &CPEMIs) {
679
691
default :
680
692
continue ; // Ignore other JT branches
681
693
case ARM::t2BR_JT:
694
+ case ARM::tBR_JTr:
682
695
T2JumpTables.push_back (&I);
683
696
continue ; // Does not get an entry in ImmBranches
684
697
case ARM::Bcc:
@@ -1943,7 +1956,7 @@ bool ARMConstantIslands::preserveBaseRegister(MachineInstr *JumpMI,
1943
1956
1944
1957
if (RemovableAdd) {
1945
1958
RemovableAdd->eraseFromParent ();
1946
- DeadSize += 4 ;
1959
+ DeadSize += isThumb2 ? 4 : 2 ;
1947
1960
} else if (BaseReg == EntryReg) {
1948
1961
// The add wasn't removable, but clobbered the base for the TBB. So we can't
1949
1962
// preserve it.
@@ -2010,25 +2023,80 @@ bool ARMConstantIslands::optimizeThumb2JumpTables() {
2010
2023
if (!ByteOk && !HalfWordOk)
2011
2024
continue ;
2012
2025
2026
+ CPUser &User = CPUsers[JumpTableUserIndices[JTI]];
2013
2027
MachineBasicBlock *MBB = MI->getParent ();
2014
2028
if (!MI->getOperand (0 ).isKill ()) // FIXME: needed now?
2015
2029
continue ;
2016
- unsigned IdxReg = MI->getOperand (1 ).getReg ();
2017
- bool IdxRegKill = MI->getOperand (1 ).isKill ();
2018
2030
2019
- CPUser &User = CPUsers[JumpTableUserIndices[JTI]];
2020
2031
unsigned DeadSize = 0 ;
2021
2032
bool CanDeleteLEA = false ;
2022
2033
bool BaseRegKill = false ;
2023
- bool PreservedBaseReg =
2034
+
2035
+ unsigned IdxReg = ~0U ;
2036
+ bool IdxRegKill = true ;
2037
+ if (isThumb2) {
2038
+ IdxReg = MI->getOperand (1 ).getReg ();
2039
+ IdxRegKill = MI->getOperand (1 ).isKill ();
2040
+
2041
+ bool PreservedBaseReg =
2024
2042
preserveBaseRegister (MI, User.MI , DeadSize, CanDeleteLEA, BaseRegKill);
2043
+ if (!jumpTableFollowsTB (MI, User.CPEMI ) && !PreservedBaseReg)
2044
+ continue ;
2045
+ } else {
2046
+ // We're in thumb-1 mode, so we must have something like:
2047
+ // %idx = tLSLri %idx, 2
2048
+ // %base = tLEApcrelJT
2049
+ // %t = tLDRr %idx, %base
2050
+ unsigned BaseReg = User.MI ->getOperand (0 ).getReg ();
2051
+
2052
+ MachineInstr *Shift = User.MI ->getPrevNode ();
2053
+ if (Shift->getOpcode () != ARM::tLSLri ||
2054
+ Shift->getOperand (3 ).getImm () != 2 ||
2055
+ !Shift->getOperand (2 ).isKill ())
2056
+ continue ;
2057
+ IdxReg = Shift->getOperand (2 ).getReg ();
2058
+ unsigned ShiftedIdxReg = Shift->getOperand (0 ).getReg ();
2025
2059
2026
- if (!jumpTableFollowsTB (MI, User.CPEMI ) && !PreservedBaseReg)
2027
- continue ;
2060
+ MachineInstr *Load = User.MI ->getNextNode ();
2061
+ if (Load->getOpcode () != ARM::tLDRr)
2062
+ continue ;
2063
+ if (Load->getOperand (1 ).getReg () != ShiftedIdxReg ||
2064
+ Load->getOperand (2 ).getReg () != BaseReg ||
2065
+ !Load->getOperand (1 ).isKill ())
2066
+ continue ;
2028
2067
2068
+ // If we're in PIC mode, there should be another ADD following.
2069
+ if (isPositionIndependentOrROPI) {
2070
+ MachineInstr *Add = Load->getNextNode ();
2071
+ if (Add->getOpcode () != ARM::tADDrr ||
2072
+ Add->getOperand (2 ).getReg () != Load->getOperand (0 ).getReg () ||
2073
+ Add->getOperand (3 ).getReg () != BaseReg ||
2074
+ !Add->getOperand (2 ).isKill ())
2075
+ continue ;
2076
+ if (Add->getOperand (0 ).getReg () != MI->getOperand (0 ).getReg ())
2077
+ continue ;
2078
+
2079
+ Add->eraseFromParent ();
2080
+ DeadSize += 2 ;
2081
+ } else {
2082
+ if (Load->getOperand (0 ).getReg () != MI->getOperand (0 ).getReg ())
2083
+ continue ;
2084
+ }
2085
+
2086
+
2087
+ // Now safe to delete the load and lsl. The LEA will be removed later.
2088
+ CanDeleteLEA = true ;
2089
+ Shift->eraseFromParent ();
2090
+ Load->eraseFromParent ();
2091
+ DeadSize += 4 ;
2092
+ }
2093
+
2029
2094
DEBUG (dbgs () << " Shrink JT: " << *MI);
2030
2095
MachineInstr *CPEMI = User.CPEMI ;
2031
2096
unsigned Opc = ByteOk ? ARM::t2TBB_JT : ARM::t2TBH_JT;
2097
+ if (!isThumb2)
2098
+ Opc = ByteOk ? ARM::tTBB_JT : ARM::tTBH_JT;
2099
+
2032
2100
MachineBasicBlock::iterator MI_JT = MI;
2033
2101
MachineInstr *NewJTMI =
2034
2102
BuildMI (*MBB, MI_JT, MI->getDebugLoc (), TII->get (Opc))
@@ -2048,7 +2116,7 @@ bool ARMConstantIslands::optimizeThumb2JumpTables() {
2048
2116
2049
2117
if (CanDeleteLEA) {
2050
2118
User.MI ->eraseFromParent ();
2051
- DeadSize += 4 ;
2119
+ DeadSize += isThumb2 ? 4 : 2 ;
2052
2120
2053
2121
// The LEA was eliminated, the TBB instruction becomes the only new user
2054
2122
// of the jump table.
@@ -2164,9 +2232,16 @@ adjustJTTargetBlockForward(MachineBasicBlock *BB, MachineBasicBlock *JTBB) {
2164
2232
// Add an unconditional branch from NewBB to BB.
2165
2233
// There doesn't seem to be meaningful DebugInfo available; this doesn't
2166
2234
// 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 );
2235
+ if (isThumb2)
2236
+ BuildMI (NewBB, DebugLoc (), TII->get (ARM::t2B))
2237
+ .addMBB (BB)
2238
+ .addImm (ARMCC::AL)
2239
+ .addReg (0 );
2240
+ else
2241
+ BuildMI (NewBB, DebugLoc (), TII->get (ARM::tB))
2242
+ .addMBB (BB)
2243
+ .addImm (ARMCC::AL)
2244
+ .addReg (0 );
2170
2245
2171
2246
// Update internal data structures to account for the newly inserted MBB.
2172
2247
MF->RenumberBlocks (NewBB);
0 commit comments