10b57cec5SDimitry Andric //===-- SIFixVGPRCopies.cpp - Fix VGPR Copies after regalloc --------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric /// \file 100b57cec5SDimitry Andric /// Add implicit use of exec to vector register copies. 110b57cec5SDimitry Andric /// 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #include "AMDGPU.h" 15e8d8bef9SDimitry Andric #include "GCNSubtarget.h" 160b57cec5SDimitry Andric #include "MCTargetDesc/AMDGPUMCTargetDesc.h" 170b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h" 180b57cec5SDimitry Andric 190b57cec5SDimitry Andric using namespace llvm; 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric #define DEBUG_TYPE "si-fix-vgpr-copies" 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric namespace { 240b57cec5SDimitry Andric 250b57cec5SDimitry Andric class SIFixVGPRCopies : public MachineFunctionPass { 260b57cec5SDimitry Andric public: 270b57cec5SDimitry Andric static char ID; 280b57cec5SDimitry Andric 290b57cec5SDimitry Andric public: SIFixVGPRCopies()300b57cec5SDimitry Andric SIFixVGPRCopies() : MachineFunctionPass(ID) { 310b57cec5SDimitry Andric initializeSIFixVGPRCopiesPass(*PassRegistry::getPassRegistry()); 320b57cec5SDimitry Andric } 330b57cec5SDimitry Andric getAnalysisUsage(AnalysisUsage & AU) const34*06c3fb27SDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override { 35*06c3fb27SDimitry Andric AU.setPreservesAll(); 36*06c3fb27SDimitry Andric MachineFunctionPass::getAnalysisUsage(AU); 37*06c3fb27SDimitry Andric } 38*06c3fb27SDimitry Andric 390b57cec5SDimitry Andric bool runOnMachineFunction(MachineFunction &MF) override; 400b57cec5SDimitry Andric getPassName() const410b57cec5SDimitry Andric StringRef getPassName() const override { return "SI Fix VGPR copies"; } 420b57cec5SDimitry Andric }; 430b57cec5SDimitry Andric 440b57cec5SDimitry Andric } // End anonymous namespace. 450b57cec5SDimitry Andric 460b57cec5SDimitry Andric INITIALIZE_PASS(SIFixVGPRCopies, DEBUG_TYPE, "SI Fix VGPR copies", false, false) 470b57cec5SDimitry Andric 480b57cec5SDimitry Andric char SIFixVGPRCopies::ID = 0; 490b57cec5SDimitry Andric 500b57cec5SDimitry Andric char &llvm::SIFixVGPRCopiesID = SIFixVGPRCopies::ID; 510b57cec5SDimitry Andric runOnMachineFunction(MachineFunction & MF)520b57cec5SDimitry Andricbool SIFixVGPRCopies::runOnMachineFunction(MachineFunction &MF) { 530b57cec5SDimitry Andric const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>(); 540b57cec5SDimitry Andric const SIRegisterInfo *TRI = ST.getRegisterInfo(); 550b57cec5SDimitry Andric const SIInstrInfo *TII = ST.getInstrInfo(); 560b57cec5SDimitry Andric bool Changed = false; 570b57cec5SDimitry Andric 580b57cec5SDimitry Andric for (MachineBasicBlock &MBB : MF) { 590b57cec5SDimitry Andric for (MachineInstr &MI : MBB) { 600b57cec5SDimitry Andric switch (MI.getOpcode()) { 610b57cec5SDimitry Andric case AMDGPU::COPY: 620b57cec5SDimitry Andric if (TII->isVGPRCopy(MI) && !MI.readsRegister(AMDGPU::EXEC, TRI)) { 630b57cec5SDimitry Andric MI.addOperand(MF, 640b57cec5SDimitry Andric MachineOperand::CreateReg(AMDGPU::EXEC, false, true)); 650b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Add exec use to " << MI); 660b57cec5SDimitry Andric Changed = true; 670b57cec5SDimitry Andric } 680b57cec5SDimitry Andric break; 690b57cec5SDimitry Andric default: 700b57cec5SDimitry Andric break; 710b57cec5SDimitry Andric } 720b57cec5SDimitry Andric } 730b57cec5SDimitry Andric } 740b57cec5SDimitry Andric 750b57cec5SDimitry Andric return Changed; 760b57cec5SDimitry Andric } 77