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 45namespace SPIRV{ 46template<class T, class B> 47spv_ostream & 48operator<< (spv_ostream &O, const std::multiset<T *, B>& V) { 49 for (auto &I: V) 50 O << *I; 51 return O; 52} 53 54SPIRVDecorateGeneric::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 64SPIRVDecorateGeneric::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 76SPIRVDecorateGeneric::SPIRVDecorateGeneric(Op OC) 77 :SPIRVAnnotationGeneric(OC), Dec(DecorationRelaxedPrecision), Owner(nullptr){ 78} 79 80Decoration 81SPIRVDecorateGeneric::getDecorateKind()const { 82 return Dec; 83} 84 85SPIRVWord 86SPIRVDecorateGeneric::getLiteral(size_t i) const { 87 assert(0 <= i && i <= Literals.size() && "Out of bounds"); 88 return Literals[i]; 89} 90 91size_t 92SPIRVDecorateGeneric::getLiteralCount() const { 93 return Literals.size(); 94} 95 96void 97SPIRVDecorate::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 106void 107SPIRVDecorate::setWordCount(SPIRVWord Count){ 108 WordCount = Count; 109 Literals.resize(WordCount - FixedWC); 110} 111 112void 113SPIRVDecorate::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 123void 124SPIRVMemberDecorate::encode(spv_ostream &O)const { 125 getEncoder(O) << Target << MemberNumber << Dec << Literals; 126} 127 128void 129SPIRVMemberDecorate::setWordCount(SPIRVWord Count){ 130 WordCount = Count; 131 Literals.resize(WordCount - FixedWC); 132} 133 134void 135SPIRVMemberDecorate::decode(std::istream &I){ 136 getDecoder(I) >> Target >> MemberNumber >> Dec >> Literals; 137 getOrCreateTarget()->addMemberDecorate(this); 138} 139 140void 141SPIRVDecorationGroup::encode(spv_ostream &O)const { 142 getEncoder(O) << Id; 143} 144 145void 146SPIRVDecorationGroup::decode(std::istream &I){ 147 getDecoder(I) >> Id; 148 Module->addDecorationGroup(this); 149} 150 151void 152SPIRVDecorationGroup::encodeAll(spv_ostream &O) const { 153 O << Decorations; 154 SPIRVEntry::encodeAll(O); 155} 156 157void 158SPIRVGroupDecorateGeneric::encode(spv_ostream &O)const { 159 getEncoder(O) << DecorationGroup << Targets; 160} 161 162void 163SPIRVGroupDecorateGeneric::decode(std::istream &I){ 164 getDecoder(I) >> DecorationGroup >> Targets; 165 Module->addGroupDecorateGeneric(this); 166} 167 168void 169SPIRVGroupDecorate::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 179void 180SPIRVGroupMemberDecorate::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 190bool 191SPIRVDecorateGeneric::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 220bool 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