31#include "llvm/IR/IntrinsicsNVPTX.h"
42#define NVVM_REFLECT_FUNCTION "__nvvm_reflect"
43#define NVVM_REFLECT_OCL_FUNCTION "__nvvm_reflect_ocl"
45#define CUDA_ARCH_NAME "__CUDA_ARCH"
47#define CUDA_FTZ_NAME "__CUDA_FTZ"
49#define CUDA_FTZ_MODULE_NAME "nvvm-reflect-ftz"
53#define DEBUG_TYPE "nvvm-reflect"
61 void populateReflectMap(
Module &M);
67 explicit NVVMReflect(
unsigned SmVersion)
69 bool runOnModule(
Module &M);
72class NVVMReflectLegacyPass :
public ModulePass {
77 NVVMReflectLegacyPass(
unsigned SmVersion) :
ModulePass(
ID), Impl(SmVersion) {}
83 return new NVVMReflectLegacyPass(SmVersion);
88 cl::desc(
"NVVM reflection, enabled by default"));
90char NVVMReflectLegacyPass::ID = 0;
92 "Replace occurrences of __nvvm_reflect() calls with 0/1",
false,
99static cl::list<
std::
string> ReflectList(
100 "nvvm-reflect-add", cl::value_desc("
name=<
int>"), cl::Hidden,
101 cl::desc("
A key=
value pair. Replace __nvvm_reflect(
name) with
value."),
106void NVVMReflect::populateReflectMap(
Module &M) {
107 if (
auto *Flag = mdconst::extract_or_null<ConstantInt>(
111 for (
auto &Option : ReflectList) {
114 auto [
Name, Val] = OptionRef.split(
'=');
122 if (!to_integer(Val.trim(), ValInt, 10))
124 Twine(
"integer value expected in nvvm-reflect-add option '") +
126 ReflectMap[
Name] = ValInt;
133bool NVVMReflect::handleReflectFunction(
Module &M,
StringRef ReflectName) {
137 assert(
F->isDeclaration() &&
"_reflect function should not have a body");
138 assert(
F->getReturnType()->isIntegerTy() &&
139 "_reflect's return type should be integer");
141 const bool Changed = !
F->use_empty();
148 auto *
Call = dyn_cast<CallInst>(U);
151 "__nvvm_reflect can only be used in a call instruction");
152 if (
Call->getNumOperands() != 2)
156 dyn_cast<Constant>(
Call->getArgOperand(0)->stripPointerCasts());
161 dyn_cast<ConstantDataSequential>(
GlobalStr->getOperand(0));
164 if (!ConstantStr->isCString())
166 "__nvvm_reflect argument must be a null-terminated string");
169 if (ReflectArg.
empty())
173 unsigned ReflectVal = 0;
174 if (ReflectMap.contains(ReflectArg))
175 ReflectVal = ReflectMap[ReflectArg];
177 LLVM_DEBUG(
dbgs() <<
"Replacing call of reflect function " <<
F->getName()
178 <<
"(" << ReflectArg <<
") with value " << ReflectVal
180 auto *NewValue = ConstantInt::get(
Call->getType(), ReflectVal);
181 foldReflectCall(Call, NewValue);
182 Call->eraseFromParent();
186 F->eraseFromParent();
195 for (
auto *U :
I->users())
196 if (
auto *UI = dyn_cast<Instruction>(U))
198 I->replaceAllUsesWith(
C);
201 ReplaceInstructionWithConst(Call, NewValue);
203 auto &
DL =
Call->getModule()->getDataLayout();
204 while (!Worklist.
empty()) {
207 ReplaceInstructionWithConst(
I,
C);
209 I->eraseFromParent();
210 }
else if (
I->isTerminator()) {
216bool NVVMReflect::runOnModule(
Module &M) {
219 populateReflectMap(M);
228bool NVVMReflectLegacyPass::runOnModule(
Module &M) {
229 return Impl.runOnModule(M);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Given that RA is a live value
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
static cl::opt< std::string > GlobalStr("nvptx-lower-global-ctor-dtor-id", cl::desc("Override unique ID of ctor/dtor globals."), cl::init(""), cl::Hidden)
#define CUDA_FTZ_MODULE_NAME
#define NVVM_REFLECT_OCL_FUNCTION
#define NVVM_REFLECT_FUNCTION
static cl::opt< bool > NVVMReflectEnabled("nvvm-reflect-enable", cl::init(true), cl::Hidden, cl::desc("NVVM reflection, enabled by default"))
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
This file defines the SmallVector class.
A container for analyses that lazily runs them and caches their results.
This class represents a function call, abstracting a target machine's calling convention.
This is an important base class in LLVM.
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
virtual bool runOnModule(Module &M)=0
runOnModule - Virtual method overriden by subclasses to process the module being operated on.
A Module instance is used to store all the information related to an LLVM module.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
StringRef - Represent a constant reference to a string, i.e.
constexpr bool empty() const
empty - Check if the string is empty.
StringRef drop_back(size_t N=1) const
Return a StringRef equal to 'this' but with the last N elements dropped.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
LLVM_ABI StringRef getName(ID id)
Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx".
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI bool ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions=false, const TargetLibraryInfo *TLI=nullptr, DomTreeUpdater *DTU=nullptr)
If a terminator instruction is predicated on a constant value, convert it into an unconditional branc...
LLVM_ABI Constant * ConstantFoldInstruction(const Instruction *I, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr)
ConstantFoldInstruction - Try to constant fold the specified instruction.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
LLVM_ABI bool isInstructionTriviallyDead(Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction is not used, and the instruction will return.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
ModulePass * createNVVMReflectPass(unsigned int SmVersion)
Implement std::hash so that hash_code can be used in STL containers.
PreservedAnalyses run(Module &F, ModuleAnalysisManager &AM)