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#define DEBUG_TYPE "thumb2-it"
1106e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng#include "ARM.h"
1206e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng#include "ARMMachineFunctionInfo.h"
13ed338e80f92d6efa961d9f8c29239dde1507e683Evan Cheng#include "Thumb2InstrInfo.h"
1406e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng#include "llvm/CodeGen/MachineInstr.h"
1506e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng#include "llvm/CodeGen/MachineInstrBuilder.h"
16ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng#include "llvm/CodeGen/MachineInstrBundle.h"
1706e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng#include "llvm/CodeGen/MachineFunctionPass.h"
18d84712421121744797210a7814aafce8c5377d92Evan Cheng#include "llvm/ADT/SmallSet.h"
1906e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng#include "llvm/ADT/Statistic.h"
2006e16587ebc81e43b42157fa3afcfd806b59b296Evan Chengusing namespace llvm;
2106e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng
22d84712421121744797210a7814aafce8c5377d92Evan ChengSTATISTIC(NumITs,        "Number of IT blocks inserted");
23d84712421121744797210a7814aafce8c5377d92Evan ChengSTATISTIC(NumMovedInsts, "Number of predicated instructions moved");
2406e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng
2506e16587ebc81e43b42157fa3afcfd806b59b296Evan Chengnamespace {
26d84712421121744797210a7814aafce8c5377d92Evan Cheng  class Thumb2ITBlockPass : public MachineFunctionPass {
27d84712421121744797210a7814aafce8c5377d92Evan Cheng  public:
2806e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng    static char ID;
2990c579de5a383cee278acc3f7e7b9d0a656e6a35Owen Anderson    Thumb2ITBlockPass() : MachineFunctionPass(ID) {}
3006e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng
31ed338e80f92d6efa961d9f8c29239dde1507e683Evan Cheng    const Thumb2InstrInfo *TII;
3286050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng    const TargetRegisterInfo *TRI;
3306e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng    ARMFunctionInfo *AFI;
3406e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng
3506e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng    virtual bool runOnMachineFunction(MachineFunction &Fn);
3606e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng
3706e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng    virtual const char *getPassName() const {
3806e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng      return "Thumb IT blocks insertion pass";
3906e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng    }
4006e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng
4106e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng  private:
4286050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng    bool MoveCopyOutOfITBlock(MachineInstr *MI,
4386050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng                              ARMCC::CondCodes CC, ARMCC::CondCodes OCC,
4486050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng                              SmallSet<unsigned, 4> &Defs,
4586050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng                              SmallSet<unsigned, 4> &Uses);
46d84712421121744797210a7814aafce8c5377d92Evan Cheng    bool InsertITInstructions(MachineBasicBlock &MBB);
4706e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng  };
4806e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng  char Thumb2ITBlockPass::ID = 0;
4906e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng}
5006e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng
5186050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng/// TrackDefUses - Tracking what registers are being defined and used by
5286050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng/// instructions in the IT block. This also tracks "dependencies", i.e. uses
5386050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng/// in the IT block that are defined before the IT instruction.
5486050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Chengstatic void TrackDefUses(MachineInstr *MI,
5586050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng                         SmallSet<unsigned, 4> &Defs,
5686050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng                         SmallSet<unsigned, 4> &Uses,
5786050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng                         const TargetRegisterInfo *TRI) {
5886050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng  SmallVector<unsigned, 4> LocalDefs;
5986050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng  SmallVector<unsigned, 4> LocalUses;
6086050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng
61d84712421121744797210a7814aafce8c5377d92Evan Cheng  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
62d84712421121744797210a7814aafce8c5377d92Evan Cheng    MachineOperand &MO = MI->getOperand(i);
63d84712421121744797210a7814aafce8c5377d92Evan Cheng    if (!MO.isReg())
64d84712421121744797210a7814aafce8c5377d92Evan Cheng      continue;
65d84712421121744797210a7814aafce8c5377d92Evan Cheng    unsigned Reg = MO.getReg();
6686050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng    if (!Reg || Reg == ARM::ITSTATE || Reg == ARM::SP)
67d84712421121744797210a7814aafce8c5377d92Evan Cheng      continue;
6886050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng    if (MO.isUse())
6986050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng      LocalUses.push_back(Reg);
70d84712421121744797210a7814aafce8c5377d92Evan Cheng    else
7186050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng      LocalDefs.push_back(Reg);
7286050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng  }
7386050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng
7486050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng  for (unsigned i = 0, e = LocalUses.size(); i != e; ++i) {
7586050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng    unsigned Reg = LocalUses[i];
7686050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng    Uses.insert(Reg);
77396618b43a85e12d290a90b181c6af5d7c0c5f11Jakob Stoklund Olesen    for (MCSubRegIterator Subreg(Reg, TRI); Subreg.isValid(); ++Subreg)
7886050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng      Uses.insert(*Subreg);
7986050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng  }
8086050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng
8186050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng  for (unsigned i = 0, e = LocalDefs.size(); i != e; ++i) {
8286050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng    unsigned Reg = LocalDefs[i];
8386050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng    Defs.insert(Reg);
84396618b43a85e12d290a90b181c6af5d7c0c5f11Jakob Stoklund Olesen    for (MCSubRegIterator Subreg(Reg, TRI); Subreg.isValid(); ++Subreg)
8586050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng      Defs.insert(*Subreg);
8686050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng    if (Reg == ARM::CPSR)
8786050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng      continue;
8886050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng  }
8986050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng}
9086050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng
91c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesenstatic bool isCopy(MachineInstr *MI) {
92c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen  switch (MI->getOpcode()) {
93c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen  default:
94c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen    return false;
95c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen  case ARM::MOVr:
96c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen  case ARM::MOVr_TC:
97c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen  case ARM::tMOVr:
98c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen  case ARM::t2MOVr:
99c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen    return true;
100c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen  }
101c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen}
102c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen
10386050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Chengbool
10486050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan ChengThumb2ITBlockPass::MoveCopyOutOfITBlock(MachineInstr *MI,
10586050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng                                      ARMCC::CondCodes CC, ARMCC::CondCodes OCC,
10686050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng                                        SmallSet<unsigned, 4> &Defs,
10786050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng                                        SmallSet<unsigned, 4> &Uses) {
108c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen  if (!isCopy(MI))
109c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen    return false;
110c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen  // llvm models select's as two-address instructions. That means a copy
111c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen  // is inserted before a t2MOVccr, etc. If the copy is scheduled in
112c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen  // between selects we would end up creating multiple IT blocks.
113c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen  assert(MI->getOperand(0).getSubReg() == 0 &&
114c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen         MI->getOperand(1).getSubReg() == 0 &&
115c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen         "Sub-register indices still around?");
116c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen
117c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen  unsigned DstReg = MI->getOperand(0).getReg();
118c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen  unsigned SrcReg = MI->getOperand(1).getReg();
119c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen
120c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen  // First check if it's safe to move it.
121c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen  if (Uses.count(DstReg) || Defs.count(SrcReg))
122c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen    return false;
123c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen
124721e1d266902f4d906645b130d1b2a905d75fa31Bill Wendling  // If the CPSR is defined by this copy, then we don't want to move it. E.g.,
125721e1d266902f4d906645b130d1b2a905d75fa31Bill Wendling  // if we have:
126721e1d266902f4d906645b130d1b2a905d75fa31Bill Wendling  //
127721e1d266902f4d906645b130d1b2a905d75fa31Bill Wendling  //   movs  r1, r1
128721e1d266902f4d906645b130d1b2a905d75fa31Bill Wendling  //   rsb   r1, 0
129721e1d266902f4d906645b130d1b2a905d75fa31Bill Wendling  //   movs  r2, r2
130721e1d266902f4d906645b130d1b2a905d75fa31Bill Wendling  //   rsb   r2, 0
131721e1d266902f4d906645b130d1b2a905d75fa31Bill Wendling  //
132721e1d266902f4d906645b130d1b2a905d75fa31Bill Wendling  // we don't want this to be converted to:
133721e1d266902f4d906645b130d1b2a905d75fa31Bill Wendling  //
134721e1d266902f4d906645b130d1b2a905d75fa31Bill Wendling  //   movs  r1, r1
135721e1d266902f4d906645b130d1b2a905d75fa31Bill Wendling  //   movs  r2, r2
136721e1d266902f4d906645b130d1b2a905d75fa31Bill Wendling  //   itt   mi
137721e1d266902f4d906645b130d1b2a905d75fa31Bill Wendling  //   rsb   r1, 0
138721e1d266902f4d906645b130d1b2a905d75fa31Bill Wendling  //   rsb   r2, 0
139721e1d266902f4d906645b130d1b2a905d75fa31Bill Wendling  //
1403f56d4b957b04aaaf3ad27900713ea4d67f3189eBill Wendling  const MCInstrDesc &MCID = MI->getDesc();
1415a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng  if (MI->hasOptionalDef() &&
1423f56d4b957b04aaaf3ad27900713ea4d67f3189eBill Wendling      MI->getOperand(MCID.getNumOperands() - 1).getReg() == ARM::CPSR)
1433f56d4b957b04aaaf3ad27900713ea4d67f3189eBill Wendling    return false;
144721e1d266902f4d906645b130d1b2a905d75fa31Bill Wendling
145c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen  // Then peek at the next instruction to see if it's predicated on CC or OCC.
146c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen  // If not, then there is nothing to be gained by moving the copy.
147c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen  MachineBasicBlock::iterator I = MI; ++I;
148c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen  MachineBasicBlock::iterator E = MI->getParent()->end();
149c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen  while (I != E && I->isDebugValue())
150c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen    ++I;
151c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen  if (I != E) {
152c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen    unsigned NPredReg = 0;
153c89c744b69cecac576317a98322fd295e36e9886Craig Topper    ARMCC::CondCodes NCC = getITInstrPredicate(I, NPredReg);
154c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen    if (NCC == CC || NCC == OCC)
155c66756ba16a3df8b6426aee4ffd9c308f38bea57Jakob Stoklund Olesen      return true;
156d84712421121744797210a7814aafce8c5377d92Evan Cheng  }
15786050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng  return false;
158d84712421121744797210a7814aafce8c5377d92Evan Cheng}
159d84712421121744797210a7814aafce8c5377d92Evan Cheng
160d84712421121744797210a7814aafce8c5377d92Evan Chengbool Thumb2ITBlockPass::InsertITInstructions(MachineBasicBlock &MBB) {
16106e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng  bool Modified = false;
16206e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng
163d84712421121744797210a7814aafce8c5377d92Evan Cheng  SmallSet<unsigned, 4> Defs;
164d84712421121744797210a7814aafce8c5377d92Evan Cheng  SmallSet<unsigned, 4> Uses;
16506e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng  MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
16606e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng  while (MBBI != E) {
16706e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng    MachineInstr *MI = &*MBBI;
1685adb66a646e2ec32265263739f5b01c3f50c176aEvan Cheng    DebugLoc dl = MI->getDebugLoc();
1695adb66a646e2ec32265263739f5b01c3f50c176aEvan Cheng    unsigned PredReg = 0;
170c89c744b69cecac576317a98322fd295e36e9886Craig Topper    ARMCC::CondCodes CC = getITInstrPredicate(MI, PredReg);
17106e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng    if (CC == ARMCC::AL) {
17206e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng      ++MBBI;
17306e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng      continue;
17406e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng    }
17506e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng
176d84712421121744797210a7814aafce8c5377d92Evan Cheng    Defs.clear();
177d84712421121744797210a7814aafce8c5377d92Evan Cheng    Uses.clear();
17886050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng    TrackDefUses(MI, Defs, Uses, TRI);
179d84712421121744797210a7814aafce8c5377d92Evan Cheng
18006e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng    // Insert an IT instruction.
18106e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng    MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII->get(ARM::t2IT))
18206e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng      .addImm(CC);
18386050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng
18486050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng    // Add implicit use of ITSTATE to IT block instructions.
18586050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng    MI->addOperand(MachineOperand::CreateReg(ARM::ITSTATE, false/*ifDef*/,
18686050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng                                             true/*isImp*/, false/*isKill*/));
18786050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng
18886050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng    MachineInstr *LastITMI = MI;
189d84712421121744797210a7814aafce8c5377d92Evan Cheng    MachineBasicBlock::iterator InsertPos = MIB;
19006e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng    ++MBBI;
19106e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng
19286050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng    // Form IT block.
19306e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng    ARMCC::CondCodes OCC = ARMCC::getOppositeCondition(CC);
194bc9b754091ea281e769e487f396b40f6675b9edbEvan Cheng    unsigned Mask = 0, Pos = 3;
195452b54a8aebee45088b2157a66ae0f9f6a9088faSandeep Patel    // Branches, including tricky ones like LDM_RET, need to end an IT
196452b54a8aebee45088b2157a66ae0f9f6a9088faSandeep Patel    // block so check the instruction we just put in the block.
1978077e76f934d575437a55315a0d5fcdcab6d6608Jim Grosbach    for (; MBBI != E && Pos &&
1985a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng           (!MI->isBranch() && !MI->isReturn()) ; ++MBBI) {
1998077e76f934d575437a55315a0d5fcdcab6d6608Jim Grosbach      if (MBBI->isDebugValue())
2008077e76f934d575437a55315a0d5fcdcab6d6608Jim Grosbach        continue;
201d84712421121744797210a7814aafce8c5377d92Evan Cheng
202fd847118eda59dcfa318dcb0895d1764c2a7a0baEvan Cheng      MachineInstr *NMI = &*MBBI;
203452b54a8aebee45088b2157a66ae0f9f6a9088faSandeep Patel      MI = NMI;
204d84712421121744797210a7814aafce8c5377d92Evan Cheng
205fd847118eda59dcfa318dcb0895d1764c2a7a0baEvan Cheng      unsigned NPredReg = 0;
206c89c744b69cecac576317a98322fd295e36e9886Craig Topper      ARMCC::CondCodes NCC = getITInstrPredicate(NMI, NPredReg);
20786050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng      if (NCC == CC || NCC == OCC) {
208b675e255d0def28e9718c62336be6fd6e7a22e54Johnny Chen        Mask |= (NCC & 1) << Pos;
20986050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng        // Add implicit use of ITSTATE.
21086050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng        NMI->addOperand(MachineOperand::CreateReg(ARM::ITSTATE, false/*ifDef*/,
211e9e3f20ffbb20ebae6c48c3499c9b069f28e28fcJim Grosbach                                               true/*isImp*/, false/*isKill*/));
21286050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng        LastITMI = NMI;
21386050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng      } else {
214d84712421121744797210a7814aafce8c5377d92Evan Cheng        if (NCC == ARMCC::AL &&
21586050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng            MoveCopyOutOfITBlock(NMI, CC, OCC, Defs, Uses)) {
21686050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng          --MBBI;
21786050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng          MBB.remove(NMI);
21886050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng          MBB.insert(InsertPos, NMI);
21986050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng          ++NumMovedInsts;
22086050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng          continue;
221d84712421121744797210a7814aafce8c5377d92Evan Cheng        }
22206e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng        break;
223d84712421121744797210a7814aafce8c5377d92Evan Cheng      }
22486050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng      TrackDefUses(NMI, Defs, Uses, TRI);
225bc9b754091ea281e769e487f396b40f6675b9edbEvan Cheng      --Pos;
22606e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng    }
227d84712421121744797210a7814aafce8c5377d92Evan Cheng
22886050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng    // Finalize IT mask.
229bc9b754091ea281e769e487f396b40f6675b9edbEvan Cheng    Mask |= (1 << Pos);
230b675e255d0def28e9718c62336be6fd6e7a22e54Johnny Chen    // Tag along (firstcond[0] << 4) with the mask.
231b675e255d0def28e9718c62336be6fd6e7a22e54Johnny Chen    Mask |= (CC & 1) << 4;
23206e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng    MIB.addImm(Mask);
23386050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng
23486050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng    // Last instruction in IT block kills ITSTATE.
23586050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng    LastITMI->findRegisterUseOperand(ARM::ITSTATE)->setIsKill();
23686050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng
237ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng    // Finalize the bundle.
238bca15f9c8059ccb9244853f86593c35ac35c8801Evan Cheng    MachineBasicBlock::instr_iterator LI = LastITMI;
239bca15f9c8059ccb9244853f86593c35ac35c8801Evan Cheng    finalizeBundle(MBB, InsertPos.getInstrIterator(), llvm::next(LI));
240ddfd1377d2e4154d44dc3ad217735adc15af2e3fEvan Cheng
24106e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng    Modified = true;
24206e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng    ++NumITs;
24306e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng  }
24406e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng
24506e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng  return Modified;
24606e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng}
24706e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng
24806e16587ebc81e43b42157fa3afcfd806b59b296Evan Chengbool Thumb2ITBlockPass::runOnMachineFunction(MachineFunction &Fn) {
24906e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng  const TargetMachine &TM = Fn.getTarget();
25006e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng  AFI = Fn.getInfo<ARMFunctionInfo>();
251ed338e80f92d6efa961d9f8c29239dde1507e683Evan Cheng  TII = static_cast<const Thumb2InstrInfo*>(TM.getInstrInfo());
25286050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng  TRI = TM.getRegisterInfo();
25306e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng
25406e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng  if (!AFI->isThumbFunction())
25506e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng    return false;
25606e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng
25706e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng  bool Modified = false;
258d84712421121744797210a7814aafce8c5377d92Evan Cheng  for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E; ) {
25906e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng    MachineBasicBlock &MBB = *MFI;
260d84712421121744797210a7814aafce8c5377d92Evan Cheng    ++MFI;
261dca653951c693edf47437cf0a10d0d0dbb57276dEvan Cheng    Modified |= InsertITInstructions(MBB);
26206e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng  }
26306e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng
264dca653951c693edf47437cf0a10d0d0dbb57276dEvan Cheng  if (Modified)
26586050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng    AFI->setHasITBlocks(true);
26686050dc8cc0aaea8c9dfeb89de02cafbd7f48d92Evan Cheng
26706e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng  return Modified;
26806e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng}
26906e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng
27034f8a029e341a74fd02ccb198f4d4f0c8b38c015Evan Cheng/// createThumb2ITBlockPass - Returns an instance of the Thumb2 IT blocks
27106e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng/// insertion pass.
272dca653951c693edf47437cf0a10d0d0dbb57276dEvan ChengFunctionPass *llvm::createThumb2ITBlockPass() {
273dca653951c693edf47437cf0a10d0d0dbb57276dEvan Cheng  return new Thumb2ITBlockPass();
27406e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng}
275