3
3
// Use of this source code is governed by a BSD-style license that can be
4
4
// found in the LICENSE file.
5
5
//
6
- // PruneNoOps.cpp: The PruneNoOps function prunes:
7
- // 1. Empty declarations "int;". Empty declarators will be pruned as well, so for example:
8
- // int , a;
9
- // is turned into
10
- // int a;
11
- // 2. Literal statements: "1.0;". The ESSL output doesn't define a default precision for float,
12
- // so float literal statements would end up with no precision which is invalid ESSL.
13
- // 3. Statements after discard, return, break and continue.
6
+ // PruneNoOps.cpp: The PruneNoOps function prunes no-op statements.
14
7
15
8
#include " compiler/translator/tree_ops/PruneNoOps.h"
16
9
@@ -22,6 +15,67 @@ namespace sh
22
15
23
16
namespace
24
17
{
18
+ uint32_t GetSwitchConstantAsUInt (const TConstantUnion *value)
19
+ {
20
+ TConstantUnion asUInt;
21
+ if (value->getType () == EbtYuvCscStandardEXT)
22
+ {
23
+ asUInt.setUConst (value->getYuvCscStandardEXTConst ());
24
+ }
25
+ else
26
+ {
27
+ bool valid = asUInt.cast (EbtUInt, *value);
28
+ ASSERT (valid);
29
+ }
30
+ return asUInt.getUConst ();
31
+ }
32
+
33
+ bool IsNoOpSwitch (TIntermSwitch *node)
34
+ {
35
+ if (node == nullptr )
36
+ {
37
+ return false ;
38
+ }
39
+
40
+ TIntermConstantUnion *expr = node->getInit ()->getAsConstantUnion ();
41
+ if (expr == nullptr )
42
+ {
43
+ return false ;
44
+ }
45
+
46
+ const uint32_t exprValue = GetSwitchConstantAsUInt (expr->getConstantValue ());
47
+
48
+ // See if any block matches the constant value
49
+ const TIntermSequence &statements = *node->getStatementList ()->getSequence ();
50
+
51
+ for (TIntermNode *statement : statements)
52
+ {
53
+ TIntermCase *caseLabel = statement->getAsCaseNode ();
54
+ if (caseLabel == nullptr )
55
+ {
56
+ continue ;
57
+ }
58
+
59
+ // Default matches everything, consider it not a no-op.
60
+ if (!caseLabel->hasCondition ())
61
+ {
62
+ return false ;
63
+ }
64
+
65
+ TIntermConstantUnion *condition = caseLabel->getCondition ()->getAsConstantUnion ();
66
+ ASSERT (condition != nullptr );
67
+
68
+ // If any case matches the value, it's not a no-op.
69
+ const uint32_t caseValue = GetSwitchConstantAsUInt (condition->getConstantValue ());
70
+ if (caseValue == exprValue)
71
+ {
72
+ return false ;
73
+ }
74
+ }
75
+
76
+ // No case matched the constant value the switch was used on, so the entire switch is a no-op.
77
+ return true ;
78
+ }
25
79
26
80
bool IsNoOp (TIntermNode *node)
27
81
{
@@ -32,6 +86,11 @@ bool IsNoOp(TIntermNode *node)
32
86
return true ;
33
87
}
34
88
89
+ if (IsNoOpSwitch (node->getAsSwitchNode ()))
90
+ {
91
+ return true ;
92
+ }
93
+
35
94
if (node->getAsTyped () == nullptr || node->getAsFunctionPrototypeNode () != nullptr )
36
95
{
37
96
return false ;
0 commit comments