First cut at new loop codegen.
Change-Id: Id3bdf8b7a5606e7ce5d856ef225d5ddbe59a584b
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 @@
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();
+ 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 (node->getBody()) {
- breakForLoop.push(true);
- node->getBody()->traverse(this);
- breakForLoop.pop();
- }
-
- if (loopTerminal.top())
- loopTerminal.top()->traverse(this);
-
- builder.closeLoop();
-
- loopTerminal.pop();
-
+ builder.setBuildPoint(&blocks.merge);
return false;
}