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"
59 NVVMReflect() : NVVMReflect(0) {}
74 cl::desc(
"NVVM reflection, enabled by default"));
76char NVVMReflect::ID = 0;
78 "Replace occurrences of __nvvm_reflect() calls with 0/1",
false,
87 assert(
F.isDeclaration() &&
"_reflect function should not have a body");
88 assert(
F.getReturnType()->isIntegerTy() &&
89 "_reflect's return type should be integer");
126 Function *Callee = Call->getCalledFunction();
129 Callee->getIntrinsicID() != Intrinsic::nvvm_reflect))
133 assert(Call->getNumOperands() == 2 &&
134 "Wrong number of operands to __nvvm_reflect function");
138 const Value *Str = Call->getArgOperand(0);
139 if (
const CallInst *ConvCall = dyn_cast<CallInst>(Str)) {
141 Str = ConvCall->getArgOperand(0);
145 Str = Str->stripPointerCasts();
146 assert(isa<Constant>(Str) &&
147 "Format of __nvvm_reflect function not recognized");
149 const Value *Operand = cast<Constant>(Str)->getOperand(0);
150 if (
const GlobalVariable *GV = dyn_cast<GlobalVariable>(Operand)) {
153 assert(GV->hasInitializer() &&
154 "Format of _reflect function not recognized");
155 const Constant *Initializer = GV->getInitializer();
156 Operand = Initializer;
159 assert(isa<ConstantDataSequential>(Operand) &&
160 "Format of _reflect function not recognized");
161 assert(cast<ConstantDataSequential>(Operand)->isCString() &&
162 "Format of _reflect function not recognized");
164 StringRef ReflectArg = cast<ConstantDataSequential>(Operand)->getAsString();
165 ReflectArg = ReflectArg.
substr(0, ReflectArg.
size() - 1);
169 if (ReflectArg ==
"__CUDA_FTZ") {
173 if (
auto *Flag = mdconst::extract_or_null<ConstantInt>(
174 F.getParent()->getModuleFlag(
"nvvm-reflect-ftz")))
175 ReflectVal = Flag->getSExtValue();
176 }
else if (ReflectArg ==
"__CUDA_ARCH") {
181 for (
User *U : Call->users())
185 Call->replaceAllUsesWith(ConstantInt::get(Call->getType(), ReflectVal));
195 for (
User *U :
I->users())
199 I->replaceAllUsesWith(
C);
203 }
else if (
I->isTerminator()) {
215 I->eraseFromParent();
220bool 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.
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.
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)