LLVM API Documentation
00001 //===-- Thumb2ITBlockPass.cpp - Insert Thumb-2 IT blocks ------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 00010 #include "ARM.h" 00011 #include "ARMMachineFunctionInfo.h" 00012 #include "Thumb2InstrInfo.h" 00013 #include "llvm/ADT/SmallSet.h" 00014 #include "llvm/ADT/Statistic.h" 00015 #include "llvm/CodeGen/MachineFunctionPass.h" 00016 #include "llvm/CodeGen/MachineInstr.h" 00017 #include "llvm/CodeGen/MachineInstrBuilder.h" 00018 #include "llvm/CodeGen/MachineInstrBundle.h" 00019 using namespace llvm; 00020 00021 #define DEBUG_TYPE "thumb2-it" 00022 00023 STATISTIC(NumITs, "Number of IT blocks inserted"); 00024 STATISTIC(NumMovedInsts, "Number of predicated instructions moved"); 00025 00026 namespace { 00027 class Thumb2ITBlockPass : public MachineFunctionPass { 00028 public: 00029 static char ID; 00030 Thumb2ITBlockPass() : MachineFunctionPass(ID) {} 00031 00032 bool restrictIT; 00033 const Thumb2InstrInfo *TII; 00034 const TargetRegisterInfo *TRI; 00035 ARMFunctionInfo *AFI; 00036 00037 bool runOnMachineFunction(MachineFunction &Fn) override; 00038 00039 const char *getPassName() const override { 00040 return "Thumb IT blocks insertion pass"; 00041 } 00042 00043 private: 00044 bool MoveCopyOutOfITBlock(MachineInstr *MI, 00045 ARMCC::CondCodes CC, ARMCC::CondCodes OCC, 00046 SmallSet<unsigned, 4> &Defs, 00047 SmallSet<unsigned, 4> &Uses); 00048 bool InsertITInstructions(MachineBasicBlock &MBB); 00049 }; 00050 char Thumb2ITBlockPass::ID = 0; 00051 } 00052 00053 /// TrackDefUses - Tracking what registers are being defined and used by 00054 /// instructions in the IT block. This also tracks "dependencies", i.e. uses 00055 /// in the IT block that are defined before the IT instruction. 00056 static void TrackDefUses(MachineInstr *MI, 00057 SmallSet<unsigned, 4> &Defs, 00058 SmallSet<unsigned, 4> &Uses, 00059 const TargetRegisterInfo *TRI) { 00060 SmallVector<unsigned, 4> LocalDefs; 00061 SmallVector<unsigned, 4> LocalUses; 00062 00063 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 00064 MachineOperand &MO = MI->getOperand(i); 00065 if (!MO.isReg()) 00066 continue; 00067 unsigned Reg = MO.getReg(); 00068 if (!Reg || Reg == ARM::ITSTATE || Reg == ARM::SP) 00069 continue; 00070 if (MO.isUse()) 00071 LocalUses.push_back(Reg); 00072 else 00073 LocalDefs.push_back(Reg); 00074 } 00075 00076 for (unsigned i = 0, e = LocalUses.size(); i != e; ++i) { 00077 unsigned Reg = LocalUses[i]; 00078 for (MCSubRegIterator Subreg(Reg, TRI, /*IncludeSelf=*/true); 00079 Subreg.isValid(); ++Subreg) 00080 Uses.insert(*Subreg); 00081 } 00082 00083 for (unsigned i = 0, e = LocalDefs.size(); i != e; ++i) { 00084 unsigned Reg = LocalDefs[i]; 00085 for (MCSubRegIterator Subreg(Reg, TRI, /*IncludeSelf=*/true); 00086 Subreg.isValid(); ++Subreg) 00087 Defs.insert(*Subreg); 00088 if (Reg == ARM::CPSR) 00089 continue; 00090 } 00091 } 00092 00093 static bool isCopy(MachineInstr *MI) { 00094 switch (MI->getOpcode()) { 00095 default: 00096 return false; 00097 case ARM::MOVr: 00098 case ARM::MOVr_TC: 00099 case ARM::tMOVr: 00100 case ARM::t2MOVr: 00101 return true; 00102 } 00103 } 00104 00105 bool 00106 Thumb2ITBlockPass::MoveCopyOutOfITBlock(MachineInstr *MI, 00107 ARMCC::CondCodes CC, ARMCC::CondCodes OCC, 00108 SmallSet<unsigned, 4> &Defs, 00109 SmallSet<unsigned, 4> &Uses) { 00110 if (!isCopy(MI)) 00111 return false; 00112 // llvm models select's as two-address instructions. That means a copy 00113 // is inserted before a t2MOVccr, etc. If the copy is scheduled in 00114 // between selects we would end up creating multiple IT blocks. 00115 assert(MI->getOperand(0).getSubReg() == 0 && 00116 MI->getOperand(1).getSubReg() == 0 && 00117 "Sub-register indices still around?"); 00118 00119 unsigned DstReg = MI->getOperand(0).getReg(); 00120 unsigned SrcReg = MI->getOperand(1).getReg(); 00121 00122 // First check if it's safe to move it. 00123 if (Uses.count(DstReg) || Defs.count(SrcReg)) 00124 return false; 00125 00126 // If the CPSR is defined by this copy, then we don't want to move it. E.g., 00127 // if we have: 00128 // 00129 // movs r1, r1 00130 // rsb r1, 0 00131 // movs r2, r2 00132 // rsb r2, 0 00133 // 00134 // we don't want this to be converted to: 00135 // 00136 // movs r1, r1 00137 // movs r2, r2 00138 // itt mi 00139 // rsb r1, 0 00140 // rsb r2, 0 00141 // 00142 const MCInstrDesc &MCID = MI->getDesc(); 00143 if (MI->hasOptionalDef() && 00144 MI->getOperand(MCID.getNumOperands() - 1).getReg() == ARM::CPSR) 00145 return false; 00146 00147 // Then peek at the next instruction to see if it's predicated on CC or OCC. 00148 // If not, then there is nothing to be gained by moving the copy. 00149 MachineBasicBlock::iterator I = MI; ++I; 00150 MachineBasicBlock::iterator E = MI->getParent()->end(); 00151 while (I != E && I->isDebugValue()) 00152 ++I; 00153 if (I != E) { 00154 unsigned NPredReg = 0; 00155 ARMCC::CondCodes NCC = getITInstrPredicate(I, NPredReg); 00156 if (NCC == CC || NCC == OCC) 00157 return true; 00158 } 00159 return false; 00160 } 00161 00162 bool Thumb2ITBlockPass::InsertITInstructions(MachineBasicBlock &MBB) { 00163 bool Modified = false; 00164 00165 SmallSet<unsigned, 4> Defs; 00166 SmallSet<unsigned, 4> Uses; 00167 MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end(); 00168 while (MBBI != E) { 00169 MachineInstr *MI = &*MBBI; 00170 DebugLoc dl = MI->getDebugLoc(); 00171 unsigned PredReg = 0; 00172 ARMCC::CondCodes CC = getITInstrPredicate(MI, PredReg); 00173 if (CC == ARMCC::AL) { 00174 ++MBBI; 00175 continue; 00176 } 00177 00178 Defs.clear(); 00179 Uses.clear(); 00180 TrackDefUses(MI, Defs, Uses, TRI); 00181 00182 // Insert an IT instruction. 00183 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII->get(ARM::t2IT)) 00184 .addImm(CC); 00185 00186 // Add implicit use of ITSTATE to IT block instructions. 00187 MI->addOperand(MachineOperand::CreateReg(ARM::ITSTATE, false/*ifDef*/, 00188 true/*isImp*/, false/*isKill*/)); 00189 00190 MachineInstr *LastITMI = MI; 00191 MachineBasicBlock::iterator InsertPos = MIB; 00192 ++MBBI; 00193 00194 // Form IT block. 00195 ARMCC::CondCodes OCC = ARMCC::getOppositeCondition(CC); 00196 unsigned Mask = 0, Pos = 3; 00197 00198 // v8 IT blocks are limited to one conditional op unless -arm-no-restrict-it 00199 // is set: skip the loop 00200 if (!restrictIT) { 00201 // Branches, including tricky ones like LDM_RET, need to end an IT 00202 // block so check the instruction we just put in the block. 00203 for (; MBBI != E && Pos && 00204 (!MI->isBranch() && !MI->isReturn()) ; ++MBBI) { 00205 if (MBBI->isDebugValue()) 00206 continue; 00207 00208 MachineInstr *NMI = &*MBBI; 00209 MI = NMI; 00210 00211 unsigned NPredReg = 0; 00212 ARMCC::CondCodes NCC = getITInstrPredicate(NMI, NPredReg); 00213 if (NCC == CC || NCC == OCC) { 00214 Mask |= (NCC & 1) << Pos; 00215 // Add implicit use of ITSTATE. 00216 NMI->addOperand(MachineOperand::CreateReg(ARM::ITSTATE, false/*ifDef*/, 00217 true/*isImp*/, false/*isKill*/)); 00218 LastITMI = NMI; 00219 } else { 00220 if (NCC == ARMCC::AL && 00221 MoveCopyOutOfITBlock(NMI, CC, OCC, Defs, Uses)) { 00222 --MBBI; 00223 MBB.remove(NMI); 00224 MBB.insert(InsertPos, NMI); 00225 ++NumMovedInsts; 00226 continue; 00227 } 00228 break; 00229 } 00230 TrackDefUses(NMI, Defs, Uses, TRI); 00231 --Pos; 00232 } 00233 } 00234 00235 // Finalize IT mask. 00236 Mask |= (1 << Pos); 00237 // Tag along (firstcond[0] << 4) with the mask. 00238 Mask |= (CC & 1) << 4; 00239 MIB.addImm(Mask); 00240 00241 // Last instruction in IT block kills ITSTATE. 00242 LastITMI->findRegisterUseOperand(ARM::ITSTATE)->setIsKill(); 00243 00244 // Finalize the bundle. 00245 MachineBasicBlock::instr_iterator LI = LastITMI; 00246 finalizeBundle(MBB, InsertPos.getInstrIterator(), std::next(LI)); 00247 00248 Modified = true; 00249 ++NumITs; 00250 } 00251 00252 return Modified; 00253 } 00254 00255 bool Thumb2ITBlockPass::runOnMachineFunction(MachineFunction &Fn) { 00256 const TargetMachine &TM = Fn.getTarget(); 00257 AFI = Fn.getInfo<ARMFunctionInfo>(); 00258 TII = static_cast<const Thumb2InstrInfo *>( 00259 TM.getSubtargetImpl()->getInstrInfo()); 00260 TRI = TM.getSubtargetImpl()->getRegisterInfo(); 00261 restrictIT = TM.getSubtarget<ARMSubtarget>().restrictIT(); 00262 00263 if (!AFI->isThumbFunction()) 00264 return false; 00265 00266 bool Modified = false; 00267 for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E; ) { 00268 MachineBasicBlock &MBB = *MFI; 00269 ++MFI; 00270 Modified |= InsertITInstructions(MBB); 00271 } 00272 00273 if (Modified) 00274 AFI->setHasITBlocks(true); 00275 00276 return Modified; 00277 } 00278 00279 /// createThumb2ITBlockPass - Returns an instance of the Thumb2 IT blocks 00280 /// insertion pass. 00281 FunctionPass *llvm::createThumb2ITBlockPass() { 00282 return new Thumb2ITBlockPass(); 00283 }