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

Generated by: LCOV version 1.13