glslang -> SPV: improved support for do-while/continue. Contributed by David Neto (dneto@google.com).
git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@31205 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
@@ -357,13 +357,33 @@ public:
|
||||
// Start the beginning of a new loop.
|
||||
void makeNewLoop();
|
||||
|
||||
// Add the branch at the end of the loop header, and leave the build position
|
||||
// in the first block of the body.
|
||||
// 'condition' is true if should exit the loop
|
||||
void createLoopHeaderBranch(Id condition);
|
||||
// Add the branch for the loop test, based on the given condition.
|
||||
// The true branch goes to the block that remains inside the loop, and
|
||||
// the false branch goes to the loop's merge block. The builder insertion
|
||||
// point will be placed at the start of the inside-the-loop block.
|
||||
void createLoopTestBranch(Id condition);
|
||||
|
||||
// Add a back-edge (e.g "continue") for the innermost loop that you're in
|
||||
void createLoopBackEdge(bool implicit=false);
|
||||
// Finish generating the loop header block in the case where the loop test
|
||||
// is at the bottom of the loop. It will include the LoopMerge instruction
|
||||
// and a branch to the rest of the body. The loop header block must be
|
||||
// separate from the rest of the body to make room for the the two kinds
|
||||
// of *Merge instructions that might have to occur just before a branch:
|
||||
// the loop header must have a LoopMerge as its second-last instruction,
|
||||
// and the body might begin with a conditional branch, which must have its
|
||||
// own SelectionMerge instruction.
|
||||
// Also create the basic block that will contain the loop test, but don't
|
||||
// insert it into the function yet. Any "continue" constructs in this loop
|
||||
// will branch to the loop test block. The builder insertion point will be
|
||||
// placed at the start of the body block.
|
||||
void endLoopHeaderWithoutTest();
|
||||
|
||||
// Generate a branch to the loop test block. This can only be called if
|
||||
// the loop test is at the bottom of the loop. The builder insertion point
|
||||
// is left at the start of the test block.
|
||||
void createBranchToLoopTest();
|
||||
|
||||
// Add a branch to the test of the current (innermost) loop.
|
||||
void createLoopContinue();
|
||||
|
||||
// Add an exit (e.g. "break") for the innermost loop that you're in
|
||||
void createLoopExit();
|
||||
@@ -507,8 +527,23 @@ protected:
|
||||
|
||||
// Data that needs to be kept in order to properly handle loops.
|
||||
struct Loop {
|
||||
// The header is the first block generated for the loop.
|
||||
// It dominates all the blocks in the loop, i.e. it is always
|
||||
// executed before any others.
|
||||
// If the loop test is executed before the body (as in "while" and
|
||||
// "for" loops), then the header begins with the test code.
|
||||
// Otherwise, the loop is a "do-while" loop and the header contains the
|
||||
// start of the body of the loop (if the body exists).
|
||||
Block* header;
|
||||
// The merge block marks the end of the loop. Control is transferred
|
||||
// to the merge block when either the loop test fails, or when a
|
||||
// nested "break" is encountered.
|
||||
Block* merge;
|
||||
// If not NULL, the test block is the basic block containing the loop
|
||||
// test and the conditional branch back to the header or the merge
|
||||
// block. This is created for "do-while" loops, and is the target of
|
||||
// any "continue" constructs that might exist.
|
||||
Block* test;
|
||||
Function* function;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user