1 //===-- SIFixControlFlowLiveIntervals.cpp - Fix CF live intervals ---------===//
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 /// \brief Spilling of EXEC masks used for control flow messes up control flow
12 /// lowering, so mark all live intervals associated with CF instructions as
13 /// non-spillable.
14 ///
15 //===----------------------------------------------------------------------===//
16 
17 #include "AMDGPU.h"
18 #include "SIInstrInfo.h"
19 #include "llvm/CodeGen/LiveIntervalAnalysis.h"
20 #include "llvm/CodeGen/MachineFunctionPass.h"
21 #include "llvm/CodeGen/MachineRegisterInfo.h"
22 
23 using namespace llvm;
24 
25 #define DEBUG_TYPE "si-fix-cf-live-intervals"
26 
27 namespace {
28 
29 class SIFixControlFlowLiveIntervals : public MachineFunctionPass {
30 public:
31   static char ID;
32 
33 public:
SIFixControlFlowLiveIntervals()34   SIFixControlFlowLiveIntervals() : MachineFunctionPass(ID) {
35     initializeSIFixControlFlowLiveIntervalsPass(*PassRegistry::getPassRegistry());
36   }
37 
38   bool runOnMachineFunction(MachineFunction &MF) override;
39 
getPassName() const40   const char *getPassName() const override {
41     return "SI Fix CF Live Intervals";
42   }
43 
getAnalysisUsage(AnalysisUsage & AU) const44   void getAnalysisUsage(AnalysisUsage &AU) const override {
45     AU.addRequired<LiveIntervals>();
46     AU.setPreservesAll();
47     MachineFunctionPass::getAnalysisUsage(AU);
48   }
49 };
50 
51 } // End anonymous namespace.
52 
53 INITIALIZE_PASS_BEGIN(SIFixControlFlowLiveIntervals, DEBUG_TYPE,
54                       "SI Fix CF Live Intervals", false, false)
55 INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
56 INITIALIZE_PASS_END(SIFixControlFlowLiveIntervals, DEBUG_TYPE,
57                     "SI Fix CF Live Intervals", false, false)
58 
59 char SIFixControlFlowLiveIntervals::ID = 0;
60 
61 char &llvm::SIFixControlFlowLiveIntervalsID = SIFixControlFlowLiveIntervals::ID;
62 
createSIFixControlFlowLiveIntervalsPass()63 FunctionPass *llvm::createSIFixControlFlowLiveIntervalsPass() {
64   return new SIFixControlFlowLiveIntervals();
65 }
66 
runOnMachineFunction(MachineFunction & MF)67 bool SIFixControlFlowLiveIntervals::runOnMachineFunction(MachineFunction &MF) {
68   LiveIntervals *LIS = &getAnalysis<LiveIntervals>();
69 
70   for (const MachineBasicBlock &MBB : MF) {
71     for (const MachineInstr &MI : MBB) {
72       switch (MI.getOpcode()) {
73         case AMDGPU::SI_IF:
74         case AMDGPU::SI_ELSE:
75         case AMDGPU::SI_BREAK:
76         case AMDGPU::SI_IF_BREAK:
77         case AMDGPU::SI_ELSE_BREAK:
78         case AMDGPU::SI_END_CF: {
79           unsigned Reg = MI.getOperand(0).getReg();
80           LIS->getInterval(Reg).markNotSpillable();
81           break;
82         }
83         default:
84           break;
85       }
86     }
87   }
88 
89   return false;
90 }
91