brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.5 KiB · 93ba0a3 Raw
244 lines · cpp
1//===-- SIProgramInfo.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/// \file10///11/// The SIProgramInfo tracks resource usage and hardware flags for kernels and12/// entry functions.13//14//===----------------------------------------------------------------------===//15//16 17#include "SIProgramInfo.h"18#include "GCNSubtarget.h"19#include "SIDefines.h"20#include "Utils/AMDGPUBaseInfo.h"21#include "llvm/MC/MCExpr.h"22 23using namespace llvm;24 25void SIProgramInfo::reset(const MachineFunction &MF) {26  MCContext &Ctx = MF.getContext();27 28  const MCExpr *ZeroExpr = MCConstantExpr::create(0, Ctx);29 30  CodeSizeInBytes.reset();31 32  VGPRBlocks = ZeroExpr;33  SGPRBlocks = ZeroExpr;34  Priority = 0;35  FloatMode = 0;36  Priv = 0;37  DX10Clamp = 0;38  DebugMode = 0;39  IEEEMode = 0;40  WgpMode = 0;41  MemOrdered = 0;42  FwdProgress = 0;43  RrWgMode = 0;44  ScratchSize = ZeroExpr;45 46  LDSBlocks = 0;47  ScratchBlocks = ZeroExpr;48 49  ScratchEnable = ZeroExpr;50  UserSGPR = 0;51  TrapHandlerEnable = 0;52  TGIdXEnable = 0;53  TGIdYEnable = 0;54  TGIdZEnable = 0;55  TGSizeEnable = 0;56  TIdIGCompCount = 0;57  EXCPEnMSB = 0;58  LdsSize = 0;59  EXCPEnable = 0;60 61  ComputePGMRSrc3 = ZeroExpr;62 63  NumVGPR = ZeroExpr;64  NumArchVGPR = ZeroExpr;65  NumAccVGPR = ZeroExpr;66  AccumOffset = ZeroExpr;67  TgSplit = 0;68  NumSGPR = ZeroExpr;69  SGPRSpill = 0;70  VGPRSpill = 0;71  LDSSize = 0;72  FlatUsed = ZeroExpr;73 74  NumSGPRsForWavesPerEU = ZeroExpr;75  NumVGPRsForWavesPerEU = ZeroExpr;76  NamedBarCnt = ZeroExpr;77  Occupancy = ZeroExpr;78  DynamicCallStack = ZeroExpr;79  VCCUsed = ZeroExpr;80}81 82static uint64_t getComputePGMRSrc1Reg(const SIProgramInfo &ProgInfo,83                                      const GCNSubtarget &ST) {84  uint64_t Reg = S_00B848_PRIORITY(ProgInfo.Priority) |85                 S_00B848_FLOAT_MODE(ProgInfo.FloatMode) |86                 S_00B848_PRIV(ProgInfo.Priv) |87                 S_00B848_DEBUG_MODE(ProgInfo.DebugMode) |88                 S_00B848_WGP_MODE(ProgInfo.WgpMode) |89                 S_00B848_MEM_ORDERED(ProgInfo.MemOrdered) |90                 S_00B848_FWD_PROGRESS(ProgInfo.FwdProgress);91 92  if (ST.hasDX10ClampMode())93    Reg |= S_00B848_DX10_CLAMP(ProgInfo.DX10Clamp);94 95  if (ST.hasIEEEMode())96    Reg |= S_00B848_IEEE_MODE(ProgInfo.IEEEMode);97 98  if (ST.hasRrWGMode())99    Reg |= S_00B848_RR_WG_MODE(ProgInfo.RrWgMode);100 101  return Reg;102}103 104static uint64_t getPGMRSrc1Reg(const SIProgramInfo &ProgInfo,105                               CallingConv::ID CC, const GCNSubtarget &ST) {106  uint64_t Reg = S_00B848_PRIORITY(ProgInfo.Priority) |107                 S_00B848_FLOAT_MODE(ProgInfo.FloatMode) |108                 S_00B848_PRIV(ProgInfo.Priv) |109                 S_00B848_DEBUG_MODE(ProgInfo.DebugMode);110 111  if (ST.hasDX10ClampMode())112    Reg |= S_00B848_DX10_CLAMP(ProgInfo.DX10Clamp);113 114  if (ST.hasIEEEMode())115    Reg |= S_00B848_IEEE_MODE(ProgInfo.IEEEMode);116 117  if (ST.hasRrWGMode())118    Reg |= S_00B848_RR_WG_MODE(ProgInfo.RrWgMode);119 120  switch (CC) {121  case CallingConv::AMDGPU_PS:122    Reg |= S_00B028_MEM_ORDERED(ProgInfo.MemOrdered);123    break;124  case CallingConv::AMDGPU_VS:125    Reg |= S_00B128_MEM_ORDERED(ProgInfo.MemOrdered);126    break;127  case CallingConv::AMDGPU_GS:128    Reg |= S_00B228_WGP_MODE(ProgInfo.WgpMode) |129           S_00B228_MEM_ORDERED(ProgInfo.MemOrdered);130    break;131  case CallingConv::AMDGPU_HS:132    Reg |= S_00B428_WGP_MODE(ProgInfo.WgpMode) |133           S_00B428_MEM_ORDERED(ProgInfo.MemOrdered);134    break;135  default:136    break;137  }138  return Reg;139}140 141static uint64_t getComputePGMRSrc2Reg(const SIProgramInfo &ProgInfo) {142  uint64_t Reg = S_00B84C_USER_SGPR(ProgInfo.UserSGPR) |143                 S_00B84C_TRAP_HANDLER(ProgInfo.TrapHandlerEnable) |144                 S_00B84C_TGID_X_EN(ProgInfo.TGIdXEnable) |145                 S_00B84C_TGID_Y_EN(ProgInfo.TGIdYEnable) |146                 S_00B84C_TGID_Z_EN(ProgInfo.TGIdZEnable) |147                 S_00B84C_TG_SIZE_EN(ProgInfo.TGSizeEnable) |148                 S_00B84C_TIDIG_COMP_CNT(ProgInfo.TIdIGCompCount) |149                 S_00B84C_EXCP_EN_MSB(ProgInfo.EXCPEnMSB) |150                 S_00B84C_LDS_SIZE(ProgInfo.LdsSize) |151                 S_00B84C_EXCP_EN(ProgInfo.EXCPEnable);152 153  return Reg;154}155 156static const MCExpr *MaskShift(const MCExpr *Val, uint32_t Mask, uint32_t Shift,157                               MCContext &Ctx) {158  if (Mask) {159    const MCExpr *MaskExpr = MCConstantExpr::create(Mask, Ctx);160    Val = MCBinaryExpr::createAnd(Val, MaskExpr, Ctx);161  }162  if (Shift) {163    const MCExpr *ShiftExpr = MCConstantExpr::create(Shift, Ctx);164    Val = MCBinaryExpr::createShl(Val, ShiftExpr, Ctx);165  }166  return Val;167}168 169const MCExpr *SIProgramInfo::getComputePGMRSrc1(const GCNSubtarget &ST,170                                                MCContext &Ctx) const {171  uint64_t Reg = getComputePGMRSrc1Reg(*this, ST);172  const MCExpr *RegExpr = MCConstantExpr::create(Reg, Ctx);173  const MCExpr *Res = MCBinaryExpr::createOr(174      MaskShift(VGPRBlocks, /*Mask=*/0x3F, /*Shift=*/0, Ctx),175      MaskShift(SGPRBlocks, /*Mask=*/0xF, /*Shift=*/6, Ctx), Ctx);176  return MCBinaryExpr::createOr(RegExpr, Res, Ctx);177}178 179const MCExpr *SIProgramInfo::getPGMRSrc1(CallingConv::ID CC,180                                         const GCNSubtarget &ST,181                                         MCContext &Ctx) const {182  if (AMDGPU::isCompute(CC)) {183    return getComputePGMRSrc1(ST, Ctx);184  }185 186  uint64_t Reg = getPGMRSrc1Reg(*this, CC, ST);187  const MCExpr *RegExpr = MCConstantExpr::create(Reg, Ctx);188  const MCExpr *Res = MCBinaryExpr::createOr(189      MaskShift(VGPRBlocks, /*Mask=*/0x3F, /*Shift=*/0, Ctx),190      MaskShift(SGPRBlocks, /*Mask=*/0xF, /*Shift=*/6, Ctx), Ctx);191  return MCBinaryExpr::createOr(RegExpr, Res, Ctx);192}193 194const MCExpr *SIProgramInfo::getComputePGMRSrc2(MCContext &Ctx) const {195  uint64_t Reg = getComputePGMRSrc2Reg(*this);196  const MCExpr *RegExpr = MCConstantExpr::create(Reg, Ctx);197  return MCBinaryExpr::createOr(ScratchEnable, RegExpr, Ctx);198}199 200const MCExpr *SIProgramInfo::getPGMRSrc2(CallingConv::ID CC,201                                         MCContext &Ctx) const {202  if (AMDGPU::isCompute(CC))203    return getComputePGMRSrc2(Ctx);204 205  return MCConstantExpr::create(0, Ctx);206}207 208uint64_t SIProgramInfo::getFunctionCodeSize(const MachineFunction &MF,209                                            bool IsLowerBound) {210  if (!IsLowerBound && CodeSizeInBytes.has_value())211    return *CodeSizeInBytes;212 213  const GCNSubtarget &STM = MF.getSubtarget<GCNSubtarget>();214  const SIInstrInfo *TII = STM.getInstrInfo();215 216  uint64_t CodeSize = 0;217 218  for (const MachineBasicBlock &MBB : MF) {219    // The amount of padding to align code can be both underestimated and220    // overestimated. In case of inline asm used getInstSizeInBytes() will221    // return a maximum size of a single instruction, where the real size may222    // differ. At this point CodeSize may be already off.223    if (!IsLowerBound)224      CodeSize = alignTo(CodeSize, MBB.getAlignment());225 226    for (const MachineInstr &MI : MBB) {227      // TODO: CodeSize should account for multiple functions.228 229      if (MI.isMetaInstruction())230        continue;231 232      // We cannot properly estimate inline asm size. It can be as small as zero233      // if that is just a comment.234      if (IsLowerBound && MI.isInlineAsm())235        continue;236 237      CodeSize += TII->getInstSizeInBytes(MI);238    }239  }240 241  CodeSizeInBytes = CodeSize;242  return CodeSize;243}244