diff --git a/SPIRV/SpvBuilder.cpp b/SPIRV/SpvBuilder.cpp index 29dabb80..e46c02cc 100644 --- a/SPIRV/SpvBuilder.cpp +++ b/SPIRV/SpvBuilder.cpp @@ -1683,6 +1683,7 @@ void Builder::addSwitchBreak() { // 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::simplifyAccessChainSwizzle() 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 585af82d..6ea0a0c5 100644 --- a/SPIRV/spvIR.h +++ b/SPIRV/spvIR.h @@ -162,8 +162,6 @@ protected: 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 @@ public: 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 @@ public: void dump(std::vector& 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 @@ protected: std::vector predecessors; std::vector 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 @@ __inline void Function::addLocalVariable(Instruction* inst) 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 0ca1c533..ff42d88b 100644 --- a/Test/baseResults/switch.frag.out +++ b/Test/baseResults/switch.frag.out @@ -17,7 +17,7 @@ ERROR: 0:120: 'default' : cannot appear outside switch statement 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 @@ ERROR: node is still EOpNull! 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:? Sequence -0:152 Branch: Break -0:153 case: with expression -0:153 Constant: -0:153 6 (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: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 @@ ERROR: node is still EOpNull! 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:? Sequence -0:152 Branch: Break -0:153 case: with expression -0:153 Constant: -0:153 6 (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: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 9874d543..f0860fae 100644 --- a/Test/switch.frag +++ b/Test/switch.frag @@ -144,6 +144,7 @@ void main() case 3: int linearZ; break; + break; case 4: int linearY = linearZ; break;