LLVM API Documentation

SIFixSGPRLiveRanges.cpp
Go to the documentation of this file.
00001 //===-- SIFixSGPRLiveRanges.cpp - Fix SGPR live ranges ----------------------===//
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 /// \file
00011 /// SALU instructions ignore control flow, so we need to modify the live ranges
00012 /// of the registers they define.
00013 ///
00014 /// The strategy is to view the entire program as if it were a single basic
00015 /// block and calculate the intervals accordingly.  We implement this
00016 /// by walking this list of segments for each LiveRange and setting the
00017 /// end of each segment equal to the start of the segment that immediately
00018 /// follows it.
00019 
00020 #include "AMDGPU.h"
00021 #include "SIRegisterInfo.h"
00022 #include "llvm/CodeGen/LiveIntervalAnalysis.h"
00023 #include "llvm/CodeGen/MachineFunctionPass.h"
00024 #include "llvm/CodeGen/MachineRegisterInfo.h"
00025 #include "llvm/Support/Debug.h"
00026 #include "llvm/Target/TargetMachine.h"
00027 
00028 using namespace llvm;
00029 
00030 #define DEBUG_TYPE "si-fix-sgpr-live-ranges"
00031 
00032 namespace {
00033 
00034 class SIFixSGPRLiveRanges : public MachineFunctionPass {
00035 public:
00036   static char ID;
00037 
00038 public:
00039   SIFixSGPRLiveRanges() : MachineFunctionPass(ID) {
00040     initializeSIFixSGPRLiveRangesPass(*PassRegistry::getPassRegistry());
00041   }
00042 
00043   bool runOnMachineFunction(MachineFunction &MF) override;
00044 
00045   const char *getPassName() const override {
00046     return "SI Fix SGPR live ranges";
00047   }
00048 
00049   void getAnalysisUsage(AnalysisUsage &AU) const override {
00050     AU.addRequired<LiveIntervals>();
00051     AU.addPreserved<LiveIntervals>();
00052     AU.addPreserved<SlotIndexes>();
00053     AU.setPreservesCFG();
00054     MachineFunctionPass::getAnalysisUsage(AU);
00055   }
00056 };
00057 
00058 } // End anonymous namespace.
00059 
00060 INITIALIZE_PASS_BEGIN(SIFixSGPRLiveRanges, DEBUG_TYPE,
00061                       "SI Fix SGPR Live Ranges", false, false)
00062 INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
00063 INITIALIZE_PASS_END(SIFixSGPRLiveRanges, DEBUG_TYPE,
00064                     "SI Fix SGPR Live Ranges", false, false)
00065 
00066 char SIFixSGPRLiveRanges::ID = 0;
00067 
00068 char &llvm::SIFixSGPRLiveRangesID = SIFixSGPRLiveRanges::ID;
00069 
00070 FunctionPass *llvm::createSIFixSGPRLiveRangesPass() {
00071   return new SIFixSGPRLiveRanges();
00072 }
00073 
00074 bool SIFixSGPRLiveRanges::runOnMachineFunction(MachineFunction &MF) {
00075   MachineRegisterInfo &MRI = MF.getRegInfo();
00076   const SIRegisterInfo *TRI =
00077       static_cast<const SIRegisterInfo *>(MF.getSubtarget().getRegisterInfo());
00078   LiveIntervals *LIS = &getAnalysis<LiveIntervals>();
00079 
00080   for (MachineFunction::iterator BI = MF.begin(), BE = MF.end();
00081                                                   BI != BE; ++BI) {
00082 
00083     MachineBasicBlock &MBB = *BI;
00084     for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
00085                                                       I != E; ++I) {
00086       MachineInstr &MI = *I;
00087       MachineOperand *ExecUse = MI.findRegisterUseOperand(AMDGPU::EXEC);
00088       if (ExecUse)
00089         continue;
00090 
00091       for (const MachineOperand &Def : MI.operands()) {
00092         if (!Def.isReg() || !Def.isDef() ||!TargetRegisterInfo::isVirtualRegister(Def.getReg()))
00093           continue;
00094 
00095         const TargetRegisterClass *RC = MRI.getRegClass(Def.getReg());
00096 
00097         if (!TRI->isSGPRClass(RC))
00098           continue;
00099         LiveInterval &LI = LIS->getInterval(Def.getReg());
00100         for (unsigned i = 0, e = LI.size() - 1; i != e; ++i) {
00101           LiveRange::Segment &Seg = LI.segments[i];
00102           LiveRange::Segment &Next = LI.segments[i + 1];
00103           Seg.end = Next.start;
00104         }
00105       }
00106     }
00107   }
00108 
00109   return false;
00110 }