29
29
#include " llvm/CodeGen/LivePhysRegs.h"
30
30
#include " llvm/CodeGen/MachineBasicBlock.h"
31
31
#include " llvm/CodeGen/MachineConstantPool.h"
32
+ #include " llvm/CodeGen/MachineDominators.h"
32
33
#include " llvm/CodeGen/MachineFunction.h"
33
34
#include " llvm/CodeGen/MachineFunctionPass.h"
34
35
#include " llvm/CodeGen/MachineInstr.h"
@@ -70,6 +71,7 @@ STATISTIC(NumT2BrShrunk, "Number of Thumb2 immediate branches shrunk");
70
71
STATISTIC (NumCBZ, " Number of CBZ / CBNZ formed" );
71
72
STATISTIC (NumJTMoved, " Number of jump table destination blocks moved" );
72
73
STATISTIC (NumJTInserted, " Number of jump table intermediate blocks inserted" );
74
+ STATISTIC (NumLEInserted, " Number of LE backwards branches inserted" );
73
75
74
76
static cl::opt<bool >
75
77
AdjustJumpTableBlocks (" arm-adjust-jump-tables" , cl::Hidden, cl::init(true ),
@@ -213,6 +215,7 @@ namespace {
213
215
const ARMBaseInstrInfo *TII;
214
216
const ARMSubtarget *STI;
215
217
ARMFunctionInfo *AFI;
218
+ MachineDominatorTree *DT = nullptr ;
216
219
bool isThumb;
217
220
bool isThumb1;
218
221
bool isThumb2;
@@ -225,6 +228,12 @@ namespace {
225
228
226
229
bool runOnMachineFunction (MachineFunction &MF) override ;
227
230
231
+ void getAnalysisUsage (AnalysisUsage &AU) const override {
232
+ AU.setPreservesCFG ();
233
+ AU.addRequired <MachineDominatorTree>();
234
+ MachineFunctionPass::getAnalysisUsage (AU);
235
+ }
236
+
228
237
MachineFunctionProperties getRequiredProperties () const override {
229
238
return MachineFunctionProperties ().set (
230
239
MachineFunctionProperties::Property::NoVRegs);
@@ -350,6 +359,7 @@ bool ARMConstantIslands::runOnMachineFunction(MachineFunction &mf) {
350
359
isPositionIndependentOrROPI =
351
360
STI->getTargetLowering ()->isPositionIndependent () || STI->isROPI ();
352
361
AFI = MF->getInfo <ARMFunctionInfo>();
362
+ DT = &getAnalysis<MachineDominatorTree>();
353
363
354
364
isThumb = AFI->isThumbFunction ();
355
365
isThumb1 = AFI->isThumb1OnlyFunction ();
@@ -1809,16 +1819,10 @@ bool ARMConstantIslands::optimizeThumb2Instructions() {
1809
1819
return MadeChange;
1810
1820
}
1811
1821
1822
+
1812
1823
bool ARMConstantIslands::optimizeThumb2Branches () {
1813
- bool MadeChange = false ;
1814
1824
1815
- // The order in which branches appear in ImmBranches is approximately their
1816
- // order within the function body. By visiting later branches first, we reduce
1817
- // the distance between earlier forward branches and their targets, making it
1818
- // more likely that the cbn?z optimization, which can only apply to forward
1819
- // branches, will succeed.
1820
- for (unsigned i = ImmBranches.size (); i != 0 ; --i) {
1821
- ImmBranch &Br = ImmBranches[i-1 ];
1825
+ auto TryShrinkBranch = [this ](ImmBranch &Br) {
1822
1826
unsigned Opcode = Br.MI ->getOpcode ();
1823
1827
unsigned NewOpc = 0 ;
1824
1828
unsigned Scale = 1 ;
@@ -1846,47 +1850,115 @@ bool ARMConstantIslands::optimizeThumb2Branches() {
1846
1850
BBUtils->adjustBBSize (MBB, -2 );
1847
1851
BBUtils->adjustBBOffsetsAfter (MBB);
1848
1852
++NumT2BrShrunk;
1849
- MadeChange = true ;
1853
+ return true ;
1850
1854
}
1851
1855
}
1856
+ return false ;
1857
+ };
1852
1858
1853
- Opcode = Br.MI ->getOpcode ();
1854
- if (Opcode != ARM::tBcc)
1855
- continue ;
1859
+ struct ImmCompare {
1860
+ MachineInstr* MI = nullptr ;
1861
+ unsigned NewOpc = 0 ;
1862
+ };
1863
+
1864
+ auto FindCmpForCBZ = [this ](ImmBranch &Br, ImmCompare &ImmCmp,
1865
+ MachineBasicBlock *DestBB) {
1866
+ ImmCmp.MI = nullptr ;
1867
+ ImmCmp.NewOpc = 0 ;
1856
1868
1857
1869
// If the conditional branch doesn't kill CPSR, then CPSR can be liveout
1858
1870
// so this transformation is not safe.
1859
1871
if (!Br.MI ->killsRegister (ARM::CPSR))
1860
- continue ;
1872
+ return false ;
1861
1873
1862
- NewOpc = 0 ;
1863
1874
unsigned PredReg = 0 ;
1875
+ unsigned NewOpc = 0 ;
1864
1876
ARMCC::CondCodes Pred = getInstrPredicate (*Br.MI , PredReg);
1865
1877
if (Pred == ARMCC::EQ)
1866
1878
NewOpc = ARM::tCBZ;
1867
1879
else if (Pred == ARMCC::NE)
1868
1880
NewOpc = ARM::tCBNZ;
1869
- if (!NewOpc)
1870
- continue ;
1871
- MachineBasicBlock *DestBB = Br. MI -> getOperand ( 0 ). getMBB ();
1881
+ else
1882
+ return false ;
1883
+
1872
1884
// Check if the distance is within 126. Subtract starting offset by 2
1873
1885
// because the cmp will be eliminated.
1874
1886
unsigned BrOffset = BBUtils->getOffsetOf (Br.MI ) + 4 - 2 ;
1875
1887
BBInfoVector &BBInfo = BBUtils->getBBInfo ();
1876
1888
unsigned DestOffset = BBInfo[DestBB->getNumber ()].Offset ;
1877
1889
if (BrOffset >= DestOffset || (DestOffset - BrOffset) > 126 )
1878
- continue ;
1890
+ return false ;
1879
1891
1880
1892
// Search backwards to find a tCMPi8
1881
1893
auto *TRI = STI->getRegisterInfo ();
1882
1894
MachineInstr *CmpMI = findCMPToFoldIntoCBZ (Br.MI , TRI);
1883
1895
if (!CmpMI || CmpMI->getOpcode () != ARM::tCMPi8)
1896
+ return false ;
1897
+
1898
+ ImmCmp.MI = CmpMI;
1899
+ ImmCmp.NewOpc = NewOpc;
1900
+ return true ;
1901
+ };
1902
+
1903
+ auto TryConvertToLE = [this ](ImmBranch &Br, ImmCompare &Cmp) {
1904
+ if (Br.MI ->getOpcode () != ARM::t2Bcc || !STI->hasLOB () ||
1905
+ STI->hasMinSize ())
1906
+ return false ;
1907
+
1908
+ MachineBasicBlock *MBB = Br.MI ->getParent ();
1909
+ MachineBasicBlock *DestBB = Br.MI ->getOperand (0 ).getMBB ();
1910
+ if (BBUtils->getOffsetOf (MBB) < BBUtils->getOffsetOf (DestBB) ||
1911
+ !BBUtils->isBBInRange (Br.MI , DestBB, 4094 ))
1912
+ return false ;
1913
+
1914
+ if (!DT->dominates (DestBB, MBB))
1915
+ return false ;
1916
+
1917
+ // We queried for the CBN?Z opcode based upon the 'ExitBB', the opposite
1918
+ // target of Br. So now we need to reverse the condition.
1919
+ Cmp.NewOpc = Cmp.NewOpc == ARM::tCBZ ? ARM::tCBNZ : ARM::tCBZ;
1920
+
1921
+ MachineInstrBuilder MIB = BuildMI (*MBB, Br.MI , Br.MI ->getDebugLoc (),
1922
+ TII->get (ARM::t2LE));
1923
+ MIB.add (Br.MI ->getOperand (0 ));
1924
+ Br.MI ->eraseFromParent ();
1925
+ Br.MI = MIB;
1926
+ ++NumLEInserted;
1927
+ return true ;
1928
+ };
1929
+
1930
+ bool MadeChange = false ;
1931
+
1932
+ // The order in which branches appear in ImmBranches is approximately their
1933
+ // order within the function body. By visiting later branches first, we reduce
1934
+ // the distance between earlier forward branches and their targets, making it
1935
+ // more likely that the cbn?z optimization, which can only apply to forward
1936
+ // branches, will succeed.
1937
+ for (ImmBranch &Br : reverse (ImmBranches)) {
1938
+ MachineBasicBlock *DestBB = Br.MI ->getOperand (0 ).getMBB ();
1939
+ MachineBasicBlock *MBB = Br.MI ->getParent ();
1940
+ MachineBasicBlock *ExitBB = &MBB->back () == Br.MI ?
1941
+ MBB->getFallThrough () :
1942
+ MBB->back ().getOperand (0 ).getMBB ();
1943
+
1944
+ ImmCompare Cmp;
1945
+ if (FindCmpForCBZ (Br, Cmp, ExitBB) && TryConvertToLE (Br, Cmp)) {
1946
+ DestBB = ExitBB;
1947
+ MadeChange = true ;
1948
+ } else {
1949
+ FindCmpForCBZ (Br, Cmp, DestBB);
1950
+ MadeChange |= TryShrinkBranch (Br);
1951
+ }
1952
+
1953
+ unsigned Opcode = Br.MI ->getOpcode ();
1954
+ if ((Opcode != ARM::tBcc && Opcode != ARM::t2LE) || !Cmp.NewOpc )
1884
1955
continue ;
1885
1956
1886
- Register Reg = CmpMI ->getOperand (0 ).getReg ();
1957
+ Register Reg = Cmp. MI ->getOperand (0 ).getReg ();
1887
1958
1888
1959
// Check for Kill flags on Reg. If they are present remove them and set kill
1889
1960
// on the new CBZ.
1961
+ auto *TRI = STI->getRegisterInfo ();
1890
1962
MachineBasicBlock::iterator KillMI = Br.MI ;
1891
1963
bool RegKilled = false ;
1892
1964
do {
@@ -1896,19 +1968,32 @@ bool ARMConstantIslands::optimizeThumb2Branches() {
1896
1968
RegKilled = true ;
1897
1969
break ;
1898
1970
}
1899
- } while (KillMI != CmpMI );
1971
+ } while (KillMI != Cmp. MI );
1900
1972
1901
1973
// Create the new CBZ/CBNZ
1902
- MachineBasicBlock *MBB = Br.MI ->getParent ();
1903
- LLVM_DEBUG (dbgs () << " Fold: " << *CmpMI << " and: " << *Br.MI );
1974
+ LLVM_DEBUG (dbgs () << " Fold: " << *Cmp.MI << " and: " << *Br.MI );
1904
1975
MachineInstr *NewBR =
1905
- BuildMI (*MBB, Br.MI , Br.MI ->getDebugLoc (), TII->get (NewOpc))
1976
+ BuildMI (*MBB, Br.MI , Br.MI ->getDebugLoc (), TII->get (Cmp. NewOpc ))
1906
1977
.addReg (Reg, getKillRegState (RegKilled))
1907
1978
.addMBB (DestBB, Br.MI ->getOperand (0 ).getTargetFlags ());
1908
- CmpMI-> eraseFromParent ();
1909
- Br .MI ->eraseFromParent ();
1910
- Br. MI = NewBR ;
1979
+
1980
+ Cmp .MI ->eraseFromParent ();
1981
+ BBInfoVector &BBInfo = BBUtils-> getBBInfo () ;
1911
1982
BBInfo[MBB->getNumber ()].Size -= 2 ;
1983
+
1984
+ if (Br.MI ->getOpcode () == ARM::tBcc) {
1985
+ Br.MI ->eraseFromParent ();
1986
+ Br.MI = NewBR;
1987
+ } else if (&MBB->back () != Br.MI ) {
1988
+ // We've generated an LE and already erased the original conditional
1989
+ // branch. The CBN?Z is now used to branch to the other successor, so an
1990
+ // unconditional branch terminator is now redundant.
1991
+ MachineInstr *LastMI = &MBB->back ();
1992
+ if (LastMI != Br.MI ) {
1993
+ BBInfo[MBB->getNumber ()].Size -= LastMI->getDesc ().getSize ();
1994
+ LastMI->eraseFromParent ();
1995
+ }
1996
+ }
1912
1997
BBUtils->adjustBBOffsetsAfter (MBB);
1913
1998
++NumCBZ;
1914
1999
MadeChange = true ;
0 commit comments