From a72a093bc703a10dcb117d236bb9704e40bb86a5 Mon Sep 17 00:00:00 2001 From: qlin Date: Mon, 4 Jun 2018 14:15:54 +0800 Subject: [PATCH] Add support of OpDecorationGroup, OpGroupDecorate, OpGroupMemberDecorate. This change is port from AMDVLK --- lib/SPIRV/libSPIRV/SPIRVDecorate.cpp | 45 +++++++++++++++++++++++----- lib/SPIRV/libSPIRV/SPIRVDecorate.h | 34 ++++++++++++++------- lib/SPIRV/libSPIRV/SPIRVEntry.cpp | 21 ++++++++++--- lib/SPIRV/libSPIRV/SPIRVEntry.h | 6 ++-- lib/SPIRV/libSPIRV/SPIRVModule.cpp | 6 ++-- lib/SPIRV/libSPIRV/SPIRVModule.h | 2 +- 6 files changed, 85 insertions(+), 29 deletions(-) diff --git a/lib/SPIRV/libSPIRV/SPIRVDecorate.cpp b/lib/SPIRV/libSPIRV/SPIRVDecorate.cpp index 087efbff57b..a5f5086e742 100644 --- a/lib/SPIRV/libSPIRV/SPIRVDecorate.cpp +++ b/lib/SPIRV/libSPIRV/SPIRVDecorate.cpp @@ -155,12 +155,12 @@ SPIRVDecorationGroup::encodeAll(spv_ostream &O) const { } void -SPIRVGroupDecorateGeneric::encode(spv_ostream &O)const { +SPIRVGroupDecorate::encode(spv_ostream &O)const { getEncoder(O) << DecorationGroup << Targets; } void -SPIRVGroupDecorateGeneric::decode(std::istream &I){ +SPIRVGroupDecorate::decode(std::istream &I){ getDecoder(I) >> DecorationGroup >> Targets; Module->addGroupDecorateGeneric(this); } @@ -171,18 +171,49 @@ SPIRVGroupDecorate::decorateTargets() { auto Target = getOrCreate(I); for (auto &Dec:DecorationGroup->getDecorations()) { assert(Dec->isDecorate()); - Target->addDecorate(static_cast(Dec)); + Target->addDecorate(static_cast(Dec)); } } } +void +SPIRVGroupMemberDecorate::encode(spv_ostream &O)const { + std::vector Pairs; + assert(Targets.size() == MemberNumbers.size()); + for (uint32_t J = 0, E = Targets.size(); J < E; ++J) { + Pairs.push_back(Targets[J]); + Pairs.push_back(MemberNumbers[J]); + } + getEncoder(O) << DecorationGroup << Pairs; +} + +void +SPIRVGroupMemberDecorate::decode(std::istream &I) { + std::vector Pairs(WordCount - FixedWC); + getDecoder(I) >> DecorationGroup >> Pairs; + assert(Pairs.size() % 2 == 0); + for (uint32_t J = 0, E = Pairs.size(); J < E; J += 2) { + Targets.push_back(Pairs[J]); + MemberNumbers.push_back(Pairs[J + 1]); + } + Module->addGroupDecorateGeneric(this); +} + void SPIRVGroupMemberDecorate::decorateTargets() { - for(auto &I:Targets) { - auto Target = getOrCreate(I); + assert(Targets.size() == MemberNumbers.size()); + for (uint32_t I = 0, E = Targets.size(); I < E; ++I) { + auto Target = getOrCreate(Targets[I]); for (auto &Dec:DecorationGroup->getDecorations()) { - assert(Dec->isMemberDecorate()); - Target->addMemberDecorate(static_cast(Dec)); + assert(Dec->isDecorate()); + auto TheDec = static_cast(Dec); + if (TheDec->getLiteralCount() == 0) + Target->addMemberDecorate(MemberNumbers[I], TheDec->getDecorateKind()); + else { + assert(TheDec->getLiteralCount() == 1); + Target->addMemberDecorate(MemberNumbers[I], TheDec->getDecorateKind(), + TheDec->getLiteral(0)); + } } } } diff --git a/lib/SPIRV/libSPIRV/SPIRVDecorate.h b/lib/SPIRV/libSPIRV/SPIRVDecorate.h index 1683d451892..fe924ecbab5 100644 --- a/lib/SPIRV/libSPIRV/SPIRVDecorate.h +++ b/lib/SPIRV/libSPIRV/SPIRVDecorate.h @@ -105,12 +105,12 @@ class SPIRVDecorateGeneric:public SPIRVAnnotationGeneric{ SPIRVDecorationGroup *Owner; // Owning decorate group }; -class SPIRVDecorateSet: public std::multiset { public: - typedef std::multiset BaseType; - iterator insert(value_type& Dec) { + iterator insert(const value_type& Dec) { auto ER = BaseType::equal_range(Dec); for (auto I = ER.first, E = ER.second; I != E; ++I) { SPIRVDBG(spvdbgs() << "[compare decorate] " << *Dec @@ -244,10 +244,16 @@ class SPIRVDecorationGroup:public SPIRVEntry{ _SPIRV_DCL_ENCDEC // Move the given decorates to the decoration group void takeDecorates(SPIRVDecorateSet &Decs) { - Decorations = std::move(Decs); + for (auto &I:Decs) { + // Insert decorates whose target ID is this decoration group + if (I->getTargetId() == Id) { + const_cast(I)->setOwner(this); + Decorations.insert(I); + } + } + // Remove those inserted decorates from original set for (auto &I:Decorations) - const_cast(I)->setOwner(this); - Decs.clear(); + Decs.erase(I); } SPIRVDecorateSet& getDecorations() { @@ -276,12 +282,7 @@ class SPIRVGroupDecorateGeneric:public SPIRVEntryNoIdGeneric{ SPIRVGroupDecorateGeneric(Op OC) :SPIRVEntryNoIdGeneric(OC), DecorationGroup(nullptr){} - void setWordCount(SPIRVWord WC) { - SPIRVEntryNoIdGeneric::setWordCount(WC); - Targets.resize(WC - FixedWC); - } virtual void decorateTargets() = 0; - _SPIRV_DCL_ENCDEC protected: SPIRVDecorationGroup *DecorationGroup; std::vector Targets; @@ -298,7 +299,12 @@ class SPIRVGroupDecorate:public SPIRVGroupDecorateGeneric{ SPIRVGroupDecorate() :SPIRVGroupDecorateGeneric(OC){} + void setWordCount(SPIRVWord WC) { + SPIRVEntryNoIdGeneric::setWordCount(WC); + Targets.resize(WC - FixedWC); + } virtual void decorateTargets(); + _SPIRV_DCL_ENCDEC }; class SPIRVGroupMemberDecorate:public SPIRVGroupDecorateGeneric{ @@ -312,7 +318,13 @@ class SPIRVGroupMemberDecorate:public SPIRVGroupDecorateGeneric{ SPIRVGroupMemberDecorate() :SPIRVGroupDecorateGeneric(OC){} + void setWordCount(SPIRVWord WC) { + SPIRVEntryNoIdGeneric::setWordCount(WC); + } virtual void decorateTargets(); + _SPIRV_DCL_ENCDEC +protected: + std::vector MemberNumbers; }; } diff --git a/lib/SPIRV/libSPIRV/SPIRVEntry.cpp b/lib/SPIRV/libSPIRV/SPIRVEntry.cpp index 3bd881880de..f13e6c16f35 100644 --- a/lib/SPIRV/libSPIRV/SPIRVEntry.cpp +++ b/lib/SPIRV/libSPIRV/SPIRVEntry.cpp @@ -282,7 +282,7 @@ SPIRVEntry::validateBuiltin(SPIRVWord TheSet, SPIRVWord Index)const { } void -SPIRVEntry::addDecorate(SPIRVDecorate *Dec) { +SPIRVEntry::addDecorate(const SPIRVDecorate *Dec) { auto Kind = Dec->getDecorateKind(); Decorates.insert(std::make_pair(Dec->getDecorateKind(), Dec)); Module->addDecorate(Dec); @@ -321,9 +321,8 @@ SPIRVEntry::setLine(const std::shared_ptr& L){ } void -SPIRVEntry::addMemberDecorate(SPIRVMemberDecorate *Dec){ - assert(canHaveMemberDecorates() && MemberDecorates.find(Dec->getPair()) == - MemberDecorates.end()); +SPIRVEntry::addMemberDecorate(const SPIRVMemberDecorate *Dec){ + assert(canHaveMemberDecorates()); MemberDecorates[Dec->getPair()] = Dec; Module->addDecorate(Dec); SPIRVDBG(spvdbgs() << "[addMemberDecorate] " << *Dec << '\n';) @@ -372,6 +371,20 @@ SPIRVEntry::hasDecorate(Decoration Kind, size_t Index, SPIRVWord *Result)const { return true; } +// Check if an entry has Kind of member decoration at MemberIndex and get the +// literal of the first decoration of such kind at Index. +bool +SPIRVEntry::hasMemberDecorate(SPIRVWord MemberIndex, Decoration Kind, + size_t Index, SPIRVWord *Result)const { + MemberDecorateMapType::const_iterator Loc = + MemberDecorates.find(std::make_pair(MemberIndex, Kind)); + if (Loc == MemberDecorates.end()) + return false; + if (Result) + *Result = Loc->second->getLiteral(Index); + return true; +} + // Get literals of all decorations of Kind at Index. std::set SPIRVEntry::getDecorate(Decoration Kind, size_t Index) const { diff --git a/lib/SPIRV/libSPIRV/SPIRVEntry.h b/lib/SPIRV/libSPIRV/SPIRVEntry.h index b994bf1c02b..6ac832cad75 100644 --- a/lib/SPIRV/libSPIRV/SPIRVEntry.h +++ b/lib/SPIRV/libSPIRV/SPIRVEntry.h @@ -251,6 +251,8 @@ class SPIRVEntry { const std::string& getName() const { return Name;} bool hasDecorate(Decoration Kind, size_t Index = 0, SPIRVWord *Result=0)const; + bool hasMemberDecorate(SPIRVWord MemberIndex, Decoration Kind, + size_t Index = 0, SPIRVWord *Result = 0)const; std::set getDecorate(Decoration Kind, size_t Index = 0)const; bool hasId() const { return !(Attrib & SPIRVEA_NOID);} bool hasLine() const { return Line != nullptr;} @@ -273,11 +275,11 @@ class SPIRVEntry { return false; } - void addDecorate(SPIRVDecorate *); + void addDecorate(const SPIRVDecorate *); void addDecorate(Decoration Kind); void addDecorate(Decoration Kind, SPIRVWord Literal); void eraseDecorate(Decoration); - void addMemberDecorate(SPIRVMemberDecorate *); + void addMemberDecorate(const SPIRVMemberDecorate *); void addMemberDecorate(SPIRVWord MemberNumber, Decoration Kind); void addMemberDecorate(SPIRVWord MemberNumber, Decoration Kind, SPIRVWord Literal); diff --git a/lib/SPIRV/libSPIRV/SPIRVModule.cpp b/lib/SPIRV/libSPIRV/SPIRVModule.cpp index b1887c07a3d..52c079d8c13 100644 --- a/lib/SPIRV/libSPIRV/SPIRVModule.cpp +++ b/lib/SPIRV/libSPIRV/SPIRVModule.cpp @@ -168,7 +168,7 @@ class SPIRVModuleImpl : public SPIRVModule { virtual void setCurrentLine(const std::shared_ptr &Line); virtual void addCapability(SPIRVCapabilityKind); virtual void addCapabilityInternal(SPIRVCapabilityKind); - virtual const SPIRVDecorateGeneric *addDecorate(SPIRVDecorateGeneric *); + virtual const SPIRVDecorateGeneric *addDecorate(const SPIRVDecorateGeneric *); virtual SPIRVDecorationGroup *addDecorationGroup(); virtual SPIRVDecorationGroup *addDecorationGroup(SPIRVDecorationGroup *Group); virtual SPIRVGroupDecorate *addGroupDecorate(SPIRVDecorationGroup *Group, @@ -841,8 +841,7 @@ SPIRVModuleImpl::addBasicBlock(SPIRVFunction *Func, SPIRVId Id) { } const SPIRVDecorateGeneric * -SPIRVModuleImpl::addDecorate(SPIRVDecorateGeneric *Dec) { - add(Dec); +SPIRVModuleImpl::addDecorate(const SPIRVDecorateGeneric *Dec) { SPIRVId Id = Dec->getTargetId(); SPIRVEntry *Target = nullptr; bool Found = exist(Id, &Target); @@ -1432,7 +1431,6 @@ SPIRVModuleImpl::addDecorationGroup(SPIRVDecorationGroup* Group) { DecGroupVec.push_back(Group); SPIRVDBG(spvdbgs() << "[addDecorationGroup] {" << *Group << "}\n"; spvdbgs() << " Remaining DecorateSet: {" << DecorateSet << "}\n"); - assert(DecorateSet.empty()); return Group; } diff --git a/lib/SPIRV/libSPIRV/SPIRVModule.h b/lib/SPIRV/libSPIRV/SPIRVModule.h index 577893a7dd5..a5e3f28ecd2 100644 --- a/lib/SPIRV/libSPIRV/SPIRVModule.h +++ b/lib/SPIRV/libSPIRV/SPIRVModule.h @@ -170,7 +170,7 @@ class SPIRVModule { SPIRVWord Column) = 0; virtual const std::shared_ptr& getCurrentLine() const = 0; virtual void setCurrentLine(const std::shared_ptr&) = 0; - virtual const SPIRVDecorateGeneric *addDecorate(SPIRVDecorateGeneric*) + virtual const SPIRVDecorateGeneric *addDecorate(const SPIRVDecorateGeneric*) = 0; virtual SPIRVDecorationGroup *addDecorationGroup() = 0; virtual SPIRVDecorationGroup *addDecorationGroup(SPIRVDecorationGroup *Group)