xref: /aosp_15_r20/external/llvm/lib/Target/ARM/Thumb2ITBlockPass.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- Thumb2ITBlockPass.cpp - Insert Thumb-2 IT blocks ------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker 
10*9880d681SAndroid Build Coastguard Worker #include "ARM.h"
11*9880d681SAndroid Build Coastguard Worker #include "ARMMachineFunctionInfo.h"
12*9880d681SAndroid Build Coastguard Worker #include "Thumb2InstrInfo.h"
13*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallSet.h"
14*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Statistic.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunctionPass.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineInstr.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineInstrBuilder.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineInstrBundle.h"
19*9880d681SAndroid Build Coastguard Worker using namespace llvm;
20*9880d681SAndroid Build Coastguard Worker 
21*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "thumb2-it"
22*9880d681SAndroid Build Coastguard Worker 
23*9880d681SAndroid Build Coastguard Worker STATISTIC(NumITs,        "Number of IT blocks inserted");
24*9880d681SAndroid Build Coastguard Worker STATISTIC(NumMovedInsts, "Number of predicated instructions moved");
25*9880d681SAndroid Build Coastguard Worker 
26*9880d681SAndroid Build Coastguard Worker namespace {
27*9880d681SAndroid Build Coastguard Worker   class Thumb2ITBlockPass : public MachineFunctionPass {
28*9880d681SAndroid Build Coastguard Worker   public:
29*9880d681SAndroid Build Coastguard Worker     static char ID;
Thumb2ITBlockPass()30*9880d681SAndroid Build Coastguard Worker     Thumb2ITBlockPass() : MachineFunctionPass(ID) {}
31*9880d681SAndroid Build Coastguard Worker 
32*9880d681SAndroid Build Coastguard Worker     bool restrictIT;
33*9880d681SAndroid Build Coastguard Worker     const Thumb2InstrInfo *TII;
34*9880d681SAndroid Build Coastguard Worker     const TargetRegisterInfo *TRI;
35*9880d681SAndroid Build Coastguard Worker     ARMFunctionInfo *AFI;
36*9880d681SAndroid Build Coastguard Worker 
37*9880d681SAndroid Build Coastguard Worker     bool runOnMachineFunction(MachineFunction &Fn) override;
38*9880d681SAndroid Build Coastguard Worker 
getRequiredProperties() const39*9880d681SAndroid Build Coastguard Worker     MachineFunctionProperties getRequiredProperties() const override {
40*9880d681SAndroid Build Coastguard Worker       return MachineFunctionProperties().set(
41*9880d681SAndroid Build Coastguard Worker           MachineFunctionProperties::Property::AllVRegsAllocated);
42*9880d681SAndroid Build Coastguard Worker     }
43*9880d681SAndroid Build Coastguard Worker 
getPassName() const44*9880d681SAndroid Build Coastguard Worker     const char *getPassName() const override {
45*9880d681SAndroid Build Coastguard Worker       return "Thumb IT blocks insertion pass";
46*9880d681SAndroid Build Coastguard Worker     }
47*9880d681SAndroid Build Coastguard Worker 
48*9880d681SAndroid Build Coastguard Worker   private:
49*9880d681SAndroid Build Coastguard Worker     bool MoveCopyOutOfITBlock(MachineInstr *MI,
50*9880d681SAndroid Build Coastguard Worker                               ARMCC::CondCodes CC, ARMCC::CondCodes OCC,
51*9880d681SAndroid Build Coastguard Worker                               SmallSet<unsigned, 4> &Defs,
52*9880d681SAndroid Build Coastguard Worker                               SmallSet<unsigned, 4> &Uses);
53*9880d681SAndroid Build Coastguard Worker     bool InsertITInstructions(MachineBasicBlock &MBB);
54*9880d681SAndroid Build Coastguard Worker   };
55*9880d681SAndroid Build Coastguard Worker   char Thumb2ITBlockPass::ID = 0;
56*9880d681SAndroid Build Coastguard Worker }
57*9880d681SAndroid Build Coastguard Worker 
58*9880d681SAndroid Build Coastguard Worker /// TrackDefUses - Tracking what registers are being defined and used by
59*9880d681SAndroid Build Coastguard Worker /// instructions in the IT block. This also tracks "dependencies", i.e. uses
60*9880d681SAndroid Build Coastguard Worker /// in the IT block that are defined before the IT instruction.
TrackDefUses(MachineInstr * MI,SmallSet<unsigned,4> & Defs,SmallSet<unsigned,4> & Uses,const TargetRegisterInfo * TRI)61*9880d681SAndroid Build Coastguard Worker static void TrackDefUses(MachineInstr *MI,
62*9880d681SAndroid Build Coastguard Worker                          SmallSet<unsigned, 4> &Defs,
63*9880d681SAndroid Build Coastguard Worker                          SmallSet<unsigned, 4> &Uses,
64*9880d681SAndroid Build Coastguard Worker                          const TargetRegisterInfo *TRI) {
65*9880d681SAndroid Build Coastguard Worker   SmallVector<unsigned, 4> LocalDefs;
66*9880d681SAndroid Build Coastguard Worker   SmallVector<unsigned, 4> LocalUses;
67*9880d681SAndroid Build Coastguard Worker 
68*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
69*9880d681SAndroid Build Coastguard Worker     MachineOperand &MO = MI->getOperand(i);
70*9880d681SAndroid Build Coastguard Worker     if (!MO.isReg())
71*9880d681SAndroid Build Coastguard Worker       continue;
72*9880d681SAndroid Build Coastguard Worker     unsigned Reg = MO.getReg();
73*9880d681SAndroid Build Coastguard Worker     if (!Reg || Reg == ARM::ITSTATE || Reg == ARM::SP)
74*9880d681SAndroid Build Coastguard Worker       continue;
75*9880d681SAndroid Build Coastguard Worker     if (MO.isUse())
76*9880d681SAndroid Build Coastguard Worker       LocalUses.push_back(Reg);
77*9880d681SAndroid Build Coastguard Worker     else
78*9880d681SAndroid Build Coastguard Worker       LocalDefs.push_back(Reg);
79*9880d681SAndroid Build Coastguard Worker   }
80*9880d681SAndroid Build Coastguard Worker 
81*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = LocalUses.size(); i != e; ++i) {
82*9880d681SAndroid Build Coastguard Worker     unsigned Reg = LocalUses[i];
83*9880d681SAndroid Build Coastguard Worker     for (MCSubRegIterator Subreg(Reg, TRI, /*IncludeSelf=*/true);
84*9880d681SAndroid Build Coastguard Worker          Subreg.isValid(); ++Subreg)
85*9880d681SAndroid Build Coastguard Worker       Uses.insert(*Subreg);
86*9880d681SAndroid Build Coastguard Worker   }
87*9880d681SAndroid Build Coastguard Worker 
88*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = LocalDefs.size(); i != e; ++i) {
89*9880d681SAndroid Build Coastguard Worker     unsigned Reg = LocalDefs[i];
90*9880d681SAndroid Build Coastguard Worker     for (MCSubRegIterator Subreg(Reg, TRI, /*IncludeSelf=*/true);
91*9880d681SAndroid Build Coastguard Worker          Subreg.isValid(); ++Subreg)
92*9880d681SAndroid Build Coastguard Worker       Defs.insert(*Subreg);
93*9880d681SAndroid Build Coastguard Worker     if (Reg == ARM::CPSR)
94*9880d681SAndroid Build Coastguard Worker       continue;
95*9880d681SAndroid Build Coastguard Worker   }
96*9880d681SAndroid Build Coastguard Worker }
97*9880d681SAndroid Build Coastguard Worker 
98*9880d681SAndroid Build Coastguard Worker /// Clear kill flags for any uses in the given set.  This will likely
99*9880d681SAndroid Build Coastguard Worker /// conservatively remove more kill flags than are necessary, but removing them
100*9880d681SAndroid Build Coastguard Worker /// is safer than incorrect kill flags remaining on instructions.
ClearKillFlags(MachineInstr * MI,SmallSet<unsigned,4> & Uses)101*9880d681SAndroid Build Coastguard Worker static void ClearKillFlags(MachineInstr *MI, SmallSet<unsigned, 4> &Uses) {
102*9880d681SAndroid Build Coastguard Worker   for (MachineOperand &MO : MI->operands()) {
103*9880d681SAndroid Build Coastguard Worker     if (!MO.isReg() || MO.isDef() || !MO.isKill())
104*9880d681SAndroid Build Coastguard Worker       continue;
105*9880d681SAndroid Build Coastguard Worker     if (!Uses.count(MO.getReg()))
106*9880d681SAndroid Build Coastguard Worker       continue;
107*9880d681SAndroid Build Coastguard Worker     MO.setIsKill(false);
108*9880d681SAndroid Build Coastguard Worker   }
109*9880d681SAndroid Build Coastguard Worker }
110*9880d681SAndroid Build Coastguard Worker 
isCopy(MachineInstr * MI)111*9880d681SAndroid Build Coastguard Worker static bool isCopy(MachineInstr *MI) {
112*9880d681SAndroid Build Coastguard Worker   switch (MI->getOpcode()) {
113*9880d681SAndroid Build Coastguard Worker   default:
114*9880d681SAndroid Build Coastguard Worker     return false;
115*9880d681SAndroid Build Coastguard Worker   case ARM::MOVr:
116*9880d681SAndroid Build Coastguard Worker   case ARM::MOVr_TC:
117*9880d681SAndroid Build Coastguard Worker   case ARM::tMOVr:
118*9880d681SAndroid Build Coastguard Worker   case ARM::t2MOVr:
119*9880d681SAndroid Build Coastguard Worker     return true;
120*9880d681SAndroid Build Coastguard Worker   }
121*9880d681SAndroid Build Coastguard Worker }
122*9880d681SAndroid Build Coastguard Worker 
123*9880d681SAndroid Build Coastguard Worker bool
MoveCopyOutOfITBlock(MachineInstr * MI,ARMCC::CondCodes CC,ARMCC::CondCodes OCC,SmallSet<unsigned,4> & Defs,SmallSet<unsigned,4> & Uses)124*9880d681SAndroid Build Coastguard Worker Thumb2ITBlockPass::MoveCopyOutOfITBlock(MachineInstr *MI,
125*9880d681SAndroid Build Coastguard Worker                                       ARMCC::CondCodes CC, ARMCC::CondCodes OCC,
126*9880d681SAndroid Build Coastguard Worker                                         SmallSet<unsigned, 4> &Defs,
127*9880d681SAndroid Build Coastguard Worker                                         SmallSet<unsigned, 4> &Uses) {
128*9880d681SAndroid Build Coastguard Worker   if (!isCopy(MI))
129*9880d681SAndroid Build Coastguard Worker     return false;
130*9880d681SAndroid Build Coastguard Worker   // llvm models select's as two-address instructions. That means a copy
131*9880d681SAndroid Build Coastguard Worker   // is inserted before a t2MOVccr, etc. If the copy is scheduled in
132*9880d681SAndroid Build Coastguard Worker   // between selects we would end up creating multiple IT blocks.
133*9880d681SAndroid Build Coastguard Worker   assert(MI->getOperand(0).getSubReg() == 0 &&
134*9880d681SAndroid Build Coastguard Worker          MI->getOperand(1).getSubReg() == 0 &&
135*9880d681SAndroid Build Coastguard Worker          "Sub-register indices still around?");
136*9880d681SAndroid Build Coastguard Worker 
137*9880d681SAndroid Build Coastguard Worker   unsigned DstReg = MI->getOperand(0).getReg();
138*9880d681SAndroid Build Coastguard Worker   unsigned SrcReg = MI->getOperand(1).getReg();
139*9880d681SAndroid Build Coastguard Worker 
140*9880d681SAndroid Build Coastguard Worker   // First check if it's safe to move it.
141*9880d681SAndroid Build Coastguard Worker   if (Uses.count(DstReg) || Defs.count(SrcReg))
142*9880d681SAndroid Build Coastguard Worker     return false;
143*9880d681SAndroid Build Coastguard Worker 
144*9880d681SAndroid Build Coastguard Worker   // If the CPSR is defined by this copy, then we don't want to move it. E.g.,
145*9880d681SAndroid Build Coastguard Worker   // if we have:
146*9880d681SAndroid Build Coastguard Worker   //
147*9880d681SAndroid Build Coastguard Worker   //   movs  r1, r1
148*9880d681SAndroid Build Coastguard Worker   //   rsb   r1, 0
149*9880d681SAndroid Build Coastguard Worker   //   movs  r2, r2
150*9880d681SAndroid Build Coastguard Worker   //   rsb   r2, 0
151*9880d681SAndroid Build Coastguard Worker   //
152*9880d681SAndroid Build Coastguard Worker   // we don't want this to be converted to:
153*9880d681SAndroid Build Coastguard Worker   //
154*9880d681SAndroid Build Coastguard Worker   //   movs  r1, r1
155*9880d681SAndroid Build Coastguard Worker   //   movs  r2, r2
156*9880d681SAndroid Build Coastguard Worker   //   itt   mi
157*9880d681SAndroid Build Coastguard Worker   //   rsb   r1, 0
158*9880d681SAndroid Build Coastguard Worker   //   rsb   r2, 0
159*9880d681SAndroid Build Coastguard Worker   //
160*9880d681SAndroid Build Coastguard Worker   const MCInstrDesc &MCID = MI->getDesc();
161*9880d681SAndroid Build Coastguard Worker   if (MI->hasOptionalDef() &&
162*9880d681SAndroid Build Coastguard Worker       MI->getOperand(MCID.getNumOperands() - 1).getReg() == ARM::CPSR)
163*9880d681SAndroid Build Coastguard Worker     return false;
164*9880d681SAndroid Build Coastguard Worker 
165*9880d681SAndroid Build Coastguard Worker   // Then peek at the next instruction to see if it's predicated on CC or OCC.
166*9880d681SAndroid Build Coastguard Worker   // If not, then there is nothing to be gained by moving the copy.
167*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock::iterator I = MI; ++I;
168*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock::iterator E = MI->getParent()->end();
169*9880d681SAndroid Build Coastguard Worker   while (I != E && I->isDebugValue())
170*9880d681SAndroid Build Coastguard Worker     ++I;
171*9880d681SAndroid Build Coastguard Worker   if (I != E) {
172*9880d681SAndroid Build Coastguard Worker     unsigned NPredReg = 0;
173*9880d681SAndroid Build Coastguard Worker     ARMCC::CondCodes NCC = getITInstrPredicate(*I, NPredReg);
174*9880d681SAndroid Build Coastguard Worker     if (NCC == CC || NCC == OCC)
175*9880d681SAndroid Build Coastguard Worker       return true;
176*9880d681SAndroid Build Coastguard Worker   }
177*9880d681SAndroid Build Coastguard Worker   return false;
178*9880d681SAndroid Build Coastguard Worker }
179*9880d681SAndroid Build Coastguard Worker 
InsertITInstructions(MachineBasicBlock & MBB)180*9880d681SAndroid Build Coastguard Worker bool Thumb2ITBlockPass::InsertITInstructions(MachineBasicBlock &MBB) {
181*9880d681SAndroid Build Coastguard Worker   bool Modified = false;
182*9880d681SAndroid Build Coastguard Worker 
183*9880d681SAndroid Build Coastguard Worker   SmallSet<unsigned, 4> Defs;
184*9880d681SAndroid Build Coastguard Worker   SmallSet<unsigned, 4> Uses;
185*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
186*9880d681SAndroid Build Coastguard Worker   while (MBBI != E) {
187*9880d681SAndroid Build Coastguard Worker     MachineInstr *MI = &*MBBI;
188*9880d681SAndroid Build Coastguard Worker     DebugLoc dl = MI->getDebugLoc();
189*9880d681SAndroid Build Coastguard Worker     unsigned PredReg = 0;
190*9880d681SAndroid Build Coastguard Worker     ARMCC::CondCodes CC = getITInstrPredicate(*MI, PredReg);
191*9880d681SAndroid Build Coastguard Worker     if (CC == ARMCC::AL) {
192*9880d681SAndroid Build Coastguard Worker       ++MBBI;
193*9880d681SAndroid Build Coastguard Worker       continue;
194*9880d681SAndroid Build Coastguard Worker     }
195*9880d681SAndroid Build Coastguard Worker 
196*9880d681SAndroid Build Coastguard Worker     Defs.clear();
197*9880d681SAndroid Build Coastguard Worker     Uses.clear();
198*9880d681SAndroid Build Coastguard Worker     TrackDefUses(MI, Defs, Uses, TRI);
199*9880d681SAndroid Build Coastguard Worker 
200*9880d681SAndroid Build Coastguard Worker     // Insert an IT instruction.
201*9880d681SAndroid Build Coastguard Worker     MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII->get(ARM::t2IT))
202*9880d681SAndroid Build Coastguard Worker       .addImm(CC);
203*9880d681SAndroid Build Coastguard Worker 
204*9880d681SAndroid Build Coastguard Worker     // Add implicit use of ITSTATE to IT block instructions.
205*9880d681SAndroid Build Coastguard Worker     MI->addOperand(MachineOperand::CreateReg(ARM::ITSTATE, false/*ifDef*/,
206*9880d681SAndroid Build Coastguard Worker                                              true/*isImp*/, false/*isKill*/));
207*9880d681SAndroid Build Coastguard Worker 
208*9880d681SAndroid Build Coastguard Worker     MachineInstr *LastITMI = MI;
209*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock::iterator InsertPos = MIB.getInstr();
210*9880d681SAndroid Build Coastguard Worker     ++MBBI;
211*9880d681SAndroid Build Coastguard Worker 
212*9880d681SAndroid Build Coastguard Worker     // Form IT block.
213*9880d681SAndroid Build Coastguard Worker     ARMCC::CondCodes OCC = ARMCC::getOppositeCondition(CC);
214*9880d681SAndroid Build Coastguard Worker     unsigned Mask = 0, Pos = 3;
215*9880d681SAndroid Build Coastguard Worker 
216*9880d681SAndroid Build Coastguard Worker     // v8 IT blocks are limited to one conditional op unless -arm-no-restrict-it
217*9880d681SAndroid Build Coastguard Worker     // is set: skip the loop
218*9880d681SAndroid Build Coastguard Worker     if (!restrictIT) {
219*9880d681SAndroid Build Coastguard Worker       // Branches, including tricky ones like LDM_RET, need to end an IT
220*9880d681SAndroid Build Coastguard Worker       // block so check the instruction we just put in the block.
221*9880d681SAndroid Build Coastguard Worker       for (; MBBI != E && Pos &&
222*9880d681SAndroid Build Coastguard Worker              (!MI->isBranch() && !MI->isReturn()) ; ++MBBI) {
223*9880d681SAndroid Build Coastguard Worker         if (MBBI->isDebugValue())
224*9880d681SAndroid Build Coastguard Worker           continue;
225*9880d681SAndroid Build Coastguard Worker 
226*9880d681SAndroid Build Coastguard Worker         MachineInstr *NMI = &*MBBI;
227*9880d681SAndroid Build Coastguard Worker         MI = NMI;
228*9880d681SAndroid Build Coastguard Worker 
229*9880d681SAndroid Build Coastguard Worker         unsigned NPredReg = 0;
230*9880d681SAndroid Build Coastguard Worker         ARMCC::CondCodes NCC = getITInstrPredicate(*NMI, NPredReg);
231*9880d681SAndroid Build Coastguard Worker         if (NCC == CC || NCC == OCC) {
232*9880d681SAndroid Build Coastguard Worker           Mask |= (NCC & 1) << Pos;
233*9880d681SAndroid Build Coastguard Worker           // Add implicit use of ITSTATE.
234*9880d681SAndroid Build Coastguard Worker           NMI->addOperand(MachineOperand::CreateReg(ARM::ITSTATE, false/*ifDef*/,
235*9880d681SAndroid Build Coastguard Worker                                                  true/*isImp*/, false/*isKill*/));
236*9880d681SAndroid Build Coastguard Worker           LastITMI = NMI;
237*9880d681SAndroid Build Coastguard Worker         } else {
238*9880d681SAndroid Build Coastguard Worker           if (NCC == ARMCC::AL &&
239*9880d681SAndroid Build Coastguard Worker               MoveCopyOutOfITBlock(NMI, CC, OCC, Defs, Uses)) {
240*9880d681SAndroid Build Coastguard Worker             --MBBI;
241*9880d681SAndroid Build Coastguard Worker             MBB.remove(NMI);
242*9880d681SAndroid Build Coastguard Worker             MBB.insert(InsertPos, NMI);
243*9880d681SAndroid Build Coastguard Worker             ClearKillFlags(MI, Uses);
244*9880d681SAndroid Build Coastguard Worker             ++NumMovedInsts;
245*9880d681SAndroid Build Coastguard Worker             continue;
246*9880d681SAndroid Build Coastguard Worker           }
247*9880d681SAndroid Build Coastguard Worker           break;
248*9880d681SAndroid Build Coastguard Worker         }
249*9880d681SAndroid Build Coastguard Worker         TrackDefUses(NMI, Defs, Uses, TRI);
250*9880d681SAndroid Build Coastguard Worker         --Pos;
251*9880d681SAndroid Build Coastguard Worker       }
252*9880d681SAndroid Build Coastguard Worker     }
253*9880d681SAndroid Build Coastguard Worker 
254*9880d681SAndroid Build Coastguard Worker     // Finalize IT mask.
255*9880d681SAndroid Build Coastguard Worker     Mask |= (1 << Pos);
256*9880d681SAndroid Build Coastguard Worker     // Tag along (firstcond[0] << 4) with the mask.
257*9880d681SAndroid Build Coastguard Worker     Mask |= (CC & 1) << 4;
258*9880d681SAndroid Build Coastguard Worker     MIB.addImm(Mask);
259*9880d681SAndroid Build Coastguard Worker 
260*9880d681SAndroid Build Coastguard Worker     // Last instruction in IT block kills ITSTATE.
261*9880d681SAndroid Build Coastguard Worker     LastITMI->findRegisterUseOperand(ARM::ITSTATE)->setIsKill();
262*9880d681SAndroid Build Coastguard Worker 
263*9880d681SAndroid Build Coastguard Worker     // Finalize the bundle.
264*9880d681SAndroid Build Coastguard Worker     finalizeBundle(MBB, InsertPos.getInstrIterator(),
265*9880d681SAndroid Build Coastguard Worker                    ++LastITMI->getIterator());
266*9880d681SAndroid Build Coastguard Worker 
267*9880d681SAndroid Build Coastguard Worker     Modified = true;
268*9880d681SAndroid Build Coastguard Worker     ++NumITs;
269*9880d681SAndroid Build Coastguard Worker   }
270*9880d681SAndroid Build Coastguard Worker 
271*9880d681SAndroid Build Coastguard Worker   return Modified;
272*9880d681SAndroid Build Coastguard Worker }
273*9880d681SAndroid Build Coastguard Worker 
runOnMachineFunction(MachineFunction & Fn)274*9880d681SAndroid Build Coastguard Worker bool Thumb2ITBlockPass::runOnMachineFunction(MachineFunction &Fn) {
275*9880d681SAndroid Build Coastguard Worker   const ARMSubtarget &STI =
276*9880d681SAndroid Build Coastguard Worker       static_cast<const ARMSubtarget &>(Fn.getSubtarget());
277*9880d681SAndroid Build Coastguard Worker   if (!STI.isThumb2())
278*9880d681SAndroid Build Coastguard Worker     return false;
279*9880d681SAndroid Build Coastguard Worker   AFI = Fn.getInfo<ARMFunctionInfo>();
280*9880d681SAndroid Build Coastguard Worker   TII = static_cast<const Thumb2InstrInfo *>(STI.getInstrInfo());
281*9880d681SAndroid Build Coastguard Worker   TRI = STI.getRegisterInfo();
282*9880d681SAndroid Build Coastguard Worker   restrictIT = STI.restrictIT();
283*9880d681SAndroid Build Coastguard Worker 
284*9880d681SAndroid Build Coastguard Worker   if (!AFI->isThumbFunction())
285*9880d681SAndroid Build Coastguard Worker     return false;
286*9880d681SAndroid Build Coastguard Worker 
287*9880d681SAndroid Build Coastguard Worker   bool Modified = false;
288*9880d681SAndroid Build Coastguard Worker   for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E; ) {
289*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock &MBB = *MFI;
290*9880d681SAndroid Build Coastguard Worker     ++MFI;
291*9880d681SAndroid Build Coastguard Worker     Modified |= InsertITInstructions(MBB);
292*9880d681SAndroid Build Coastguard Worker   }
293*9880d681SAndroid Build Coastguard Worker 
294*9880d681SAndroid Build Coastguard Worker   if (Modified)
295*9880d681SAndroid Build Coastguard Worker     AFI->setHasITBlocks(true);
296*9880d681SAndroid Build Coastguard Worker 
297*9880d681SAndroid Build Coastguard Worker   return Modified;
298*9880d681SAndroid Build Coastguard Worker }
299*9880d681SAndroid Build Coastguard Worker 
300*9880d681SAndroid Build Coastguard Worker /// createThumb2ITBlockPass - Returns an instance of the Thumb2 IT blocks
301*9880d681SAndroid Build Coastguard Worker /// insertion pass.
createThumb2ITBlockPass()302*9880d681SAndroid Build Coastguard Worker FunctionPass *llvm::createThumb2ITBlockPass() {
303*9880d681SAndroid Build Coastguard Worker   return new Thumb2ITBlockPass();
304*9880d681SAndroid Build Coastguard Worker }
305