Path: blob/main/contrib/llvm-project/llvm/lib/Target/SPIRV/SPIRVMetadata.cpp
35294 views
//===--- SPIRVMetadata.cpp ---- IR Metadata Parsing Funcs -------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file contains functions needed for parsing LLVM IR metadata relevant9// to the SPIR-V target.10//11//===----------------------------------------------------------------------===//1213#include "SPIRVMetadata.h"1415using namespace llvm;1617static MDString *getOCLKernelArgAttribute(const Function &F, unsigned ArgIdx,18const StringRef AttributeName) {19assert(20F.getCallingConv() == CallingConv::SPIR_KERNEL &&21"Kernel attributes are attached/belong only to OpenCL kernel functions");2223// Lookup the argument attribute in metadata attached to the kernel function.24MDNode *Node = F.getMetadata(AttributeName);25if (Node && ArgIdx < Node->getNumOperands())26return cast<MDString>(Node->getOperand(ArgIdx));2728// Sometimes metadata containing kernel attributes is not attached to the29// function, but can be found in the named module-level metadata instead.30// For example:31// !opencl.kernels = !{!0}32// !0 = !{void ()* @someKernelFunction, !1, ...}33// !1 = !{!"kernel_arg_addr_space", ...}34// In this case the actual index of searched argument attribute is ArgIdx + 1,35// since the first metadata node operand is occupied by attribute name36// ("kernel_arg_addr_space" in the example above).37unsigned MDArgIdx = ArgIdx + 1;38NamedMDNode *OpenCLKernelsMD =39F.getParent()->getNamedMetadata("opencl.kernels");40if (!OpenCLKernelsMD || OpenCLKernelsMD->getNumOperands() == 0)41return nullptr;4243// KernelToMDNodeList contains kernel function declarations followed by44// corresponding MDNodes for each attribute. Search only MDNodes "belonging"45// to the currently lowered kernel function.46MDNode *KernelToMDNodeList = OpenCLKernelsMD->getOperand(0);47bool FoundLoweredKernelFunction = false;48for (const MDOperand &Operand : KernelToMDNodeList->operands()) {49ValueAsMetadata *MaybeValue = dyn_cast<ValueAsMetadata>(Operand);50if (MaybeValue &&51dyn_cast<Function>(MaybeValue->getValue())->getName() == F.getName()) {52FoundLoweredKernelFunction = true;53continue;54}55if (MaybeValue && FoundLoweredKernelFunction)56return nullptr;5758MDNode *MaybeNode = dyn_cast<MDNode>(Operand);59if (FoundLoweredKernelFunction && MaybeNode &&60cast<MDString>(MaybeNode->getOperand(0))->getString() ==61AttributeName &&62MDArgIdx < MaybeNode->getNumOperands())63return cast<MDString>(MaybeNode->getOperand(MDArgIdx));64}65return nullptr;66}6768namespace llvm {6970MDString *getOCLKernelArgAccessQual(const Function &F, unsigned ArgIdx) {71assert(72F.getCallingConv() == CallingConv::SPIR_KERNEL &&73"Kernel attributes are attached/belong only to OpenCL kernel functions");74return getOCLKernelArgAttribute(F, ArgIdx, "kernel_arg_access_qual");75}7677MDString *getOCLKernelArgTypeQual(const Function &F, unsigned ArgIdx) {78assert(79F.getCallingConv() == CallingConv::SPIR_KERNEL &&80"Kernel attributes are attached/belong only to OpenCL kernel functions");81return getOCLKernelArgAttribute(F, ArgIdx, "kernel_arg_type_qual");82}8384} // namespace llvm858687