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