Don't emit duplicate decorations. (#3635)
It is invalid if the same decoration is applied to the same id multiple times. This adds a check before adding a decoration that the decoration is not already in the list. If it is, then the duplicate is not added. Fixes #3627
This commit is contained in:
parent
7c40de7aa2
commit
33c7e30860
575 changed files with 3482 additions and 3414 deletions
|
|
@ -1979,7 +1979,7 @@ void Builder::addDecoration(Id id, Decoration decoration, int num)
|
|||
if (num >= 0)
|
||||
dec->addImmediateOperand(num);
|
||||
|
||||
decorations.push_back(std::unique_ptr<Instruction>(dec));
|
||||
decorations.insert(std::unique_ptr<Instruction>(dec));
|
||||
}
|
||||
|
||||
void Builder::addDecoration(Id id, Decoration decoration, const char* s)
|
||||
|
|
@ -1993,7 +1993,7 @@ void Builder::addDecoration(Id id, Decoration decoration, const char* s)
|
|||
dec->addImmediateOperand(decoration);
|
||||
dec->addStringOperand(s);
|
||||
|
||||
decorations.push_back(std::unique_ptr<Instruction>(dec));
|
||||
decorations.insert(std::unique_ptr<Instruction>(dec));
|
||||
}
|
||||
|
||||
void Builder::addDecoration(Id id, Decoration decoration, const std::vector<unsigned>& literals)
|
||||
|
|
@ -2008,7 +2008,7 @@ void Builder::addDecoration(Id id, Decoration decoration, const std::vector<unsi
|
|||
for (auto literal : literals)
|
||||
dec->addImmediateOperand(literal);
|
||||
|
||||
decorations.push_back(std::unique_ptr<Instruction>(dec));
|
||||
decorations.insert(std::unique_ptr<Instruction>(dec));
|
||||
}
|
||||
|
||||
void Builder::addDecoration(Id id, Decoration decoration, const std::vector<const char*>& strings)
|
||||
|
|
@ -2023,7 +2023,7 @@ void Builder::addDecoration(Id id, Decoration decoration, const std::vector<cons
|
|||
for (auto string : strings)
|
||||
dec->addStringOperand(string);
|
||||
|
||||
decorations.push_back(std::unique_ptr<Instruction>(dec));
|
||||
decorations.insert(std::unique_ptr<Instruction>(dec));
|
||||
}
|
||||
|
||||
void Builder::addLinkageDecoration(Id id, const char* name, spv::LinkageType linkType) {
|
||||
|
|
@ -2034,7 +2034,7 @@ void Builder::addLinkageDecoration(Id id, const char* name, spv::LinkageType lin
|
|||
dec->addStringOperand(name);
|
||||
dec->addImmediateOperand(linkType);
|
||||
|
||||
decorations.push_back(std::unique_ptr<Instruction>(dec));
|
||||
decorations.insert(std::unique_ptr<Instruction>(dec));
|
||||
}
|
||||
|
||||
void Builder::addDecorationId(Id id, Decoration decoration, Id idDecoration)
|
||||
|
|
@ -2048,7 +2048,7 @@ void Builder::addDecorationId(Id id, Decoration decoration, Id idDecoration)
|
|||
dec->addImmediateOperand(decoration);
|
||||
dec->addIdOperand(idDecoration);
|
||||
|
||||
decorations.push_back(std::unique_ptr<Instruction>(dec));
|
||||
decorations.insert(std::unique_ptr<Instruction>(dec));
|
||||
}
|
||||
|
||||
void Builder::addDecorationId(Id id, Decoration decoration, const std::vector<Id>& operandIds)
|
||||
|
|
@ -2064,7 +2064,7 @@ void Builder::addDecorationId(Id id, Decoration decoration, const std::vector<Id
|
|||
for (auto operandId : operandIds)
|
||||
dec->addIdOperand(operandId);
|
||||
|
||||
decorations.push_back(std::unique_ptr<Instruction>(dec));
|
||||
decorations.insert(std::unique_ptr<Instruction>(dec));
|
||||
}
|
||||
|
||||
void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decoration, int num)
|
||||
|
|
@ -2080,7 +2080,7 @@ void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decorat
|
|||
if (num >= 0)
|
||||
dec->addImmediateOperand(num);
|
||||
|
||||
decorations.push_back(std::unique_ptr<Instruction>(dec));
|
||||
decorations.insert(std::unique_ptr<Instruction>(dec));
|
||||
}
|
||||
|
||||
void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decoration, const char *s)
|
||||
|
|
@ -2095,7 +2095,7 @@ void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decorat
|
|||
dec->addImmediateOperand(decoration);
|
||||
dec->addStringOperand(s);
|
||||
|
||||
decorations.push_back(std::unique_ptr<Instruction>(dec));
|
||||
decorations.insert(std::unique_ptr<Instruction>(dec));
|
||||
}
|
||||
|
||||
void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decoration, const std::vector<unsigned>& literals)
|
||||
|
|
@ -2111,7 +2111,7 @@ void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decorat
|
|||
for (auto literal : literals)
|
||||
dec->addImmediateOperand(literal);
|
||||
|
||||
decorations.push_back(std::unique_ptr<Instruction>(dec));
|
||||
decorations.insert(std::unique_ptr<Instruction>(dec));
|
||||
}
|
||||
|
||||
void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decoration, const std::vector<const char*>& strings)
|
||||
|
|
@ -2127,7 +2127,7 @@ void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decorat
|
|||
for (auto string : strings)
|
||||
dec->addStringOperand(string);
|
||||
|
||||
decorations.push_back(std::unique_ptr<Instruction>(dec));
|
||||
decorations.insert(std::unique_ptr<Instruction>(dec));
|
||||
}
|
||||
|
||||
void Builder::addInstruction(std::unique_ptr<Instruction> inst) {
|
||||
|
|
@ -4330,11 +4330,10 @@ void Builder::dumpSourceInstructions(std::vector<unsigned int>& out) const
|
|||
dumpSourceInstructions(iItr->first, *iItr->second, out);
|
||||
}
|
||||
|
||||
void Builder::dumpInstructions(std::vector<unsigned int>& out,
|
||||
const std::vector<std::unique_ptr<Instruction> >& instructions) const
|
||||
template <class Range> void Builder::dumpInstructions(std::vector<unsigned int>& out, const Range& instructions) const
|
||||
{
|
||||
for (int i = 0; i < (int)instructions.size(); ++i) {
|
||||
instructions[i]->dump(out);
|
||||
for (const auto& inst : instructions) {
|
||||
inst->dump(out);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4347,4 +4346,40 @@ void Builder::dumpModuleProcesses(std::vector<unsigned int>& out) const
|
|||
}
|
||||
}
|
||||
|
||||
bool Builder::DecorationInstructionLessThan::operator()(const std::unique_ptr<Instruction>& lhs,
|
||||
const std::unique_ptr<Instruction>& rhs) const
|
||||
{
|
||||
// Order by the id to which the decoration applies first. This is more intuitive.
|
||||
assert(lhs->isIdOperand(0) && rhs->isIdOperand(0));
|
||||
if (lhs->getIdOperand(0) != rhs->getIdOperand(0)) {
|
||||
return lhs->getIdOperand(0) < rhs->getIdOperand(0);
|
||||
}
|
||||
|
||||
if (lhs->getOpCode() != rhs->getOpCode())
|
||||
return lhs->getOpCode() < rhs->getOpCode();
|
||||
|
||||
// Now compare the operands.
|
||||
int minSize = std::min(lhs->getNumOperands(), rhs->getNumOperands());
|
||||
for (int i = 1; i < minSize; ++i) {
|
||||
if (lhs->isIdOperand(i) != rhs->isIdOperand(i)) {
|
||||
return lhs->isIdOperand(i) < rhs->isIdOperand(i);
|
||||
}
|
||||
|
||||
if (lhs->isIdOperand(i)) {
|
||||
if (lhs->getIdOperand(i) != rhs->getIdOperand(i)) {
|
||||
return lhs->getIdOperand(i) < rhs->getIdOperand(i);
|
||||
}
|
||||
} else {
|
||||
if (lhs->getImmediateOperand(i) != rhs->getImmediateOperand(i)) {
|
||||
return lhs->getImmediateOperand(i) < rhs->getImmediateOperand(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lhs->getNumOperands() != rhs->getNumOperands())
|
||||
return lhs->getNumOperands() < rhs->getNumOperands();
|
||||
|
||||
// In this case they are equal.
|
||||
return false;
|
||||
}
|
||||
} // end spv namespace
|
||||
|
|
|
|||
|
|
@ -890,10 +890,13 @@ public:
|
|||
void createSelectionMerge(Block* mergeBlock, unsigned int control);
|
||||
void dumpSourceInstructions(std::vector<unsigned int>&) const;
|
||||
void dumpSourceInstructions(const spv::Id fileId, const std::string& text, std::vector<unsigned int>&) const;
|
||||
void dumpInstructions(std::vector<unsigned int>&, const std::vector<std::unique_ptr<Instruction> >&) const;
|
||||
template <class Range> void dumpInstructions(std::vector<unsigned int>& out, const Range& instructions) const;
|
||||
void dumpModuleProcesses(std::vector<unsigned int>&) const;
|
||||
spv::MemoryAccessMask sanitizeMemoryAccessForStorageClass(spv::MemoryAccessMask memoryAccess, StorageClass sc)
|
||||
const;
|
||||
struct DecorationInstructionLessThan {
|
||||
bool operator()(const std::unique_ptr<Instruction>& lhs, const std::unique_ptr<Instruction>& rhs) const;
|
||||
};
|
||||
|
||||
unsigned int spvVersion; // the version of SPIR-V to emit in the header
|
||||
SourceLanguage sourceLang;
|
||||
|
|
@ -950,7 +953,7 @@ public:
|
|||
std::vector<std::unique_ptr<Instruction> > entryPoints;
|
||||
std::vector<std::unique_ptr<Instruction> > executionModes;
|
||||
std::vector<std::unique_ptr<Instruction> > names;
|
||||
std::vector<std::unique_ptr<Instruction> > decorations;
|
||||
std::set<std::unique_ptr<Instruction>, DecorationInstructionLessThan> decorations;
|
||||
std::vector<std::unique_ptr<Instruction> > constantsTypesGlobals;
|
||||
std::vector<std::unique_ptr<Instruction> > externals;
|
||||
std::vector<std::unique_ptr<Function> > functions;
|
||||
|
|
|
|||
|
|
@ -387,12 +387,14 @@ void Builder::postProcessCFG()
|
|||
}
|
||||
|
||||
// Remove unneeded decorations, for unreachable instructions
|
||||
decorations.erase(std::remove_if(decorations.begin(), decorations.end(),
|
||||
[&unreachableDefinitions](std::unique_ptr<Instruction>& I) -> bool {
|
||||
Id decoration_id = I.get()->getIdOperand(0);
|
||||
return unreachableDefinitions.count(decoration_id) != 0;
|
||||
}),
|
||||
decorations.end());
|
||||
for (auto decorationIter = decorations.begin(); decorationIter != decorations.end();) {
|
||||
Id decorationId = (*decorationIter)->getIdOperand(0);
|
||||
if (unreachableDefinitions.count(decorationId) != 0) {
|
||||
decorationIter = decorations.erase(decorationIter);
|
||||
} else {
|
||||
++decorationIter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// comment in header
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue