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 (to\_integer(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 (F)

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 = F->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())

198 I->replaceAllUsesWith(C);

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