First cut at new loop codegen.

Change-Id: Id3bdf8b7a5606e7ce5d856ef225d5ddbe59a584b
This commit is contained in:
Dejan Mircevski 2016-01-10 12:15:13 -05:00
parent c92e370e87
commit 9c6734c8df
4 changed files with 93 additions and 52 deletions

View File

@ -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();
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;
}

View File

@ -1753,6 +1753,19 @@ void Builder::endSwitch(std::vector<Block*>& /*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)
{

View File

@ -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<unsigned int>&) 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<unsigned int>&, const std::vector<Instruction*>&) const;
struct Loop; // Defined below.

View File

@ -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