LLVM  13.0.0git
NVVMIntrRange.cpp
Go to the documentation of this file.
1 //===- NVVMIntrRange.cpp - Set !range metadata for NVVM intrinsics --------===//
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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This pass adds appropriate !range metadata for calls to NVVM
10 // intrinsics that return a limited range of values.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "NVPTX.h"
15 #include "llvm/IR/Constants.h"
16 #include "llvm/IR/InstIterator.h"
17 #include "llvm/IR/Instructions.h"
18 #include "llvm/IR/Intrinsics.h"
19 #include "llvm/IR/IntrinsicsNVPTX.h"
20 #include "llvm/IR/PassManager.h"
22 
23 using namespace llvm;
24 
25 #define DEBUG_TYPE "nvvm-intr-range"
26 
27 namespace llvm { void initializeNVVMIntrRangePass(PassRegistry &); }
28 
29 // Add !range metadata based on limits of given SM variant.
30 static cl::opt<unsigned> NVVMIntrRangeSM("nvvm-intr-range-sm", cl::init(20),
31  cl::Hidden, cl::desc("SM variant"));
32 
33 namespace {
34 class NVVMIntrRange : public FunctionPass {
35  private:
36  unsigned SmVersion;
37 
38  public:
39  static char ID;
40  NVVMIntrRange() : NVVMIntrRange(NVVMIntrRangeSM) {}
41  NVVMIntrRange(unsigned int SmVersion)
43 
45  }
46 
47  bool runOnFunction(Function &) override;
48 };
49 }
50 
52  return new NVVMIntrRange(SmVersion);
53 }
54 
55 char NVVMIntrRange::ID = 0;
56 INITIALIZE_PASS(NVVMIntrRange, "nvvm-intr-range",
57  "Add !range metadata to NVVM intrinsics.", false, false)
58 
59 // Adds the passed-in [Low,High) range information as metadata to the
60 // passed-in call instruction.
61 static bool addRangeMetadata(uint64_t Low, uint64_t High, CallInst *C) {
62  // This call already has range metadata, nothing to do.
63  if (C->getMetadata(LLVMContext::MD_range))
64  return false;
65 
66  LLVMContext &Context = C->getParent()->getContext();
71  C->setMetadata(LLVMContext::MD_range, MDNode::get(Context, LowAndHigh));
72  return true;
73 }
74 
75 static bool runNVVMIntrRange(Function &F, unsigned SmVersion) {
76  struct {
77  unsigned x, y, z;
78  } MaxBlockSize, MaxGridSize;
79  MaxBlockSize.x = 1024;
80  MaxBlockSize.y = 1024;
81  MaxBlockSize.z = 64;
82 
83  MaxGridSize.x = SmVersion >= 30 ? 0x7fffffff : 0xffff;
84  MaxGridSize.y = 0xffff;
85  MaxGridSize.z = 0xffff;
86 
87  // Go through the calls in this function.
88  bool Changed = false;
89  for (Instruction &I : instructions(F)) {
90  CallInst *Call = dyn_cast<CallInst>(&I);
91  if (!Call)
92  continue;
93 
94  if (Function *Callee = Call->getCalledFunction()) {
95  switch (Callee->getIntrinsicID()) {
96  // Index within block
97  case Intrinsic::nvvm_read_ptx_sreg_tid_x:
98  Changed |= addRangeMetadata(0, MaxBlockSize.x, Call);
99  break;
100  case Intrinsic::nvvm_read_ptx_sreg_tid_y:
101  Changed |= addRangeMetadata(0, MaxBlockSize.y, Call);
102  break;
103  case Intrinsic::nvvm_read_ptx_sreg_tid_z:
104  Changed |= addRangeMetadata(0, MaxBlockSize.z, Call);
105  break;
106 
107  // Block size
108  case Intrinsic::nvvm_read_ptx_sreg_ntid_x:
109  Changed |= addRangeMetadata(1, MaxBlockSize.x+1, Call);
110  break;
111  case Intrinsic::nvvm_read_ptx_sreg_ntid_y:
112  Changed |= addRangeMetadata(1, MaxBlockSize.y+1, Call);
113  break;
114  case Intrinsic::nvvm_read_ptx_sreg_ntid_z:
115  Changed |= addRangeMetadata(1, MaxBlockSize.z+1, Call);
116  break;
117 
118  // Index within grid
119  case Intrinsic::nvvm_read_ptx_sreg_ctaid_x:
120  Changed |= addRangeMetadata(0, MaxGridSize.x, Call);
121  break;
122  case Intrinsic::nvvm_read_ptx_sreg_ctaid_y:
123  Changed |= addRangeMetadata(0, MaxGridSize.y, Call);
124  break;
125  case Intrinsic::nvvm_read_ptx_sreg_ctaid_z:
126  Changed |= addRangeMetadata(0, MaxGridSize.z, Call);
127  break;
128 
129  // Grid size
130  case Intrinsic::nvvm_read_ptx_sreg_nctaid_x:
131  Changed |= addRangeMetadata(1, MaxGridSize.x+1, Call);
132  break;
133  case Intrinsic::nvvm_read_ptx_sreg_nctaid_y:
134  Changed |= addRangeMetadata(1, MaxGridSize.y+1, Call);
135  break;
136  case Intrinsic::nvvm_read_ptx_sreg_nctaid_z:
137  Changed |= addRangeMetadata(1, MaxGridSize.z+1, Call);
138  break;
139 
140  // warp size is constant 32.
141  case Intrinsic::nvvm_read_ptx_sreg_warpsize:
142  Changed |= addRangeMetadata(32, 32+1, Call);
143  break;
144 
145  // Lane ID is [0..warpsize)
146  case Intrinsic::nvvm_read_ptx_sreg_laneid:
147  Changed |= addRangeMetadata(0, 32, Call);
148  break;
149 
150  default:
151  break;
152  }
153  }
154  }
155 
156  return Changed;
157 }
158 
160  return runNVVMIntrRange(F, SmVersion);
161 }
162 
164 
167  return runNVVMIntrRange(F, SmVersion) ? PreservedAnalyses::none()
169 }
z
return z
Definition: README.txt:14
runNVVMIntrRange
static bool runNVVMIntrRange(Function &F, unsigned SmVersion)
Definition: NVVMIntrRange.cpp:75
llvm::PreservedAnalyses
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:155
Int32Ty
IntegerType * Int32Ty
Definition: NVVMIntrRange.cpp:67
llvm
Definition: AllocatorList.h:23
InstIterator.h
llvm::Function
Definition: Function.h:61
High
uint64_t High
Definition: NVVMIntrRange.cpp:61
llvm::cl::Hidden
@ Hidden
Definition: CommandLine.h:140
llvm::PreservedAnalyses::none
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition: PassManager.h:158
llvm::ConstantAsMetadata::get
static ConstantAsMetadata * get(Constant *C)
Definition: Metadata.h:419
llvm::NVVMIntrRangePass::run
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition: NVVMIntrRange.cpp:165
llvm::Type::getInt32Ty
static IntegerType * getInt32Ty(LLVMContext &C)
Definition: Type.cpp:204
llvm::MDNode::get
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition: Metadata.h:1198
F
#define F(x, y, z)
Definition: MD5.cpp:56
NVPTX.h
Context
LLVMContext & Context
Definition: NVVMIntrRange.cpp:66
CommandLine.h
llvm::NVVMIntrRangePass::NVVMIntrRangePass
NVVMIntrRangePass()
Definition: NVVMIntrRange.cpp:163
llvm::PassRegistry::getPassRegistry
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Definition: PassRegistry.cpp:31
llvm::NVVMIntrRangePass
Definition: NVPTX.h:51
Constants.h
Intrinsics.h
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
INITIALIZE_PASS
INITIALIZE_PASS(NVVMIntrRange, "nvvm-intr-range", "Add !range metadata to NVVM intrinsics.", false, false) static bool addRangeMetadata(uint64_t Low
llvm::IntegerType
Class to represent integer types.
Definition: DerivedTypes.h:40
llvm::Instruction
Definition: Instruction.h:45
llvm::PassRegistry
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
Definition: PassRegistry.h:38
llvm::ConstantInt::get
static Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
Definition: Constants.cpp:885
llvm::Metadata
Root of the metadata hierarchy.
Definition: Metadata.h:62
llvm::createNVVMIntrRangePass
FunctionPass * createNVVMIntrRangePass(unsigned int SmVersion)
Definition: NVVMIntrRange.cpp:51
llvm::cl::opt
Definition: CommandLine.h:1419
llvm::instructions
inst_range instructions(Function *F)
Definition: InstIterator.h:133
llvm::LLVMContext
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:68
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:440
SmVersion
unsigned SmVersion
Definition: NVVMReflect.cpp:77
Callee
amdgpu Simplify well known AMD library false FunctionCallee Callee
Definition: AMDGPULibCalls.cpp:205
runOnFunction
static bool runOnFunction(Function &F, bool PostInlining)
Definition: EntryExitInstrumenter.cpp:69
llvm::PreservedAnalyses::all
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: PassManager.h:161
LowAndHigh
Metadata * LowAndHigh[]
Definition: NVVMIntrRange.cpp:68
PassManager.h
x
TODO unsigned x
Definition: README.txt:10
y
into llvm powi allowing the code generator to produce balanced multiplication trees the intrinsic needs to be extended to support and second the code generator needs to be enhanced to lower these to multiplication trees Interesting testcase for add shift mul int y
Definition: README.txt:61
NVVMIntrRangeSM
static cl::opt< unsigned > NVVMIntrRangeSM("nvvm-intr-range-sm", cl::init(20), cl::Hidden, cl::desc("SM variant"))
Instructions.h
llvm::AnalysisManager
A container for analyses that lazily runs them and caches their results.
Definition: InstructionSimplify.h:44
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:298
llvm::CallInst
This class represents a function call, abstracting a target machine's calling convention.
Definition: Instructions.h:1450
llvm::cl::desc
Definition: CommandLine.h:411
llvm::initializeNVVMIntrRangePass
void initializeNVVMIntrRangePass(PassRegistry &)
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38