30#include "llvm/IR/IntrinsicsNVPTX.h"
42#define NVVM_REFLECT_FUNCTION "__nvvm_reflect"
43#define NVVM_REFLECT_OCL_FUNCTION "__nvvm_reflect_ocl"
47#define DEBUG_TYPE "nvptx-reflect"
56 NVVMReflect() : NVVMReflect(0) {}
71 cl::desc(
"NVVM reflection, enabled by default"));
73char NVVMReflect::ID = 0;
75 "Replace occurrences of __nvvm_reflect() calls with 0/1",
false,
84 assert(
F.isDeclaration() &&
"_reflect function should not have a body");
85 assert(
F.getReturnType()->isIntegerTy() &&
86 "_reflect's return type should be integer");
123 Function *Callee = Call->getCalledFunction();
126 Callee->getIntrinsicID() != Intrinsic::nvvm_reflect))
130 assert(Call->getNumOperands() == 2 &&
131 "Wrong number of operands to __nvvm_reflect function");
135 const Value *Str = Call->getArgOperand(0);
136 if (
const CallInst *ConvCall = dyn_cast<CallInst>(Str)) {
138 Str = ConvCall->getArgOperand(0);
142 Str = Str->stripPointerCasts();
143 assert(isa<Constant>(Str) &&
144 "Format of __nvvm_reflect function not recognized");
146 const Value *Operand = cast<Constant>(Str)->getOperand(0);
147 if (
const GlobalVariable *GV = dyn_cast<GlobalVariable>(Operand)) {
150 assert(GV->hasInitializer() &&
151 "Format of _reflect function not recognized");
152 const Constant *Initializer = GV->getInitializer();
153 Operand = Initializer;
156 assert(isa<ConstantDataSequential>(Operand) &&
157 "Format of _reflect function not recognized");
158 assert(cast<ConstantDataSequential>(Operand)->isCString() &&
159 "Format of _reflect function not recognized");
161 StringRef ReflectArg = cast<ConstantDataSequential>(Operand)->getAsString();
162 ReflectArg = ReflectArg.
substr(0, ReflectArg.
size() - 1);
166 if (ReflectArg ==
"__CUDA_FTZ") {
170 if (
auto *Flag = mdconst::extract_or_null<ConstantInt>(
171 F.getParent()->getModuleFlag(
"nvvm-reflect-ftz")))
172 ReflectVal = Flag->getSExtValue();
173 }
else if (ReflectArg ==
"__CUDA_ARCH") {
178 for (
User *U : Call->users())
182 Call->replaceAllUsesWith(ConstantInt::get(Call->getType(), ReflectVal));
193 for (
User *U :
I->users())
197 I->replaceAllUsesWith(
C);
201 }
else if (
I->isTerminator()) {
213 I->eraseFromParent();
218bool 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)