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 11 /// SALU instructions ignore control flow, so we need to modify the live ranges 12 /// of the registers they define. 13 /// 14 /// The strategy is to view the entire program as if it were a single basic 15 /// block and calculate the intervals accordingly. We implement this 16 /// by walking this list of segments for each LiveRange and setting the 17 /// end of each segment equal to the start of the segment that immediately 18 /// follows it. 19 20 #include "AMDGPU.h" 21 #include "SIRegisterInfo.h" 22 #include "llvm/CodeGen/LiveIntervalAnalysis.h" 23 #include "llvm/CodeGen/MachineFunctionPass.h" 24 #include "llvm/CodeGen/MachineRegisterInfo.h" 25 #include "llvm/Support/Debug.h" 26 #include "llvm/Target/TargetMachine.h" 27 28 using namespace llvm; 29 30 #define DEBUG_TYPE "si-fix-sgpr-live-ranges" 31 32 namespace { 33 34 class SIFixSGPRLiveRanges : public MachineFunctionPass { 35 public: 36 static char ID; 37 38 public: 39 SIFixSGPRLiveRanges() : MachineFunctionPass(ID) { 40 initializeSIFixSGPRLiveRangesPass(*PassRegistry::getPassRegistry()); 41 } 42 43 virtual bool runOnMachineFunction(MachineFunction &MF) override; 44 45 virtual const char *getPassName() const override { 46 return "SI Fix SGPR live ranges"; 47 } 48 49 virtual void getAnalysisUsage(AnalysisUsage &AU) const override { 50 AU.addRequired<LiveIntervals>(); 51 AU.addPreserved<LiveIntervals>(); 52 AU.addPreserved<SlotIndexes>(); 53 AU.setPreservesCFG(); 54 MachineFunctionPass::getAnalysisUsage(AU); 55 } 56 }; 57 58 } // End anonymous namespace. 59 60 INITIALIZE_PASS_BEGIN(SIFixSGPRLiveRanges, DEBUG_TYPE, 61 "SI Fix SGPR Live Ranges", false, false) 62 INITIALIZE_PASS_DEPENDENCY(LiveIntervals) 63 INITIALIZE_PASS_END(SIFixSGPRLiveRanges, DEBUG_TYPE, 64 "SI Fix SGPR Live Ranges", false, false) 65 66 char SIFixSGPRLiveRanges::ID = 0; 67 68 char &llvm::SIFixSGPRLiveRangesID = SIFixSGPRLiveRanges::ID; 69 70 FunctionPass *llvm::createSIFixSGPRLiveRangesPass() { 71 return new SIFixSGPRLiveRanges(); 72 } 73 74 bool SIFixSGPRLiveRanges::runOnMachineFunction(MachineFunction &MF) { 75 MachineRegisterInfo &MRI = MF.getRegInfo(); 76 const SIRegisterInfo *TRI = static_cast<const SIRegisterInfo *>( 77 MF.getTarget().getRegisterInfo()); 78 LiveIntervals *LIS = &getAnalysis<LiveIntervals>(); 79 80 for (MachineFunction::iterator BI = MF.begin(), BE = MF.end(); 81 BI != BE; ++BI) { 82 83 MachineBasicBlock &MBB = *BI; 84 for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); 85 I != E; ++I) { 86 MachineInstr &MI = *I; 87 MachineOperand *ExecUse = MI.findRegisterUseOperand(AMDGPU::EXEC); 88 if (ExecUse) 89 continue; 90 91 for (const MachineOperand &Def : MI.operands()) { 92 if (!Def.isReg() || !Def.isDef() ||!TargetRegisterInfo::isVirtualRegister(Def.getReg())) 93 continue; 94 95 const TargetRegisterClass *RC = MRI.getRegClass(Def.getReg()); 96 97 if (!TRI->isSGPRClass(RC)) 98 continue; 99 LiveInterval &LI = LIS->getInterval(Def.getReg()); 100 for (unsigned i = 0, e = LI.size() - 1; i != e; ++i) { 101 LiveRange::Segment &Seg = LI.segments[i]; 102 LiveRange::Segment &Next = LI.segments[i + 1]; 103 Seg.end = Next.start; 104 } 105 } 106 } 107 } 108 109 return false; 110 } 111