зеркало из https://github.com/stride3d/xkslang.git
Merge pull request #195 from Qining/remove-decoration-on-undef-IDs
SPV: Remove decoration of undefined IDs
This commit is contained in:
Коммит
5639f3aca5
|
@ -719,6 +719,7 @@ void TGlslangToSpvTraverser::dumpSpv(std::vector<unsigned int>& out)
|
||||||
for (auto it = iOSet.cbegin(); it != iOSet.cend(); ++it)
|
for (auto it = iOSet.cbegin(); it != iOSet.cend(); ++it)
|
||||||
entryPoint->addIdOperand(*it);
|
entryPoint->addIdOperand(*it);
|
||||||
|
|
||||||
|
builder.eliminateDeadDecorations();
|
||||||
builder.dump(out);
|
builder.dump(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2130,6 +2130,42 @@ Id Builder::accessChainGetInferredType()
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// comment in header
|
||||||
|
void Builder::eliminateDeadDecorations() {
|
||||||
|
std::unordered_set<const Block*> reachable_blocks;
|
||||||
|
std::unordered_set<Id> unreachable_definitions;
|
||||||
|
// Collect IDs defined in unreachable blocks. For each function, label the
|
||||||
|
// reachable blocks first. Then for each unreachable block, collect the
|
||||||
|
// result IDs of the instructions in it.
|
||||||
|
for (std::vector<Function*>::const_iterator fi = module.getFunctions().cbegin();
|
||||||
|
fi != module.getFunctions().cend(); fi++) {
|
||||||
|
Function* f = *fi;
|
||||||
|
Block* entry = f->getEntryBlock();
|
||||||
|
inReadableOrder(entry, [&reachable_blocks](const Block* b) {
|
||||||
|
reachable_blocks.insert(b);
|
||||||
|
});
|
||||||
|
for (std::vector<Block*>::const_iterator bi = f->getBlocks().cbegin();
|
||||||
|
bi != f->getBlocks().cend(); bi++) {
|
||||||
|
Block* b = *bi;
|
||||||
|
if (!reachable_blocks.count(b)) {
|
||||||
|
for (std::vector<std::unique_ptr<Instruction> >::const_iterator
|
||||||
|
ii = b->getInstructions().cbegin();
|
||||||
|
ii != b->getInstructions().cend(); ii++) {
|
||||||
|
Instruction* i = ii->get();
|
||||||
|
unreachable_definitions.insert(i->getResultId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
decorations.erase(std::remove_if(decorations.begin(), decorations.end(),
|
||||||
|
[&unreachable_definitions](std::unique_ptr<Instruction>& I) {
|
||||||
|
Instruction* inst = I.get();
|
||||||
|
Id decoration_id = inst->getIdOperand(0);
|
||||||
|
return unreachable_definitions.count(decoration_id) != 0;
|
||||||
|
}),
|
||||||
|
decorations.end());
|
||||||
|
}
|
||||||
|
|
||||||
void Builder::dump(std::vector<unsigned int>& out) const
|
void Builder::dump(std::vector<unsigned int>& out) const
|
||||||
{
|
{
|
||||||
// Header, before first instructions:
|
// Header, before first instructions:
|
||||||
|
|
|
@ -512,6 +512,9 @@ public:
|
||||||
// based on the type of the base and the chain of dereferences.
|
// based on the type of the base and the chain of dereferences.
|
||||||
Id accessChainGetInferredType();
|
Id accessChainGetInferredType();
|
||||||
|
|
||||||
|
// Remove OpDecorate instructions whose operands are defined in unreachable
|
||||||
|
// blocks.
|
||||||
|
void eliminateDeadDecorations();
|
||||||
void dump(std::vector<unsigned int>&) const;
|
void dump(std::vector<unsigned int>&) const;
|
||||||
|
|
||||||
void createBranch(Block* block);
|
void createBranch(Block* block);
|
||||||
|
|
|
@ -182,6 +182,9 @@ public:
|
||||||
void addLocalVariable(std::unique_ptr<Instruction> inst) { localVariables.push_back(std::move(inst)); }
|
void addLocalVariable(std::unique_ptr<Instruction> inst) { localVariables.push_back(std::move(inst)); }
|
||||||
const std::vector<Block*>& getPredecessors() const { return predecessors; }
|
const std::vector<Block*>& getPredecessors() const { return predecessors; }
|
||||||
const std::vector<Block*>& getSuccessors() const { return successors; }
|
const std::vector<Block*>& getSuccessors() const { return successors; }
|
||||||
|
const std::vector<std::unique_ptr<Instruction> >& getInstructions() const {
|
||||||
|
return instructions;
|
||||||
|
}
|
||||||
void setUnreachable() { unreachable = true; }
|
void setUnreachable() { unreachable = true; }
|
||||||
bool isUnreachable() const { return unreachable; }
|
bool isUnreachable() const { return unreachable; }
|
||||||
// Returns the block's merge instruction, if one exists (otherwise null).
|
// Returns the block's merge instruction, if one exists (otherwise null).
|
||||||
|
@ -275,6 +278,7 @@ public:
|
||||||
Module& getParent() const { return parent; }
|
Module& getParent() const { return parent; }
|
||||||
Block* getEntryBlock() const { return blocks.front(); }
|
Block* getEntryBlock() const { return blocks.front(); }
|
||||||
Block* getLastBlock() const { return blocks.back(); }
|
Block* getLastBlock() const { return blocks.back(); }
|
||||||
|
const std::vector<Block*>& getBlocks() const { return blocks; }
|
||||||
void addLocalVariable(std::unique_ptr<Instruction> inst);
|
void addLocalVariable(std::unique_ptr<Instruction> inst);
|
||||||
Id getReturnType() const { return functionInstruction.getTypeId(); }
|
Id getReturnType() const { return functionInstruction.getTypeId(); }
|
||||||
void dump(std::vector<unsigned int>& out) const
|
void dump(std::vector<unsigned int>& out) const
|
||||||
|
@ -326,6 +330,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
Instruction* getInstruction(Id id) const { return idToInstruction[id]; }
|
Instruction* getInstruction(Id id) const { return idToInstruction[id]; }
|
||||||
|
const std::vector<Function*>& getFunctions() const { return functions; }
|
||||||
spv::Id getTypeId(Id resultId) const { return idToInstruction[resultId]->getTypeId(); }
|
spv::Id getTypeId(Id resultId) const { return idToInstruction[resultId]->getTypeId(); }
|
||||||
StorageClass getStorageClass(Id typeId) const
|
StorageClass getStorageClass(Id typeId) const
|
||||||
{
|
{
|
||||||
|
|
Загрузка…
Ссылка в новой задаче