1 //===-- Thumb2ITBlockPass.cpp - Insert Thumb-2 IT blocks ------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #define DEBUG_TYPE "thumb2-it" 11 #include "ARM.h" 12 #include "ARMMachineFunctionInfo.h" 13 #include "Thumb2InstrInfo.h" 14 #include "llvm/ADT/SmallSet.h" 15 #include "llvm/ADT/Statistic.h" 16 #include "llvm/CodeGen/MachineFunctionPass.h" 17 #include "llvm/CodeGen/MachineInstr.h" 18 #include "llvm/CodeGen/MachineInstrBuilder.h" 19 #include "llvm/CodeGen/MachineInstrBundle.h" 20 using namespace llvm; 21 22 STATISTIC(NumITs, "Number of IT blocks inserted"); 23 STATISTIC(NumMovedInsts, "Number of predicated instructions moved"); 24 25 namespace { 26 class Thumb2ITBlockPass : public MachineFunctionPass { 27 public: 28 static char ID; 29 Thumb2ITBlockPass() : MachineFunctionPass(ID) {} 30 31 const Thumb2InstrInfo *TII; 32 const TargetRegisterInfo *TRI; 33 ARMFunctionInfo *AFI; 34 35 virtual bool runOnMachineFunction(MachineFunction &Fn); 36 37 virtual const char *getPassName() const { 38 return "Thumb IT blocks insertion pass"; 39 } 40 41 private: 42 bool MoveCopyOutOfITBlock(MachineInstr *MI, 43 ARMCC::CondCodes CC, ARMCC::CondCodes OCC, 44 SmallSet<unsigned, 4> &Defs, 45 SmallSet<unsigned, 4> &Uses); 46 bool InsertITInstructions(MachineBasicBlock &MBB); 47 }; 48 char Thumb2ITBlockPass::ID = 0; 49 } 50 51 /// TrackDefUses - Tracking what registers are being defined and used by 52 /// instructions in the IT block. This also tracks "dependencies", i.e. uses 53 /// in the IT block that are defined before the IT instruction. 54 static void TrackDefUses(MachineInstr *MI, 55 SmallSet<unsigned, 4> &Defs, 56 SmallSet<unsigned, 4> &Uses, 57 const TargetRegisterInfo *TRI) { 58 SmallVector<unsigned, 4> LocalDefs; 59 SmallVector<unsigned, 4> LocalUses; 60 61 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 62 MachineOperand &MO = MI->getOperand(i); 63 if (!MO.isReg()) 64 continue; 65 unsigned Reg = MO.getReg(); 66 if (!Reg || Reg == ARM::ITSTATE || Reg == ARM::SP) 67 continue; 68 if (MO.isUse()) 69 LocalUses.push_back(Reg); 70 else 71 LocalDefs.push_back(Reg); 72 } 73 74 for (unsigned i = 0, e = LocalUses.size(); i != e; ++i) { 75 unsigned Reg = LocalUses[i]; 76 for (MCSubRegIterator Subreg(Reg, TRI, /*IncludeSelf=*/true); 77 Subreg.isValid(); ++Subreg) 78 Uses.insert(*Subreg); 79 } 80 81 for (unsigned i = 0, e = LocalDefs.size(); i != e; ++i) { 82 unsigned Reg = LocalDefs[i]; 83 for (MCSubRegIterator Subreg(Reg, TRI, /*IncludeSelf=*/true); 84 Subreg.isValid(); ++Subreg) 85 Defs.insert(*Subreg); 86 if (Reg == ARM::CPSR) 87 continue; 88 } 89 } 90 91 static bool isCopy(MachineInstr *MI) { 92 switch (MI->getOpcode()) { 93 default: 94 return false; 95 case ARM::MOVr: 96 case ARM::MOVr_TC: 97 case ARM::tMOVr: 98 case ARM::t2MOVr: 99 return true; 100 } 101 } 102 103 bool 104 Thumb2ITBlockPass::MoveCopyOutOfITBlock(MachineInstr *MI, 105 ARMCC::CondCodes CC, ARMCC::CondCodes OCC, 106 SmallSet<unsigned, 4> &Defs, 107 SmallSet<unsigned, 4> &Uses) { 108 if (!isCopy(MI)) 109 return false; 110 // llvm models select's as two-address instructions. That means a copy 111 // is inserted before a t2MOVccr, etc. If the copy is scheduled in 112 // between selects we would end up creating multiple IT blocks. 113 assert(MI->getOperand(0).getSubReg() == 0 && 114 MI->getOperand(1).getSubReg() == 0 && 115 "Sub-register indices still around?"); 116 117 unsigned DstReg = MI->getOperand(0).getReg(); 118 unsigned SrcReg = MI->getOperand(1).getReg(); 119 120 // First check if it's safe to move it. 121 if (Uses.count(DstReg) || Defs.count(SrcReg)) 122 return false; 123 124 // If the CPSR is defined by this copy, then we don't want to move it. E.g., 125 // if we have: 126 // 127 // movs r1, r1 128 // rsb r1, 0 129 // movs r2, r2 130 // rsb r2, 0 131 // 132 // we don't want this to be converted to: 133 // 134 // movs r1, r1 135 // movs r2, r2 136 // itt mi 137 // rsb r1, 0 138 // rsb r2, 0 139 // 140 const MCInstrDesc &MCID = MI->getDesc(); 141 if (MI->hasOptionalDef() && 142 MI->getOperand(MCID.getNumOperands() - 1).getReg() == ARM::CPSR) 143 return false; 144 145 // Then peek at the next instruction to see if it's predicated on CC or OCC. 146 // If not, then there is nothing to be gained by moving the copy. 147 MachineBasicBlock::iterator I = MI; ++I; 148 MachineBasicBlock::iterator E = MI->getParent()->end(); 149 while (I != E && I->isDebugValue()) 150 ++I; 151 if (I != E) { 152 unsigned NPredReg = 0; 153 ARMCC::CondCodes NCC = getITInstrPredicate(I, NPredReg); 154 if (NCC == CC || NCC == OCC) 155 return true; 156 } 157 return false; 158 } 159 160 bool Thumb2ITBlockPass::InsertITInstructions(MachineBasicBlock &MBB) { 161 bool Modified = false; 162 163 SmallSet<unsigned, 4> Defs; 164 SmallSet<unsigned, 4> Uses; 165 MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end(); 166 while (MBBI != E) { 167 MachineInstr *MI = &*MBBI; 168 DebugLoc dl = MI->getDebugLoc(); 169 unsigned PredReg = 0; 170 ARMCC::CondCodes CC = getITInstrPredicate(MI, PredReg); 171 if (CC == ARMCC::AL) { 172 ++MBBI; 173 continue; 174 } 175 176 Defs.clear(); 177 Uses.clear(); 178 TrackDefUses(MI, Defs, Uses, TRI); 179 180 // Insert an IT instruction. 181 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII->get(ARM::t2IT)) 182 .addImm(CC); 183 184 // Add implicit use of ITSTATE to IT block instructions. 185 MI->addOperand(MachineOperand::CreateReg(ARM::ITSTATE, false/*ifDef*/, 186 true/*isImp*/, false/*isKill*/)); 187 188 MachineInstr *LastITMI = MI; 189 MachineBasicBlock::iterator InsertPos = MIB; 190 ++MBBI; 191 192 // Form IT block. 193 ARMCC::CondCodes OCC = ARMCC::getOppositeCondition(CC); 194 unsigned Mask = 0, Pos = 3; 195 // Branches, including tricky ones like LDM_RET, need to end an IT 196 // block so check the instruction we just put in the block. 197 for (; MBBI != E && Pos && 198 (!MI->isBranch() && !MI->isReturn()) ; ++MBBI) { 199 if (MBBI->isDebugValue()) 200 continue; 201 202 MachineInstr *NMI = &*MBBI; 203 MI = NMI; 204 205 unsigned NPredReg = 0; 206 ARMCC::CondCodes NCC = getITInstrPredicate(NMI, NPredReg); 207 if (NCC == CC || NCC == OCC) { 208 Mask |= (NCC & 1) << Pos; 209 // Add implicit use of ITSTATE. 210 NMI->addOperand(MachineOperand::CreateReg(ARM::ITSTATE, false/*ifDef*/, 211 true/*isImp*/, false/*isKill*/)); 212 LastITMI = NMI; 213 } else { 214 if (NCC == ARMCC::AL && 215 MoveCopyOutOfITBlock(NMI, CC, OCC, Defs, Uses)) { 216 --MBBI; 217 MBB.remove(NMI); 218 MBB.insert(InsertPos, NMI); 219 ++NumMovedInsts; 220 continue; 221 } 222 break; 223 } 224 TrackDefUses(NMI, Defs, Uses, TRI); 225 --Pos; 226 } 227 228 // Finalize IT mask. 229 Mask |= (1 << Pos); 230 // Tag along (firstcond[0] << 4) with the mask. 231 Mask |= (CC & 1) << 4; 232 MIB.addImm(Mask); 233 234 // Last instruction in IT block kills ITSTATE. 235 LastITMI->findRegisterUseOperand(ARM::ITSTATE)->setIsKill(); 236 237 // Finalize the bundle. 238 MachineBasicBlock::instr_iterator LI = LastITMI; 239 finalizeBundle(MBB, InsertPos.getInstrIterator(), llvm::next(LI)); 240 241 Modified = true; 242 ++NumITs; 243 } 244 245 return Modified; 246 } 247 248 bool Thumb2ITBlockPass::runOnMachineFunction(MachineFunction &Fn) { 249 const TargetMachine &TM = Fn.getTarget(); 250 AFI = Fn.getInfo<ARMFunctionInfo>(); 251 TII = static_cast<const Thumb2InstrInfo*>(TM.getInstrInfo()); 252 TRI = TM.getRegisterInfo(); 253 254 if (!AFI->isThumbFunction()) 255 return false; 256 257 bool Modified = false; 258 for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E; ) { 259 MachineBasicBlock &MBB = *MFI; 260 ++MFI; 261 Modified |= InsertITInstructions(MBB); 262 } 263 264 if (Modified) 265 AFI->setHasITBlocks(true); 266 267 return Modified; 268 } 269 270 /// createThumb2ITBlockPass - Returns an instance of the Thumb2 IT blocks 271 /// insertion pass. 272 FunctionPass *llvm::createThumb2ITBlockPass() { 273 return new Thumb2ITBlockPass(); 274 } 275