LLVM: lib/Target/NVPTX/NVPTXUtilities.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

23#include

24#include

25#include

26#include

27#include

28#include

29

30namespace llvm {

31

32namespace {

33typedef std::map<std::string, std::vector> key_val_pair_t;

34typedef std::map<const GlobalValue *, key_val_pair_t> global_val_annot_t;

35

36struct AnnotationCache {

38 std::map<const Module *, global_val_annot_t> Cache;

39};

40

41AnnotationCache &getAnnotationCache() {

42 static AnnotationCache AC;

43 return AC;

44}

45}

46

48 auto &AC = getAnnotationCache();

49 std::lock_guardsys::Mutex Guard(AC.Lock);

50 AC.Cache.erase(Mod);

51}

52

54 std::vector &Vec) {

55 for (unsigned i = 0, e = MetadataNode->getNumOperands(); i != e; ++i) {

57 mdconst::extract(MetadataNode->getOperand(i));

59 }

60}

61

63 key_val_pair_t &retval) {

64 auto &AC = getAnnotationCache();

65 std::lock_guardsys::Mutex Guard(AC.Lock);

66 assert(MetadataNode && "Invalid mdnode for annotation");

68 "Invalid number of operands");

69

70

71 for (unsigned i = 1, e = MetadataNode->getNumOperands(); i != e; i += 2) {

72

73 const MDString *prop = dyn_cast(MetadataNode->getOperand(i));

74 assert(prop && "Annotation property not a string");

76

77

78 if (ConstantInt *Val = mdconst::dyn_extract(

80 retval[Key].push_back(Val->getZExtValue());

81 } else if (MDNode *VecMd =

82 dyn_cast(MetadataNode->getOperand(i + 1))) {

83

84

85

86

87 auto [It, Inserted] = retval.try_emplace(Key);

88 if (Inserted) {

90 continue;

91 }

92 } else {

93 llvm_unreachable("Value operand not a constant int or an mdnode");

94 }

95 }

96}

97

99 auto &AC = getAnnotationCache();

100 std::lock_guardsys::Mutex Guard(AC.Lock);

102 if (!NMD)

103 return;

104 key_val_pair_t tmp;

105 for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {

107

109 mdconst::dyn_extract_or_null(elem->getOperand(0));

110

111 if (!entity)

112 continue;

113 if (entity != gv)

114 continue;

115

116

118 }

119

120 if (tmp.empty())

121 return;

122

123 AC.Cache[m][gv] = std::move(tmp);

124}

125

127 const std::string &prop) {

128 auto &AC = getAnnotationCache();

129 std::lock_guardsys::Mutex Guard(AC.Lock);

131 if (AC.Cache.find(m) == AC.Cache.end())

133 else if (AC.Cache[m].find(gv) == AC.Cache[m].end())

135 if (AC.Cache[m][gv].find(prop) == AC.Cache[m][gv].end())

136 return std::nullopt;

137 return AC.Cache[m][gv][prop][0];

138}

139

141 const std::string &prop,

142 std::vector &retval) {

143 auto &AC = getAnnotationCache();

144 std::lock_guardsys::Mutex Guard(AC.Lock);

146 if (AC.Cache.find(m) == AC.Cache.end())

148 else if (AC.Cache[m].find(gv) == AC.Cache[m].end())

150 if (AC.Cache[m][gv].find(prop) == AC.Cache[m][gv].end())

151 return false;

152 retval = AC.Cache[m][gv][prop];

153 return true;

154}

155

157 if (const auto *GV = dyn_cast(&V))

159 assert((*Annot == 1) && "Unexpected annotation on a symbol");

160 return true;

161 }

162

163 return false;

164}

165

167 const std::string &Annotation,

168 const bool StartArgIndexAtOne = false) {

169 if (const Argument *Arg = dyn_cast(&Val)) {

170 const Function *Func = Arg->getParent();

171 std::vector Annot;

173 const unsigned BaseOffset = StartArgIndexAtOne ? 1 : 0;

174 if (is_contained(Annot, BaseOffset + Arg->getArgNo())) {

175 return true;

176 }

177 }

178 }

179 return false;

180}

181

183 if (const Argument *Arg = dyn_cast(&V)) {

184

185 if (Arg->hasByValAttr() &&

187 true)) {

189 "only kernel arguments can be grid_constant");

190 return true;

191 }

192 }

193 return false;

194}

195

197

199

201 const char *AnnotationName = "sampler";

202

205}

206

209}

210

213}

214

217}

218

221}

222

224

226 assert(V.hasName() && "Found texture variable with no name");

227 return V.getName();

228}

229

231 assert(V.hasName() && "Found surface variable with no name");

232 return V.getName();

233}

234

236 assert(V.hasName() && "Found sampler variable with no name");

237 return V.getName();

238}

239

242}

243

246}

247

250}

251

253

254

255

256

257

258

259 std::optional MaxNTIDx = getMaxNTIDx(F);

260 std::optional MaxNTIDy = getMaxNTIDy(F);

261 std::optional MaxNTIDz = getMaxNTIDz(F);

262 if (MaxNTIDx || MaxNTIDy || MaxNTIDz)

263 return MaxNTIDx.value_or(1) * MaxNTIDy.value_or(1) * MaxNTIDz.value_or(1);

264 return std::nullopt;

265}

266

269}

270

273}

274

277}

278

281}

282

285}

286

289}

290

293}

294

296

297 std::optional ReqNTIDx = getReqNTIDx(F);

298 std::optional ReqNTIDy = getReqNTIDy(F);

299 std::optional ReqNTIDz = getReqNTIDz(F);

300 if (ReqNTIDx || ReqNTIDy || ReqNTIDz)

301 return ReqNTIDx.value_or(1) * ReqNTIDy.value_or(1) * ReqNTIDz.value_or(1);

302 return std::nullopt;

303}

304

307}

308

311}

312

315 return true;

316

318 return (*X == 1);

319

320 return false;

321}

322

324

326 F.getAttributes().getAttributes(Index).getStackAlignment())

327 return StackAlign;

328

329

330 std::vector Vs;

332 if (!retval)

333 return std::nullopt;

334 for (unsigned V : Vs)

335 if ((V >> 16) == Index)

336 return Align(V & 0xFFFF);

337

338 return std::nullopt;

339}

340

342

344 I.getAttributes().getAttributes(Index).getStackAlignment())

345 return StackAlign;

346

347

348 if (MDNode *alignNode = I.getMetadata("callalign")) {

349 for (int i = 0, n = alignNode->getNumOperands(); i < n; i++) {

351 mdconst::dyn_extract(alignNode->getOperand(i))) {

352 unsigned V = CI->getZExtValue();

353 if ((V >> 16) == Index)

354 return Align(V & 0xFFFF);

355 if ((V >> 16) > Index)

356 return std::nullopt;

357 }

358 }

359 }

360 return std::nullopt;

361}

362

365}

366

368 const auto &ST =

370 if (!ST.hasNoReturn())

371 return false;

372

373 assert((isa(V) || isa(V)) &&

374 "Expect either a call instruction or a function");

375

376 if (const CallInst *CallI = dyn_cast(V))

377 return CallI->doesNotReturn() &&

378 CallI->getFunctionType()->getReturnType()->isVoidTy();

379

380 const Function *F = cast(V);

381 return F->doesNotReturn() &&

382 F->getFunctionType()->getReturnType()->isVoidTy() &&

384}

385

387 return (VT == MVT::v2f16 || VT == MVT::v2bf16 || VT == MVT::v2i16);

388}

389

390}

This file contains the declarations for the subclasses of Constant, which represent the different fla...

static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")

Module.h This file contains the declarations for the Module class.

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

This class represents an incoming formal argument to a Function.

Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...

Value * getCalledOperand() const

This class represents a function call, abstracting a target machine's calling convention.

This is the shared class of boolean and integer constants.

uint64_t getZExtValue() const

Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...

Module * getParent()

Get the module that this global value is contained inside of...

const MDOperand & getOperand(unsigned I) const

unsigned getNumOperands() const

Return number of MDNode operands.

StringRef getString() const

A Module instance is used to store all the information related to an LLVM module.

NamedMDNode * getNamedMetadata(StringRef Name) const

Return the first NamedMDNode in the module with the specified name.

MDNode * getOperand(unsigned i) const

unsigned getNumOperands() const

StringRef - Represent a constant reference to a string, i.e.

std::string str() const

str - Get the contents as an std::string.

Primary interface to the complete machine description for the target machine.

LLVM Value Representation.

const Value * stripPointerCasts() const

Strip off pointer casts, all-zero GEPs and address space casts.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

@ PTX_Kernel

Call to a PTX kernel. Passes all arguments in parameter space.

SmartMutex< false > Mutex

Mutex - A standard, always enforced mutex.

This is an optimization pass for GlobalISel generic memory operations.

bool isManaged(const Value &V)

bool shouldEmitPTXNoReturn(const Value *V, const TargetMachine &TM)

static bool globalHasNVVMAnnotation(const Value &V, const std::string &Prop)

std::optional< unsigned > getMaxNReg(const Function &F)

std::optional< unsigned > getMaxNTIDy(const Function &F)

static void readIntVecFromMDNode(const MDNode *MetadataNode, std::vector< unsigned > &Vec)

bool isParamGridConstant(const Value &V)

StringRef getSamplerName(const Value &V)

bool isImageReadWrite(const Value &V)

bool isImageReadOnly(const Value &V)

std::optional< unsigned > getMaxNTIDz(const Function &F)

MaybeAlign getAlign(const Function &F, unsigned Index)

std::optional< unsigned > getMaxNTIDx(const Function &F)

std::optional< unsigned > getMinCTASm(const Function &F)

bool isImage(const Value &V)

bool isSampler(const Value &V)

static void cacheAnnotationFromMD(const MDNode *MetadataNode, key_val_pair_t &retval)

void clearAnnotationCache(const Module *Mod)

std::optional< unsigned > getReqNTIDy(const Function &F)

bool isSurface(const Value &V)

static bool findAllNVVMAnnotation(const GlobalValue *gv, const std::string &prop, std::vector< unsigned > &retval)

std::optional< unsigned > getMaxClusterRank(const Function &F)

StringRef getTextureName(const Value &V)

std::optional< unsigned > getClusterDimx(const Function &F)

@ Mod

The access may modify the value stored in memory.

static bool argHasNVVMAnnotation(const Value &Val, const std::string &Annotation, const bool StartArgIndexAtOne=false)

StringRef getSurfaceName(const Value &V)

std::optional< unsigned > getClusterDimy(const Function &F)

static std::optional< unsigned > findOneNVVMAnnotation(const GlobalValue *gv, const std::string &prop)

bool isKernelFunction(const Function &F)

bool isTexture(const Value &V)

Function * getMaybeBitcastedCallee(const CallBase *CB)

bool isImageWriteOnly(const Value &V)

bool is_contained(R &&Range, const E &Element)

Returns true if Element is found in Range.

std::optional< unsigned > getReqNTIDz(const Function &F)

std::optional< unsigned > getReqNTIDx(const Function &F)

std::optional< unsigned > getClusterDimz(const Function &F)

std::optional< unsigned > getReqNTID(const Function &F)

std::optional< unsigned > getMaxNTID(const Function &F)

This struct is a compact representation of a valid (non-zero power of two) alignment.

This struct is a compact representation of a valid (power of two) or undefined (0) alignment.