LCOV - code coverage report
Current view: top level - lib/Target/AMDGPU - AMDGPUHSAMetadataStreamer.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 226 234 96.6 %
Date: 2018-10-20 13:21:21 Functions: 21 21 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===--- AMDGPUHSAMetadataStreamer.cpp --------------------------*- C++ -*-===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : //
      10             : /// \file
      11             : /// AMDGPU HSA Metadata Streamer.
      12             : ///
      13             : //
      14             : //===----------------------------------------------------------------------===//
      15             : 
      16             : #include "AMDGPUHSAMetadataStreamer.h"
      17             : #include "AMDGPU.h"
      18             : #include "AMDGPUSubtarget.h"
      19             : #include "SIMachineFunctionInfo.h"
      20             : #include "SIProgramInfo.h"
      21             : #include "Utils/AMDGPUBaseInfo.h"
      22             : #include "llvm/ADT/StringSwitch.h"
      23             : #include "llvm/IR/Constants.h"
      24             : #include "llvm/IR/Module.h"
      25             : #include "llvm/Support/raw_ostream.h"
      26             : 
      27             : namespace llvm {
      28             : 
      29             : static cl::opt<bool> DumpHSAMetadata(
      30             :     "amdgpu-dump-hsa-metadata",
      31             :     cl::desc("Dump AMDGPU HSA Metadata"));
      32             : static cl::opt<bool> VerifyHSAMetadata(
      33             :     "amdgpu-verify-hsa-metadata",
      34             :     cl::desc("Verify AMDGPU HSA Metadata"));
      35             : 
      36             : namespace AMDGPU {
      37             : namespace HSAMD {
      38             : 
      39           4 : void MetadataStreamer::dump(StringRef HSAMetadataString) const {
      40           4 :   errs() << "AMDGPU HSA Metadata:\n" << HSAMetadataString << '\n';
      41           4 : }
      42             : 
      43           4 : void MetadataStreamer::verify(StringRef HSAMetadataString) const {
      44           4 :   errs() << "AMDGPU HSA Metadata Parser Test: ";
      45             : 
      46           4 :   HSAMD::Metadata FromHSAMetadataString;
      47           8 :   if (fromString(HSAMetadataString, FromHSAMetadataString)) {
      48           0 :     errs() << "FAIL\n";
      49           0 :     return;
      50             :   }
      51             : 
      52             :   std::string ToHSAMetadataString;
      53           4 :   if (toString(FromHSAMetadataString, ToHSAMetadataString)) {
      54           0 :     errs() << "FAIL\n";
      55             :     return;
      56             :   }
      57             : 
      58           8 :   errs() << (HSAMetadataString == ToHSAMetadataString ? "PASS" : "FAIL")
      59             :          << '\n';
      60             :   if (HSAMetadataString != ToHSAMetadataString) {
      61           0 :     errs() << "Original input: " << HSAMetadataString << '\n'
      62           0 :            << "Produced output: " << ToHSAMetadataString << '\n';
      63             :   }
      64             : }
      65             : 
      66        6022 : AccessQualifier MetadataStreamer::getAccessQualifier(StringRef AccQual) const {
      67        6022 :   if (AccQual.empty())
      68             :     return AccessQualifier::Unknown;
      69             : 
      70         337 :   return StringSwitch<AccessQualifier>(AccQual)
      71         674 :              .Case("read_only",  AccessQualifier::ReadOnly)
      72         337 :              .Case("write_only", AccessQualifier::WriteOnly)
      73         337 :              .Case("read_write", AccessQualifier::ReadWrite)
      74             :              .Default(AccessQualifier::Default);
      75             : }
      76             : 
      77        3629 : AddressSpaceQualifier MetadataStreamer::getAddressSpaceQualifer(
      78             :     unsigned AddressSpace) const {
      79             :   switch (AddressSpace) {
      80             :   case AMDGPUAS::PRIVATE_ADDRESS:
      81             :     return AddressSpaceQualifier::Private;
      82             :   case AMDGPUAS::GLOBAL_ADDRESS:
      83             :     return AddressSpaceQualifier::Global;
      84             :   case AMDGPUAS::CONSTANT_ADDRESS:
      85             :     return AddressSpaceQualifier::Constant;
      86             :   case AMDGPUAS::LOCAL_ADDRESS:
      87             :     return AddressSpaceQualifier::Local;
      88             :   case AMDGPUAS::FLAT_ADDRESS:
      89             :     return AddressSpaceQualifier::Generic;
      90             :   case AMDGPUAS::REGION_ADDRESS:
      91             :     return AddressSpaceQualifier::Region;
      92             :   default:
      93             :     return AddressSpaceQualifier::Unknown;
      94             :   }
      95             : }
      96             : 
      97        4644 : ValueKind MetadataStreamer::getValueKind(Type *Ty, StringRef TypeQual,
      98             :                                          StringRef BaseTypeName) const {
      99        4644 :   if (TypeQual.find("pipe") != StringRef::npos)
     100             :     return ValueKind::Pipe;
     101             : 
     102        4638 :   return StringSwitch<ValueKind>(BaseTypeName)
     103             :              .Case("image1d_t", ValueKind::Image)
     104             :              .Case("image1d_array_t", ValueKind::Image)
     105             :              .Case("image1d_buffer_t", ValueKind::Image)
     106             :              .Case("image2d_t", ValueKind::Image)
     107             :              .Case("image2d_array_t", ValueKind::Image)
     108             :              .Case("image2d_array_depth_t", ValueKind::Image)
     109             :              .Case("image2d_array_msaa_t", ValueKind::Image)
     110             :              .Case("image2d_array_msaa_depth_t", ValueKind::Image)
     111             :              .Case("image2d_depth_t", ValueKind::Image)
     112             :              .Case("image2d_msaa_t", ValueKind::Image)
     113             :              .Case("image2d_msaa_depth_t", ValueKind::Image)
     114             :              .Case("image3d_t", ValueKind::Image)
     115             :              .Case("sampler_t", ValueKind::Sampler)
     116             :              .Case("queue_t", ValueKind::Queue)
     117        4638 :              .Default(isa<PointerType>(Ty) ?
     118             :                           (Ty->getPointerAddressSpace() ==
     119        2947 :                            AMDGPUAS::LOCAL_ADDRESS ?
     120             :                            ValueKind::DynamicSharedPointer :
     121             :                            ValueKind::GlobalBuffer) :
     122             :                       ValueKind::ByValue);
     123             : }
     124             : 
     125        6022 : ValueType MetadataStreamer::getValueType(Type *Ty, StringRef TypeName) const {
     126       11361 :   switch (Ty->getTypeID()) {
     127             :   case Type::IntegerTyID: {
     128        4684 :     auto Signed = !TypeName.startswith("u");
     129        4684 :     switch (Ty->getIntegerBitWidth()) {
     130        1077 :     case 8:
     131        1077 :       return Signed ? ValueType::I8 : ValueType::U8;
     132         428 :     case 16:
     133         428 :       return Signed ? ValueType::I16 : ValueType::U16;
     134        2151 :     case 32:
     135        2151 :       return Signed ? ValueType::I32 : ValueType::U32;
     136         956 :     case 64:
     137         956 :       return Signed ? ValueType::I64 : ValueType::U64;
     138             :     default:
     139             :       return ValueType::Struct;
     140             :     }
     141             :   }
     142             :   case Type::HalfTyID:
     143             :     return ValueType::F16;
     144         222 :   case Type::FloatTyID:
     145         222 :     return ValueType::F32;
     146         100 :   case Type::DoubleTyID:
     147         100 :     return ValueType::F64;
     148        3644 :   case Type::PointerTyID:
     149        7288 :     return getValueType(Ty->getPointerElementType(), TypeName);
     150        1695 :   case Type::VectorTyID:
     151        3390 :     return getValueType(Ty->getVectorElementType(), TypeName);
     152         297 :   default:
     153         297 :     return ValueType::Struct;
     154             :   }
     155             : }
     156             : 
     157          66 : std::string MetadataStreamer::getTypeName(Type *Ty, bool Signed) const {
     158          66 :   switch (Ty->getTypeID()) {
     159          36 :   case Type::IntegerTyID: {
     160          36 :     if (!Signed)
     161          12 :       return (Twine('u') + getTypeName(Ty, true)).str();
     162             : 
     163             :     auto BitWidth = Ty->getIntegerBitWidth();
     164          30 :     switch (BitWidth) {
     165             :     case 8:
     166           6 :       return "char";
     167             :     case 16:
     168           6 :       return "short";
     169             :     case 32:
     170          12 :       return "int";
     171             :     case 64:
     172           6 :       return "long";
     173             :     default:
     174           0 :       return (Twine('i') + Twine(BitWidth)).str();
     175             :     }
     176             :   }
     177             :   case Type::HalfTyID:
     178           6 :     return "half";
     179             :   case Type::FloatTyID:
     180           6 :     return "float";
     181             :   case Type::DoubleTyID:
     182           6 :     return "double";
     183             :   case Type::VectorTyID: {
     184             :     auto VecTy = cast<VectorType>(Ty);
     185           6 :     auto ElTy = VecTy->getElementType();
     186             :     auto NumElements = VecTy->getVectorNumElements();
     187          12 :     return (Twine(getTypeName(ElTy, Signed)) + Twine(NumElements)).str();
     188             :   }
     189             :   default:
     190           6 :     return "unknown";
     191             :   }
     192             : }
     193             : 
     194          12 : std::vector<uint32_t> MetadataStreamer::getWorkGroupDimensions(
     195             :     MDNode *Node) const {
     196             :   std::vector<uint32_t> Dims;
     197          12 :   if (Node->getNumOperands() != 3)
     198             :     return Dims;
     199             : 
     200          48 :   for (auto &Op : Node->operands())
     201          36 :     Dims.push_back(mdconst::extract<ConstantInt>(Op)->getZExtValue());
     202             :   return Dims;
     203             : }
     204             : 
     205        2434 : Kernel::CodeProps::Metadata MetadataStreamer::getHSACodeProps(
     206             :     const MachineFunction &MF,
     207             :     const SIProgramInfo &ProgramInfo) const {
     208        2434 :   const GCNSubtarget &STM = MF.getSubtarget<GCNSubtarget>();
     209             :   const SIMachineFunctionInfo &MFI = *MF.getInfo<SIMachineFunctionInfo>();
     210        2434 :   HSAMD::Kernel::CodeProps::Metadata HSACodeProps;
     211        2434 :   const Function &F = MF.getFunction();
     212             : 
     213             :   assert(F.getCallingConv() == CallingConv::AMDGPU_KERNEL ||
     214             :          F.getCallingConv() == CallingConv::SPIR_KERNEL);
     215             : 
     216             :   unsigned MaxKernArgAlign;
     217        2434 :   HSACodeProps.mKernargSegmentSize = STM.getKernArgSegmentSize(F,
     218             :                                                                MaxKernArgAlign);
     219        2434 :   HSACodeProps.mGroupSegmentFixedSize = ProgramInfo.LDSSize;
     220        2434 :   HSACodeProps.mPrivateSegmentFixedSize = ProgramInfo.ScratchSize;
     221        2434 :   HSACodeProps.mKernargSegmentAlign = std::max(MaxKernArgAlign, 4u);
     222        2434 :   HSACodeProps.mWavefrontSize = STM.getWavefrontSize();
     223        2434 :   HSACodeProps.mNumSGPRs = ProgramInfo.NumSGPR;
     224        2434 :   HSACodeProps.mNumVGPRs = ProgramInfo.NumVGPR;
     225        2434 :   HSACodeProps.mMaxFlatWorkGroupSize = MFI.getMaxFlatWorkGroupSize();
     226        2434 :   HSACodeProps.mIsDynamicCallStack = ProgramInfo.DynamicCallStack;
     227        2434 :   HSACodeProps.mIsXNACKEnabled = STM.isXNACKEnabled();
     228        2434 :   HSACodeProps.mNumSpilledSGPRs = MFI.getNumSpilledSGPRs();
     229        2434 :   HSACodeProps.mNumSpilledVGPRs = MFI.getNumSpilledVGPRs();
     230             : 
     231        2434 :   return HSACodeProps;
     232             : }
     233             : 
     234        2434 : Kernel::DebugProps::Metadata MetadataStreamer::getHSADebugProps(
     235             :     const MachineFunction &MF,
     236             :     const SIProgramInfo &ProgramInfo) const {
     237        2434 :   const GCNSubtarget &STM = MF.getSubtarget<GCNSubtarget>();
     238             :   HSAMD::Kernel::DebugProps::Metadata HSADebugProps;
     239             : 
     240             :   if (!STM.debuggerSupported())
     241             :     return HSADebugProps;
     242             : 
     243           3 :   HSADebugProps.mDebuggerABIVersion.push_back(1);
     244           3 :   HSADebugProps.mDebuggerABIVersion.push_back(0);
     245             : 
     246           3 :   if (STM.debuggerEmitPrologue()) {
     247           3 :     HSADebugProps.mPrivateSegmentBufferSGPR =
     248           3 :         ProgramInfo.DebuggerPrivateSegmentBufferSGPR;
     249           3 :     HSADebugProps.mWavefrontPrivateSegmentOffsetSGPR =
     250           3 :         ProgramInfo.DebuggerWavefrontPrivateSegmentOffsetSGPR;
     251             :   }
     252             : 
     253             :   return HSADebugProps;
     254             : }
     255             : 
     256         324 : void MetadataStreamer::emitVersion() {
     257         324 :   auto &Version = HSAMetadata.mVersion;
     258             : 
     259         324 :   Version.push_back(VersionMajor);
     260         324 :   Version.push_back(VersionMinor);
     261         324 : }
     262             : 
     263         324 : void MetadataStreamer::emitPrintf(const Module &Mod) {
     264         324 :   auto &Printf = HSAMetadata.mPrintf;
     265             : 
     266         324 :   auto Node = Mod.getNamedMetadata("llvm.printf.fmts");
     267         324 :   if (!Node)
     268             :     return;
     269             : 
     270          18 :   for (auto Op : Node->operands())
     271          12 :     if (Op->getNumOperands())
     272          24 :       Printf.push_back(cast<MDString>(Op->getOperand(0))->getString());
     273             : }
     274             : 
     275        2434 : void MetadataStreamer::emitKernelLanguage(const Function &Func) {
     276             :   auto &Kernel = HSAMetadata.mKernels.back();
     277             : 
     278             :   // TODO: What about other languages?
     279        4868 :   auto Node = Func.getParent()->getNamedMetadata("opencl.ocl.version");
     280        2434 :   if (!Node || !Node->getNumOperands())
     281        2209 :     return;
     282         225 :   auto Op0 = Node->getOperand(0);
     283         225 :   if (Op0->getNumOperands() <= 1)
     284             :     return;
     285             : 
     286         225 :   Kernel.mLanguage = "OpenCL C";
     287         450 :   Kernel.mLanguageVersion.push_back(
     288             :       mdconst::extract<ConstantInt>(Op0->getOperand(0))->getZExtValue());
     289         225 :   Kernel.mLanguageVersion.push_back(
     290             :       mdconst::extract<ConstantInt>(Op0->getOperand(1))->getZExtValue());
     291             : }
     292             : 
     293        2434 : void MetadataStreamer::emitKernelAttrs(const Function &Func) {
     294             :   auto &Attrs = HSAMetadata.mKernels.back().mAttrs;
     295             : 
     296        4868 :   if (auto Node = Func.getMetadata("reqd_work_group_size"))
     297          12 :     Attrs.mReqdWorkGroupSize = getWorkGroupDimensions(Node);
     298        2434 :   if (auto Node = Func.getMetadata("work_group_size_hint"))
     299          12 :     Attrs.mWorkGroupSizeHint = getWorkGroupDimensions(Node);
     300        2434 :   if (auto Node = Func.getMetadata("vec_type_hint")) {
     301         216 :     Attrs.mVecTypeHint = getTypeName(
     302             :         cast<ValueAsMetadata>(Node->getOperand(0))->getType(),
     303          54 :         mdconst::extract<ConstantInt>(Node->getOperand(1))->getZExtValue());
     304             :   }
     305        2434 :   if (Func.hasFnAttribute("runtime-handle")) {
     306             :     Attrs.mRuntimeHandle =
     307          18 :         Func.getFnAttribute("runtime-handle").getValueAsString().str();
     308             :   }
     309        2434 : }
     310             : 
     311        2434 : void MetadataStreamer::emitKernelArgs(const Function &Func) {
     312        7078 :   for (auto &Arg : Func.args())
     313        4644 :     emitKernelArg(Arg);
     314             : 
     315        2434 :   emitHiddenKernelArgs(Func);
     316        2434 : }
     317             : 
     318        4644 : void MetadataStreamer::emitKernelArg(const Argument &Arg) {
     319        4644 :   auto Func = Arg.getParent();
     320        4644 :   auto ArgNo = Arg.getArgNo();
     321             :   const MDNode *Node;
     322             : 
     323        4644 :   StringRef Name;
     324        9288 :   Node = Func->getMetadata("kernel_arg_name");
     325        4644 :   if (Node && ArgNo < Node->getNumOperands())
     326           0 :     Name = cast<MDString>(Node->getOperand(ArgNo))->getString();
     327        4644 :   else if (Arg.hasName())
     328        4447 :     Name = Arg.getName();
     329             : 
     330        4644 :   StringRef TypeName;
     331        4644 :   Node = Func->getMetadata("kernel_arg_type");
     332        4644 :   if (Node && ArgNo < Node->getNumOperands())
     333         370 :     TypeName = cast<MDString>(Node->getOperand(ArgNo))->getString();
     334             : 
     335        4644 :   StringRef BaseTypeName;
     336        4644 :   Node = Func->getMetadata("kernel_arg_base_type");
     337        4644 :   if (Node && ArgNo < Node->getNumOperands())
     338         370 :     BaseTypeName = cast<MDString>(Node->getOperand(ArgNo))->getString();
     339             : 
     340        4644 :   StringRef AccQual;
     341        9332 :   if (Arg.getType()->isPointerTy() && Arg.onlyReadsMemory() &&
     342          44 :       Arg.hasNoAliasAttr()) {
     343           4 :     AccQual = "read_only";
     344             :   } else {
     345        4640 :     Node = Func->getMetadata("kernel_arg_access_qual");
     346        4640 :     if (Node && ArgNo < Node->getNumOperands())
     347         333 :       AccQual = cast<MDString>(Node->getOperand(ArgNo))->getString();
     348             :   }
     349             : 
     350        4644 :   StringRef TypeQual;
     351        4644 :   Node = Func->getMetadata("kernel_arg_type_qual");
     352        4644 :   if (Node && ArgNo < Node->getNumOperands())
     353         334 :     TypeQual = cast<MDString>(Node->getOperand(ArgNo))->getString();
     354             : 
     355        4644 :   Type *Ty = Arg.getType();
     356        4644 :   const DataLayout &DL = Func->getParent()->getDataLayout();
     357             : 
     358             :   unsigned PointeeAlign = 0;
     359             :   if (auto PtrTy = dyn_cast<PointerType>(Ty)) {
     360        2953 :     if (PtrTy->getAddressSpace() == AMDGPUAS::LOCAL_ADDRESS) {
     361         175 :       PointeeAlign = Arg.getParamAlignment();
     362         175 :       if (PointeeAlign == 0)
     363         132 :         PointeeAlign = DL.getABITypeAlignment(PtrTy->getElementType());
     364             :     }
     365             :   }
     366             : 
     367        4644 :   emitKernelArg(DL, Ty, getValueKind(Arg.getType(), TypeQual, BaseTypeName),
     368             :                 PointeeAlign, Name, TypeName, BaseTypeName, AccQual, TypeQual);
     369        4644 : }
     370             : 
     371        6022 : void MetadataStreamer::emitKernelArg(const DataLayout &DL, Type *Ty,
     372             :                                      ValueKind ValueKind,
     373             :                                      unsigned PointeeAlign,
     374             :                                      StringRef Name,
     375             :                                      StringRef TypeName, StringRef BaseTypeName,
     376             :                                      StringRef AccQual, StringRef TypeQual) {
     377        6022 :   HSAMetadata.mKernels.back().mArgs.push_back(Kernel::Arg::Metadata());
     378             :   auto &Arg = HSAMetadata.mKernels.back().mArgs.back();
     379             : 
     380       12044 :   Arg.mName = Name;
     381        6022 :   Arg.mTypeName = TypeName;
     382        6022 :   Arg.mSize = DL.getTypeAllocSize(Ty);
     383        6022 :   Arg.mAlign = DL.getABITypeAlignment(Ty);
     384        6022 :   Arg.mValueKind = ValueKind;
     385        6022 :   Arg.mValueType = getValueType(Ty, BaseTypeName);
     386        6022 :   Arg.mPointeeAlign = PointeeAlign;
     387             : 
     388             :   if (auto PtrTy = dyn_cast<PointerType>(Ty))
     389        3629 :     Arg.mAddrSpaceQual = getAddressSpaceQualifer(PtrTy->getAddressSpace());
     390             : 
     391        6022 :   Arg.mAccQual = getAccessQualifier(AccQual);
     392             : 
     393             :   // TODO: Emit Arg.mActualAccQual.
     394             : 
     395             :   SmallVector<StringRef, 1> SplitTypeQuals;
     396        6022 :   TypeQual.split(SplitTypeQuals, " ", -1, false);
     397        6048 :   for (StringRef Key : SplitTypeQuals) {
     398           0 :     auto P = StringSwitch<bool*>(Key)
     399          26 :                  .Case("const",    &Arg.mIsConst)
     400          26 :                  .Case("restrict", &Arg.mIsRestrict)
     401          26 :                  .Case("volatile", &Arg.mIsVolatile)
     402          26 :                  .Case("pipe",     &Arg.mIsPipe)
     403             :                  .Default(nullptr);
     404          26 :     if (P)
     405          26 :       *P = true;
     406             :   }
     407        6022 : }
     408             : 
     409        2434 : void MetadataStreamer::emitHiddenKernelArgs(const Function &Func) {
     410             :   int HiddenArgNumBytes =
     411        2434 :       getIntegerAttribute(Func, "amdgpu-implicitarg-num-bytes", 0);
     412             : 
     413        2434 :   if (!HiddenArgNumBytes)
     414             :     return;
     415             : 
     416         237 :   auto &DL = Func.getParent()->getDataLayout();
     417         237 :   auto Int64Ty = Type::getInt64Ty(Func.getContext());
     418             : 
     419         237 :   if (HiddenArgNumBytes >= 8)
     420         237 :     emitKernelArg(DL, Int64Ty, ValueKind::HiddenGlobalOffsetX);
     421         237 :   if (HiddenArgNumBytes >= 16)
     422         234 :     emitKernelArg(DL, Int64Ty, ValueKind::HiddenGlobalOffsetY);
     423         237 :   if (HiddenArgNumBytes >= 24)
     424         231 :     emitKernelArg(DL, Int64Ty, ValueKind::HiddenGlobalOffsetZ);
     425             : 
     426         237 :   auto Int8PtrTy = Type::getInt8PtrTy(Func.getContext(),
     427             :                                       AMDGPUAS::GLOBAL_ADDRESS);
     428             : 
     429             :   // Emit "printf buffer" argument if printf is used, otherwise emit dummy
     430             :   // "none" argument.
     431         237 :   if (HiddenArgNumBytes >= 32) {
     432         456 :     if (Func.getParent()->getNamedMetadata("llvm.printf.fmts"))
     433         210 :       emitKernelArg(DL, Int8PtrTy, ValueKind::HiddenPrintfBuffer);
     434             :     else
     435          18 :       emitKernelArg(DL, Int8PtrTy, ValueKind::HiddenNone);
     436             :   }
     437             : 
     438             :   // Emit "default queue" and "completion action" arguments if enqueue kernel is
     439             :   // used, otherwise emit dummy "none" arguments.
     440         237 :   if (HiddenArgNumBytes >= 48) {
     441         224 :     if (Func.hasFnAttribute("calls-enqueue-kernel")) {
     442           8 :       emitKernelArg(DL, Int8PtrTy, ValueKind::HiddenDefaultQueue);
     443           8 :       emitKernelArg(DL, Int8PtrTy, ValueKind::HiddenCompletionAction);
     444             :     } else {
     445         216 :       emitKernelArg(DL, Int8PtrTy, ValueKind::HiddenNone);
     446         216 :       emitKernelArg(DL, Int8PtrTy, ValueKind::HiddenNone);
     447             :     }
     448             :   }
     449             : }
     450             : 
     451         324 : void MetadataStreamer::begin(const Module &Mod) {
     452         324 :   emitVersion();
     453         324 :   emitPrintf(Mod);
     454         324 : }
     455             : 
     456         323 : void MetadataStreamer::end() {
     457             :   std::string HSAMetadataString;
     458         323 :   if (toString(HSAMetadata, HSAMetadataString))
     459             :     return;
     460             : 
     461         323 :   if (DumpHSAMetadata)
     462           4 :     dump(HSAMetadataString);
     463         323 :   if (VerifyHSAMetadata)
     464           4 :     verify(HSAMetadataString);
     465             : }
     466             : 
     467        2437 : void MetadataStreamer::emitKernel(const MachineFunction &MF, const SIProgramInfo &ProgramInfo) {
     468        2437 :   auto &Func = MF.getFunction();
     469        2437 :   if (Func.getCallingConv() != CallingConv::AMDGPU_KERNEL)
     470           3 :     return;
     471             : 
     472        2434 :   auto CodeProps = getHSACodeProps(MF, ProgramInfo);
     473        2434 :   auto DebugProps = getHSADebugProps(MF, ProgramInfo);
     474             : 
     475        4868 :   HSAMetadata.mKernels.push_back(Kernel::Metadata());
     476             :   auto &Kernel = HSAMetadata.mKernels.back();
     477             : 
     478        7302 :   Kernel.mName = Func.getName();
     479        4868 :   Kernel.mSymbolName = (Twine(Func.getName()) + Twine("@kd")).str();
     480        2434 :   emitKernelLanguage(Func);
     481        2434 :   emitKernelAttrs(Func);
     482        2434 :   emitKernelArgs(Func);
     483        2434 :   HSAMetadata.mKernels.back().mCodeProps = CodeProps;
     484             :   HSAMetadata.mKernels.back().mDebugProps = DebugProps;
     485             : }
     486             : 
     487             : } // end namespace HSAMD
     488             : } // end namespace AMDGPU
     489             : } // end namespace llvm

Generated by: LCOV version 1.13