You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
238 lines
7.0 KiB
238 lines
7.0 KiB
//===- SPIRVDecorate.cpp -SPIR-V Decorations ---------------------*- C++ -*-===// |
|
// |
|
// The LLVM/SPIRV Translator |
|
// |
|
// This file is distributed under the University of Illinois Open Source |
|
// License. See LICENSE.TXT for details. |
|
// |
|
// Copyright (c) 2014 Advanced Micro Devices, Inc. All rights reserved. |
|
// |
|
// Permission is hereby granted, free of charge, to any person obtaining a |
|
// copy of this software and associated documentation files (the "Software"), |
|
// to deal with the Software without restriction, including without limitation |
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense, |
|
// and/or sell copies of the Software, and to permit persons to whom the |
|
// Software is furnished to do so, subject to the following conditions: |
|
// |
|
// Redistributions of source code must retain the above copyright notice, |
|
// this list of conditions and the following disclaimers. |
|
// Redistributions in binary form must reproduce the above copyright notice, |
|
// this list of conditions and the following disclaimers in the documentation |
|
// and/or other materials provided with the distribution. |
|
// Neither the names of Advanced Micro Devices, Inc., nor the names of its |
|
// contributors may be used to endorse or promote products derived from this |
|
// Software without specific prior written permission. |
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|
// CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH |
|
// THE SOFTWARE. |
|
// |
|
//===----------------------------------------------------------------------===// |
|
/// \file |
|
/// |
|
/// This file implements SPIR-V decorations. |
|
/// |
|
//===----------------------------------------------------------------------===// |
|
|
|
#include "SPIRVDecorate.h" |
|
#include "SPIRVStream.h" |
|
#include "SPIRVValue.h" |
|
#include "SPIRVModule.h" |
|
|
|
namespace SPIRV{ |
|
template<class T, class B> |
|
spv_ostream & |
|
operator<< (spv_ostream &O, const std::multiset<T *, B>& V) { |
|
for (auto &I: V) |
|
O << *I; |
|
return O; |
|
} |
|
|
|
SPIRVDecorateGeneric::SPIRVDecorateGeneric(Op OC, SPIRVWord WC, |
|
Decoration TheDec, |
|
SPIRVEntry *TheTarget) |
|
: SPIRVAnnotationGeneric(TheTarget->getModule(), WC, OC, |
|
TheTarget->getId()), |
|
Dec(TheDec), Owner(nullptr) { |
|
validate(); |
|
updateModuleVersion(); |
|
} |
|
|
|
SPIRVDecorateGeneric::SPIRVDecorateGeneric(Op OC, SPIRVWord WC, |
|
Decoration TheDec, |
|
SPIRVEntry *TheTarget, |
|
SPIRVWord V) |
|
: SPIRVAnnotationGeneric(TheTarget->getModule(), WC, OC, |
|
TheTarget->getId()), |
|
Dec(TheDec), Owner(nullptr) { |
|
Literals.push_back(V); |
|
validate(); |
|
updateModuleVersion(); |
|
} |
|
|
|
SPIRVDecorateGeneric::SPIRVDecorateGeneric(Op OC) |
|
:SPIRVAnnotationGeneric(OC), Dec(DecorationRelaxedPrecision), Owner(nullptr){ |
|
} |
|
|
|
Decoration |
|
SPIRVDecorateGeneric::getDecorateKind()const { |
|
return Dec; |
|
} |
|
|
|
SPIRVWord |
|
SPIRVDecorateGeneric::getLiteral(size_t i) const { |
|
assert(0 <= i && i <= Literals.size() && "Out of bounds"); |
|
return Literals[i]; |
|
} |
|
|
|
size_t |
|
SPIRVDecorateGeneric::getLiteralCount() const { |
|
return Literals.size(); |
|
} |
|
|
|
void |
|
SPIRVDecorate::encode(spv_ostream &O)const { |
|
SPIRVEncoder Encoder = getEncoder(O); |
|
Encoder << Target << Dec; |
|
if ( Dec == DecorationLinkageAttributes ) |
|
SPIRVDecorateLinkageAttr::encodeLiterals(Encoder, Literals); |
|
else |
|
Encoder << Literals; |
|
} |
|
|
|
void |
|
SPIRVDecorate::setWordCount(SPIRVWord Count){ |
|
WordCount = Count; |
|
Literals.resize(WordCount - FixedWC); |
|
} |
|
|
|
void |
|
SPIRVDecorate::decode(std::istream &I){ |
|
SPIRVDecoder Decoder = getDecoder(I); |
|
Decoder >> Target >> Dec; |
|
if(Dec == DecorationLinkageAttributes) |
|
SPIRVDecorateLinkageAttr::decodeLiterals(Decoder, Literals); |
|
else |
|
Decoder >> Literals; |
|
getOrCreateTarget()->addDecorate(this); |
|
} |
|
|
|
void |
|
SPIRVMemberDecorate::encode(spv_ostream &O)const { |
|
getEncoder(O) << Target << MemberNumber << Dec << Literals; |
|
} |
|
|
|
void |
|
SPIRVMemberDecorate::setWordCount(SPIRVWord Count){ |
|
WordCount = Count; |
|
Literals.resize(WordCount - FixedWC); |
|
} |
|
|
|
void |
|
SPIRVMemberDecorate::decode(std::istream &I){ |
|
getDecoder(I) >> Target >> MemberNumber >> Dec >> Literals; |
|
getOrCreateTarget()->addMemberDecorate(this); |
|
} |
|
|
|
void |
|
SPIRVDecorationGroup::encode(spv_ostream &O)const { |
|
getEncoder(O) << Id; |
|
} |
|
|
|
void |
|
SPIRVDecorationGroup::decode(std::istream &I){ |
|
getDecoder(I) >> Id; |
|
Module->addDecorationGroup(this); |
|
} |
|
|
|
void |
|
SPIRVDecorationGroup::encodeAll(spv_ostream &O) const { |
|
O << Decorations; |
|
SPIRVEntry::encodeAll(O); |
|
} |
|
|
|
void |
|
SPIRVGroupDecorateGeneric::encode(spv_ostream &O)const { |
|
getEncoder(O) << DecorationGroup << Targets; |
|
} |
|
|
|
void |
|
SPIRVGroupDecorateGeneric::decode(std::istream &I){ |
|
getDecoder(I) >> DecorationGroup >> Targets; |
|
Module->addGroupDecorateGeneric(this); |
|
} |
|
|
|
void |
|
SPIRVGroupDecorate::decorateTargets() { |
|
for(auto &I:Targets) { |
|
auto Target = getOrCreate(I); |
|
for (auto &Dec:DecorationGroup->getDecorations()) { |
|
assert(Dec->isDecorate()); |
|
Target->addDecorate(static_cast<const SPIRVDecorate *const>(Dec)); |
|
} |
|
} |
|
} |
|
|
|
void |
|
SPIRVGroupMemberDecorate::decorateTargets() { |
|
for(auto &I:Targets) { |
|
auto Target = getOrCreate(I); |
|
for (auto &Dec:DecorationGroup->getDecorations()) { |
|
assert(Dec->isMemberDecorate()); |
|
Target->addMemberDecorate(static_cast<const SPIRVMemberDecorate*>(Dec)); |
|
} |
|
} |
|
} |
|
|
|
bool |
|
SPIRVDecorateGeneric::Comparator::operator()(const SPIRVDecorateGeneric *A, |
|
const SPIRVDecorateGeneric *B) { |
|
auto Action = [=](){ |
|
if (A->getOpCode() < B->getOpCode()) |
|
return true; |
|
if (A->getOpCode() > B->getOpCode()) |
|
return false; |
|
if (A->getDecorateKind() < B->getDecorateKind()) |
|
return true; |
|
if (A->getDecorateKind() > B->getDecorateKind()) |
|
return false; |
|
if (A->getLiteralCount() < B->getLiteralCount()) |
|
return true; |
|
if (A->getLiteralCount() > B->getLiteralCount()) |
|
return false; |
|
for (size_t I = 0, E = A->getLiteralCount(); I != E; ++I) { |
|
auto EA = A->getLiteral(I); |
|
auto EB = B->getLiteral(I); |
|
if (EA < EB) |
|
return true; |
|
if (EA > EB) |
|
return false; |
|
} |
|
return false; |
|
}; |
|
auto Res = Action(); |
|
return Res; |
|
} |
|
|
|
bool operator==(const SPIRVDecorateGeneric &A, const SPIRVDecorateGeneric &B) { |
|
if (A.getTargetId() != B.getTargetId()) |
|
return false; |
|
if (A.getOpCode() != B.getOpCode()) |
|
return false; |
|
if (A.getDecorateKind() != B.getDecorateKind()) |
|
return false; |
|
if (A.getLiteralCount() != B.getLiteralCount()) |
|
return false; |
|
for (size_t I = 0, E = A.getLiteralCount(); I != E; ++I) { |
|
auto EA = A.getLiteral(I); |
|
auto EB = B.getLiteral(I); |
|
if (EA != EB) |
|
return false; |
|
} |
|
return true; |
|
} |
|
} |
|
|
|
|