1 //===-- SIFixSGPRLiveRanges.cpp - Fix SGPR live ranges ----------------------===// 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 /// \file SALU instructions ignore the execution mask, so we need to modify the 11 /// live ranges of the registers they define in some cases. 12 /// 13 /// The main case we need to handle is when a def is used in one side of a 14 /// branch and not another. For example: 15 /// 16 /// %def 17 /// IF 18 /// ... 19 /// ... 20 /// ELSE 21 /// %use 22 /// ... 23 /// ENDIF 24 /// 25 /// Here we need the register allocator to avoid assigning any of the defs 26 /// inside of the IF to the same register as %def. In traditional live 27 /// interval analysis %def is not live inside the IF branch, however, since 28 /// SALU instructions inside of IF will be executed even if the branch is not 29 /// taken, there is the chance that one of the instructions will overwrite the 30 /// value of %def, so the use in ELSE will see the wrong value. 31 /// 32 /// The strategy we use for solving this is to add an extra use after the ENDIF: 33 /// 34 /// %def 35 /// IF 36 /// ... 37 /// ... 38 /// ELSE 39 /// %use 40 /// ... 41 /// ENDIF 42 /// %use 43 /// 44 /// Adding this use will make the def live throughout the IF branch, which is 45 /// what we want. 46 47 #include "AMDGPU.h" 48 #include "SIInstrInfo.h" 49 #include "SIRegisterInfo.h" 50 #include "llvm/ADT/DepthFirstIterator.h" 51 #include "llvm/CodeGen/LiveIntervalAnalysis.h" 52 #include "llvm/CodeGen/LiveVariables.h" 53 #include "llvm/CodeGen/MachineFunctionPass.h" 54 #include "llvm/CodeGen/MachineInstrBuilder.h" 55 #include "llvm/CodeGen/MachinePostDominators.h" 56 #include "llvm/CodeGen/MachineRegisterInfo.h" 57 #include "llvm/Support/Debug.h" 58 #include "llvm/Support/raw_ostream.h" 59 #include "llvm/Target/TargetMachine.h" 60 61 using namespace llvm; 62 63 #define DEBUG_TYPE "si-fix-sgpr-live-ranges" 64 65 namespace { 66 67 class SIFixSGPRLiveRanges : public MachineFunctionPass { 68 public: 69 static char ID; 70 71 public: 72 SIFixSGPRLiveRanges() : MachineFunctionPass(ID) { 73 initializeSIFixSGPRLiveRangesPass(*PassRegistry::getPassRegistry()); 74 } 75 76 bool runOnMachineFunction(MachineFunction &MF) override; 77 78 const char *getPassName() const override { 79 return "SI Fix SGPR live ranges"; 80 } 81 82 void getAnalysisUsage(AnalysisUsage &AU) const override { 83 AU.addRequired<LiveVariables>(); 84 AU.addPreserved<LiveVariables>(); 85 86 AU.addRequired<MachinePostDominatorTree>(); 87 AU.addPreserved<MachinePostDominatorTree>(); 88 AU.setPreservesCFG(); 89 90 MachineFunctionPass::getAnalysisUsage(AU); 91 } 92 }; 93 94 } // End anonymous namespace. 95 96 INITIALIZE_PASS_BEGIN(SIFixSGPRLiveRanges, DEBUG_TYPE, 97 "SI Fix SGPR Live Ranges", false, false) 98 INITIALIZE_PASS_DEPENDENCY(LiveVariables) 99 INITIALIZE_PASS_DEPENDENCY(MachinePostDominatorTree) 100 INITIALIZE_PASS_END(SIFixSGPRLiveRanges, DEBUG_TYPE, 101 "SI Fix SGPR Live Ranges", false, false) 102 103 char SIFixSGPRLiveRanges::ID = 0; 104 105 char &llvm::SIFixSGPRLiveRangesID = SIFixSGPRLiveRanges::ID; 106 107 FunctionPass *llvm::createSIFixSGPRLiveRangesPass() { 108 return new SIFixSGPRLiveRanges(); 109 } 110 111 bool SIFixSGPRLiveRanges::runOnMachineFunction(MachineFunction &MF) { 112 MachineRegisterInfo &MRI = MF.getRegInfo(); 113 const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo(); 114 const SIRegisterInfo *TRI = static_cast<const SIRegisterInfo *>( 115 MF.getSubtarget().getRegisterInfo()); 116 bool MadeChange = false; 117 118 MachinePostDominatorTree *PDT = &getAnalysis<MachinePostDominatorTree>(); 119 SmallVector<unsigned, 16> SGPRLiveRanges; 120 121 LiveVariables *LV = &getAnalysis<LiveVariables>(); 122 MachineBasicBlock *Entry = &MF.front(); 123 124 // Use a depth first order so that in SSA, we encounter all defs before 125 // uses. Once the defs of the block have been found, attempt to insert 126 // SGPR_USE instructions in successor blocks if required. 127 for (MachineBasicBlock *MBB : depth_first(Entry)) { 128 for (const MachineInstr &MI : *MBB) { 129 for (const MachineOperand &MO : MI.defs()) { 130 // We should never see a live out def of a physical register, so we also 131 // do not need to worry about implicit_defs(). 132 unsigned Def = MO.getReg(); 133 if (TargetRegisterInfo::isVirtualRegister(Def)) { 134 if (TRI->isSGPRClass(MRI.getRegClass(Def))) { 135 // Only consider defs that are live outs. We don't care about def / 136 // use within the same block. 137 138 // LiveVariables does not consider registers that are only used in a 139 // phi in a sucessor block as live out, unlike LiveIntervals. 140 // 141 // This is OK because SIFixSGPRCopies replaced any SGPR phis with 142 // VGPRs. 143 if (LV->isLiveOut(Def, *MBB)) 144 SGPRLiveRanges.push_back(Def); 145 } 146 } 147 } 148 } 149 150 if (MBB->succ_size() < 2) 151 continue; 152 153 // We have structured control flow, so the number of successors should be 154 // two. 155 assert(MBB->succ_size() == 2); 156 MachineBasicBlock *SuccA = *MBB->succ_begin(); 157 MachineBasicBlock *SuccB = *(++MBB->succ_begin()); 158 MachineBasicBlock *NCD = PDT->findNearestCommonDominator(SuccA, SuccB); 159 160 if (!NCD) 161 continue; 162 163 MachineBasicBlock::iterator NCDTerm = NCD->getFirstTerminator(); 164 165 if (NCDTerm != NCD->end() && NCDTerm->getOpcode() == AMDGPU::SI_ELSE) { 166 assert(NCD->succ_size() == 2); 167 // We want to make sure we insert the Use after the ENDIF, not after 168 // the ELSE. 169 NCD = PDT->findNearestCommonDominator(*NCD->succ_begin(), 170 *(++NCD->succ_begin())); 171 } 172 173 for (unsigned Reg : SGPRLiveRanges) { 174 // FIXME: We could be smarter here. If the register is Live-In to one 175 // block, but the other doesn't have any SGPR defs, then there won't be a 176 // conflict. Also, if the branch condition is uniform then there will be 177 // no conflict. 178 bool LiveInToA = LV->isLiveIn(Reg, *SuccA); 179 bool LiveInToB = LV->isLiveIn(Reg, *SuccB); 180 181 if (!LiveInToA && !LiveInToB) { 182 DEBUG(dbgs() << PrintReg(Reg, TRI, 0) 183 << " is live into neither successor\n"); 184 continue; 185 } 186 187 if (LiveInToA && LiveInToB) { 188 DEBUG(dbgs() << PrintReg(Reg, TRI, 0) 189 << " is live into both successors\n"); 190 continue; 191 } 192 193 // This interval is live in to one successor, but not the other, so 194 // we need to update its range so it is live in to both. 195 DEBUG(dbgs() << "Possible SGPR conflict detected for " 196 << PrintReg(Reg, TRI, 0) 197 << " BB#" << SuccA->getNumber() 198 << ", BB#" << SuccB->getNumber() 199 << " with NCD = BB#" << NCD->getNumber() << '\n'); 200 201 assert(TargetRegisterInfo::isVirtualRegister(Reg) && 202 "Not expecting to extend live range of physreg"); 203 204 // FIXME: Need to figure out how to update LiveRange here so this pass 205 // will be able to preserve LiveInterval analysis. 206 MachineInstr *NCDSGPRUse = 207 BuildMI(*NCD, NCD->getFirstNonPHI(), DebugLoc(), 208 TII->get(AMDGPU::SGPR_USE)) 209 .addReg(Reg, RegState::Implicit); 210 211 MadeChange = true; 212 LV->HandleVirtRegUse(Reg, NCD, NCDSGPRUse); 213 214 DEBUG(NCDSGPRUse->dump()); 215 } 216 } 217 218 return MadeChange; 219 } 220