1317017Sdim//===-- SIFixVGPRCopies.cpp - Fix VGPR Copies after regalloc --------------===//
2317017Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6317017Sdim//
7317017Sdim//===----------------------------------------------------------------------===//
8317017Sdim//
9317017Sdim/// \file
10341825Sdim/// Add implicit use of exec to vector register copies.
11317017Sdim///
12317017Sdim//===----------------------------------------------------------------------===//
13317017Sdim
14317017Sdim#include "AMDGPU.h"
15317017Sdim#include "AMDGPUSubtarget.h"
16317017Sdim#include "SIInstrInfo.h"
17341825Sdim#include "MCTargetDesc/AMDGPUMCTargetDesc.h"
18317017Sdim#include "llvm/CodeGen/MachineFunctionPass.h"
19317017Sdim
20317017Sdimusing namespace llvm;
21317017Sdim
22317017Sdim#define DEBUG_TYPE "si-fix-vgpr-copies"
23317017Sdim
24317017Sdimnamespace {
25317017Sdim
26317017Sdimclass SIFixVGPRCopies : public MachineFunctionPass {
27317017Sdimpublic:
28317017Sdim  static char ID;
29317017Sdim
30317017Sdimpublic:
31317017Sdim  SIFixVGPRCopies() : MachineFunctionPass(ID) {
32317017Sdim    initializeSIFixVGPRCopiesPass(*PassRegistry::getPassRegistry());
33317017Sdim  }
34317017Sdim
35317017Sdim  bool runOnMachineFunction(MachineFunction &MF) override;
36317017Sdim
37317017Sdim  StringRef getPassName() const override { return "SI Fix VGPR copies"; }
38317017Sdim};
39317017Sdim
40317017Sdim} // End anonymous namespace.
41317017Sdim
42317017SdimINITIALIZE_PASS(SIFixVGPRCopies, DEBUG_TYPE, "SI Fix VGPR copies", false, false)
43317017Sdim
44317017Sdimchar SIFixVGPRCopies::ID = 0;
45317017Sdim
46317017Sdimchar &llvm::SIFixVGPRCopiesID = SIFixVGPRCopies::ID;
47317017Sdim
48317017Sdimbool SIFixVGPRCopies::runOnMachineFunction(MachineFunction &MF) {
49341825Sdim  const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
50317017Sdim  const SIRegisterInfo *TRI = ST.getRegisterInfo();
51317017Sdim  const SIInstrInfo *TII = ST.getInstrInfo();
52317017Sdim  bool Changed = false;
53317017Sdim
54317017Sdim  for (MachineBasicBlock &MBB : MF) {
55317017Sdim    for (MachineInstr &MI : MBB) {
56317017Sdim      switch (MI.getOpcode()) {
57317017Sdim      case AMDGPU::COPY:
58317017Sdim        if (TII->isVGPRCopy(MI) && !MI.readsRegister(AMDGPU::EXEC, TRI)) {
59317017Sdim          MI.addOperand(MF,
60317017Sdim                        MachineOperand::CreateReg(AMDGPU::EXEC, false, true));
61341825Sdim          LLVM_DEBUG(dbgs() << "Add exec use to " << MI);
62317017Sdim          Changed = true;
63317017Sdim        }
64317017Sdim        break;
65317017Sdim      default:
66317017Sdim        break;
67317017Sdim      }
68317017Sdim    }
69317017Sdim  }
70317017Sdim
71317017Sdim  return Changed;
72317017Sdim}
73