Home | History | Annotate | Download | only in R600
      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