From 9c6734c8dfc2708cbb7311b68fc7c6040681486b Mon Sep 17 00:00:00 2001 From: Dejan Mircevski Date: Sun, 10 Jan 2016 12:15:13 -0500 Subject: [PATCH] First cut at new loop codegen. Change-Id: Id3bdf8b7a5606e7ce5d856ef225d5ddbe59a584b --- SPIRV/GlslangToSpv.cpp | 62 ++++++++++++++++++++------------ SPIRV/SpvBuilder.cpp | 13 +++++++ SPIRV/SpvBuilder.h | 16 ++++++--- Test/baseResults/spv.for-simple.vert.out | 54 ++++++++++++++-------------- 4 files changed, 93 insertions(+), 52 deletions(-) diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index 0fff30e..769cf50 100755 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -1342,33 +1342,51 @@ void TGlslangToSpvTraverser::visitConstantUnion(glslang::TIntermConstantUnion* n bool TGlslangToSpvTraverser::visitLoop(glslang::TVisit /* visit */, glslang::TIntermLoop* node) { - // body emission needs to know what the for-loop terminal is when it sees a "continue" - loopTerminal.push(node->getTerminal()); + auto blocks = builder.makeNewLoop(); + if (node->testFirst() && node->getTest()) { + spv::Block& head = builder.makeNewBlock(); + builder.createBranch(&head); - builder.makeNewLoop(node->testFirst()); - - if (node->getTest()) { + builder.setBuildPoint(&head); node->getTest()->traverse(this); - // the AST only contained the test computation, not the branch, we have to add it - spv::Id condition = builder.accessChainLoad(convertGlslangToSpvType(node->getTest()->getType())); - builder.createLoopTestBranch(condition); + spv::Id condition = + builder.accessChainLoad(convertGlslangToSpvType(node->getTest()->getType())); + builder.createLoopMerge(&blocks.merge, &blocks.continue_target, spv::LoopControlMaskNone); + builder.createConditionalBranch(condition, &blocks.body, &blocks.merge); + + builder.setBuildPoint(&blocks.body); + if (node->getBody()) + node->getBody()->traverse(this); // continue->cont, break->exit + builder.createBranch(&blocks.continue_target); + + builder.setBuildPoint(&blocks.continue_target); + if (node->getTerminal()) + node->getTerminal()->traverse(this); + builder.createBranch(&head); } else { - builder.createBranchToBody(); - } - - if (node->getBody()) { - breakForLoop.push(true); - node->getBody()->traverse(this); - breakForLoop.pop(); + builder.createBranch(&blocks.body); + + builder.setBuildPoint(&blocks.body); + if (node->getBody()) + node->getBody()->traverse(this); // continue->cont, break->exit + builder.createBranch(&blocks.continue_target); + + builder.setBuildPoint(&blocks.continue_target); + if (node->getTerminal()) + node->getTerminal()->traverse(this); + if (node->getTest()) { + node->getTest()->traverse(this); + spv::Id condition = + builder.accessChainLoad(convertGlslangToSpvType(node->getTest()->getType())); + builder.createLoopMerge(&blocks.merge, &blocks.continue_target, + spv::LoopControlMaskNone); + builder.createConditionalBranch(condition, &blocks.body, &blocks.merge); + } else { + builder.createBranch(&blocks.body); + } } - if (loopTerminal.top()) - loopTerminal.top()->traverse(this); - - builder.closeLoop(); - - loopTerminal.pop(); - + builder.setBuildPoint(&blocks.merge); return false; } diff --git a/SPIRV/SpvBuilder.cpp b/SPIRV/SpvBuilder.cpp index a46c924..57e27e0 100755 --- a/SPIRV/SpvBuilder.cpp +++ b/SPIRV/SpvBuilder.cpp @@ -1753,6 +1753,19 @@ void Builder::endSwitch(std::vector& /*segmentBlock*/) switchMerges.pop(); } +Block& Builder::makeNewBlock() +{ + Function& function = buildPoint->getParent(); + auto block = new Block(getUniqueId(), function); + function.addBlock(block); + return *block; +} + +Builder::LoopBlocks Builder::makeNewLoop() +{ + return {makeNewBlock(), makeNewBlock(), makeNewBlock()}; +} + // Comments in header void Builder::makeNewLoop(bool loopTestFirst) { diff --git a/SPIRV/SpvBuilder.h b/SPIRV/SpvBuilder.h index 5750b00..d3e7ad9 100755 --- a/SPIRV/SpvBuilder.h +++ b/SPIRV/SpvBuilder.h @@ -378,6 +378,13 @@ public: // The loopTestFirst parameter is true when the loop test executes before // the body. (It is false for do-while loops.) void makeNewLoop(bool loopTestFirst); + struct LoopBlocks { + Block &body, &merge, &continue_target; + }; + LoopBlocks makeNewLoop(); + + // Create a new block in the function containing the build point. + Block& makeNewBlock(); // Add the branch for the loop test, based on the given condition. // The true branch goes to the first block in the loop body, and @@ -494,7 +501,11 @@ public: void dump(std::vector&) const; -protected: + void createBranch(Block* block); + void createConditionalBranch(Id condition, Block* thenBlock, Block* elseBlock); + void createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control); + + protected: Id makeIntConstant(Id typeId, unsigned value, bool specConstant); Id findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned value) const; Id findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned v1, unsigned v2) const; @@ -503,10 +514,7 @@ protected: void transferAccessChainSwizzle(bool dynamic); void simplifyAccessChainSwizzle(); void createAndSetNoPredecessorBlock(const char*); - void createBranch(Block* block); void createSelectionMerge(Block* mergeBlock, unsigned int control); - void createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control); - void createConditionalBranch(Id condition, Block* thenBlock, Block* elseBlock); void dumpInstructions(std::vector&, const std::vector&) const; struct Loop; // Defined below. diff --git a/Test/baseResults/spv.for-simple.vert.out b/Test/baseResults/spv.for-simple.vert.out index 95ca758..3dd4fc3 100755 --- a/Test/baseResults/spv.for-simple.vert.out +++ b/Test/baseResults/spv.for-simple.vert.out @@ -5,49 +5,51 @@ Linked vertex stage: // Module Version 10000 // Generated by (magic number): 80001 -// Id's are bound by 25 +// Id's are bound by 26 Capability Shader 1: ExtInstImport "GLSL.std.450" MemoryModel Logical GLSL450 - EntryPoint Vertex 4 "main" 23 24 + EntryPoint Vertex 4 "main" 24 25 Source ESSL 300 Name 4 "main" Name 8 "i" - Name 17 "j" - Name 23 "gl_VertexID" - Name 24 "gl_InstanceID" - Decorate 23(gl_VertexID) BuiltIn VertexId - Decorate 24(gl_InstanceID) BuiltIn InstanceId + Name 18 "j" + Name 24 "gl_VertexID" + Name 25 "gl_InstanceID" + Decorate 24(gl_VertexID) BuiltIn VertexId + Decorate 25(gl_InstanceID) BuiltIn InstanceId 2: TypeVoid 3: TypeFunction 2 6: TypeInt 32 1 7: TypePointer Function 6(int) 9: 6(int) Constant 0 - 14: 6(int) Constant 10 - 15: TypeBool - 18: 6(int) Constant 12 - 20: 6(int) Constant 1 - 22: TypePointer Input 6(int) - 23(gl_VertexID): 22(ptr) Variable Input -24(gl_InstanceID): 22(ptr) Variable Input + 15: 6(int) Constant 10 + 16: TypeBool + 19: 6(int) Constant 12 + 21: 6(int) Constant 1 + 23: TypePointer Input 6(int) + 24(gl_VertexID): 23(ptr) Variable Input +25(gl_InstanceID): 23(ptr) Variable Input 4(main): 2 Function None 3 5: Label 8(i): 7(ptr) Variable Function - 17(j): 7(ptr) Variable Function + 18(j): 7(ptr) Variable Function Store 8(i) 9 - Branch 10 + Branch 13 10: Label - 13: 6(int) Load 8(i) - 16: 15(bool) SLessThan 13 14 - LoopMerge 11 10 None - BranchConditional 16 12 11 - 12: Label - Store 17(j) 18 - 19: 6(int) Load 8(i) - 21: 6(int) IAdd 19 20 - Store 8(i) 21 - Branch 10 + Store 18(j) 19 + Branch 12 11: Label Return + 12: Label + 20: 6(int) Load 8(i) + 22: 6(int) IAdd 20 21 + Store 8(i) 22 + Branch 13 + 13: Label + 14: 6(int) Load 8(i) + 17: 16(bool) SLessThan 14 15 + LoopMerge 11 12 None + BranchConditional 17 10 11 FunctionEnd -- 2.7.4