Proteus
Programmable JIT compilation and optimization for C/C++ using LLVM
Loading...
Searching...
No Matches
Helpers.h
Go to the documentation of this file.
1#ifndef PROTEUS_PASS_HELPERS_H
2#define PROTEUS_PASS_HELPERS_H
3
4#include "proteus/Error.h"
7
8#include <llvm/ADT/SetVector.h>
9#include <llvm/Demangle/Demangle.h>
10#include <llvm/IR/Module.h>
11#include <llvm/TargetParser/Triple.h>
12
13#define DEBUG_TYPE "proteus-pass"
14#define DEBUG(x) \
15 do \
16 if (isDebugOutputEnabled()) { \
17 x; \
18 } \
19 while (0);
20
21#if PROTEUS_ENABLE_HIP
22constexpr char const *RegisterFunctionName = "__hipRegisterFunction";
23constexpr char const *LaunchFunctionName = "hipLaunchKernel";
24constexpr char const *RegisterVarName = "__hipRegisterVar";
25constexpr char const *RegisterFatBinaryName = "__hipRegisterFatBinary";
26#elif PROTEUS_ENABLE_CUDA
27constexpr char const *RegisterFunctionName = "__cudaRegisterFunction";
28constexpr char const *LaunchFunctionName = "cudaLaunchKernel";
29constexpr char const *RegisterVarName = "__cudaRegisterVar";
30constexpr char const *RegisterFatBinaryName = "__cudaRegisterFatBinary";
31#else
32constexpr char const *RegisterFunctionName = nullptr;
33constexpr char const *LaunchFunctionName = nullptr;
34constexpr char const *RegisterVarName = nullptr;
35constexpr char const *RegisterFatBinaryName = nullptr;
36#endif
37
38namespace proteus {
39
40using namespace llvm;
41
43 SmallSetVector<RuntimeConstantInfo, 16> ConstantArgs;
44 std::string ModuleIR;
45};
46
47struct ModuleInfo {
48 const Module &M;
49 ModuleInfo(const Module &M) : M(M) {}
50};
51
52inline bool isDebugOutputEnabled() {
53 auto GetEnvVar = []() {
54 const char *EnvValue = std::getenv("PROTEUS_DEBUG_OUTPUT");
55 return EnvValue ? static_cast<bool>(std::stoi(EnvValue)) : false;
56 };
57
58 static bool IsEnabled = GetEnvVar();
59 return IsEnabled;
60}
61
62bool inline isDeviceCompilation(Module &M) {
63 Triple TargetTriple(M.getTargetTriple());
64 DEBUG(Logger::logs("proteus-pass")
65 << "TargetTriple " << TargetTriple.str() << "\n");
66 if (TargetTriple.isNVPTX() || TargetTriple.isAMDGCN())
67 return true;
68
69 return false;
70}
71
72inline std::string getUniqueFileID(Module &M) {
73 llvm::sys::fs::UniqueID ID;
74 if (auto EC = llvm::sys::fs::getUniqueID(M.getSourceFileName(), ID))
75 reportFatalError("Could not get unique id for source file " + EC.message());
76
77 SmallString<64> Out;
78 llvm::raw_svector_ostream OutStr(Out);
79 OutStr << llvm::format("%x_%x", ID.getDevice(), ID.getFile());
80
81 return std::string(Out);
82}
83
84// Resolve the module source path so consumers of the embedded bitcode can
85// locate the translation unit independently of the compile working directory.
86inline std::string getCanonicalSourceFileName(Module &M) {
87 SmallString<256> RealPath;
88 if (llvm::sys::fs::real_path(M.getSourceFileName(), RealPath))
89 return M.getSourceFileName();
90
91 return std::string(RealPath);
92}
93
94inline bool isDeviceKernel(const Function *F) {
95 if (!F)
96 reportFatalError("Expected non-null function");
97
98#if PROTEUS_ENABLE_CUDA
99#if LLVM_VERSION_MAJOR >= 20
100 return (F->getCallingConv() == CallingConv::PTX_Kernel);
101#else
102 const Module &M = *F->getParent();
103 auto GetDeviceKernels = [&M]() {
104 SmallPtrSet<Function *, 16> Kernels;
105 NamedMDNode *MD = M.getNamedMetadata("nvvm.annotations");
106
107 if (!MD)
108 return Kernels;
109
110 for (auto *Op : MD->operands()) {
111 if (Op->getNumOperands() < 2)
112 continue;
113 MDString *KindID = dyn_cast<MDString>(Op->getOperand(1));
114 if (!KindID || KindID->getString() != "kernel")
115 continue;
116
117 Function *KernelFn =
118 mdconst::dyn_extract_or_null<Function>(Op->getOperand(0));
119 if (!KernelFn)
120 continue;
121
122 Kernels.insert(KernelFn);
123 }
124
125 return Kernels;
126 };
127
128 // Create a kernel cache per module, assumes we don't insert/remove kernels
129 // after parsing nvvm.annotations.
130 static DenseMap<const Module *, SmallPtrSet<Function *, 16>> KernelCache;
131 auto It = KernelCache.find(&M);
132 if (It == KernelCache.end())
133 It = KernelCache.insert({&M, GetDeviceKernels()}).first;
134 const auto &KernelSet = It->second;
135 if (KernelSet.contains(F))
136 return true;
137
138 return false;
139#endif
140#endif
141
142#if PROTEUS_ENABLE_HIP
143 return (F->getCallingConv() == CallingConv::AMDGPU_KERNEL);
144#endif
145
146 return false;
147}
148
149} // namespace proteus
150
151namespace llvm {
152
153using namespace proteus;
154
155template <> struct DenseMapInfo<RuntimeConstantInfo> {
158 return K;
159 }
160
163 return K;
164 }
165
166 static unsigned getHashValue(const RuntimeConstantInfo &Val) {
167 return hash_combine(Val.ArgInfo.Type, Val.ArgInfo.Pos);
168 }
169
170 static bool isEqual(const RuntimeConstantInfo &LHS,
171 const RuntimeConstantInfo &RHS) {
172 return ((LHS.ArgInfo.Type == RHS.ArgInfo.Type) &&
173 (LHS.ArgInfo.Pos == RHS.ArgInfo.Pos));
174 }
175};
176
178 const DenseMap<Value *, GlobalVariable *> &StubToKernelMap, Function &Fn) {
179 if (StubToKernelMap.contains(&Fn))
180 return true;
181
182 return false;
183}
184
185} // namespace llvm
186
187#endif
constexpr char const * LaunchFunctionName
Definition Helpers.h:33
#define DEBUG(x)
Definition Helpers.h:14
constexpr char const * RegisterFunctionName
Definition Helpers.h:32
constexpr char const * RegisterVarName
Definition Helpers.h:34
constexpr char const * RegisterFatBinaryName
Definition Helpers.h:35
static llvm::raw_ostream & logs(const std::string &Name)
Definition Logger.h:19
Definition CompiledLibrary.h:8
bool isDeviceKernelHostStub(const DenseMap< Value *, GlobalVariable * > &StubToKernelMap, Function &Fn)
Definition Helpers.h:177
Definition MemoryCache.h:27
@ END
Definition CompilerInterfaceTypes.h:35
@ BEGIN
Definition CompilerInterfaceTypes.h:21
bool isDeviceKernel(const Function *F)
Definition Helpers.h:94
std::string getCanonicalSourceFileName(Module &M)
Definition Helpers.h:86
void reportFatalError(const llvm::Twine &Reason, const char *FILE, unsigned Line)
Definition Error.cpp:14
std::string getUniqueFileID(Module &M)
Definition Helpers.h:72
bool isDebugOutputEnabled()
Definition Helpers.h:52
bool isDeviceCompilation(Module &M)
Definition Helpers.h:62
static bool isEqual(const RuntimeConstantInfo &LHS, const RuntimeConstantInfo &RHS)
Definition Helpers.h:170
static unsigned getHashValue(const RuntimeConstantInfo &Val)
Definition Helpers.h:166
static RuntimeConstantInfo getEmptyKey()
Definition Helpers.h:156
static RuntimeConstantInfo getTombstoneKey()
Definition Helpers.h:161
Definition Helpers.h:42
std::string ModuleIR
Definition Helpers.h:44
SmallSetVector< RuntimeConstantInfo, 16 > ConstantArgs
Definition Helpers.h:43
Definition Helpers.h:47
ModuleInfo(const Module &M)
Definition Helpers.h:49
const Module & M
Definition Helpers.h:48
int32_t Pos
Definition CompilerInterfaceRuntimeConstantInfo.h:20
RuntimeConstantType Type
Definition CompilerInterfaceRuntimeConstantInfo.h:19
Definition CompilerInterfaceRuntimeConstantInfo.h:60
RuntimeConstantArgInfo ArgInfo
Definition CompilerInterfaceRuntimeConstantInfo.h:61