43 "llvm.OpenCL.sampler.get.resource.id";
50 "kernel_arg_addr_space",
51 "kernel_arg_access_qual",
53 "kernel_arg_base_type",
54 "kernel_arg_type_qual"};
68 return TypeString ==
"image2d_t" || TypeString ==
"image3d_t";
73 return TypeString ==
"sampler_t";
81 size_t NumOps = Node->getNumOperands();
85 auto F = mdconst::dyn_extract<Function>(Node->getOperand(0));
90 size_t ExpectNumArgNodeOps =
F->arg_size() + 1;
92 MDNode *ArgNode = dyn_cast_or_null<MDNode>(Node->getOperand(i + 1));
111 return cast<MDString>(ArgAQNode->
getOperand(ArgIdx + 1))->getString();
117 return cast<MDString>(ArgTypeNode->
getOperand(ArgIdx + 1))->getString();
125 Res.push_back(Node->getOperand(OpIdx));
134 MD.ArgVector[i].push_back(V[i]);
140 class R600OpenCLImageTypeLoweringPass :
public ModulePass {
146 Type *ImageFormatType;
154 for (
auto &
Use : ImageArg.
uses()) {
155 auto Inst = dyn_cast<CallInst>(
Use.
getUser());
164 Value *Replacement =
nullptr;
169 Replacement = &ImageSizeArg;
171 Replacement = &ImageFormatArg;
187 for (
const auto &
Use : SamplerArg.
uses()) {
188 auto Inst = dyn_cast<CallInst>(
Use.
getUser());
197 Value *Replacement =
nullptr;
205 Inst->replaceAllUsesWith(Replacement);
219 InstsToErase.
clear();
220 for (
auto ArgI =
F->arg_begin(); ArgI !=
F->arg_end(); ++ArgI) {
228 if (AccessQual ==
"read_only") {
229 ResourceID = NumReadOnlyImageArgs++;
230 }
else if (AccessQual ==
"write_only") {
231 ResourceID = NumWriteOnlyImageArgs++;
238 Modified |= replaceImageUses(
Arg, ResourceID, SizeArg, FormatArg);
242 uint32_t ResourceID = NumSamplerArgs++;
246 for (
unsigned i = 0; i < InstsToErase.
size(); ++i) {
247 InstsToErase[i]->eraseFromParent();
253 std::tuple<Function *, MDNode *>
261 KernelArgMD NewArgMDs;
267 MDVector ArgMD =
GetArgMD(KernelMDNode, i + 1);
286 return std::make_tuple(
nullptr,
nullptr);
293 auto NewFArgIt = NewF->arg_begin();
294 for (
auto &
Arg:
F->args()) {
295 auto ArgName =
Arg.getName();
296 NewFArgIt->setName(ArgName);
297 VMap[&
Arg] = &(*NewFArgIt++);
299 (NewFArgIt++)->setName(
Twine(
"__size_") + ArgName);
300 (NewFArgIt++)->setName(
Twine(
"__format_") + ArgName);
313 return std::make_tuple(NewF, NewMDNode);
316 bool transformKernels(
Module &M) {
330 std::tie(NewF, NewMDNode) = addImplicitArgs(
F, KernelMDNode);
333 F->eraseFromParent();
334 M.getFunctionList().push_back(NewF);
340 KernelMDNode = NewMDNode;
344 Modified |= replaceImageAndSamplerUses(
F, KernelMDNode);
353 bool runOnModule(
Module &M)
override {
359 return transformKernels(M);
363 return "R600 OpenCL Image Type Pass";
372 return new R600OpenCLImageTypeLoweringPass();
iterator_range< use_iterator > uses()
This class represents an incoming formal argument to a Function.
MDNode * getOperand(unsigned i) const
static StringRef AccessQualFromMD(MDNode *KernelMDNode, unsigned ArgIdx)
This class represents lattice values for constants.
Type * getParamType(unsigned i) const
Parameter type accessors.
static StringRef GetImageFormatFunc
A Module instance is used to store all the information related to an LLVM module.
ModulePass * createR600OpenCLImageTypeLoweringPass()
static MDString * get(LLVMContext &Context, StringRef Str)
void push_back(const T &Elt)
const MDOperand & getOperand(unsigned I) const
static StringRef ImageFormatArgMDType
void setOperand(unsigned I, MDNode *New)
static StringRef KernelsMDNodeName
static StringRef GetSamplerResourceIDFunc
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
A Use represents the edge between a Value definition and its users.
void CloneFunctionInto(Function *NewFunc, const Function *OldFunc, ValueToValueMapTy &VMap, bool ModuleLevelChanges, SmallVectorImpl< ReturnInst * > &Returns, const char *NameSuffix="", ClonedCodeInfo *CodeInfo=nullptr, ValueMapTypeRemapper *TypeMapper=nullptr, ValueMaterializer *Materializer=nullptr)
Clone OldFunc into NewFunc, transforming the old arguments into references to VMap values.
static bool IsImageType(StringRef TypeString)
unsigned getNumOperands() const
Class to represent function types.
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
static StringRef ImageSizeArgMDType
AttributeList getAttributes() const
Return the attribute list for this Function.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
StringRef getString() const
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
The instances of the Type class are immutable: once they are created, they are never changed.
This is an important class for using LLVM in a threaded context.
static MDVector GetArgMD(MDNode *KernelMDNode, unsigned OpIdx)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
static void PushArgMD(KernelArgMD &MD, const MDVector &V)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
User * getUser() const
Returns the User that contains this Use.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Type * getReturnType() const
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
static StringRef KernelArgMDNodeNames[]
FunctionType * getFunctionType() const
Returns the FunctionType for me.
static const unsigned NumKernelArgMDNodes
static StringRef GetImageResourceIDFunc
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
static IntegerType * getInt32Ty(LLVMContext &C)
StringRef getName() const
Return a constant reference to the value's name.
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
static ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
static Function * GetFunctionFromMDNode(MDNode *Node)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
StringRef - Represent a constant reference to a string, i.e.
static bool IsSamplerType(StringRef TypeString)
static StringRef GetImageSizeFunc
unsigned getNumOperands() const
Return number of MDNode operands.
static StringRef ArgTypeFromMD(MDNode *KernelMDNode, unsigned ArgIdx)