Merge pull request #195 from Qining/remove-decoration-on-undef-IDs
SPV: Remove decoration of undefined IDs
This commit is contained in:
		
						commit
						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
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user