Go to the documentation of this file.
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;
177 InstsToErase.push_back(Inst);
187 for (
const auto &
Use : SamplerArg.
uses()) {
188 auto Inst = dyn_cast<CallInst>(
Use.
getUser());
197 Value *Replacement =
nullptr;
205 Inst->replaceAllUsesWith(Replacement);
206 InstsToErase.push_back(Inst);
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);
274 ArgTypes.push_back(ImageSizeType);
279 ArgTypes.push_back(ImageFormatType);
286 return std::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);
310 for (
const MDVector &MDV : NewArgMDs.ArgVector)
314 return std::tuple(NewF, NewMDNode);
317 bool transformKernels(
Module &M) {
331 std::tie(NewF, NewMDNode) = addImplicitArgs(
F, KernelMDNode);
334 F->eraseFromParent();
335 M.getFunctionList().push_back(NewF);
341 KernelMDNode = NewMDNode;
345 Modified |= replaceImageAndSamplerUses(
F, KernelMDNode);
354 bool runOnModule(
Module &M)
override {
360 return transformKernels(M);
364 return "R600 OpenCL Image Type Pass";
373 return new R600OpenCLImageTypeLoweringPass();
This class represents an incoming formal argument to a Function.
This is an optimization pass for GlobalISel generic memory operations.
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
unsigned getNumOperands() const
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
void setOperand(unsigned I, MDNode *New)
The instances of the Type class are immutable: once they are created, they are never changed.
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
ModulePass * createR600OpenCLImageTypeLoweringPass()
static bool IsImageType(StringRef TypeString)
static IntegerType * getInt32Ty(LLVMContext &C)
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
unsigned getNumOperands() const
Return number of MDNode operands.
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
static StringRef ImageFormatArgMDType
static void PushArgMD(KernelArgMD &MD, const MDVector &V)
static StringRef GetSamplerResourceIDFunc
iterator_range< use_iterator > uses()
static StringRef GetImageFormatFunc
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.
User * getUser() const
Returns the User that contains this Use.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
AttributeList getAttributes() const
Return the attribute list for this Function.
static StringRef GetImageSizeFunc
const MDOperand & getOperand(unsigned I) const
static StringRef ImageSizeArgMDType
static StringRef ArgTypeFromMD(MDNode *KernelMDNode, unsigned ArgIdx)
std::vector< std::string > ArgVector
This is an important class for using LLVM in a threaded context.
Type * getParamType(unsigned i) const
Parameter type accessors.
static MDString * get(LLVMContext &Context, StringRef Str)
MDNode * getOperand(unsigned i) const
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static StringRef GetImageResourceIDFunc
static ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
A Module instance is used to store all the information related to an LLVM module.
static StringRef KernelArgMDNodeNames[]
StringRef - Represent a constant reference to a string, i.e.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
static StringRef KernelsMDNodeName
StringRef getName() const
Return a constant reference to the value's name.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static Function * GetFunctionFromMDNode(MDNode *Node)
static StringRef AccessQualFromMD(MDNode *KernelMDNode, unsigned ArgIdx)
FunctionType * getFunctionType() const
Returns the FunctionType for me.
static MDVector GetArgMD(MDNode *KernelMDNode, unsigned OpIdx)
static bool IsSamplerType(StringRef TypeString)
static const unsigned NumKernelArgMDNodes
void CloneFunctionInto(Function *NewFunc, const Function *OldFunc, ValueToValueMapTy &VMap, CloneFunctionChangeType Changes, 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.
StringRef getString() const
Type * getReturnType() const
LLVM Value Representation.
Class to represent function types.
A Use represents the edge between a Value definition and its users.