Commit 9dea48f3 by Arun Patole Committed by Jamie Madill

Support constant folding of trigonometry built-ins

This change adds constant folding support for trigonometry built-in functions. Constant folding for these functions also fixes constant expression issues where constant initializer is a built-in trignometry function whose arguments are all constant expressions. BUG=angleproject:913 TEST= dEQP tests dEQP-GLES3.functional.shaders.constant_expressions.builtin_functions.angle_and_trigonometry* (112 out of 120 tests pass with this change) Change-Id: I2b7a61320819dcd095827faa1fd16e835f4688b4 Reviewed-on: https://chromium-review.googlesource.com/265819Tested-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 56c6e3cb
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <float.h> #include <float.h>
#include <limits.h> #include <limits.h>
#include <math.h>
#include <algorithm> #include <algorithm>
#include "compiler/translator/HashNames.h" #include "compiler/translator/HashNames.h"
...@@ -19,6 +20,10 @@ ...@@ -19,6 +20,10 @@
namespace namespace
{ {
const float kPi = 3.14159265358979323846f;
const float kDegreesToRadiansMultiplier = kPi / 180.0f;
const float kRadiansToDegreesMultiplier = 180.0f / kPi;
TPrecision GetHigherPrecision(TPrecision left, TPrecision right) TPrecision GetHigherPrecision(TPrecision left, TPrecision right)
{ {
return left > right ? left : right; return left > right ? left : right;
...@@ -1185,6 +1190,100 @@ TIntermTyped *TIntermConstantUnion::fold( ...@@ -1185,6 +1190,100 @@ TIntermTyped *TIntermConstantUnion::fold(
} }
break; break;
case EOpRadians:
if (getType().getBasicType() == EbtFloat)
{
tempConstArray[i].setFConst(kDegreesToRadiansMultiplier * unionArray[i].getFConst());
break;
}
infoSink.info.message(
EPrefixInternalError, getLine(),
"Unary operation not folded into constant");
return nullptr;
case EOpDegrees:
if (getType().getBasicType() == EbtFloat)
{
tempConstArray[i].setFConst(kRadiansToDegreesMultiplier * unionArray[i].getFConst());
break;
}
infoSink.info.message(
EPrefixInternalError, getLine(),
"Unary operation not folded into constant");
return nullptr;
case EOpSin:
if (!foldFloatTypeUnary(unionArray[i], &sinf, infoSink, &tempConstArray[i]))
return nullptr;
break;
case EOpCos:
if (!foldFloatTypeUnary(unionArray[i], &cosf, infoSink, &tempConstArray[i]))
return nullptr;
break;
case EOpTan:
if (!foldFloatTypeUnary(unionArray[i], &tanf, infoSink, &tempConstArray[i]))
return nullptr;
break;
case EOpAsin:
// For asin(x), results are undefined if |x| > 1, we are choosing to set result to 0.
if (getType().getBasicType() == EbtFloat && fabsf(unionArray[i].getFConst()) > 1.0f)
tempConstArray[i].setFConst(0.0f);
else if (!foldFloatTypeUnary(unionArray[i], &asinf, infoSink, &tempConstArray[i]))
return nullptr;
break;
case EOpAcos:
// For acos(x), results are undefined if |x| > 1, we are choosing to set result to 0.
if (getType().getBasicType() == EbtFloat && fabsf(unionArray[i].getFConst()) > 1.0f)
tempConstArray[i].setFConst(0.0f);
else if (!foldFloatTypeUnary(unionArray[i], &acosf, infoSink, &tempConstArray[i]))
return nullptr;
break;
case EOpAtan:
if (!foldFloatTypeUnary(unionArray[i], &atanf, infoSink, &tempConstArray[i]))
return nullptr;
break;
case EOpSinh:
if (!foldFloatTypeUnary(unionArray[i], &sinhf, infoSink, &tempConstArray[i]))
return nullptr;
break;
case EOpCosh:
if (!foldFloatTypeUnary(unionArray[i], &coshf, infoSink, &tempConstArray[i]))
return nullptr;
break;
case EOpTanh:
if (!foldFloatTypeUnary(unionArray[i], &tanhf, infoSink, &tempConstArray[i]))
return nullptr;
break;
case EOpAsinh:
if (!foldFloatTypeUnary(unionArray[i], &asinhf, infoSink, &tempConstArray[i]))
return nullptr;
break;
case EOpAcosh:
// For acosh(x), results are undefined if x < 1, we are choosing to set result to 0.
if (getType().getBasicType() == EbtFloat && unionArray[i].getFConst() < 1.0f)
tempConstArray[i].setFConst(0.0f);
else if (!foldFloatTypeUnary(unionArray[i], &acoshf, infoSink, &tempConstArray[i]))
return nullptr;
break;
case EOpAtanh:
// For atanh(x), results are undefined if |x| >= 1, we are choosing to set result to 0.
if (getType().getBasicType() == EbtFloat && fabsf(unionArray[i].getFConst()) >= 1.0f)
tempConstArray[i].setFConst(0.0f);
else if (!foldFloatTypeUnary(unionArray[i], &atanhf, infoSink, &tempConstArray[i]))
return nullptr;
break;
default: default:
return NULL; return NULL;
} }
...@@ -1195,6 +1294,23 @@ TIntermTyped *TIntermConstantUnion::fold( ...@@ -1195,6 +1294,23 @@ TIntermTyped *TIntermConstantUnion::fold(
} }
} }
bool TIntermConstantUnion::foldFloatTypeUnary(const ConstantUnion &parameter, FloatTypeUnaryFunc builtinFunc,
TInfoSink &infoSink, ConstantUnion *result) const
{
ASSERT(builtinFunc);
if (getType().getBasicType() == EbtFloat)
{
result->setFConst(builtinFunc(parameter.getFConst()));
return true;
}
infoSink.info.message(
EPrefixInternalError, getLine(),
"Unary operation not folded into constant");
return false;
}
// static // static
TString TIntermTraverser::hash(const TString &name, ShHashFunction64 hashFunction) TString TIntermTraverser::hash(const TString &name, ShHashFunction64 hashFunction)
{ {
......
...@@ -292,6 +292,10 @@ class TIntermConstantUnion : public TIntermTyped ...@@ -292,6 +292,10 @@ class TIntermConstantUnion : public TIntermTyped
protected: protected:
ConstantUnion *mUnionArrayPointer; ConstantUnion *mUnionArrayPointer;
private:
typedef float(*FloatTypeUnaryFunc) (float);
bool foldFloatTypeUnary(const ConstantUnion &parameter, FloatTypeUnaryFunc builtinFunc, TInfoSink &infoSink, ConstantUnion *result) const;
}; };
// //
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment