Allow constant folding some non-constant expressions
This requires removing the assumption that constant folding implies
constness in the constant expression sense from various places in the
code.
This particularly benefits ternary operators, which can now be simplified
if just the condition is a compile-time constant.
In the future, the groundwork that is laid here could be used to implement
more aggressive constant folding of user-defined functions for example.
TEST=angle_unittests
BUG=angleproject:851
Change-Id: I0eede806570d56746c3dad1e01aa89a91d66013d
Reviewed-on: https://chromium-review.googlesource.com/310750
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Tested-by: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Zhenyao Mo <zmo@chromium.org>
diff --git a/src/compiler/translator/Intermediate.cpp b/src/compiler/translator/Intermediate.cpp
index 931a4d9..dca1177 100644
--- a/src/compiler/translator/Intermediate.cpp
+++ b/src/compiler/translator/Intermediate.cpp
@@ -260,7 +260,7 @@
// test now.
//
- if (cond->getAsTyped() && cond->getAsTyped()->getAsConstantUnion())
+ if (cond->getAsConstantUnion())
{
if (cond->getAsConstantUnion()->getBConst(0) == true)
{
@@ -325,19 +325,20 @@
{
resultQualifier = EvqConst;
}
- // Right now it's safe to fold ternary operators only when all operands
- // are constant. If only the condition is constant, it's theoretically
- // possible to fold the ternary operator, but that requires making sure
- // that the node returned from here won't be treated as a constant
- // expression in case the node that gets eliminated was not a constant
- // expression.
- if (resultQualifier == EvqConst && cond->getAsConstantUnion() &&
- trueBlock->getAsConstantUnion() && falseBlock->getAsConstantUnion())
+ // Note that the node resulting from here can be a constant union without being qualified as
+ // constant.
+ if (cond->getAsConstantUnion())
{
if (cond->getAsConstantUnion()->getBConst(0))
+ {
+ trueBlock->getTypePointer()->setQualifier(resultQualifier);
return trueBlock;
+ }
else
+ {
+ falseBlock->getTypePointer()->setQualifier(resultQualifier);
return falseBlock;
+ }
}
//