glslang -> SPV: 1) Include post switch-break unreachable blocks and 2) Generally, don't emit degenerate (basically empty) unreachable blocks.
git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@31023 e7fa87d3-cd2b-0410-9028-fcbf551c1848
diff --git a/SPIRV/SpvBuilder.cpp b/SPIRV/SpvBuilder.cpp
index 29dabb8..e46c02c 100644
--- a/SPIRV/SpvBuilder.cpp
+++ b/SPIRV/SpvBuilder.cpp
@@ -1683,6 +1683,7 @@
{
// branch to the top of the merge block stack
createBranch(switchMerges.top());
+ createAndSetNoPredecessorBlock("post-switch-break");
}
// Comments in header
@@ -1993,11 +1994,12 @@
void Builder::createAndSetNoPredecessorBlock(const char* name)
{
Block* block = new Block(getUniqueId(), buildPoint->getParent());
+ block->setUnreachable();
buildPoint->getParent().addBlock(block);
setBuildPoint(block);
- if (name)
- addName(block->getId(), name);
+ //if (name)
+ // addName(block->getId(), name);
}
// Comments in header
diff --git a/SPIRV/spvIR.h b/SPIRV/spvIR.h
index 585af82..6ea0a0c 100644
--- a/SPIRV/spvIR.h
+++ b/SPIRV/spvIR.h
@@ -162,8 +162,6 @@
class Block {
public:
- // Setting insert to true indicates to add this new block
- // to the end of the parent function.
Block(Id id, Function& parent);
virtual ~Block()
{
@@ -177,6 +175,8 @@
void addPredecessor(Block* pred) { predecessors.push_back(pred); }
void addLocalVariable(Instruction* inst) { localVariables.push_back(inst); }
int getNumPredecessors() const { return (int)predecessors.size(); }
+ void setUnreachable() { unreachable = true; }
+ bool isUnreachable() const { return unreachable; }
bool isTerminated() const
{
@@ -195,6 +195,12 @@
void dump(std::vector<unsigned int>& out) const
{
+ // skip the degenerate unreachable blocks
+ // TODO: code gen: skip all unreachable blocks (transitive closure)
+ // (but, until that's done safer to keep non-degenerate unreachable blocks, in case others depend on something)
+ if (unreachable && instructions.size() <= 2)
+ return;
+
instructions[0]->dump(out);
for (int i = 0; i < (int)localVariables.size(); ++i)
localVariables[i]->dump(out);
@@ -212,6 +218,11 @@
std::vector<Block*> predecessors;
std::vector<Instruction*> localVariables;
Function& parent;
+
+ // track whether this block is known to be uncreachable (not necessarily
+ // true for all unreachable blocks, but should be set at least
+ // for the extraneous ones introduced by the builder).
+ bool unreachable;
};
//
@@ -338,7 +349,7 @@
parent.mapInstruction(inst);
}
-__inline Block::Block(Id id, Function& parent) : parent(parent)
+__inline Block::Block(Id id, Function& parent) : parent(parent), unreachable(false)
{
instructions.push_back(new Instruction(id, NoType, OpLabel));
}
diff --git a/Test/baseResults/switch.frag.out b/Test/baseResults/switch.frag.out
index 0ca1c53..ff42d88 100644
--- a/Test/baseResults/switch.frag.out
+++ b/Test/baseResults/switch.frag.out
@@ -17,7 +17,7 @@
ERROR: 0:126: 'onlyInSwitch' : undeclared identifier
WARNING: 0:128: 'switch' : last case/default label not followed by statements
ERROR: 0:140: 'nestedX' : undeclared identifier
-ERROR: 0:156: 'nestedZ' : undeclared identifier
+ERROR: 0:157: 'nestedZ' : undeclared identifier
ERROR: 17 compilation errors. No code generated.
@@ -322,27 +322,28 @@
0:144 3 (const int)
0:? Sequence
0:146 Branch: Break
-0:147 case: with expression
-0:147 Constant:
-0:147 4 (const int)
+0:147 Branch: Break
+0:148 case: with expression
+0:148 Constant:
+0:148 4 (const int)
0:? Sequence
-0:148 Sequence
-0:148 move second child to first child (temp mediump int)
-0:148 'linearY' (temp mediump int)
-0:148 'linearZ' (temp mediump int)
-0:149 Branch: Break
-0:150 case: with expression
-0:150 Constant:
-0:150 5 (const int)
+0:149 Sequence
+0:149 move second child to first child (temp mediump int)
+0:149 'linearY' (temp mediump int)
+0:149 'linearZ' (temp mediump int)
+0:150 Branch: Break
+0:151 case: with expression
+0:151 Constant:
+0:151 5 (const int)
0:? Sequence
-0:152 Branch: Break
-0:153 case: with expression
-0:153 Constant:
-0:153 6 (const int)
-0:? Sequence
+0:153 Branch: Break
+0:154 case: with expression
0:154 Constant:
-0:154 4 (const int)
-0:156 'nestedZ' (temp float)
+0:154 6 (const int)
+0:? Sequence
+0:155 Constant:
+0:155 4 (const int)
+0:157 'nestedZ' (temp float)
0:? Linker Objects
0:? 'c' (uniform mediump int)
0:? 'd' (uniform mediump int)
@@ -653,27 +654,28 @@
0:144 3 (const int)
0:? Sequence
0:146 Branch: Break
-0:147 case: with expression
-0:147 Constant:
-0:147 4 (const int)
+0:147 Branch: Break
+0:148 case: with expression
+0:148 Constant:
+0:148 4 (const int)
0:? Sequence
-0:148 Sequence
-0:148 move second child to first child (temp mediump int)
-0:148 'linearY' (temp mediump int)
-0:148 'linearZ' (temp mediump int)
-0:149 Branch: Break
-0:150 case: with expression
-0:150 Constant:
-0:150 5 (const int)
+0:149 Sequence
+0:149 move second child to first child (temp mediump int)
+0:149 'linearY' (temp mediump int)
+0:149 'linearZ' (temp mediump int)
+0:150 Branch: Break
+0:151 case: with expression
+0:151 Constant:
+0:151 5 (const int)
0:? Sequence
-0:152 Branch: Break
-0:153 case: with expression
-0:153 Constant:
-0:153 6 (const int)
-0:? Sequence
+0:153 Branch: Break
+0:154 case: with expression
0:154 Constant:
-0:154 4 (const int)
-0:156 'nestedZ' (temp float)
+0:154 6 (const int)
+0:? Sequence
+0:155 Constant:
+0:155 4 (const int)
+0:157 'nestedZ' (temp float)
0:? Linker Objects
0:? 'c' (uniform mediump int)
0:? 'd' (uniform mediump int)
diff --git a/Test/switch.frag b/Test/switch.frag
index 9874d54..f0860fa 100644
--- a/Test/switch.frag
+++ b/Test/switch.frag
@@ -144,6 +144,7 @@
case 3:
int linearZ;
break;
+ break;
case 4:
int linearY = linearZ;
break;