LCOV - code coverage report
Current view: top level - lib/Target/AMDGPU - AMDGPUUnifyMetadata.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 25 37 67.6 %
Date: 2018-10-20 13:21:21 Functions: 5 6 83.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- AMDGPUUnifyMetadata.cpp - Unify OpenCL metadata --------------------===//
       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             : // This pass that unifies multiple OpenCL metadata due to linking.
      12             : //
      13             : //===----------------------------------------------------------------------===//
      14             : 
      15             : #include "AMDGPU.h"
      16             : #include "llvm/ADT/SmallVector.h"
      17             : #include "llvm/ADT/StringRef.h"
      18             : #include "llvm/IR/Constants.h"
      19             : #include "llvm/IR/Metadata.h"
      20             : #include "llvm/IR/Module.h"
      21             : #include "llvm/Pass.h"
      22             : #include <algorithm>
      23             : #include <cassert>
      24             : 
      25             : using namespace llvm;
      26             : 
      27             : namespace {
      28             : 
      29             :   namespace kOCLMD {
      30             : 
      31             :     const char SpirVer[]            = "opencl.spir.version";
      32             :     const char OCLVer[]             = "opencl.ocl.version";
      33             :     const char UsedExt[]            = "opencl.used.extensions";
      34             :     const char UsedOptCoreFeat[]    = "opencl.used.optional.core.features";
      35             :     const char CompilerOptions[]    = "opencl.compiler.options";
      36             :     const char LLVMIdent[]          = "llvm.ident";
      37             : 
      38             :   } // end namespace kOCLMD
      39             : 
      40             :   /// Unify multiple OpenCL metadata due to linking.
      41             :   class AMDGPUUnifyMetadata : public ModulePass {
      42             :   public:
      43             :     static char ID;
      44             : 
      45          74 :     explicit AMDGPUUnifyMetadata() : ModulePass(ID) {}
      46             : 
      47             :   private:
      48             :     bool runOnModule(Module &M) override;
      49             : 
      50             :     /// Unify version metadata.
      51             :     /// \return true if changes are made.
      52             :     /// Assume the named metadata has operands each of which is a pair of
      53             :     /// integer constant, e.g.
      54             :     /// !Name = {!n1, !n2}
      55             :     /// !n1 = {i32 1, i32 2}
      56             :     /// !n2 = {i32 2, i32 0}
      57             :     /// Keep the largest version as the sole operand if PickFirst is false.
      58             :     /// Otherwise pick it from the first value, representing kernel module.
      59         148 :     bool unifyVersionMD(Module &M, StringRef Name, bool PickFirst) {
      60         148 :       auto NamedMD = M.getNamedMetadata(Name);
      61         148 :       if (!NamedMD || NamedMD->getNumOperands() <= 1)
      62         147 :         return false;
      63             :       MDNode *MaxMD = nullptr;
      64             :       auto MaxVer = 0U;
      65           1 :       for (const auto &VersionMD : NamedMD->operands()) {
      66             :         assert(VersionMD->getNumOperands() == 2);
      67             :         auto CMajor = mdconst::extract<ConstantInt>(VersionMD->getOperand(0));
      68             :         auto VersionMajor = CMajor->getZExtValue();
      69             :         auto CMinor = mdconst::extract<ConstantInt>(VersionMD->getOperand(1));
      70             :         auto VersionMinor = CMinor->getZExtValue();
      71           1 :         auto Ver = (VersionMajor * 100) + (VersionMinor * 10);
      72           1 :         if (Ver > MaxVer) {
      73           1 :           MaxVer = Ver;
      74             :           MaxMD = VersionMD;
      75             :         }
      76           1 :         if (PickFirst)
      77             :           break;
      78             :       }
      79           1 :       NamedMD->eraseFromParent();
      80           1 :       NamedMD = M.getOrInsertNamedMetadata(Name);
      81           1 :       NamedMD->addOperand(MaxMD);
      82           1 :       return true;
      83             :     }
      84             : 
      85             :   /// Unify version metadata.
      86             :   /// \return true if changes are made.
      87             :   /// Assume the named metadata has operands each of which is a list e.g.
      88             :   /// !Name = {!n1, !n2}
      89             :   /// !n1 = !{!"cl_khr_fp16", {!"cl_khr_fp64"}}
      90             :   /// !n2 = !{!"cl_khr_image"}
      91             :   /// Combine it into a single list with unique operands.
      92           0 :   bool unifyExtensionMD(Module &M, StringRef Name) {
      93           0 :     auto NamedMD = M.getNamedMetadata(Name);
      94           0 :     if (!NamedMD || NamedMD->getNumOperands() == 1)
      95           0 :       return false;
      96             : 
      97             :     SmallVector<Metadata *, 4> All;
      98           0 :     for (const auto &MD : NamedMD->operands())
      99           0 :       for (const auto &Op : MD->operands())
     100           0 :         if (std::find(All.begin(), All.end(), Op.get()) == All.end())
     101           0 :           All.push_back(Op.get());
     102             : 
     103           0 :     NamedMD->eraseFromParent();
     104           0 :     NamedMD = M.getOrInsertNamedMetadata(Name);
     105           0 :     for (const auto &MD : All)
     106           0 :       NamedMD->addOperand(MDNode::get(M.getContext(), MD));
     107             : 
     108             :     return true;
     109             :   }
     110             : };
     111             : 
     112             : } // end anonymous namespace
     113             : 
     114             : char AMDGPUUnifyMetadata::ID = 0;
     115             : 
     116             : char &llvm::AMDGPUUnifyMetadataID = AMDGPUUnifyMetadata::ID;
     117             : 
     118      199024 : INITIALIZE_PASS(AMDGPUUnifyMetadata, "amdgpu-unify-metadata",
     119             :                 "Unify multiple OpenCL metadata due to linking",
     120             :                 false, false)
     121             : 
     122          73 : ModulePass* llvm::createAMDGPUUnifyMetadataPass() {
     123          73 :   return new AMDGPUUnifyMetadata();
     124             : }
     125             : 
     126          74 : bool AMDGPUUnifyMetadata::runOnModule(Module &M) {
     127          74 :   const char* Vers[] = {
     128             :       kOCLMD::SpirVer,
     129             :       kOCLMD::OCLVer
     130             :   };
     131          74 :   const char* Exts[] = {
     132             :       kOCLMD::UsedExt,
     133             :       kOCLMD::UsedOptCoreFeat,
     134             :       kOCLMD::CompilerOptions,
     135             :       kOCLMD::LLVMIdent
     136             :   };
     137             : 
     138             :   bool Changed = false;
     139             : 
     140         222 :   for (auto &I : Vers)
     141         296 :     Changed |= unifyVersionMD(M, I, true);
     142             : 
     143         370 :   for (auto &I : Exts)
     144         592 :     Changed |= unifyExtensionMD(M, I);
     145             : 
     146          74 :   return Changed;
     147             : }

Generated by: LCOV version 1.13