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