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