brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.1 KiB · 0137b3f Raw
127 lines · cpp
1//===-- AMDGPUPrepareAGPRAlloc.cpp ----------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// Make simple transformations to relax register constraints for cases which can10// allocate to AGPRs or VGPRs. Replace materialize of inline immediates into11// AGPR or VGPR with a pseudo with an AV_* class register constraint. This12// allows later passes to inflate the register class if necessary. The register13// allocator does not know to replace instructions to relax constraints.14//15//===----------------------------------------------------------------------===//16 17#include "AMDGPUPrepareAGPRAlloc.h"18#include "AMDGPU.h"19#include "GCNSubtarget.h"20#include "SIMachineFunctionInfo.h"21#include "SIRegisterInfo.h"22#include "llvm/CodeGen/LiveIntervals.h"23#include "llvm/CodeGen/MachineFunctionPass.h"24#include "llvm/InitializePasses.h"25 26using namespace llvm;27 28#define DEBUG_TYPE "amdgpu-prepare-agpr-alloc"29 30namespace {31 32class AMDGPUPrepareAGPRAllocImpl {33private:34  const SIInstrInfo &TII;35  MachineRegisterInfo &MRI;36 37  bool isAV64Imm(const MachineOperand &MO) const;38 39public:40  AMDGPUPrepareAGPRAllocImpl(const GCNSubtarget &ST, MachineRegisterInfo &MRI)41      : TII(*ST.getInstrInfo()), MRI(MRI) {}42  bool run(MachineFunction &MF);43};44 45class AMDGPUPrepareAGPRAllocLegacy : public MachineFunctionPass {46public:47  static char ID;48 49  AMDGPUPrepareAGPRAllocLegacy() : MachineFunctionPass(ID) {50    initializeAMDGPUPrepareAGPRAllocLegacyPass(51        *PassRegistry::getPassRegistry());52  }53 54  bool runOnMachineFunction(MachineFunction &MF) override;55 56  StringRef getPassName() const override { return "AMDGPU Prepare AGPR Alloc"; }57 58  void getAnalysisUsage(AnalysisUsage &AU) const override {59    AU.setPreservesAll();60    MachineFunctionPass::getAnalysisUsage(AU);61  }62};63} // End anonymous namespace.64 65INITIALIZE_PASS_BEGIN(AMDGPUPrepareAGPRAllocLegacy, DEBUG_TYPE,66                      "AMDGPU Prepare AGPR Alloc", false, false)67INITIALIZE_PASS_END(AMDGPUPrepareAGPRAllocLegacy, DEBUG_TYPE,68                    "AMDGPU Prepare AGPR Alloc", false, false)69 70char AMDGPUPrepareAGPRAllocLegacy::ID = 0;71 72char &llvm::AMDGPUPrepareAGPRAllocLegacyID = AMDGPUPrepareAGPRAllocLegacy::ID;73 74bool AMDGPUPrepareAGPRAllocLegacy::runOnMachineFunction(MachineFunction &MF) {75  if (skipFunction(MF.getFunction()))76    return false;77 78  const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();79  return AMDGPUPrepareAGPRAllocImpl(ST, MF.getRegInfo()).run(MF);80}81 82PreservedAnalyses83AMDGPUPrepareAGPRAllocPass::run(MachineFunction &MF,84                                MachineFunctionAnalysisManager &MFAM) {85  const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();86  AMDGPUPrepareAGPRAllocImpl(ST, MF.getRegInfo()).run(MF);87  return PreservedAnalyses::all();88}89 90bool AMDGPUPrepareAGPRAllocImpl::isAV64Imm(const MachineOperand &MO) const {91  return MO.isImm() && TII.isLegalAV64PseudoImm(MO.getImm());92}93 94bool AMDGPUPrepareAGPRAllocImpl::run(MachineFunction &MF) {95  if (MRI.isReserved(AMDGPU::AGPR0))96    return false;97 98  const MCInstrDesc &AVImmPseudo32 = TII.get(AMDGPU::AV_MOV_B32_IMM_PSEUDO);99  const MCInstrDesc &AVImmPseudo64 = TII.get(AMDGPU::AV_MOV_B64_IMM_PSEUDO);100 101  bool Changed = false;102  for (MachineBasicBlock &MBB : MF) {103    for (MachineInstr &MI : MBB) {104      if ((MI.getOpcode() == AMDGPU::V_MOV_B32_e32 &&105           TII.isInlineConstant(MI, 1)) ||106          (MI.getOpcode() == AMDGPU::V_ACCVGPR_WRITE_B32_e64 &&107           MI.getOperand(1).isImm())) {108        MI.setDesc(AVImmPseudo32);109        Changed = true;110        continue;111      }112 113      // TODO: If only half of the value is rewritable, is it worth splitting it114      // up?115      if ((MI.getOpcode() == AMDGPU::V_MOV_B64_e64 ||116           MI.getOpcode() == AMDGPU::V_MOV_B64_PSEUDO) &&117          isAV64Imm(MI.getOperand(1))) {118        MI.setDesc(AVImmPseudo64);119        Changed = true;120        continue;121      }122    }123  }124 125  return Changed;126}127