212 lines · c
1//===-- NVPTXUtilities - Utilities -----------------------------*- C++ -*-====//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// This file contains the declaration of the NVVM specific utility functions.10//11//===----------------------------------------------------------------------===//12 13#ifndef LLVM_LIB_TARGET_NVPTX_NVPTXUTILITIES_H14#define LLVM_LIB_TARGET_NVPTX_NVPTXUTILITIES_H15 16#include "NVPTX.h"17#include "llvm/ADT/SmallVector.h"18#include "llvm/ADT/StringExtras.h"19#include "llvm/CodeGen/ValueTypes.h"20#include "llvm/IR/CallingConv.h"21#include "llvm/IR/Function.h"22#include "llvm/IR/GlobalVariable.h"23#include "llvm/IR/IntrinsicInst.h"24#include "llvm/IR/Value.h"25#include "llvm/Support/Alignment.h"26#include "llvm/Support/FormatVariadic.h"27#include <cstdarg>28#include <string>29 30namespace llvm {31 32class TargetMachine;33 34void clearAnnotationCache(const Module *);35 36bool isTexture(const Value &);37bool isSurface(const Value &);38bool isSampler(const Value &);39bool isImage(const Value &);40bool isImageReadOnly(const Value &);41bool isImageWriteOnly(const Value &);42bool isImageReadWrite(const Value &);43bool isManaged(const Value &);44 45StringRef getTextureName(const Value &);46StringRef getSurfaceName(const Value &);47StringRef getSamplerName(const Value &);48 49SmallVector<unsigned, 3> getMaxNTID(const Function &);50SmallVector<unsigned, 3> getReqNTID(const Function &);51SmallVector<unsigned, 3> getClusterDim(const Function &);52 53std::optional<uint64_t> getOverallMaxNTID(const Function &);54std::optional<uint64_t> getOverallReqNTID(const Function &);55std::optional<uint64_t> getOverallClusterRank(const Function &);56 57std::optional<unsigned> getMaxClusterRank(const Function &);58std::optional<unsigned> getMinCTASm(const Function &);59std::optional<unsigned> getMaxNReg(const Function &);60 61bool hasBlocksAreClusters(const Function &);62 63inline bool isKernelFunction(const Function &F) {64 return F.getCallingConv() == CallingConv::PTX_Kernel;65}66 67bool isParamGridConstant(const Argument &);68 69inline MaybeAlign getAlign(const Function &F, unsigned Index) {70 return F.getAttributes().getAttributes(Index).getStackAlignment();71}72 73MaybeAlign getAlign(const CallInst &, unsigned);74Function *getMaybeBitcastedCallee(const CallBase *CB);75 76// PTX ABI requires all scalar argument/return values to have77// bit-size as a power of two of at least 32 bits.78inline unsigned promoteScalarArgumentSize(unsigned size) {79 if (size <= 32)80 return 32;81 if (size <= 64)82 return 64;83 if (size <= 128)84 return 128;85 return size;86}87 88bool shouldEmitPTXNoReturn(const Value *V, const TargetMachine &TM);89 90inline bool shouldPassAsArray(Type *Ty) {91 return Ty->isAggregateType() || Ty->isVectorTy() ||92 Ty->getScalarSizeInBits() >= 128 || Ty->isHalfTy() || Ty->isBFloatTy();93}94 95namespace NVPTX {96// Returns a list of vector types that we prefer to fit into a single PTX97// register. NOTE: This must be kept in sync with the register classes98// defined in NVPTXRegisterInfo.td.99inline auto packed_types() {100 static const auto PackedTypes = {MVT::v4i8, MVT::v2f16, MVT::v2bf16,101 MVT::v2i16, MVT::v2f32, MVT::v2i32};102 return PackedTypes;103}104 105// Checks if the type VT can fit into a single register.106inline bool isPackedVectorTy(EVT VT) {107 return any_of(packed_types(), [VT](EVT OVT) { return OVT == VT; });108}109 110// Checks if two or more of the type ET can fit into a single register.111inline bool isPackedElementTy(EVT ET) {112 return any_of(packed_types(),113 [ET](EVT OVT) { return OVT.getVectorElementType() == ET; });114}115 116inline std::string getValidPTXIdentifier(StringRef Name) {117 std::string ValidName;118 ValidName.reserve(Name.size() + 4);119 for (char C : Name)120 // While PTX also allows '%' at the start of identifiers, LLVM will throw a121 // fatal error for '%' in symbol names in MCSymbol::print. Exclude for now.122 if (isAlnum(C) || C == '_' || C == '$')123 ValidName.push_back(C);124 else125 ValidName.append({'_', '$', '_'});126 127 return ValidName;128}129 130inline std::string OrderingToString(Ordering Order) {131 switch (Order) {132 case Ordering::NotAtomic:133 return "NotAtomic";134 case Ordering::Relaxed:135 return "Relaxed";136 case Ordering::Acquire:137 return "Acquire";138 case Ordering::Release:139 return "Release";140 case Ordering::AcquireRelease:141 return "AcquireRelease";142 case Ordering::SequentiallyConsistent:143 return "SequentiallyConsistent";144 case Ordering::Volatile:145 return "Volatile";146 case Ordering::RelaxedMMIO:147 return "RelaxedMMIO";148 }149 report_fatal_error(formatv("Unknown NVPTX::Ordering \"{}\".",150 static_cast<OrderingUnderlyingType>(Order)));151}152 153inline raw_ostream &operator<<(raw_ostream &O, Ordering Order) {154 O << OrderingToString(Order);155 return O;156}157 158inline std::string ScopeToString(Scope S) {159 switch (S) {160 case Scope::Thread:161 return "Thread";162 case Scope::System:163 return "System";164 case Scope::Block:165 return "Block";166 case Scope::Cluster:167 return "Cluster";168 case Scope::Device:169 return "Device";170 case Scope::DefaultDevice:171 return "DefaultDevice";172 }173 report_fatal_error(formatv("Unknown NVPTX::Scope \"{}\".",174 static_cast<ScopeUnderlyingType>(S)));175}176 177inline raw_ostream &operator<<(raw_ostream &O, Scope S) {178 O << ScopeToString(S);179 return O;180}181 182inline std::string AddressSpaceToString(AddressSpace A) {183 switch (A) {184 case AddressSpace::Generic:185 return "generic";186 case AddressSpace::Global:187 return "global";188 case AddressSpace::Const:189 return "const";190 case AddressSpace::Shared:191 return "shared";192 case AddressSpace::SharedCluster:193 return "shared::cluster";194 case AddressSpace::Param:195 return "param";196 case AddressSpace::Local:197 return "local";198 }199 report_fatal_error(formatv("Unknown NVPTX::AddressSpace \"{}\".",200 static_cast<AddressSpaceUnderlyingType>(A)));201}202 203inline raw_ostream &operator<<(raw_ostream &O, AddressSpace A) {204 O << AddressSpaceToString(A);205 return O;206}207 208} // namespace NVPTX209} // namespace llvm210 211#endif212