Thumb2ITBlockPass.cpp revision 249423
123925Sgibbs//===-- Thumb2ITBlockPass.cpp - Insert Thumb-2 IT blocks ------------------===// 223925Sgibbs// 323925Sgibbs// The LLVM Compiler Infrastructure 423925Sgibbs// 523925Sgibbs// This file is distributed under the University of Illinois Open Source 623925Sgibbs// License. See LICENSE.TXT for details. 723925Sgibbs// 823925Sgibbs//===----------------------------------------------------------------------===// 923925Sgibbs 1023925Sgibbs#define DEBUG_TYPE "thumb2-it" 1126997Sgibbs#include "ARM.h" 1226997Sgibbs#include "ARMMachineFunctionInfo.h" 1323925Sgibbs#include "Thumb2InstrInfo.h" 1423925Sgibbs#include "llvm/ADT/SmallSet.h" 1523925Sgibbs#include "llvm/ADT/Statistic.h" 1623925Sgibbs#include "llvm/CodeGen/MachineFunctionPass.h" 1723925Sgibbs#include "llvm/CodeGen/MachineInstr.h" 1823925Sgibbs#include "llvm/CodeGen/MachineInstrBuilder.h" 1923925Sgibbs#include "llvm/CodeGen/MachineInstrBundle.h" 2023925Sgibbsusing namespace llvm; 2123925Sgibbs 2223925SgibbsSTATISTIC(NumITs, "Number of IT blocks inserted"); 2323925SgibbsSTATISTIC(NumMovedInsts, "Number of predicated instructions moved"); 2423925Sgibbs 2523925Sgibbsnamespace { 2623925Sgibbs class Thumb2ITBlockPass : public MachineFunctionPass { 2723925Sgibbs public: 2823925Sgibbs static char ID; 2923925Sgibbs Thumb2ITBlockPass() : MachineFunctionPass(ID) {} 3023925Sgibbs 3126997Sgibbs const Thumb2InstrInfo *TII; 3223925Sgibbs const TargetRegisterInfo *TRI; 3323925Sgibbs ARMFunctionInfo *AFI; 3423925Sgibbs 3523925Sgibbs virtual bool runOnMachineFunction(MachineFunction &Fn); 3623925Sgibbs 3723925Sgibbs virtual const char *getPassName() const { 3823925Sgibbs return "Thumb IT blocks insertion pass"; 3923925Sgibbs } 4023925Sgibbs 4123925Sgibbs private: 4223925Sgibbs bool MoveCopyOutOfITBlock(MachineInstr *MI, 4323925Sgibbs ARMCC::CondCodes CC, ARMCC::CondCodes OCC, 4423925Sgibbs SmallSet<unsigned, 4> &Defs, 4523925Sgibbs SmallSet<unsigned, 4> &Uses); 4623925Sgibbs bool InsertITInstructions(MachineBasicBlock &MBB); 4723925Sgibbs }; 4823925Sgibbs char Thumb2ITBlockPass::ID = 0; 4923925Sgibbs} 5023925Sgibbs 5123925Sgibbs/// TrackDefUses - Tracking what registers are being defined and used by 5223925Sgibbs/// instructions in the IT block. This also tracks "dependencies", i.e. uses 5323925Sgibbs/// in the IT block that are defined before the IT instruction. 5423925Sgibbsstatic void TrackDefUses(MachineInstr *MI, 5523925Sgibbs SmallSet<unsigned, 4> &Defs, 5623925Sgibbs SmallSet<unsigned, 4> &Uses, 5723925Sgibbs const TargetRegisterInfo *TRI) { 5823925Sgibbs SmallVector<unsigned, 4> LocalDefs; 5923925Sgibbs SmallVector<unsigned, 4> LocalUses; 6023925Sgibbs 6123925Sgibbs for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 6223925Sgibbs MachineOperand &MO = MI->getOperand(i); 6323925Sgibbs if (!MO.isReg()) 6423925Sgibbs continue; 6523925Sgibbs unsigned Reg = MO.getReg(); 6623925Sgibbs if (!Reg || Reg == ARM::ITSTATE || Reg == ARM::SP) 6723925Sgibbs continue; 6823925Sgibbs if (MO.isUse()) 6923925Sgibbs LocalUses.push_back(Reg); 7023925Sgibbs else 7123925Sgibbs LocalDefs.push_back(Reg); 7223925Sgibbs } 7323925Sgibbs 7423925Sgibbs for (unsigned i = 0, e = LocalUses.size(); i != e; ++i) { 7523925Sgibbs unsigned Reg = LocalUses[i]; 7623925Sgibbs Uses.insert(Reg); 7723925Sgibbs for (MCSubRegIterator Subreg(Reg, TRI); Subreg.isValid(); ++Subreg) 7823925Sgibbs Uses.insert(*Subreg); 7923925Sgibbs } 8023925Sgibbs 8123925Sgibbs for (unsigned i = 0, e = LocalDefs.size(); i != e; ++i) { 8223925Sgibbs unsigned Reg = LocalDefs[i]; 8323925Sgibbs Defs.insert(Reg); 8423925Sgibbs for (MCSubRegIterator Subreg(Reg, TRI); Subreg.isValid(); ++Subreg) 8523925Sgibbs Defs.insert(*Subreg); 8623925Sgibbs if (Reg == ARM::CPSR) 8723925Sgibbs continue; 8823925Sgibbs } 8923925Sgibbs} 9023925Sgibbs 9123925Sgibbsstatic bool isCopy(MachineInstr *MI) { 9223925Sgibbs switch (MI->getOpcode()) { 9323925Sgibbs default: 9423925Sgibbs return false; 9523925Sgibbs case ARM::MOVr: 9623925Sgibbs case ARM::MOVr_TC: 9723925Sgibbs case ARM::tMOVr: 9823925Sgibbs case ARM::t2MOVr: 9923925Sgibbs return true; 10023925Sgibbs } 10123925Sgibbs} 10223925Sgibbs 10323925Sgibbsbool 10423925SgibbsThumb2ITBlockPass::MoveCopyOutOfITBlock(MachineInstr *MI, 10523925Sgibbs ARMCC::CondCodes CC, ARMCC::CondCodes OCC, 10623925Sgibbs SmallSet<unsigned, 4> &Defs, 10723925Sgibbs SmallSet<unsigned, 4> &Uses) { 10823925Sgibbs if (!isCopy(MI)) 10923925Sgibbs return false; 11023925Sgibbs // llvm models select's as two-address instructions. That means a copy 11123925Sgibbs // is inserted before a t2MOVccr, etc. If the copy is scheduled in 11223925Sgibbs // between selects we would end up creating multiple IT blocks. 11323925Sgibbs assert(MI->getOperand(0).getSubReg() == 0 && 11423925Sgibbs MI->getOperand(1).getSubReg() == 0 && 11523925Sgibbs "Sub-register indices still around?"); 11623925Sgibbs 11723925Sgibbs unsigned DstReg = MI->getOperand(0).getReg(); 11823925Sgibbs unsigned SrcReg = MI->getOperand(1).getReg(); 11923925Sgibbs 12023925Sgibbs // First check if it's safe to move it. 12123925Sgibbs if (Uses.count(DstReg) || Defs.count(SrcReg)) 12223925Sgibbs return false; 12323925Sgibbs 12423925Sgibbs // If the CPSR is defined by this copy, then we don't want to move it. E.g., 12523925Sgibbs // if we have: 12623925Sgibbs // 12723925Sgibbs // movs r1, r1 12823925Sgibbs // rsb r1, 0 12923925Sgibbs // movs r2, r2 13023925Sgibbs // rsb r2, 0 13123925Sgibbs // 13223925Sgibbs // we don't want this to be converted to: 13323925Sgibbs // 13423925Sgibbs // movs r1, r1 13523925Sgibbs // movs r2, r2 13623925Sgibbs // itt mi 13723925Sgibbs // rsb r1, 0 13823925Sgibbs // rsb r2, 0 13923925Sgibbs // 14023925Sgibbs const MCInstrDesc &MCID = MI->getDesc(); 14123925Sgibbs if (MI->hasOptionalDef() && 14223925Sgibbs MI->getOperand(MCID.getNumOperands() - 1).getReg() == ARM::CPSR) 14323925Sgibbs return false; 14423925Sgibbs 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 160bool 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 248bool 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. 272FunctionPass *llvm::createThumb2ITBlockPass() { 273 return new Thumb2ITBlockPass(); 274} 275