LLVM: lib/Target/NVPTX/NVVMReflect.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
31#include "llvm/IR/IntrinsicsNVPTX.h"
42#define NVVM_REFLECT_FUNCTION "__nvvm_reflect"
43#define NVVM_REFLECT_OCL_FUNCTION "__nvvm_reflect_ocl"
44
45#define CUDA_ARCH_NAME "__CUDA_ARCH"
46
47#define CUDA_FTZ_NAME "__CUDA_FTZ"
48
49#define CUDA_FTZ_MODULE_NAME "nvvm-reflect-ftz"
50
51using namespace llvm;
52
53#define DEBUG_TYPE "nvvm-reflect"
54
55namespace {
56class NVVMReflect {
57
58
60 bool handleReflectFunction(Module &M, StringRef ReflectName);
61 void populateReflectMap(Module &M);
63
64public:
65
66
67 explicit NVVMReflect(unsigned SmVersion)
69 bool runOnModule(Module &M);
70};
71
72class NVVMReflectLegacyPass : public ModulePass {
73 NVVMReflect Impl;
74
75public:
76 static char ID;
77 NVVMReflectLegacyPass(unsigned SmVersion) : ModulePass(ID), Impl(SmVersion) {}
78 bool runOnModule(Module &M) override;
79};
80}
81
83 return new NVVMReflectLegacyPass(SmVersion);
84}
85
88 cl::desc("NVVM reflection, enabled by default"));
89
90char NVVMReflectLegacyPass::ID = 0;
92 "Replace occurrences of __nvvm_reflect() calls with 0/1", false,
93 false)
94
95
96
97
98
99static cl::list<std::string> ReflectList(
100 "nvvm-reflect-add", cl::value_desc("name="), cl::Hidden,
101 cl::desc("A key=value pair. Replace __nvvm_reflect(name) with value."),
102 cl::ValueRequired);
103
104
105
106void NVVMReflect::populateReflectMap(Module &M) {
109 ReflectMap[CUDA_FTZ_NAME] = Flag->getSExtValue();
110
111 for (auto &Option : ReflectList) {
112 LLVM_DEBUG(dbgs() << "ReflectOption : " << Option << "\n");
114 auto [Name, Val] = OptionRef.split('=');
115 if (Name.empty())
117 Option + "'");
118 if (Val.empty())
120 Option + "'");
121 unsigned ValInt;
122 if ((Val.trim(), ValInt, 10))
124 Twine("integer value expected in nvvm-reflect-add option '") +
125 Option + "'");
126 ReflectMap[Name] = ValInt;
127 }
128}
129
130
131
132
133bool NVVMReflect::handleReflectFunction(Module &M, StringRef ReflectName) {
134 Function *F = M.getFunction(ReflectName);
135 if ()
136 return false;
137 assert(F->isDeclaration() && "_reflect function should not have a body");
138 assert(F->getReturnType()->isIntegerTy() &&
139 "_reflect's return type should be integer");
140
141 const bool Changed = ->use_empty();
143
144
145
146
147
151 "__nvvm_reflect can only be used in a call instruction");
154
158 report_fatal_error("__nvvm_reflect argument must be a constant string");
159
160 auto *ConstantStr =
162 if (!ConstantStr)
163 report_fatal_error("__nvvm_reflect argument must be a string constant");
164 if (!ConstantStr->isCString())
166 "__nvvm_reflect argument must be a null-terminated string");
167
168 StringRef ReflectArg = ConstantStr->getAsString().drop_back();
169 if (ReflectArg.empty())
171
172
173 unsigned ReflectVal = 0;
174 if (ReflectMap.contains(ReflectArg))
175 ReflectVal = ReflectMap[ReflectArg];
176
177 LLVM_DEBUG(dbgs() << "Replacing call of reflect function " << F->getName()
178 << "(" << ReflectArg << ") with value " << ReflectVal
179 << "\n");
180 auto *NewValue = ConstantInt::get(Call->getType(), ReflectVal);
181 foldReflectCall(Call, NewValue);
183 }
184
185
186 F->eraseFromParent();
188}
189
190void NVVMReflect::foldReflectCall(CallInst *Call, Constant *NewValue) {
191 SmallVector<Instruction *, 8> Worklist;
192
193
195 for (auto *U : I->users())
199 };
200
201 ReplaceInstructionWithConst(Call, NewValue);
202
204 while (!Worklist.empty()) {
207 ReplaceInstructionWithConst(I, C);
209 I->eraseFromParent();
210 } else if (I->isTerminator()) {
212 }
213 }
214}
215
216bool NVVMReflect::runOnModule(Module &M) {
218 return false;
219 populateReflectMap(M);
224 handleReflectFunction(M, Intrinsic::getName(Intrinsic::nvvm_reflect));
226}
227
228bool NVVMReflectLegacyPass::runOnModule(Module &M) {
229 return Impl.runOnModule(M);
230}
231
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
Machine Check Debug Module
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
Definition NVVMReflect.cpp:49
#define NVVM_REFLECT_OCL_FUNCTION
Definition NVVMReflect.cpp:43
#define NVVM_REFLECT_FUNCTION
Definition NVVMReflect.cpp:42
static cl::opt< bool > NVVMReflectEnabled("nvvm-reflect-enable", cl::init(true), cl::Hidden, cl::desc("NVVM reflection, enabled by default"))
#define CUDA_ARCH_NAME
Definition NVVMReflect.cpp:45
#define CUDA_FTZ_NAME
Definition NVVMReflect.cpp:47
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
This file defines the SmallVector class.
Value * getArgOperand(unsigned i) const
This class represents a function call, abstracting a target machine's calling convention.
This is an important base class in LLVM.
LLVM_ABI const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
A Module instance is used to store all the information related to an LLVM module.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
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)
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
bool contains(StringRef Key) const
contains - Return true if the element is in the map, false otherwise.
StringRef - Represent a constant reference to a string, i.e.
constexpr bool empty() const
empty - Check if the string is empty.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
unsigned getNumOperands() const
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
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".
This namespace contains all of the command line option processing machinery.
initializer< Ty > init(const Ty &Val)
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract_or_null(Y &&MD)
Extract a Value from Metadata, allowing null.
friend class Instruction
Iterator for Instructions in a `BasicBlock.
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...
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
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)
bool to_integer(StringRef S, N &Num, unsigned Base=0)
Convert the string S to an integer of the specified type using the radix Base. If Base is 0,...
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Implement std::hash so that hash_code can be used in STL containers.
PreservedAnalyses run(Module &F, ModuleAnalysisManager &AM)
Definition NVVMReflect.cpp:232