Home | History | Annotate | Download | only in SPIRV
      1 //===- SPIRVMDBuilder.h -  SPIR-V metadata builder header file --*- C++ -*-===//
      2 //
      3 //                     The LLVM/SPIRV Translator
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 // Copyright (c) 2014 Advanced Micro Devices, Inc. All rights reserved.
      9 //
     10 // Permission is hereby granted, free of charge, to any person obtaining a
     11 // copy of this software and associated documentation files (the "Software"),
     12 // to deal with the Software without restriction, including without limitation
     13 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
     14 // and/or sell copies of the Software, and to permit persons to whom the
     15 // Software is furnished to do so, subject to the following conditions:
     16 //
     17 // Redistributions of source code must retain the above copyright notice,
     18 // this list of conditions and the following disclaimers.
     19 // Redistributions in binary form must reproduce the above copyright notice,
     20 // this list of conditions and the following disclaimers in the documentation
     21 // and/or other materials provided with the distribution.
     22 // Neither the names of Advanced Micro Devices, Inc., nor the names of its
     23 // contributors may be used to endorse or promote products derived from this
     24 // Software without specific prior written permission.
     25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     26 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     27 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     28 // CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     29 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     30 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH
     31 // THE SOFTWARE.
     32 //
     33 //===----------------------------------------------------------------------===//
     34 /// \file
     35 ///
     36 /// This file declares classes for creating SPIR-V metadata.
     37 ///
     38 //===----------------------------------------------------------------------===//
     39 
     40 #ifndef LIB_SPIRV_SPIRVMDBUILDER_H_
     41 #define LIB_SPIRV_SPIRVMDBUILDER_H_
     42 
     43 #include "llvm/IR/Metadata.h"
     44 #include "SPIRVInternal.h"
     45 
     46 #include <functional>
     47 using namespace llvm;
     48 
     49 namespace SPIRV {
     50 
     51 class SPIRVMDBuilder {
     52 public:
     53   template<typename ParentT> struct MDWrapper;
     54   struct NamedMDWrapper {
     55     NamedMDWrapper(NamedMDNode &Named, SPIRVMDBuilder& BB)
     56       :NMD(Named), B(BB){}
     57     MDWrapper<NamedMDWrapper> addOp() {
     58       return MDWrapper<NamedMDWrapper>(*this, B);
     59     }
     60     NamedMDWrapper &addOp(MDWrapper<NamedMDWrapper> &MD) {
     61       NMD.addOperand(MD.M);
     62       return *this;
     63     }
     64     NamedMDNode &NMD;
     65     SPIRVMDBuilder &B;
     66   };
     67   template<typename ParentT>
     68   struct MDWrapper {
     69     MDWrapper(ParentT &Parent, SPIRVMDBuilder &Builder)
     70       :M(nullptr), P(Parent), B(Builder){}
     71     MDWrapper &add(unsigned I) {
     72       V.push_back(ConstantAsMetadata::get(getUInt32(&B.M, I)));
     73       return *this;
     74     }
     75     MDWrapper &addU16(unsigned short I) {
     76       V.push_back(ConstantAsMetadata::get(getUInt16(&B.M, I)));
     77       return *this;
     78     }
     79     MDWrapper &add(StringRef S) {
     80       V.push_back(MDString::get(B.C, S));
     81       return *this;
     82     }
     83     MDWrapper &add(Function *F) {
     84       V.push_back(ConstantAsMetadata::get(F));
     85       return *this;
     86     }
     87     MDWrapper &add(SmallVectorImpl<StringRef> &S) {
     88       for (auto &I:S)
     89         add(I);
     90       return *this;
     91     }
     92     MDWrapper &addOp(MDNode *Node) {
     93       V.push_back(Node);
     94       return *this;
     95     }
     96     MDWrapper<MDWrapper> addOp() {
     97       return MDWrapper<MDWrapper>(*this, B);
     98     }
     99     MDWrapper &addOp(MDWrapper<MDWrapper> &MD) {
    100       V.push_back(MD.M);
    101       return *this;
    102     }
    103     /// Generate the scheduled MDNode and return the parent.
    104     /// If \param Ptr is not nullptr, save the generated MDNode.
    105     ParentT &done(MDNode **Ptr = nullptr) {
    106       M = MDNode::get(B.C, V);
    107       if (Ptr)
    108         *Ptr = M;
    109       return P.addOp(*this);
    110     }
    111     MDNode *M;
    112     ParentT &P;
    113     SPIRVMDBuilder &B;
    114     SmallVector<Metadata *, 10> V;
    115   };
    116   explicit SPIRVMDBuilder(Module &Mod):M(Mod), C(Mod.getContext()){}
    117   NamedMDWrapper addNamedMD(StringRef Name) {
    118     return NamedMDWrapper(*M.getOrInsertNamedMetadata(Name), *this);
    119   }
    120   SPIRVMDBuilder &eraseNamedMD(StringRef Name) {
    121     if (auto N = M.getNamedMetadata(Name))
    122       M.eraseNamedMetadata(N);
    123     return *this;
    124   }
    125   friend struct NamedMDWrapper;
    126 private:
    127   Module& M;
    128   LLVMContext& C;
    129 };
    130 
    131 } /* namespace SPIRV */
    132 
    133 #endif /* LIB_SPIRV_SPIRVMDBUILDER_H_ */
    134