Fold ternary and comma ops only after parsing is done
In case folding a ternary op or a comma op would change the qualifier
of the expression, the folding is deferred to a separate traversal
step.
After this there are no more cases where the type of a TIntermSymbol
node needs to differ from the type of the variable it is referring to.
There are still some cases where some parts of TIntermSymbol type are
changed while keeping the TVariable type the same though, like when
assigning array size to gl_PerVertex nodes or sanitizing qualifiers of
struct declarations.
BUG=angleproject:2267
TEST=angle_unittests, angle_end2end_tests
Change-Id: I1501c8d361f5f765f43ca810d1b7248d9e2c5986
Reviewed-on: https://chromium-review.googlesource.com/850672
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/compiler/translator/IntermNode.cpp b/src/compiler/translator/IntermNode.cpp
index 1f5dfa8..9bbd4e2 100644
--- a/src/compiler/translator/IntermNode.cpp
+++ b/src/compiler/translator/IntermNode.cpp
@@ -138,6 +138,42 @@
resultArray[i].setFConst(resultElements[i]);
}
+bool CanFoldAggregateBuiltInOp(TOperator op)
+{
+ switch (op)
+ {
+ case EOpAtan:
+ case EOpPow:
+ case EOpMod:
+ case EOpMin:
+ case EOpMax:
+ case EOpClamp:
+ case EOpMix:
+ case EOpStep:
+ case EOpSmoothStep:
+ case EOpLdexp:
+ case EOpMulMatrixComponentWise:
+ case EOpOuterProduct:
+ case EOpEqualComponentWise:
+ case EOpNotEqualComponentWise:
+ case EOpLessThanComponentWise:
+ case EOpLessThanEqualComponentWise:
+ case EOpGreaterThanComponentWise:
+ case EOpGreaterThanEqualComponentWise:
+ case EOpDistance:
+ case EOpDot:
+ case EOpCross:
+ case EOpFaceforward:
+ case EOpReflect:
+ case EOpRefract:
+ case EOpBitfieldExtract:
+ case EOpBitfieldInsert:
+ return true;
+ default:
+ return false;
+ }
+}
+
} // namespace anonymous
////////////////////////////////////////////////////////////////
@@ -958,18 +994,16 @@
return EvqTemporary;
}
-TIntermTyped *TIntermTernary::fold()
+TIntermTyped *TIntermTernary::fold(TDiagnostics * /* diagnostics */)
{
if (mCondition->getAsConstantUnion())
{
if (mCondition->getAsConstantUnion()->getBConst(0))
{
- mTrueExpression->getTypePointer()->setQualifier(mType.getQualifier());
return mTrueExpression;
}
else
{
- mFalseExpression->getTypePointer()->setQualifier(mType.getQualifier());
return mFalseExpression;
}
}
@@ -1280,7 +1314,7 @@
}
}
-TIntermTyped *TIntermSwizzle::fold()
+TIntermTyped *TIntermSwizzle::fold(TDiagnostics * /* diagnostics */)
{
TIntermConstantUnion *operandConstant = mOperand->getAsConstantUnion();
if (operandConstant == nullptr)
@@ -1308,7 +1342,6 @@
{
return this;
}
- mRight->getTypePointer()->setQualifier(mType.getQualifier());
return mRight;
}
case EOpIndexDirect:
@@ -1432,13 +1465,20 @@
TConstantUnion *constArray = nullptr;
if (isConstructor())
{
- constArray = TIntermConstantUnion::FoldAggregateConstructor(this);
+ // TODO(oetuaho@nvidia.com): Add support for folding array constructors.
+ if (!isArray())
+ {
+ constArray = TIntermConstantUnion::FoldAggregateConstructor(this);
+ }
}
- else
+ else if (CanFoldAggregateBuiltInOp(mOp))
{
- ASSERT(CanFoldAggregateBuiltInOp(mOp));
constArray = TIntermConstantUnion::FoldAggregateBuiltIn(this, diagnostics);
}
+ if (constArray == nullptr)
+ {
+ return this;
+ }
return CreateFoldedNode(constArray, this);
}
@@ -2585,42 +2625,6 @@
return resultArray;
}
-bool TIntermAggregate::CanFoldAggregateBuiltInOp(TOperator op)
-{
- switch (op)
- {
- case EOpAtan:
- case EOpPow:
- case EOpMod:
- case EOpMin:
- case EOpMax:
- case EOpClamp:
- case EOpMix:
- case EOpStep:
- case EOpSmoothStep:
- case EOpLdexp:
- case EOpMulMatrixComponentWise:
- case EOpOuterProduct:
- case EOpEqualComponentWise:
- case EOpNotEqualComponentWise:
- case EOpLessThanComponentWise:
- case EOpLessThanEqualComponentWise:
- case EOpGreaterThanComponentWise:
- case EOpGreaterThanEqualComponentWise:
- case EOpDistance:
- case EOpDot:
- case EOpCross:
- case EOpFaceforward:
- case EOpReflect:
- case EOpRefract:
- case EOpBitfieldExtract:
- case EOpBitfieldInsert:
- return true;
- default:
- return false;
- }
-}
-
// static
TConstantUnion *TIntermConstantUnion::FoldAggregateBuiltIn(TIntermAggregate *aggregate,
TDiagnostics *diagnostics)