• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {
NamedMDWrapperNamedMDWrapper55     NamedMDWrapper(NamedMDNode &Named, SPIRVMDBuilder& BB)
56       :NMD(Named), B(BB){}
addOpNamedMDWrapper57     MDWrapper<NamedMDWrapper> addOp() {
58       return MDWrapper<NamedMDWrapper>(*this, B);
59     }
addOpNamedMDWrapper60     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 {
MDWrapperMDWrapper69     MDWrapper(ParentT &Parent, SPIRVMDBuilder &Builder)
70       :M(nullptr), P(Parent), B(Builder){}
addMDWrapper71     MDWrapper &add(unsigned I) {
72       V.push_back(ConstantAsMetadata::get(getUInt32(&B.M, I)));
73       return *this;
74     }
addU16MDWrapper75     MDWrapper &addU16(unsigned short I) {
76       V.push_back(ConstantAsMetadata::get(getUInt16(&B.M, I)));
77       return *this;
78     }
addMDWrapper79     MDWrapper &add(StringRef S) {
80       V.push_back(MDString::get(B.C, S));
81       return *this;
82     }
addMDWrapper83     MDWrapper &add(Function *F) {
84       V.push_back(ConstantAsMetadata::get(F));
85       return *this;
86     }
addMDWrapper87     MDWrapper &add(SmallVectorImpl<StringRef> &S) {
88       for (auto &I:S)
89         add(I);
90       return *this;
91     }
addOpMDWrapper92     MDWrapper &addOp(MDNode *Node) {
93       V.push_back(Node);
94       return *this;
95     }
addOpMDWrapper96     MDWrapper<MDWrapper> addOp() {
97       return MDWrapper<MDWrapper>(*this, B);
98     }
addOpMDWrapper99     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   };
SPIRVMDBuilder(Module & Mod)116   explicit SPIRVMDBuilder(Module &Mod):M(Mod), C(Mod.getContext()){}
addNamedMD(StringRef Name)117   NamedMDWrapper addNamedMD(StringRef Name) {
118     return NamedMDWrapper(*M.getOrInsertNamedMetadata(Name), *this);
119   }
eraseNamedMD(StringRef Name)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