191585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni//===- SPIRVMDBuilder.h -  SPIR-V metadata builder header file --*- C++ -*-===//
291585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni//
391585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni//                     The LLVM/SPIRV Translator
491585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni//
591585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni// This file is distributed under the University of Illinois Open Source
691585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni// License. See LICENSE.TXT for details.
791585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni//
891585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni// Copyright (c) 2014 Advanced Micro Devices, Inc. All rights reserved.
991585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni//
1091585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni// Permission is hereby granted, free of charge, to any person obtaining a
1191585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni// copy of this software and associated documentation files (the "Software"),
1291585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni// to deal with the Software without restriction, including without limitation
1391585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni// the rights to use, copy, modify, merge, publish, distribute, sublicense,
1491585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni// and/or sell copies of the Software, and to permit persons to whom the
1591585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni// Software is furnished to do so, subject to the following conditions:
1691585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni//
1791585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni// Redistributions of source code must retain the above copyright notice,
1891585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni// this list of conditions and the following disclaimers.
1991585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni// Redistributions in binary form must reproduce the above copyright notice,
2091585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni// this list of conditions and the following disclaimers in the documentation
2191585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni// and/or other materials provided with the distribution.
2291585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni// Neither the names of Advanced Micro Devices, Inc., nor the names of its
2391585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni// contributors may be used to endorse or promote products derived from this
2491585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni// Software without specific prior written permission.
2591585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2691585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2791585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2891585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni// CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2991585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
3091585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH
3191585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni// THE SOFTWARE.
3291585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni//
3391585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni//===----------------------------------------------------------------------===//
3491585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni/// \file
3591585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni///
3691585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni/// This file declares classes for creating SPIR-V metadata.
3791585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni///
3891585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni//===----------------------------------------------------------------------===//
3991585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni
4091585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni#ifndef LIB_SPIRV_SPIRVMDBUILDER_H_
4191585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni#define LIB_SPIRV_SPIRVMDBUILDER_H_
4291585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni
4391585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni#include "llvm/IR/Metadata.h"
4491585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni#include "SPIRVInternal.h"
4591585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni
4691585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni#include <functional>
4791585d9acd75a2bdbfd177bf56c8b9436f442152Yang Niusing namespace llvm;
4891585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni
4991585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ninamespace SPIRV {
5091585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni
5191585d9acd75a2bdbfd177bf56c8b9436f442152Yang Niclass SPIRVMDBuilder {
5291585d9acd75a2bdbfd177bf56c8b9436f442152Yang Nipublic:
5391585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni  template<typename ParentT> struct MDWrapper;
5491585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni  struct NamedMDWrapper {
5591585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni    NamedMDWrapper(NamedMDNode &Named, SPIRVMDBuilder& BB)
5691585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni      :NMD(Named), B(BB){}
5791585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni    MDWrapper<NamedMDWrapper> addOp() {
5891585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni      return MDWrapper<NamedMDWrapper>(*this, B);
5991585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni    }
6091585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni    NamedMDWrapper &addOp(MDWrapper<NamedMDWrapper> &MD) {
6191585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni      NMD.addOperand(MD.M);
6291585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni      return *this;
6391585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni    }
6491585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni    NamedMDNode &NMD;
6591585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni    SPIRVMDBuilder &B;
6691585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni  };
6791585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni  template<typename ParentT>
6891585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni  struct MDWrapper {
6991585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni    MDWrapper(ParentT &Parent, SPIRVMDBuilder &Builder)
7091585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni      :M(nullptr), P(Parent), B(Builder){}
7191585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni    MDWrapper &add(unsigned I) {
7291585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni      V.push_back(ConstantAsMetadata::get(getUInt32(&B.M, I)));
7391585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni      return *this;
7491585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni    }
7591585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni    MDWrapper &addU16(unsigned short I) {
7691585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni      V.push_back(ConstantAsMetadata::get(getUInt16(&B.M, I)));
7791585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni      return *this;
7891585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni    }
7991585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni    MDWrapper &add(StringRef S) {
8091585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni      V.push_back(MDString::get(B.C, S));
8191585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni      return *this;
8291585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni    }
8391585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni    MDWrapper &add(Function *F) {
8491585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni      V.push_back(ConstantAsMetadata::get(F));
8591585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni      return *this;
8691585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni    }
8791585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni    MDWrapper &add(SmallVectorImpl<StringRef> &S) {
8891585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni      for (auto &I:S)
8991585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni        add(I);
9091585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni      return *this;
9191585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni    }
9291585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni    MDWrapper &addOp(MDNode *Node) {
9391585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni      V.push_back(Node);
9491585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni      return *this;
9591585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni    }
9691585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni    MDWrapper<MDWrapper> addOp() {
9791585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni      return MDWrapper<MDWrapper>(*this, B);
9891585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni    }
9991585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni    MDWrapper &addOp(MDWrapper<MDWrapper> &MD) {
10091585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni      V.push_back(MD.M);
10191585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni      return *this;
10291585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni    }
10391585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni    /// Generate the scheduled MDNode and return the parent.
10491585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni    /// If \param Ptr is not nullptr, save the generated MDNode.
10591585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni    ParentT &done(MDNode **Ptr = nullptr) {
10691585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni      M = MDNode::get(B.C, V);
10791585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni      if (Ptr)
10891585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni        *Ptr = M;
10991585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni      return P.addOp(*this);
11091585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni    }
11191585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni    MDNode *M;
11291585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni    ParentT &P;
11391585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni    SPIRVMDBuilder &B;
11491585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni    SmallVector<Metadata *, 10> V;
11591585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni  };
11691585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni  explicit SPIRVMDBuilder(Module &Mod):M(Mod), C(Mod.getContext()){}
11791585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni  NamedMDWrapper addNamedMD(StringRef Name) {
11891585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni    return NamedMDWrapper(*M.getOrInsertNamedMetadata(Name), *this);
11991585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni  }
12091585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni  SPIRVMDBuilder &eraseNamedMD(StringRef Name) {
12191585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni    if (auto N = M.getNamedMetadata(Name))
12291585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni      M.eraseNamedMetadata(N);
12391585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni    return *this;
12491585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni  }
12591585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni  friend struct NamedMDWrapper;
12691585d9acd75a2bdbfd177bf56c8b9436f442152Yang Niprivate:
12791585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni  Module& M;
12891585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni  LLVMContext& C;
12991585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni};
13091585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni
13191585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni} /* namespace SPIRV */
13291585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni
13391585d9acd75a2bdbfd177bf56c8b9436f442152Yang Ni#endif /* LIB_SPIRV_SPIRVMDBUILDER_H_ */
134