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()63FunctionPass *llvm::createSIFixControlFlowLiveIntervalsPass() { 64 return new SIFixControlFlowLiveIntervals(); 65 } 66 runOnMachineFunction(MachineFunction & MF)67bool 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