First cut at new loop codegen.
Change-Id: Id3bdf8b7a5606e7ce5d856ef225d5ddbe59a584b
This commit is contained in:
parent
c92e370e87
commit
9c6734c8df
@ -1342,33 +1342,51 @@ void TGlslangToSpvTraverser::visitConstantUnion(glslang::TIntermConstantUnion* n
|
|||||||
|
|
||||||
bool TGlslangToSpvTraverser::visitLoop(glslang::TVisit /* visit */, glslang::TIntermLoop* node)
|
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"
|
auto blocks = builder.makeNewLoop();
|
||||||
loopTerminal.push(node->getTerminal());
|
if (node->testFirst() && node->getTest()) {
|
||||||
|
spv::Block& head = builder.makeNewBlock();
|
||||||
|
builder.createBranch(&head);
|
||||||
|
|
||||||
builder.makeNewLoop(node->testFirst());
|
builder.setBuildPoint(&head);
|
||||||
|
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);
|
||||||
|
|
||||||
|
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.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()) {
|
if (node->getTest()) {
|
||||||
node->getTest()->traverse(this);
|
node->getTest()->traverse(this);
|
||||||
// the AST only contained the test computation, not the branch, we have to add it
|
spv::Id condition =
|
||||||
spv::Id condition = builder.accessChainLoad(convertGlslangToSpvType(node->getTest()->getType()));
|
builder.accessChainLoad(convertGlslangToSpvType(node->getTest()->getType()));
|
||||||
builder.createLoopTestBranch(condition);
|
builder.createLoopMerge(&blocks.merge, &blocks.continue_target,
|
||||||
|
spv::LoopControlMaskNone);
|
||||||
|
builder.createConditionalBranch(condition, &blocks.body, &blocks.merge);
|
||||||
} else {
|
} else {
|
||||||
builder.createBranchToBody();
|
builder.createBranch(&blocks.body);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node->getBody()) {
|
builder.setBuildPoint(&blocks.merge);
|
||||||
breakForLoop.push(true);
|
|
||||||
node->getBody()->traverse(this);
|
|
||||||
breakForLoop.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (loopTerminal.top())
|
|
||||||
loopTerminal.top()->traverse(this);
|
|
||||||
|
|
||||||
builder.closeLoop();
|
|
||||||
|
|
||||||
loopTerminal.pop();
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1753,6 +1753,19 @@ void Builder::endSwitch(std::vector<Block*>& /*segmentBlock*/)
|
|||||||
switchMerges.pop();
|
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
|
// Comments in header
|
||||||
void Builder::makeNewLoop(bool loopTestFirst)
|
void Builder::makeNewLoop(bool loopTestFirst)
|
||||||
{
|
{
|
||||||
|
@ -378,6 +378,13 @@ public:
|
|||||||
// The loopTestFirst parameter is true when the loop test executes before
|
// The loopTestFirst parameter is true when the loop test executes before
|
||||||
// the body. (It is false for do-while loops.)
|
// the body. (It is false for do-while loops.)
|
||||||
void makeNewLoop(bool loopTestFirst);
|
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.
|
// 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
|
// The true branch goes to the first block in the loop body, and
|
||||||
@ -494,6 +501,10 @@ public:
|
|||||||
|
|
||||||
void dump(std::vector<unsigned int>&) const;
|
void dump(std::vector<unsigned int>&) const;
|
||||||
|
|
||||||
|
void createBranch(Block* block);
|
||||||
|
void createConditionalBranch(Id condition, Block* thenBlock, Block* elseBlock);
|
||||||
|
void createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Id makeIntConstant(Id typeId, unsigned value, bool specConstant);
|
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 value) const;
|
||||||
@ -503,10 +514,7 @@ protected:
|
|||||||
void transferAccessChainSwizzle(bool dynamic);
|
void transferAccessChainSwizzle(bool dynamic);
|
||||||
void simplifyAccessChainSwizzle();
|
void simplifyAccessChainSwizzle();
|
||||||
void createAndSetNoPredecessorBlock(const char*);
|
void createAndSetNoPredecessorBlock(const char*);
|
||||||
void createBranch(Block* block);
|
|
||||||
void createSelectionMerge(Block* mergeBlock, unsigned int control);
|
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;
|
void dumpInstructions(std::vector<unsigned int>&, const std::vector<Instruction*>&) const;
|
||||||
|
|
||||||
struct Loop; // Defined below.
|
struct Loop; // Defined below.
|
||||||
|
@ -5,49 +5,51 @@ Linked vertex stage:
|
|||||||
|
|
||||||
// Module Version 10000
|
// Module Version 10000
|
||||||
// Generated by (magic number): 80001
|
// Generated by (magic number): 80001
|
||||||
// Id's are bound by 25
|
// Id's are bound by 26
|
||||||
|
|
||||||
Capability Shader
|
Capability Shader
|
||||||
1: ExtInstImport "GLSL.std.450"
|
1: ExtInstImport "GLSL.std.450"
|
||||||
MemoryModel Logical GLSL450
|
MemoryModel Logical GLSL450
|
||||||
EntryPoint Vertex 4 "main" 23 24
|
EntryPoint Vertex 4 "main" 24 25
|
||||||
Source ESSL 300
|
Source ESSL 300
|
||||||
Name 4 "main"
|
Name 4 "main"
|
||||||
Name 8 "i"
|
Name 8 "i"
|
||||||
Name 17 "j"
|
Name 18 "j"
|
||||||
Name 23 "gl_VertexID"
|
Name 24 "gl_VertexID"
|
||||||
Name 24 "gl_InstanceID"
|
Name 25 "gl_InstanceID"
|
||||||
Decorate 23(gl_VertexID) BuiltIn VertexId
|
Decorate 24(gl_VertexID) BuiltIn VertexId
|
||||||
Decorate 24(gl_InstanceID) BuiltIn InstanceId
|
Decorate 25(gl_InstanceID) BuiltIn InstanceId
|
||||||
2: TypeVoid
|
2: TypeVoid
|
||||||
3: TypeFunction 2
|
3: TypeFunction 2
|
||||||
6: TypeInt 32 1
|
6: TypeInt 32 1
|
||||||
7: TypePointer Function 6(int)
|
7: TypePointer Function 6(int)
|
||||||
9: 6(int) Constant 0
|
9: 6(int) Constant 0
|
||||||
14: 6(int) Constant 10
|
15: 6(int) Constant 10
|
||||||
15: TypeBool
|
16: TypeBool
|
||||||
18: 6(int) Constant 12
|
19: 6(int) Constant 12
|
||||||
20: 6(int) Constant 1
|
21: 6(int) Constant 1
|
||||||
22: TypePointer Input 6(int)
|
23: TypePointer Input 6(int)
|
||||||
23(gl_VertexID): 22(ptr) Variable Input
|
24(gl_VertexID): 23(ptr) Variable Input
|
||||||
24(gl_InstanceID): 22(ptr) Variable Input
|
25(gl_InstanceID): 23(ptr) Variable Input
|
||||||
4(main): 2 Function None 3
|
4(main): 2 Function None 3
|
||||||
5: Label
|
5: Label
|
||||||
8(i): 7(ptr) Variable Function
|
8(i): 7(ptr) Variable Function
|
||||||
17(j): 7(ptr) Variable Function
|
18(j): 7(ptr) Variable Function
|
||||||
Store 8(i) 9
|
Store 8(i) 9
|
||||||
Branch 10
|
Branch 13
|
||||||
10: Label
|
10: Label
|
||||||
13: 6(int) Load 8(i)
|
Store 18(j) 19
|
||||||
16: 15(bool) SLessThan 13 14
|
Branch 12
|
||||||
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
|
|
||||||
11: Label
|
11: Label
|
||||||
Return
|
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
|
FunctionEnd
|
||||||
|
Loading…
x
Reference in New Issue
Block a user