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 28using namespace llvm; 29 30#define DEBUG_TYPE "si-fix-sgpr-live-ranges" 31 32namespace { 33 34class SIFixSGPRLiveRanges : public MachineFunctionPass { 35public: 36 static char ID; 37 38public: 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 60INITIALIZE_PASS_BEGIN(SIFixSGPRLiveRanges, DEBUG_TYPE, 61 "SI Fix SGPR Live Ranges", false, false) 62INITIALIZE_PASS_DEPENDENCY(LiveIntervals) 63INITIALIZE_PASS_END(SIFixSGPRLiveRanges, DEBUG_TYPE, 64 "SI Fix SGPR Live Ranges", false, false) 65 66char SIFixSGPRLiveRanges::ID = 0; 67 68char &llvm::SIFixSGPRLiveRangesID = SIFixSGPRLiveRanges::ID; 69 70FunctionPass *llvm::createSIFixSGPRLiveRangesPass() { 71 return new SIFixSGPRLiveRanges(); 72} 73 74bool 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