Remove decoration of undefined IDs
Fix issue #185 by removing OpDecorate instructions whose target IDs are defined in unreachable blocks and thus not dumped in the generated SPIR-V code.
This commit is contained in:
		
							parent
							
								
									f7497e289b
								
							
						
					
					
						commit
						da39733f28
					
				| @ -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,35 @@ 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 (auto& f : module.getFunctions()) { | ||||||
|  |         Block* entry = f->getEntryBlock(); | ||||||
|  |         inReadableOrder(entry, [&reachable_blocks](const Block* b) { | ||||||
|  |             reachable_blocks.insert(b); | ||||||
|  |         }); | ||||||
|  |         for (auto& b : f->getBlocks()) { | ||||||
|  |             if (!reachable_blocks.count(b)) { | ||||||
|  |                 for (auto& i : b->getInstructions()) { | ||||||
|  |                     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
	 qining
						qining