131d157ae1ac2cd9c787dc3c1d28e64c682803844Jia Liu//===-- Thumb2ITBlockPass.cpp - Insert Thumb-2 IT blocks ------------------===//
206e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng//
306e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng//                     The LLVM Compiler Infrastructure
406e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng//
506e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng// This file is distributed under the University of Illinois Open Source
606e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng// License. See LICENSE.TXT for details.
706e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng//
806e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng//===----------------------------------------------------------------------===//
906e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng
1006e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng#include "ARM.h"
1106e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng#include "ARMMachineFunctionInfo.h"
12ed338e80f92d6efa961d9f8c29239dde1507e683Evan Cheng#include "Thumb2InstrInfo.h"
13d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/SmallSet.h"
14d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/Statistic.h"
15d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/CodeGen/MachineFunctionPass.h"
1606e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng#include "llvm/CodeGen/MachineInstr.h"
1706e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng#include "llvm/CodeGen/MachineInstrBuilder.h"
18ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng#include "llvm/CodeGen/MachineInstrBundle.h"
1906e16587ebc81e43b42157fa3afcfd806b59b296Evan Chengusing namespace llvm;
2006e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng
21dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "thumb2-it"
22dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
23d84712421121744797210a7814aafce8c5377d92Evan ChengSTATISTIC(NumITs,        "Number of IT blocks inserted");
24d84712421121744797210a7814aafce8c5377d92Evan ChengSTATISTIC(NumMovedInsts, "Number of predicated instructions moved");
2506e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng
2606e16587ebc81e43b42157fa3afcfd806b59b296Evan Chengnamespace {
27d84712421121744797210a7814aafce8c5377d92Evan Cheng  class Thumb2ITBlockPass : public MachineFunctionPass {
28d84712421121744797210a7814aafce8c5377d92Evan Cheng  public:
2906e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng    static char ID;
3090c579de5a383cee278acc3f7e7b9d0a656e6a35Owen Anderson    Thumb2ITBlockPass() : MachineFunctionPass(ID) {}
3106e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng
32929bdb23794b615dc6b0cc59db21f0450c3ce33bWeiming Zhao    bool restrictIT;
33ed338e80f92d6efa961d9f8c29239dde1507e683Evan Cheng    const Thumb2InstrInfo *TII;
3486050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng    const TargetRegisterInfo *TRI;
3506e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng    ARMFunctionInfo *AFI;
3606e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng
3736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool runOnMachineFunction(MachineFunction &Fn) override;
3806e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng
3936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const char *getPassName() const override {
4006e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng      return "Thumb IT blocks insertion pass";
4106e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng    }
4206e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng
4306e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng  private:
4486050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng    bool MoveCopyOutOfITBlock(MachineInstr *MI,
4586050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng                              ARMCC::CondCodes CC, ARMCC::CondCodes OCC,
4686050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng                              SmallSet<unsigned, 4> &Defs,
4786050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng                              SmallSet<unsigned, 4> &Uses);
48d84712421121744797210a7814aafce8c5377d92Evan Cheng    bool InsertITInstructions(MachineBasicBlock &MBB);
4906e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng  };
5006e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng  char Thumb2ITBlockPass::ID = 0;
5106e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng}
5206e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng
5386050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng/// TrackDefUses - Tracking what registers are being defined and used by
5486050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng/// instructions in the IT block. This also tracks "dependencies", i.e. uses
5586050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng/// in the IT block that are defined before the IT instruction.
5686050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Chengstatic void TrackDefUses(MachineInstr *MI,
5786050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng                         SmallSet<unsigned, 4> &Defs,
5886050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng                         SmallSet<unsigned, 4> &Uses,
5986050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng                         const TargetRegisterInfo *TRI) {
6086050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng  SmallVector<unsigned, 4> LocalDefs;
6186050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng  SmallVector<unsigned, 4> LocalUses;
6286050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng
63d84712421121744797210a7814aafce8c5377d92Evan Cheng  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
64d84712421121744797210a7814aafce8c5377d92Evan Cheng    MachineOperand &MO = MI->getOperand(i);
65d84712421121744797210a7814aafce8c5377d92Evan Cheng    if (!MO.isReg())
66d84712421121744797210a7814aafce8c5377d92Evan Cheng      continue;
67d84712421121744797210a7814aafce8c5377d92Evan Cheng    unsigned Reg = MO.getReg();
6886050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng    if (!Reg || Reg == ARM::ITSTATE || Reg == ARM::SP)
69d84712421121744797210a7814aafce8c5377d92Evan Cheng      continue;
7086050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng    if (MO.isUse())
7186050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng      LocalUses.push_back(Reg);
72d84712421121744797210a7814aafce8c5377d92Evan Cheng    else
7386050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng      LocalDefs.push_back(Reg);
7486050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng  }
7586050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng
7686050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng  for (unsigned i = 0, e = LocalUses.size(); i != e; ++i) {
7786050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng    unsigned Reg = LocalUses[i];
7862c320a755ac27ac2b7f64e927892249e0f486e0Chad Rosier    for (MCSubRegIterator Subreg(Reg, TRI, /*IncludeSelf=*/true);
7962c320a755ac27ac2b7f64e927892249e0f486e0Chad Rosier         Subreg.isValid(); ++Subreg)
8086050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng      Uses.insert(*Subreg);
8186050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng  }
8286050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng
8386050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng  for (unsigned i = 0, e = LocalDefs.size(); i != e; ++i) {
8486050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng    unsigned Reg = LocalDefs[i];
8562c320a755ac27ac2b7f64e927892249e0f486e0Chad Rosier    for (MCSubRegIterator Subreg(Reg, TRI, /*IncludeSelf=*/true);
8662c320a755ac27ac2b7f64e927892249e0f486e0Chad Rosier         Subreg.isValid(); ++Subreg)
8786050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng      Defs.insert(*Subreg);
8886050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng    if (Reg == ARM::CPSR)
8986050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng      continue;
9086050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng  }
9186050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng}
9286050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng
93c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesenstatic bool isCopy(MachineInstr *MI) {
94c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen  switch (MI->getOpcode()) {
95c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen  default:
96c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen    return false;
97c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen  case ARM::MOVr:
98c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen  case ARM::MOVr_TC:
99c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen  case ARM::tMOVr:
100c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen  case ARM::t2MOVr:
101c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen    return true;
102c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen  }
103c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen}
104c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen
10586050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Chengbool
10686050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan ChengThumb2ITBlockPass::MoveCopyOutOfITBlock(MachineInstr *MI,
10786050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng                                      ARMCC::CondCodes CC, ARMCC::CondCodes OCC,
10886050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng                                        SmallSet<unsigned, 4> &Defs,
10986050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng                                        SmallSet<unsigned, 4> &Uses) {
110c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen  if (!isCopy(MI))
111c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen    return false;
112c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen  // llvm models select's as two-address instructions. That means a copy
113c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen  // is inserted before a t2MOVccr, etc. If the copy is scheduled in
114c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen  // between selects we would end up creating multiple IT blocks.
115c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen  assert(MI->getOperand(0).getSubReg() == 0 &&
116c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen         MI->getOperand(1).getSubReg() == 0 &&
117c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen         "Sub-register indices still around?");
118c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen
119c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen  unsigned DstReg = MI->getOperand(0).getReg();
120c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen  unsigned SrcReg = MI->getOperand(1).getReg();
121c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen
122c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen  // First check if it's safe to move it.
123c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen  if (Uses.count(DstReg) || Defs.count(SrcReg))
124c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen    return false;
125c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen
126721e1d266902f4d906645b130d1b2a905d75fa31Bill Wendling  // If the CPSR is defined by this copy, then we don't want to move it. E.g.,
127721e1d266902f4d906645b130d1b2a905d75fa31Bill Wendling  // if we have:
128721e1d266902f4d906645b130d1b2a905d75fa31Bill Wendling  //
129721e1d266902f4d906645b130d1b2a905d75fa31Bill Wendling  //   movs  r1, r1
130721e1d266902f4d906645b130d1b2a905d75fa31Bill Wendling  //   rsb   r1, 0
131721e1d266902f4d906645b130d1b2a905d75fa31Bill Wendling  //   movs  r2, r2
132721e1d266902f4d906645b130d1b2a905d75fa31Bill Wendling  //   rsb   r2, 0
133721e1d266902f4d906645b130d1b2a905d75fa31Bill Wendling  //
134721e1d266902f4d906645b130d1b2a905d75fa31Bill Wendling  // we don't want this to be converted to:
135721e1d266902f4d906645b130d1b2a905d75fa31Bill Wendling  //
136721e1d266902f4d906645b130d1b2a905d75fa31Bill Wendling  //   movs  r1, r1
137721e1d266902f4d906645b130d1b2a905d75fa31Bill Wendling  //   movs  r2, r2
138721e1d266902f4d906645b130d1b2a905d75fa31Bill Wendling  //   itt   mi
139721e1d266902f4d906645b130d1b2a905d75fa31Bill Wendling  //   rsb   r1, 0
140721e1d266902f4d906645b130d1b2a905d75fa31Bill Wendling  //   rsb   r2, 0
141721e1d266902f4d906645b130d1b2a905d75fa31Bill Wendling  //
1423f56d4b957b04aaaf3ad27900713ea4d67f3189eBill Wendling  const MCInstrDesc &MCID = MI->getDesc();
1435a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng  if (MI->hasOptionalDef() &&
1443f56d4b957b04aaaf3ad27900713ea4d67f3189eBill Wendling      MI->getOperand(MCID.getNumOperands() - 1).getReg() == ARM::CPSR)
1453f56d4b957b04aaaf3ad27900713ea4d67f3189eBill Wendling    return false;
146721e1d266902f4d906645b130d1b2a905d75fa31Bill Wendling
147c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen  // Then peek at the next instruction to see if it's predicated on CC or OCC.
148c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen  // If not, then there is nothing to be gained by moving the copy.
149c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen  MachineBasicBlock::iterator I = MI; ++I;
150c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen  MachineBasicBlock::iterator E = MI->getParent()->end();
151c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen  while (I != E && I->isDebugValue())
152c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen    ++I;
153c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen  if (I != E) {
154c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen    unsigned NPredReg = 0;
155c89c744b69cecac576317a98322fd295e36e9886Craig Topper    ARMCC::CondCodes NCC = getITInstrPredicate(I, NPredReg);
156c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen    if (NCC == CC || NCC == OCC)
157c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen      return true;
158d84712421121744797210a7814aafce8c5377d92Evan Cheng  }
15986050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng  return false;
160d84712421121744797210a7814aafce8c5377d92Evan Cheng}
161d84712421121744797210a7814aafce8c5377d92Evan Cheng
162d84712421121744797210a7814aafce8c5377d92Evan Chengbool Thumb2ITBlockPass::InsertITInstructions(MachineBasicBlock &MBB) {
16306e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng  bool Modified = false;
16406e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng
165d84712421121744797210a7814aafce8c5377d92Evan Cheng  SmallSet<unsigned, 4> Defs;
166d84712421121744797210a7814aafce8c5377d92Evan Cheng  SmallSet<unsigned, 4> Uses;
16706e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng  MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
16806e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng  while (MBBI != E) {
16906e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng    MachineInstr *MI = &*MBBI;
1705adb66a646e2ec32265263739f5b01c3f50c176aEvan Cheng    DebugLoc dl = MI->getDebugLoc();
1715adb66a646e2ec32265263739f5b01c3f50c176aEvan Cheng    unsigned PredReg = 0;
172c89c744b69cecac576317a98322fd295e36e9886Craig Topper    ARMCC::CondCodes CC = getITInstrPredicate(MI, PredReg);
17306e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng    if (CC == ARMCC::AL) {
17406e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng      ++MBBI;
17506e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng      continue;
17606e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng    }
17706e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng
178d84712421121744797210a7814aafce8c5377d92Evan Cheng    Defs.clear();
179d84712421121744797210a7814aafce8c5377d92Evan Cheng    Uses.clear();
18086050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng    TrackDefUses(MI, Defs, Uses, TRI);
181d84712421121744797210a7814aafce8c5377d92Evan Cheng
18206e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng    // Insert an IT instruction.
18306e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng    MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII->get(ARM::t2IT))
18406e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng      .addImm(CC);
18586050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng
18686050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng    // Add implicit use of ITSTATE to IT block instructions.
18786050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng    MI->addOperand(MachineOperand::CreateReg(ARM::ITSTATE, false/*ifDef*/,
18886050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng                                             true/*isImp*/, false/*isKill*/));
18986050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng
19086050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng    MachineInstr *LastITMI = MI;
191d84712421121744797210a7814aafce8c5377d92Evan Cheng    MachineBasicBlock::iterator InsertPos = MIB;
19206e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng    ++MBBI;
19306e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng
19486050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng    // Form IT block.
19506e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng    ARMCC::CondCodes OCC = ARMCC::getOppositeCondition(CC);
196bc9b754091ea281e769e487f396b40f6675b9edbEvan Cheng    unsigned Mask = 0, Pos = 3;
197b57d99694b87326a2eea26d76becf67bf5784b49Joey Gouly
198929bdb23794b615dc6b0cc59db21f0450c3ce33bWeiming Zhao    // v8 IT blocks are limited to one conditional op unless -arm-no-restrict-it
199929bdb23794b615dc6b0cc59db21f0450c3ce33bWeiming Zhao    // is set: skip the loop
200929bdb23794b615dc6b0cc59db21f0450c3ce33bWeiming Zhao    if (!restrictIT) {
201b57d99694b87326a2eea26d76becf67bf5784b49Joey Gouly      // Branches, including tricky ones like LDM_RET, need to end an IT
202b57d99694b87326a2eea26d76becf67bf5784b49Joey Gouly      // block so check the instruction we just put in the block.
203b57d99694b87326a2eea26d76becf67bf5784b49Joey Gouly      for (; MBBI != E && Pos &&
204b57d99694b87326a2eea26d76becf67bf5784b49Joey Gouly             (!MI->isBranch() && !MI->isReturn()) ; ++MBBI) {
205b57d99694b87326a2eea26d76becf67bf5784b49Joey Gouly        if (MBBI->isDebugValue())
20686050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng          continue;
207b57d99694b87326a2eea26d76becf67bf5784b49Joey Gouly
208b57d99694b87326a2eea26d76becf67bf5784b49Joey Gouly        MachineInstr *NMI = &*MBBI;
209b57d99694b87326a2eea26d76becf67bf5784b49Joey Gouly        MI = NMI;
210b57d99694b87326a2eea26d76becf67bf5784b49Joey Gouly
211b57d99694b87326a2eea26d76becf67bf5784b49Joey Gouly        unsigned NPredReg = 0;
212b57d99694b87326a2eea26d76becf67bf5784b49Joey Gouly        ARMCC::CondCodes NCC = getITInstrPredicate(NMI, NPredReg);
213b57d99694b87326a2eea26d76becf67bf5784b49Joey Gouly        if (NCC == CC || NCC == OCC) {
214b57d99694b87326a2eea26d76becf67bf5784b49Joey Gouly          Mask |= (NCC & 1) << Pos;
215b57d99694b87326a2eea26d76becf67bf5784b49Joey Gouly          // Add implicit use of ITSTATE.
216b57d99694b87326a2eea26d76becf67bf5784b49Joey Gouly          NMI->addOperand(MachineOperand::CreateReg(ARM::ITSTATE, false/*ifDef*/,
217b57d99694b87326a2eea26d76becf67bf5784b49Joey Gouly                                                 true/*isImp*/, false/*isKill*/));
218b57d99694b87326a2eea26d76becf67bf5784b49Joey Gouly          LastITMI = NMI;
219b57d99694b87326a2eea26d76becf67bf5784b49Joey Gouly        } else {
220b57d99694b87326a2eea26d76becf67bf5784b49Joey Gouly          if (NCC == ARMCC::AL &&
221b57d99694b87326a2eea26d76becf67bf5784b49Joey Gouly              MoveCopyOutOfITBlock(NMI, CC, OCC, Defs, Uses)) {
222b57d99694b87326a2eea26d76becf67bf5784b49Joey Gouly            --MBBI;
223b57d99694b87326a2eea26d76becf67bf5784b49Joey Gouly            MBB.remove(NMI);
224b57d99694b87326a2eea26d76becf67bf5784b49Joey Gouly            MBB.insert(InsertPos, NMI);
225b57d99694b87326a2eea26d76becf67bf5784b49Joey Gouly            ++NumMovedInsts;
226b57d99694b87326a2eea26d76becf67bf5784b49Joey Gouly            continue;
227b57d99694b87326a2eea26d76becf67bf5784b49Joey Gouly          }
228b57d99694b87326a2eea26d76becf67bf5784b49Joey Gouly          break;
229d84712421121744797210a7814aafce8c5377d92Evan Cheng        }
230b57d99694b87326a2eea26d76becf67bf5784b49Joey Gouly        TrackDefUses(NMI, Defs, Uses, TRI);
231b57d99694b87326a2eea26d76becf67bf5784b49Joey Gouly        --Pos;
232d84712421121744797210a7814aafce8c5377d92Evan Cheng      }
23306e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng    }
234d84712421121744797210a7814aafce8c5377d92Evan Cheng
23586050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng    // Finalize IT mask.
236bc9b754091ea281e769e487f396b40f6675b9edbEvan Cheng    Mask |= (1 << Pos);
237b675e255d0def28e9718c62336be6fd6e7a22e54Johnny Chen    // Tag along (firstcond[0] << 4) with the mask.
238b675e255d0def28e9718c62336be6fd6e7a22e54Johnny Chen    Mask |= (CC & 1) << 4;
23906e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng    MIB.addImm(Mask);
24086050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng
24186050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng    // Last instruction in IT block kills ITSTATE.
24286050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng    LastITMI->findRegisterUseOperand(ARM::ITSTATE)->setIsKill();
24386050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng
244ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng    // Finalize the bundle.
245bca15f9c8059ccb9244853f86593c35ac35c8801Evan Cheng    MachineBasicBlock::instr_iterator LI = LastITMI;
24636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    finalizeBundle(MBB, InsertPos.getInstrIterator(), std::next(LI));
247ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng
24806e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng    Modified = true;
24906e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng    ++NumITs;
25006e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng  }
25106e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng
25206e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng  return Modified;
25306e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng}
25406e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng
25506e16587ebc81e43b42157fa3afcfd806b59b296Evan Chengbool Thumb2ITBlockPass::runOnMachineFunction(MachineFunction &Fn) {
25606e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng  const TargetMachine &TM = Fn.getTarget();
25706e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng  AFI = Fn.getInfo<ARMFunctionInfo>();
258ed338e80f92d6efa961d9f8c29239dde1507e683Evan Cheng  TII = static_cast<const Thumb2InstrInfo*>(TM.getInstrInfo());
25986050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng  TRI = TM.getRegisterInfo();
260929bdb23794b615dc6b0cc59db21f0450c3ce33bWeiming Zhao  restrictIT = TM.getSubtarget<ARMSubtarget>().restrictIT();
26106e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng
26206e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng  if (!AFI->isThumbFunction())
26306e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng    return false;
26406e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng
26506e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng  bool Modified = false;
266d84712421121744797210a7814aafce8c5377d92Evan Cheng  for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E; ) {
26706e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng    MachineBasicBlock &MBB = *MFI;
268d84712421121744797210a7814aafce8c5377d92Evan Cheng    ++MFI;
269dca653951c693edf47437cf0a10d0d0dbb57276dEvan Cheng    Modified |= InsertITInstructions(MBB);
27006e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng  }
27106e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng
272dca653951c693edf47437cf0a10d0d0dbb57276dEvan Cheng  if (Modified)
27386050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng    AFI->setHasITBlocks(true);
27486050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng
27506e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng  return Modified;
27606e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng}
27706e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng
27834f8a029e341a74fd02ccb198f4d4f0c8b38c015Evan Cheng/// createThumb2ITBlockPass - Returns an instance of the Thumb2 IT blocks
27906e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng/// insertion pass.
280dca653951c693edf47437cf0a10d0d0dbb57276dEvan ChengFunctionPass *llvm::createThumb2ITBlockPass() {
281dca653951c693edf47437cf0a10d0d0dbb57276dEvan Cheng  return new Thumb2ITBlockPass();
28206e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng}
283