Thumb2ITBlockPass.cpp revision 288943
1234353Sdim//===-- Thumb2ITBlockPass.cpp - Insert Thumb-2 IT blocks ------------------===// 2198090Srdivacky// 3198090Srdivacky// The LLVM Compiler Infrastructure 4198090Srdivacky// 5198090Srdivacky// This file is distributed under the University of Illinois Open Source 6198090Srdivacky// License. See LICENSE.TXT for details. 7198090Srdivacky// 8198090Srdivacky//===----------------------------------------------------------------------===// 9198090Srdivacky 10198090Srdivacky#include "ARM.h" 11198090Srdivacky#include "ARMMachineFunctionInfo.h" 12198090Srdivacky#include "Thumb2InstrInfo.h" 13249423Sdim#include "llvm/ADT/SmallSet.h" 14249423Sdim#include "llvm/ADT/Statistic.h" 15249423Sdim#include "llvm/CodeGen/MachineFunctionPass.h" 16198090Srdivacky#include "llvm/CodeGen/MachineInstr.h" 17198090Srdivacky#include "llvm/CodeGen/MachineInstrBuilder.h" 18234353Sdim#include "llvm/CodeGen/MachineInstrBundle.h" 19198090Srdivackyusing namespace llvm; 20198090Srdivacky 21276479Sdim#define DEBUG_TYPE "thumb2-it" 22276479Sdim 23210299SedSTATISTIC(NumITs, "Number of IT blocks inserted"); 24210299SedSTATISTIC(NumMovedInsts, "Number of predicated instructions moved"); 25198090Srdivacky 26198090Srdivackynamespace { 27210299Sed class Thumb2ITBlockPass : public MachineFunctionPass { 28210299Sed public: 29198090Srdivacky static char ID; 30212904Sdim Thumb2ITBlockPass() : MachineFunctionPass(ID) {} 31198090Srdivacky 32261991Sdim bool restrictIT; 33198090Srdivacky const Thumb2InstrInfo *TII; 34210299Sed const TargetRegisterInfo *TRI; 35198090Srdivacky ARMFunctionInfo *AFI; 36198090Srdivacky 37276479Sdim bool runOnMachineFunction(MachineFunction &Fn) override; 38198090Srdivacky 39276479Sdim const char *getPassName() const override { 40198090Srdivacky return "Thumb IT blocks insertion pass"; 41198090Srdivacky } 42198090Srdivacky 43198090Srdivacky private: 44210299Sed bool MoveCopyOutOfITBlock(MachineInstr *MI, 45210299Sed ARMCC::CondCodes CC, ARMCC::CondCodes OCC, 46210299Sed SmallSet<unsigned, 4> &Defs, 47210299Sed SmallSet<unsigned, 4> &Uses); 48210299Sed bool InsertITInstructions(MachineBasicBlock &MBB); 49198090Srdivacky }; 50198090Srdivacky char Thumb2ITBlockPass::ID = 0; 51198090Srdivacky} 52198090Srdivacky 53210299Sed/// TrackDefUses - Tracking what registers are being defined and used by 54210299Sed/// instructions in the IT block. This also tracks "dependencies", i.e. uses 55210299Sed/// in the IT block that are defined before the IT instruction. 56210299Sedstatic void TrackDefUses(MachineInstr *MI, 57210299Sed SmallSet<unsigned, 4> &Defs, 58210299Sed SmallSet<unsigned, 4> &Uses, 59210299Sed const TargetRegisterInfo *TRI) { 60210299Sed SmallVector<unsigned, 4> LocalDefs; 61210299Sed SmallVector<unsigned, 4> LocalUses; 62210299Sed 63210299Sed for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 64210299Sed MachineOperand &MO = MI->getOperand(i); 65210299Sed if (!MO.isReg()) 66210299Sed continue; 67210299Sed unsigned Reg = MO.getReg(); 68210299Sed if (!Reg || Reg == ARM::ITSTATE || Reg == ARM::SP) 69210299Sed continue; 70210299Sed if (MO.isUse()) 71210299Sed LocalUses.push_back(Reg); 72210299Sed else 73210299Sed LocalDefs.push_back(Reg); 74210299Sed } 75210299Sed 76210299Sed for (unsigned i = 0, e = LocalUses.size(); i != e; ++i) { 77210299Sed unsigned Reg = LocalUses[i]; 78261991Sdim for (MCSubRegIterator Subreg(Reg, TRI, /*IncludeSelf=*/true); 79261991Sdim Subreg.isValid(); ++Subreg) 80210299Sed Uses.insert(*Subreg); 81210299Sed } 82210299Sed 83210299Sed for (unsigned i = 0, e = LocalDefs.size(); i != e; ++i) { 84210299Sed unsigned Reg = LocalDefs[i]; 85261991Sdim for (MCSubRegIterator Subreg(Reg, TRI, /*IncludeSelf=*/true); 86261991Sdim Subreg.isValid(); ++Subreg) 87210299Sed Defs.insert(*Subreg); 88210299Sed if (Reg == ARM::CPSR) 89210299Sed continue; 90210299Sed } 91198090Srdivacky} 92198090Srdivacky 93288943Sdim/// Clear kill flags for any uses in the given set. This will likely 94288943Sdim/// conservatively remove more kill flags than are necessary, but removing them 95288943Sdim/// is safer than incorrect kill flags remaining on instructions. 96288943Sdimstatic void ClearKillFlags(MachineInstr *MI, SmallSet<unsigned, 4> &Uses) { 97288943Sdim for (MachineOperand &MO : MI->operands()) { 98288943Sdim if (!MO.isReg() || MO.isDef() || !MO.isKill()) 99288943Sdim continue; 100288943Sdim if (!Uses.count(MO.getReg())) 101288943Sdim continue; 102288943Sdim MO.setIsKill(false); 103288943Sdim } 104288943Sdim} 105288943Sdim 106212904Sdimstatic bool isCopy(MachineInstr *MI) { 107212904Sdim switch (MI->getOpcode()) { 108212904Sdim default: 109212904Sdim return false; 110212904Sdim case ARM::MOVr: 111212904Sdim case ARM::MOVr_TC: 112212904Sdim case ARM::tMOVr: 113212904Sdim case ARM::t2MOVr: 114212904Sdim return true; 115212904Sdim } 116212904Sdim} 117212904Sdim 118210299Sedbool 119210299SedThumb2ITBlockPass::MoveCopyOutOfITBlock(MachineInstr *MI, 120210299Sed ARMCC::CondCodes CC, ARMCC::CondCodes OCC, 121210299Sed SmallSet<unsigned, 4> &Defs, 122210299Sed SmallSet<unsigned, 4> &Uses) { 123212904Sdim if (!isCopy(MI)) 124212904Sdim return false; 125212904Sdim // llvm models select's as two-address instructions. That means a copy 126212904Sdim // is inserted before a t2MOVccr, etc. If the copy is scheduled in 127212904Sdim // between selects we would end up creating multiple IT blocks. 128212904Sdim assert(MI->getOperand(0).getSubReg() == 0 && 129212904Sdim MI->getOperand(1).getSubReg() == 0 && 130212904Sdim "Sub-register indices still around?"); 131210299Sed 132212904Sdim unsigned DstReg = MI->getOperand(0).getReg(); 133212904Sdim unsigned SrcReg = MI->getOperand(1).getReg(); 134210299Sed 135212904Sdim // First check if it's safe to move it. 136212904Sdim if (Uses.count(DstReg) || Defs.count(SrcReg)) 137212904Sdim return false; 138212904Sdim 139226633Sdim // If the CPSR is defined by this copy, then we don't want to move it. E.g., 140226633Sdim // if we have: 141226633Sdim // 142226633Sdim // movs r1, r1 143226633Sdim // rsb r1, 0 144226633Sdim // movs r2, r2 145226633Sdim // rsb r2, 0 146226633Sdim // 147226633Sdim // we don't want this to be converted to: 148226633Sdim // 149226633Sdim // movs r1, r1 150226633Sdim // movs r2, r2 151226633Sdim // itt mi 152226633Sdim // rsb r1, 0 153226633Sdim // rsb r2, 0 154226633Sdim // 155226633Sdim const MCInstrDesc &MCID = MI->getDesc(); 156234353Sdim if (MI->hasOptionalDef() && 157226633Sdim MI->getOperand(MCID.getNumOperands() - 1).getReg() == ARM::CPSR) 158226633Sdim return false; 159226633Sdim 160212904Sdim // Then peek at the next instruction to see if it's predicated on CC or OCC. 161212904Sdim // If not, then there is nothing to be gained by moving the copy. 162212904Sdim MachineBasicBlock::iterator I = MI; ++I; 163212904Sdim MachineBasicBlock::iterator E = MI->getParent()->end(); 164212904Sdim while (I != E && I->isDebugValue()) 165212904Sdim ++I; 166212904Sdim if (I != E) { 167212904Sdim unsigned NPredReg = 0; 168234353Sdim ARMCC::CondCodes NCC = getITInstrPredicate(I, NPredReg); 169212904Sdim if (NCC == CC || NCC == OCC) 170212904Sdim return true; 171210299Sed } 172210299Sed return false; 173210299Sed} 174210299Sed 175210299Sedbool Thumb2ITBlockPass::InsertITInstructions(MachineBasicBlock &MBB) { 176198090Srdivacky bool Modified = false; 177198090Srdivacky 178210299Sed SmallSet<unsigned, 4> Defs; 179210299Sed SmallSet<unsigned, 4> Uses; 180198090Srdivacky MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end(); 181198090Srdivacky while (MBBI != E) { 182198090Srdivacky MachineInstr *MI = &*MBBI; 183198090Srdivacky DebugLoc dl = MI->getDebugLoc(); 184198090Srdivacky unsigned PredReg = 0; 185234353Sdim ARMCC::CondCodes CC = getITInstrPredicate(MI, PredReg); 186198090Srdivacky if (CC == ARMCC::AL) { 187198090Srdivacky ++MBBI; 188198090Srdivacky continue; 189198090Srdivacky } 190198090Srdivacky 191210299Sed Defs.clear(); 192210299Sed Uses.clear(); 193210299Sed TrackDefUses(MI, Defs, Uses, TRI); 194210299Sed 195198090Srdivacky // Insert an IT instruction. 196198090Srdivacky MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII->get(ARM::t2IT)) 197198090Srdivacky .addImm(CC); 198210299Sed 199210299Sed // Add implicit use of ITSTATE to IT block instructions. 200210299Sed MI->addOperand(MachineOperand::CreateReg(ARM::ITSTATE, false/*ifDef*/, 201210299Sed true/*isImp*/, false/*isKill*/)); 202210299Sed 203210299Sed MachineInstr *LastITMI = MI; 204280031Sdim MachineBasicBlock::iterator InsertPos = MIB.getInstr(); 205198090Srdivacky ++MBBI; 206198090Srdivacky 207210299Sed // Form IT block. 208198090Srdivacky ARMCC::CondCodes OCC = ARMCC::getOppositeCondition(CC); 209198090Srdivacky unsigned Mask = 0, Pos = 3; 210210299Sed 211261991Sdim // v8 IT blocks are limited to one conditional op unless -arm-no-restrict-it 212261991Sdim // is set: skip the loop 213261991Sdim if (!restrictIT) { 214261991Sdim // Branches, including tricky ones like LDM_RET, need to end an IT 215261991Sdim // block so check the instruction we just put in the block. 216261991Sdim for (; MBBI != E && Pos && 217261991Sdim (!MI->isBranch() && !MI->isReturn()) ; ++MBBI) { 218261991Sdim if (MBBI->isDebugValue()) 219261991Sdim continue; 220210299Sed 221261991Sdim MachineInstr *NMI = &*MBBI; 222261991Sdim MI = NMI; 223261991Sdim 224261991Sdim unsigned NPredReg = 0; 225261991Sdim ARMCC::CondCodes NCC = getITInstrPredicate(NMI, NPredReg); 226261991Sdim if (NCC == CC || NCC == OCC) { 227261991Sdim Mask |= (NCC & 1) << Pos; 228261991Sdim // Add implicit use of ITSTATE. 229261991Sdim NMI->addOperand(MachineOperand::CreateReg(ARM::ITSTATE, false/*ifDef*/, 230261991Sdim true/*isImp*/, false/*isKill*/)); 231261991Sdim LastITMI = NMI; 232261991Sdim } else { 233261991Sdim if (NCC == ARMCC::AL && 234261991Sdim MoveCopyOutOfITBlock(NMI, CC, OCC, Defs, Uses)) { 235261991Sdim --MBBI; 236261991Sdim MBB.remove(NMI); 237261991Sdim MBB.insert(InsertPos, NMI); 238288943Sdim ClearKillFlags(MI, Uses); 239261991Sdim ++NumMovedInsts; 240261991Sdim continue; 241261991Sdim } 242261991Sdim break; 243210299Sed } 244261991Sdim TrackDefUses(NMI, Defs, Uses, TRI); 245261991Sdim --Pos; 246210299Sed } 247198090Srdivacky } 248210299Sed 249210299Sed // Finalize IT mask. 250198090Srdivacky Mask |= (1 << Pos); 251205407Srdivacky // Tag along (firstcond[0] << 4) with the mask. 252205407Srdivacky Mask |= (CC & 1) << 4; 253198090Srdivacky MIB.addImm(Mask); 254210299Sed 255210299Sed // Last instruction in IT block kills ITSTATE. 256210299Sed LastITMI->findRegisterUseOperand(ARM::ITSTATE)->setIsKill(); 257210299Sed 258234353Sdim // Finalize the bundle. 259234353Sdim MachineBasicBlock::instr_iterator LI = LastITMI; 260276479Sdim finalizeBundle(MBB, InsertPos.getInstrIterator(), std::next(LI)); 261234353Sdim 262198090Srdivacky Modified = true; 263198090Srdivacky ++NumITs; 264198090Srdivacky } 265198090Srdivacky 266198090Srdivacky return Modified; 267198090Srdivacky} 268198090Srdivacky 269198090Srdivackybool Thumb2ITBlockPass::runOnMachineFunction(MachineFunction &Fn) { 270288943Sdim const ARMSubtarget &STI = 271288943Sdim static_cast<const ARMSubtarget &>(Fn.getSubtarget()); 272288943Sdim if (!STI.isThumb2()) 273288943Sdim return false; 274198090Srdivacky AFI = Fn.getInfo<ARMFunctionInfo>(); 275288943Sdim TII = static_cast<const Thumb2InstrInfo *>(STI.getInstrInfo()); 276288943Sdim TRI = STI.getRegisterInfo(); 277288943Sdim restrictIT = STI.restrictIT(); 278198090Srdivacky 279198090Srdivacky if (!AFI->isThumbFunction()) 280198090Srdivacky return false; 281198090Srdivacky 282198090Srdivacky bool Modified = false; 283210299Sed for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E; ) { 284198090Srdivacky MachineBasicBlock &MBB = *MFI; 285210299Sed ++MFI; 286210299Sed Modified |= InsertITInstructions(MBB); 287198090Srdivacky } 288198090Srdivacky 289210299Sed if (Modified) 290210299Sed AFI->setHasITBlocks(true); 291210299Sed 292198090Srdivacky return Modified; 293198090Srdivacky} 294198090Srdivacky 295198090Srdivacky/// createThumb2ITBlockPass - Returns an instance of the Thumb2 IT blocks 296198090Srdivacky/// insertion pass. 297198090SrdivackyFunctionPass *llvm::createThumb2ITBlockPass() { 298198090Srdivacky return new Thumb2ITBlockPass(); 299198090Srdivacky} 300