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