//===-- SIFixControlFlowLiveIntervals.cpp - Fix CF live intervals ---------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // /// \file /// \brief Spilling of EXEC masks used for control flow messes up control flow /// lowering, so mark all live intervals associated with CF instructions as /// non-spillable. /// //===----------------------------------------------------------------------===// #include "AMDGPU.h" #include "SIInstrInfo.h" #include "SIRegisterInfo.h" #include "llvm/CodeGen/LiveIntervalAnalysis.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachinePostDominators.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetMachine.h" using namespace llvm; #define DEBUG_TYPE "si-fix-cf-live-intervals" namespace { class SIFixControlFlowLiveIntervals : public MachineFunctionPass { public: static char ID; public: SIFixControlFlowLiveIntervals() : MachineFunctionPass(ID) { initializeSIFixControlFlowLiveIntervalsPass(*PassRegistry::getPassRegistry()); } bool runOnMachineFunction(MachineFunction &MF) override; const char *getPassName() const override { return "SI Fix CF Live Intervals"; } void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addRequired(); AU.setPreservesAll(); MachineFunctionPass::getAnalysisUsage(AU); } }; } // End anonymous namespace. INITIALIZE_PASS_BEGIN(SIFixControlFlowLiveIntervals, DEBUG_TYPE, "SI Fix CF Live Intervals", false, false) INITIALIZE_PASS_DEPENDENCY(LiveIntervals) INITIALIZE_PASS_END(SIFixControlFlowLiveIntervals, DEBUG_TYPE, "SI Fix CF Live Intervals", false, false) char SIFixControlFlowLiveIntervals::ID = 0; char &llvm::SIFixControlFlowLiveIntervalsID = SIFixControlFlowLiveIntervals::ID; FunctionPass *llvm::createSIFixControlFlowLiveIntervalsPass() { return new SIFixControlFlowLiveIntervals(); } bool SIFixControlFlowLiveIntervals::runOnMachineFunction(MachineFunction &MF) { LiveIntervals *LIS = &getAnalysis(); for (const MachineBasicBlock &MBB : MF) { for (const MachineInstr &MI : MBB) { switch (MI.getOpcode()) { case AMDGPU::SI_IF: case AMDGPU::SI_ELSE: case AMDGPU::SI_BREAK: case AMDGPU::SI_IF_BREAK: case AMDGPU::SI_ELSE_BREAK: case AMDGPU::SI_END_CF: { unsigned Reg = MI.getOperand(0).getReg(); LIS->getInterval(Reg).markNotSpillable(); break; } default: break; } } } return false; }