31#include "llvm/IR/IntrinsicsNVPTX.h"
43#define NVVM_REFLECT_FUNCTION "__nvvm_reflect"
44#define NVVM_REFLECT_OCL_FUNCTION "__nvvm_reflect_ocl"
48#define DEBUG_TYPE "nvptx-reflect"
57 NVVMReflect() : NVVMReflect(0) {}
72 cl::desc(
"NVVM reflection, enabled by default"));
74char NVVMReflect::ID = 0;
76 "Replace occurrences of __nvvm_reflect() calls with 0/1",
false,
85 assert(
F.isDeclaration() &&
"_reflect function should not have a body");
86 assert(
F.getReturnType()->isIntegerTy() &&
87 "_reflect's return type should be integer");
124 Function *Callee = Call->getCalledFunction();
127 Callee->getIntrinsicID() != Intrinsic::nvvm_reflect))
131 assert(Call->getNumOperands() == 2 &&
132 "Wrong number of operands to __nvvm_reflect function");
136 const Value *Str = Call->getArgOperand(0);
137 if (
const CallInst *ConvCall = dyn_cast<CallInst>(Str)) {
139 Str = ConvCall->getArgOperand(0);
143 Str = Str->stripPointerCasts();
144 assert(isa<Constant>(Str) &&
145 "Format of __nvvm_reflect function not recognized");
147 const Value *Operand = cast<Constant>(Str)->getOperand(0);
148 if (
const GlobalVariable *GV = dyn_cast<GlobalVariable>(Operand)) {
151 assert(GV->hasInitializer() &&
152 "Format of _reflect function not recognized");
153 const Constant *Initializer = GV->getInitializer();
154 Operand = Initializer;
157 assert(isa<ConstantDataSequential>(Operand) &&
158 "Format of _reflect function not recognized");
159 assert(cast<ConstantDataSequential>(Operand)->isCString() &&
160 "Format of _reflect function not recognized");
162 StringRef ReflectArg = cast<ConstantDataSequential>(Operand)->getAsString();
163 ReflectArg = ReflectArg.
substr(0, ReflectArg.
size() - 1);
167 if (ReflectArg ==
"__CUDA_FTZ") {
171 if (
auto *Flag = mdconst::extract_or_null<ConstantInt>(
172 F.getParent()->getModuleFlag(
"nvvm-reflect-ftz")))
173 ReflectVal = Flag->getSExtValue();
174 }
else if (ReflectArg ==
"__CUDA_ARCH") {
179 for (
User *U : Call->users())
183 Call->replaceAllUsesWith(ConstantInt::get(Call->getType(), ReflectVal));
194 for (
User *U :
I->users())
198 I->replaceAllUsesWith(
C);
202 }
else if (
I->isTerminator()) {
214 I->eraseFromParent();
219bool NVVMReflect::runOnFunction(
Function &
F) {
Expand Atomic instructions
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.
#define NVVM_REFLECT_OCL_FUNCTION
SmallVector< Instruction *, 4 > ToSimplify
#define NVVM_REFLECT_FUNCTION
static cl::opt< bool > NVVMReflectEnabled("nvvm-reflect-enable", cl::init(true), cl::Hidden, cl::desc("NVVM reflection, enabled by default"))
SmallVector< Instruction *, 4 > ToRemove
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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.
FunctionPass class - This class is used to implement most global optimizations.
virtual bool runOnFunction(Function &F)=0
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
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.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
bool consumeInteger(unsigned Radix, T &Result)
Parse the current string as an integer of the specified radix.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
constexpr size_t size() const
size - Get the string size.
bool consume_front(StringRef Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
LLVM Value Representation.
@ C
The default llvm calling convention, compatible with C.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
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...
FunctionPass * createNVVMReflectPass(unsigned int SmVersion)
auto unique(Range &&R, Predicate P)
void initializeNVVMReflectPass(PassRegistry &)
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.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Constant * ConstantFoldInstruction(Instruction *I, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr)
ConstantFoldInstruction - Try to constant fold the specified instruction.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)