Home | History | Annotate | Download | only in libSPIRV
      1 //===- SPIRVDecorate.cpp -SPIR-V Decorations ---------------------*- 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 implements SPIR-V decorations.
     37 ///
     38 //===----------------------------------------------------------------------===//
     39 
     40 #include "SPIRVDecorate.h"
     41 #include "SPIRVStream.h"
     42 #include "SPIRVValue.h"
     43 #include "SPIRVModule.h"
     44 
     45 namespace SPIRV{
     46 template<class T, class B>
     47 spv_ostream &
     48 operator<< (spv_ostream &O, const std::multiset<T *, B>& V) {
     49   for (auto &I: V)
     50     O << *I;
     51   return O;
     52 }
     53 
     54 SPIRVDecorateGeneric::SPIRVDecorateGeneric(Op OC, SPIRVWord WC,
     55                                            Decoration TheDec,
     56                                            SPIRVEntry *TheTarget)
     57     : SPIRVAnnotationGeneric(TheTarget->getModule(), WC, OC,
     58                              TheTarget->getId()),
     59       Dec(TheDec), Owner(nullptr) {
     60   validate();
     61   updateModuleVersion();
     62 }
     63 
     64 SPIRVDecorateGeneric::SPIRVDecorateGeneric(Op OC, SPIRVWord WC,
     65                                            Decoration TheDec,
     66                                            SPIRVEntry *TheTarget,
     67                                            SPIRVWord V)
     68     : SPIRVAnnotationGeneric(TheTarget->getModule(), WC, OC,
     69                              TheTarget->getId()),
     70       Dec(TheDec), Owner(nullptr) {
     71   Literals.push_back(V);
     72   validate();
     73   updateModuleVersion();
     74 }
     75 
     76 SPIRVDecorateGeneric::SPIRVDecorateGeneric(Op OC)
     77   :SPIRVAnnotationGeneric(OC), Dec(DecorationRelaxedPrecision), Owner(nullptr){
     78 }
     79 
     80 Decoration
     81 SPIRVDecorateGeneric::getDecorateKind()const {
     82   return Dec;
     83 }
     84 
     85 SPIRVWord
     86 SPIRVDecorateGeneric::getLiteral(size_t i) const {
     87   assert(0 <= i && i <= Literals.size() && "Out of bounds");
     88   return Literals[i];
     89 }
     90 
     91 size_t
     92 SPIRVDecorateGeneric::getLiteralCount() const {
     93   return Literals.size();
     94 }
     95 
     96 void
     97 SPIRVDecorate::encode(spv_ostream &O)const {
     98   SPIRVEncoder Encoder = getEncoder(O);
     99   Encoder << Target << Dec;
    100   if ( Dec == DecorationLinkageAttributes )
    101     SPIRVDecorateLinkageAttr::encodeLiterals(Encoder, Literals);
    102   else
    103     Encoder << Literals;
    104 }
    105 
    106 void
    107 SPIRVDecorate::setWordCount(SPIRVWord Count){
    108   WordCount = Count;
    109   Literals.resize(WordCount - FixedWC);
    110 }
    111 
    112 void
    113 SPIRVDecorate::decode(std::istream &I){
    114   SPIRVDecoder Decoder = getDecoder(I);
    115   Decoder >> Target >> Dec;
    116   if(Dec == DecorationLinkageAttributes)
    117     SPIRVDecorateLinkageAttr::decodeLiterals(Decoder, Literals);
    118   else
    119     Decoder >> Literals;
    120   getOrCreateTarget()->addDecorate(this);
    121 }
    122 
    123 void
    124 SPIRVMemberDecorate::encode(spv_ostream &O)const {
    125   getEncoder(O) << Target << MemberNumber << Dec << Literals;
    126 }
    127 
    128 void
    129 SPIRVMemberDecorate::setWordCount(SPIRVWord Count){
    130   WordCount = Count;
    131   Literals.resize(WordCount - FixedWC);
    132 }
    133 
    134 void
    135 SPIRVMemberDecorate::decode(std::istream &I){
    136   getDecoder(I) >> Target >> MemberNumber >> Dec >> Literals;
    137   getOrCreateTarget()->addMemberDecorate(this);
    138 }
    139 
    140 void
    141 SPIRVDecorationGroup::encode(spv_ostream &O)const {
    142   getEncoder(O) << Id;
    143 }
    144 
    145 void
    146 SPIRVDecorationGroup::decode(std::istream &I){
    147   getDecoder(I) >> Id;
    148   Module->addDecorationGroup(this);
    149 }
    150 
    151 void
    152 SPIRVDecorationGroup::encodeAll(spv_ostream &O) const {
    153   O << Decorations;
    154   SPIRVEntry::encodeAll(O);
    155 }
    156 
    157 void
    158 SPIRVGroupDecorateGeneric::encode(spv_ostream &O)const {
    159   getEncoder(O) << DecorationGroup << Targets;
    160 }
    161 
    162 void
    163 SPIRVGroupDecorateGeneric::decode(std::istream &I){
    164   getDecoder(I) >> DecorationGroup >> Targets;
    165   Module->addGroupDecorateGeneric(this);
    166 }
    167 
    168 void
    169 SPIRVGroupDecorate::decorateTargets() {
    170   for(auto &I:Targets) {
    171     auto Target = getOrCreate(I);
    172     for (auto &Dec:DecorationGroup->getDecorations()) {
    173       assert(Dec->isDecorate());
    174       Target->addDecorate(static_cast<const SPIRVDecorate *const>(Dec));
    175     }
    176   }
    177 }
    178 
    179 void
    180 SPIRVGroupMemberDecorate::decorateTargets() {
    181   for(auto &I:Targets) {
    182     auto Target = getOrCreate(I);
    183     for (auto &Dec:DecorationGroup->getDecorations()) {
    184       assert(Dec->isMemberDecorate());
    185       Target->addMemberDecorate(static_cast<const SPIRVMemberDecorate*>(Dec));
    186     }
    187   }
    188 }
    189 
    190 bool
    191 SPIRVDecorateGeneric::Comparator::operator()(const SPIRVDecorateGeneric *A,
    192     const SPIRVDecorateGeneric *B) {
    193   auto Action = [=](){
    194   if (A->getOpCode() < B->getOpCode())
    195     return true;
    196   if (A->getOpCode() > B->getOpCode())
    197     return false;
    198   if (A->getDecorateKind() < B->getDecorateKind())
    199     return true;
    200   if (A->getDecorateKind() > B->getDecorateKind())
    201     return false;
    202   if (A->getLiteralCount() < B->getLiteralCount())
    203     return true;
    204   if (A->getLiteralCount() > B->getLiteralCount())
    205     return false;
    206   for (size_t I = 0, E = A->getLiteralCount(); I != E; ++I) {
    207     auto EA = A->getLiteral(I);
    208     auto EB = B->getLiteral(I);
    209     if (EA < EB)
    210       return true;
    211     if (EA > EB)
    212       return false;
    213   }
    214   return false;
    215   };
    216   auto Res = Action();
    217   return Res;
    218 }
    219 
    220 bool operator==(const SPIRVDecorateGeneric &A, const SPIRVDecorateGeneric &B) {
    221   if (A.getTargetId() != B.getTargetId())
    222     return false;
    223   if (A.getOpCode() != B.getOpCode())
    224     return false;
    225   if (A.getDecorateKind() != B.getDecorateKind())
    226     return false;
    227   if (A.getLiteralCount() != B.getLiteralCount())
    228     return false;
    229   for (size_t I = 0, E = A.getLiteralCount(); I != E; ++I) {
    230     auto EA = A.getLiteral(I);
    231     auto EB = B.getLiteral(I);
    232     if (EA != EB)
    233       return false;
    234   }
    235   return true;
    236 }
    237 }
    238 
    239