Commit 95310b00 by Olli Etuaho

Unify unary operator folding with binary operator folding

Implement unary operator folding in a similar way to binary operator folding, so that the code is easier to understand. TEST=dEQP-GLES3.functional.shaders.constant_expressions.* BUG=angleproject:817 Change-Id: I069bdb38f965e1badb3e8f3f954386b205b7bb00 Reviewed-on: https://chromium-review.googlesource.com/275185Reviewed-by: 's avatarZhenyao Mo <zmo@chromium.org> Tested-by: 's avatarOlli Etuaho <oetuaho@nvidia.com>
parent 2c4b746c
...@@ -766,6 +766,24 @@ TIntermTyped *TIntermBinary::fold(TInfoSink &infoSink) ...@@ -766,6 +766,24 @@ TIntermTyped *TIntermBinary::fold(TInfoSink &infoSink)
return folded; return folded;
} }
TIntermTyped *TIntermUnary::fold(TInfoSink &infoSink)
{
TIntermConstantUnion *operandConstant = mOperand->getAsConstantUnion();
if (operandConstant == nullptr)
{
return nullptr;
}
TConstantUnion *constArray = operandConstant->foldUnary(mOp, infoSink);
if (constArray == nullptr)
{
return nullptr;
}
TIntermTyped *folded = new TIntermConstantUnion(constArray, getType());
folded->getTypePointer()->setQualifier(EvqConst);
folded->setLine(getLine());
return folded;
}
// //
// The fold functions see if an operation on a constant can be done in place, // The fold functions see if an operation on a constant can be done in place,
// without generating run-time code. // without generating run-time code.
...@@ -1114,39 +1132,37 @@ TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op, TIntermConstantUn ...@@ -1114,39 +1132,37 @@ TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op, TIntermConstantUn
// The fold functions see if an operation on a constant can be done in place, // The fold functions see if an operation on a constant can be done in place,
// without generating run-time code. // without generating run-time code.
// //
// Returns the node to keep using or nullptr. // Returns the constant value to keep using or nullptr.
// //
TIntermTyped *TIntermConstantUnion::foldUnary(TOperator op, TInfoSink &infoSink) TConstantUnion *TIntermConstantUnion::foldUnary(TOperator op, TInfoSink &infoSink)
{ {
TConstantUnion *unionArray = getUnionArrayPointer(); TConstantUnion *operandArray = getUnionArrayPointer();
if (!unionArray) if (!operandArray)
return nullptr; return nullptr;
size_t objectSize = getType().getObjectSize(); size_t objectSize = getType().getObjectSize();
if (op == EOpAny || op == EOpAll || op == EOpLength) if (op == EOpAny || op == EOpAll || op == EOpLength)
{ {
// Do operations where the return type is different from the operand type. // Do operations where the return type has a different number of components compared to the operand type.
TConstantUnion *resultArray = nullptr;
TType returnType;
TConstantUnion *tempConstArray = nullptr;
switch (op) switch (op)
{ {
case EOpAny: case EOpAny:
if (getType().getBasicType() == EbtBool) if (getType().getBasicType() == EbtBool)
{ {
tempConstArray = new TConstantUnion(); resultArray = new TConstantUnion();
tempConstArray->setBConst(false); resultArray->setBConst(false);
for (size_t i = 0; i < objectSize; i++) for (size_t i = 0; i < objectSize; i++)
{ {
if (unionArray[i].getBConst()) if (operandArray[i].getBConst())
{ {
tempConstArray->setBConst(true); resultArray->setBConst(true);
break; break;
} }
} }
returnType = TType(EbtBool, EbpUndefined, EvqConst);
break; break;
} }
else else
...@@ -1158,17 +1174,16 @@ TIntermTyped *TIntermConstantUnion::foldUnary(TOperator op, TInfoSink &infoSink) ...@@ -1158,17 +1174,16 @@ TIntermTyped *TIntermConstantUnion::foldUnary(TOperator op, TInfoSink &infoSink)
case EOpAll: case EOpAll:
if (getType().getBasicType() == EbtBool) if (getType().getBasicType() == EbtBool)
{ {
tempConstArray = new TConstantUnion(); resultArray = new TConstantUnion();
tempConstArray->setBConst(true); resultArray->setBConst(true);
for (size_t i = 0; i < objectSize; i++) for (size_t i = 0; i < objectSize; i++)
{ {
if (!unionArray[i].getBConst()) if (!operandArray[i].getBConst())
{ {
tempConstArray->setBConst(false); resultArray->setBConst(false);
break; break;
} }
} }
returnType = TType(EbtBool, EbpUndefined, EvqConst);
break; break;
} }
else else
...@@ -1180,9 +1195,8 @@ TIntermTyped *TIntermConstantUnion::foldUnary(TOperator op, TInfoSink &infoSink) ...@@ -1180,9 +1195,8 @@ TIntermTyped *TIntermConstantUnion::foldUnary(TOperator op, TInfoSink &infoSink)
case EOpLength: case EOpLength:
if (getType().getBasicType() == EbtFloat) if (getType().getBasicType() == EbtFloat)
{ {
tempConstArray = new TConstantUnion(); resultArray = new TConstantUnion();
tempConstArray->setFConst(VectorLength(unionArray, objectSize)); resultArray->setFConst(VectorLength(operandArray, objectSize));
returnType = TType(EbtFloat, getType().getPrecision(), EvqConst);
break; break;
} }
else else
...@@ -1195,17 +1209,14 @@ TIntermTyped *TIntermConstantUnion::foldUnary(TOperator op, TInfoSink &infoSink) ...@@ -1195,17 +1209,14 @@ TIntermTyped *TIntermConstantUnion::foldUnary(TOperator op, TInfoSink &infoSink)
break; break;
} }
TIntermConstantUnion *tempNode = new TIntermConstantUnion(tempConstArray, returnType); return resultArray;
tempNode->setLine(getLine());
return tempNode;
} }
else else
{ {
// //
// Do unary operations where the return type is the same as operand type. // Do unary operations where the return type is the same as operand type.
// //
TIntermConstantUnion *newNode = 0; TConstantUnion *resultArray = new TConstantUnion[objectSize];
TConstantUnion* tempConstArray = new TConstantUnion[objectSize];
for (size_t i = 0; i < objectSize; i++) for (size_t i = 0; i < objectSize; i++)
{ {
switch(op) switch(op)
...@@ -1214,14 +1225,14 @@ TIntermTyped *TIntermConstantUnion::foldUnary(TOperator op, TInfoSink &infoSink) ...@@ -1214,14 +1225,14 @@ TIntermTyped *TIntermConstantUnion::foldUnary(TOperator op, TInfoSink &infoSink)
switch (getType().getBasicType()) switch (getType().getBasicType())
{ {
case EbtFloat: case EbtFloat:
tempConstArray[i].setFConst(-unionArray[i].getFConst()); resultArray[i].setFConst(-operandArray[i].getFConst());
break; break;
case EbtInt: case EbtInt:
tempConstArray[i].setIConst(-unionArray[i].getIConst()); resultArray[i].setIConst(-operandArray[i].getIConst());
break; break;
case EbtUInt: case EbtUInt:
tempConstArray[i].setUConst(static_cast<unsigned int>( resultArray[i].setUConst(static_cast<unsigned int>(
-static_cast<int>(unionArray[i].getUConst()))); -static_cast<int>(operandArray[i].getUConst())));
break; break;
default: default:
infoSink.info.message( infoSink.info.message(
...@@ -1235,14 +1246,14 @@ TIntermTyped *TIntermConstantUnion::foldUnary(TOperator op, TInfoSink &infoSink) ...@@ -1235,14 +1246,14 @@ TIntermTyped *TIntermConstantUnion::foldUnary(TOperator op, TInfoSink &infoSink)
switch (getType().getBasicType()) switch (getType().getBasicType())
{ {
case EbtFloat: case EbtFloat:
tempConstArray[i].setFConst(unionArray[i].getFConst()); resultArray[i].setFConst(operandArray[i].getFConst());
break; break;
case EbtInt: case EbtInt:
tempConstArray[i].setIConst(unionArray[i].getIConst()); resultArray[i].setIConst(operandArray[i].getIConst());
break; break;
case EbtUInt: case EbtUInt:
tempConstArray[i].setUConst(static_cast<unsigned int>( resultArray[i].setUConst(static_cast<unsigned int>(
static_cast<int>(unionArray[i].getUConst()))); static_cast<int>(operandArray[i].getUConst())));
break; break;
default: default:
infoSink.info.message( infoSink.info.message(
...@@ -1258,7 +1269,7 @@ TIntermTyped *TIntermConstantUnion::foldUnary(TOperator op, TInfoSink &infoSink) ...@@ -1258,7 +1269,7 @@ TIntermTyped *TIntermConstantUnion::foldUnary(TOperator op, TInfoSink &infoSink)
switch (getType().getBasicType()) switch (getType().getBasicType())
{ {
case EbtBool: case EbtBool:
tempConstArray[i].setBConst(!unionArray[i].getBConst()); resultArray[i].setBConst(!operandArray[i].getBConst());
break; break;
default: default:
infoSink.info.message( infoSink.info.message(
...@@ -1272,10 +1283,10 @@ TIntermTyped *TIntermConstantUnion::foldUnary(TOperator op, TInfoSink &infoSink) ...@@ -1272,10 +1283,10 @@ TIntermTyped *TIntermConstantUnion::foldUnary(TOperator op, TInfoSink &infoSink)
switch (getType().getBasicType()) switch (getType().getBasicType())
{ {
case EbtInt: case EbtInt:
tempConstArray[i].setIConst(~unionArray[i].getIConst()); resultArray[i].setIConst(~operandArray[i].getIConst());
break; break;
case EbtUInt: case EbtUInt:
tempConstArray[i].setUConst(~unionArray[i].getUConst()); resultArray[i].setUConst(~operandArray[i].getUConst());
break; break;
default: default:
infoSink.info.message( infoSink.info.message(
...@@ -1288,7 +1299,7 @@ TIntermTyped *TIntermConstantUnion::foldUnary(TOperator op, TInfoSink &infoSink) ...@@ -1288,7 +1299,7 @@ TIntermTyped *TIntermConstantUnion::foldUnary(TOperator op, TInfoSink &infoSink)
case EOpRadians: case EOpRadians:
if (getType().getBasicType() == EbtFloat) if (getType().getBasicType() == EbtFloat)
{ {
tempConstArray[i].setFConst(kDegreesToRadiansMultiplier * unionArray[i].getFConst()); resultArray[i].setFConst(kDegreesToRadiansMultiplier * operandArray[i].getFConst());
break; break;
} }
infoSink.info.message( infoSink.info.message(
...@@ -1299,7 +1310,7 @@ TIntermTyped *TIntermConstantUnion::foldUnary(TOperator op, TInfoSink &infoSink) ...@@ -1299,7 +1310,7 @@ TIntermTyped *TIntermConstantUnion::foldUnary(TOperator op, TInfoSink &infoSink)
case EOpDegrees: case EOpDegrees:
if (getType().getBasicType() == EbtFloat) if (getType().getBasicType() == EbtFloat)
{ {
tempConstArray[i].setFConst(kRadiansToDegreesMultiplier * unionArray[i].getFConst()); resultArray[i].setFConst(kRadiansToDegreesMultiplier * operandArray[i].getFConst());
break; break;
} }
infoSink.info.message( infoSink.info.message(
...@@ -1308,74 +1319,74 @@ TIntermTyped *TIntermConstantUnion::foldUnary(TOperator op, TInfoSink &infoSink) ...@@ -1308,74 +1319,74 @@ TIntermTyped *TIntermConstantUnion::foldUnary(TOperator op, TInfoSink &infoSink)
return nullptr; return nullptr;
case EOpSin: case EOpSin:
if (!foldFloatTypeUnary(unionArray[i], &sinf, infoSink, &tempConstArray[i])) if (!foldFloatTypeUnary(operandArray[i], &sinf, infoSink, &resultArray[i]))
return nullptr; return nullptr;
break; break;
case EOpCos: case EOpCos:
if (!foldFloatTypeUnary(unionArray[i], &cosf, infoSink, &tempConstArray[i])) if (!foldFloatTypeUnary(operandArray[i], &cosf, infoSink, &resultArray[i]))
return nullptr; return nullptr;
break; break;
case EOpTan: case EOpTan:
if (!foldFloatTypeUnary(unionArray[i], &tanf, infoSink, &tempConstArray[i])) if (!foldFloatTypeUnary(operandArray[i], &tanf, infoSink, &resultArray[i]))
return nullptr; return nullptr;
break; break;
case EOpAsin: case EOpAsin:
// For asin(x), results are undefined if |x| > 1, we are choosing to set result to 0. // 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) if (getType().getBasicType() == EbtFloat && fabsf(operandArray[i].getFConst()) > 1.0f)
UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &tempConstArray[i]); UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &resultArray[i]);
else if (!foldFloatTypeUnary(unionArray[i], &asinf, infoSink, &tempConstArray[i])) else if (!foldFloatTypeUnary(operandArray[i], &asinf, infoSink, &resultArray[i]))
return nullptr; return nullptr;
break; break;
case EOpAcos: case EOpAcos:
// For acos(x), results are undefined if |x| > 1, we are choosing to set result to 0. // 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) if (getType().getBasicType() == EbtFloat && fabsf(operandArray[i].getFConst()) > 1.0f)
UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &tempConstArray[i]); UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &resultArray[i]);
else if (!foldFloatTypeUnary(unionArray[i], &acosf, infoSink, &tempConstArray[i])) else if (!foldFloatTypeUnary(operandArray[i], &acosf, infoSink, &resultArray[i]))
return nullptr; return nullptr;
break; break;
case EOpAtan: case EOpAtan:
if (!foldFloatTypeUnary(unionArray[i], &atanf, infoSink, &tempConstArray[i])) if (!foldFloatTypeUnary(operandArray[i], &atanf, infoSink, &resultArray[i]))
return nullptr; return nullptr;
break; break;
case EOpSinh: case EOpSinh:
if (!foldFloatTypeUnary(unionArray[i], &sinhf, infoSink, &tempConstArray[i])) if (!foldFloatTypeUnary(operandArray[i], &sinhf, infoSink, &resultArray[i]))
return nullptr; return nullptr;
break; break;
case EOpCosh: case EOpCosh:
if (!foldFloatTypeUnary(unionArray[i], &coshf, infoSink, &tempConstArray[i])) if (!foldFloatTypeUnary(operandArray[i], &coshf, infoSink, &resultArray[i]))
return nullptr; return nullptr;
break; break;
case EOpTanh: case EOpTanh:
if (!foldFloatTypeUnary(unionArray[i], &tanhf, infoSink, &tempConstArray[i])) if (!foldFloatTypeUnary(operandArray[i], &tanhf, infoSink, &resultArray[i]))
return nullptr; return nullptr;
break; break;
case EOpAsinh: case EOpAsinh:
if (!foldFloatTypeUnary(unionArray[i], &asinhf, infoSink, &tempConstArray[i])) if (!foldFloatTypeUnary(operandArray[i], &asinhf, infoSink, &resultArray[i]))
return nullptr; return nullptr;
break; break;
case EOpAcosh: case EOpAcosh:
// For acosh(x), results are undefined if x < 1, we are choosing to set result to 0. // 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) if (getType().getBasicType() == EbtFloat && operandArray[i].getFConst() < 1.0f)
UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &tempConstArray[i]); UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &resultArray[i]);
else if (!foldFloatTypeUnary(unionArray[i], &acoshf, infoSink, &tempConstArray[i])) else if (!foldFloatTypeUnary(operandArray[i], &acoshf, infoSink, &resultArray[i]))
return nullptr; return nullptr;
break; break;
case EOpAtanh: case EOpAtanh:
// For atanh(x), results are undefined if |x| >= 1, we are choosing to set result to 0. // 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) if (getType().getBasicType() == EbtFloat && fabsf(operandArray[i].getFConst()) >= 1.0f)
UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &tempConstArray[i]); UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &resultArray[i]);
else if (!foldFloatTypeUnary(unionArray[i], &atanhf, infoSink, &tempConstArray[i])) else if (!foldFloatTypeUnary(operandArray[i], &atanhf, infoSink, &resultArray[i]))
return nullptr; return nullptr;
break; break;
...@@ -1383,10 +1394,10 @@ TIntermTyped *TIntermConstantUnion::foldUnary(TOperator op, TInfoSink &infoSink) ...@@ -1383,10 +1394,10 @@ TIntermTyped *TIntermConstantUnion::foldUnary(TOperator op, TInfoSink &infoSink)
switch (getType().getBasicType()) switch (getType().getBasicType())
{ {
case EbtFloat: case EbtFloat:
tempConstArray[i].setFConst(fabsf(unionArray[i].getFConst())); resultArray[i].setFConst(fabsf(operandArray[i].getFConst()));
break; break;
case EbtInt: case EbtInt:
tempConstArray[i].setIConst(abs(unionArray[i].getIConst())); resultArray[i].setIConst(abs(operandArray[i].getIConst()));
break; break;
default: default:
infoSink.info.message( infoSink.info.message(
...@@ -1401,24 +1412,24 @@ TIntermTyped *TIntermConstantUnion::foldUnary(TOperator op, TInfoSink &infoSink) ...@@ -1401,24 +1412,24 @@ TIntermTyped *TIntermConstantUnion::foldUnary(TOperator op, TInfoSink &infoSink)
{ {
case EbtFloat: case EbtFloat:
{ {
float fConst = unionArray[i].getFConst(); float fConst = operandArray[i].getFConst();
float fResult = 0.0f; float fResult = 0.0f;
if (fConst > 0.0f) if (fConst > 0.0f)
fResult = 1.0f; fResult = 1.0f;
else if (fConst < 0.0f) else if (fConst < 0.0f)
fResult = -1.0f; fResult = -1.0f;
tempConstArray[i].setFConst(fResult); resultArray[i].setFConst(fResult);
} }
break; break;
case EbtInt: case EbtInt:
{ {
int iConst = unionArray[i].getIConst(); int iConst = operandArray[i].getIConst();
int iResult = 0; int iResult = 0;
if (iConst > 0) if (iConst > 0)
iResult = 1; iResult = 1;
else if (iConst < 0) else if (iConst < 0)
iResult = -1; iResult = -1;
tempConstArray[i].setIConst(iResult); resultArray[i].setIConst(iResult);
} }
break; break;
default: default:
...@@ -1430,31 +1441,31 @@ TIntermTyped *TIntermConstantUnion::foldUnary(TOperator op, TInfoSink &infoSink) ...@@ -1430,31 +1441,31 @@ TIntermTyped *TIntermConstantUnion::foldUnary(TOperator op, TInfoSink &infoSink)
break; break;
case EOpFloor: case EOpFloor:
if (!foldFloatTypeUnary(unionArray[i], &floorf, infoSink, &tempConstArray[i])) if (!foldFloatTypeUnary(operandArray[i], &floorf, infoSink, &resultArray[i]))
return nullptr; return nullptr;
break; break;
case EOpTrunc: case EOpTrunc:
if (!foldFloatTypeUnary(unionArray[i], &truncf, infoSink, &tempConstArray[i])) if (!foldFloatTypeUnary(operandArray[i], &truncf, infoSink, &resultArray[i]))
return nullptr; return nullptr;
break; break;
case EOpRound: case EOpRound:
if (!foldFloatTypeUnary(unionArray[i], &roundf, infoSink, &tempConstArray[i])) if (!foldFloatTypeUnary(operandArray[i], &roundf, infoSink, &resultArray[i]))
return nullptr; return nullptr;
break; break;
case EOpRoundEven: case EOpRoundEven:
if (getType().getBasicType() == EbtFloat) if (getType().getBasicType() == EbtFloat)
{ {
float x = unionArray[i].getFConst(); float x = operandArray[i].getFConst();
float result; float result;
float fractPart = modff(x, &result); float fractPart = modff(x, &result);
if (fabsf(fractPart) == 0.5f) if (fabsf(fractPart) == 0.5f)
result = 2.0f * roundf(x / 2.0f); result = 2.0f * roundf(x / 2.0f);
else else
result = roundf(x); result = roundf(x);
tempConstArray[i].setFConst(result); resultArray[i].setFConst(result);
break; break;
} }
infoSink.info.message( infoSink.info.message(
...@@ -1463,15 +1474,15 @@ TIntermTyped *TIntermConstantUnion::foldUnary(TOperator op, TInfoSink &infoSink) ...@@ -1463,15 +1474,15 @@ TIntermTyped *TIntermConstantUnion::foldUnary(TOperator op, TInfoSink &infoSink)
return nullptr; return nullptr;
case EOpCeil: case EOpCeil:
if (!foldFloatTypeUnary(unionArray[i], &ceilf, infoSink, &tempConstArray[i])) if (!foldFloatTypeUnary(operandArray[i], &ceilf, infoSink, &resultArray[i]))
return nullptr; return nullptr;
break; break;
case EOpFract: case EOpFract:
if (getType().getBasicType() == EbtFloat) if (getType().getBasicType() == EbtFloat)
{ {
float x = unionArray[i].getFConst(); float x = operandArray[i].getFConst();
tempConstArray[i].setFConst(x - floorf(x)); resultArray[i].setFConst(x - floorf(x));
break; break;
} }
infoSink.info.message( infoSink.info.message(
...@@ -1480,39 +1491,39 @@ TIntermTyped *TIntermConstantUnion::foldUnary(TOperator op, TInfoSink &infoSink) ...@@ -1480,39 +1491,39 @@ TIntermTyped *TIntermConstantUnion::foldUnary(TOperator op, TInfoSink &infoSink)
return nullptr; return nullptr;
case EOpExp: case EOpExp:
if (!foldFloatTypeUnary(unionArray[i], &expf, infoSink, &tempConstArray[i])) if (!foldFloatTypeUnary(operandArray[i], &expf, infoSink, &resultArray[i]))
return nullptr; return nullptr;
break; break;
case EOpLog: case EOpLog:
// For log(x), results are undefined if x <= 0, we are choosing to set result to 0. // For log(x), results are undefined if x <= 0, we are choosing to set result to 0.
if (getType().getBasicType() == EbtFloat && unionArray[i].getFConst() <= 0.0f) if (getType().getBasicType() == EbtFloat && operandArray[i].getFConst() <= 0.0f)
UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &tempConstArray[i]); UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &resultArray[i]);
else if (!foldFloatTypeUnary(unionArray[i], &logf, infoSink, &tempConstArray[i])) else if (!foldFloatTypeUnary(operandArray[i], &logf, infoSink, &resultArray[i]))
return nullptr; return nullptr;
break; break;
case EOpExp2: case EOpExp2:
if (!foldFloatTypeUnary(unionArray[i], &exp2f, infoSink, &tempConstArray[i])) if (!foldFloatTypeUnary(operandArray[i], &exp2f, infoSink, &resultArray[i]))
return nullptr; return nullptr;
break; break;
case EOpLog2: case EOpLog2:
// For log2(x), results are undefined if x <= 0, we are choosing to set result to 0. // For log2(x), results are undefined if x <= 0, we are choosing to set result to 0.
// And log2f is not available on some plarforms like old android, so just using log(x)/log(2) here. // And log2f is not available on some plarforms like old android, so just using log(x)/log(2) here.
if (getType().getBasicType() == EbtFloat && unionArray[i].getFConst() <= 0.0f) if (getType().getBasicType() == EbtFloat && operandArray[i].getFConst() <= 0.0f)
UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &tempConstArray[i]); UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &resultArray[i]);
else if (!foldFloatTypeUnary(unionArray[i], &logf, infoSink, &tempConstArray[i])) else if (!foldFloatTypeUnary(operandArray[i], &logf, infoSink, &resultArray[i]))
return nullptr; return nullptr;
else else
tempConstArray[i].setFConst(tempConstArray[i].getFConst() / logf(2.0f)); resultArray[i].setFConst(resultArray[i].getFConst() / logf(2.0f));
break; break;
case EOpSqrt: case EOpSqrt:
// For sqrt(x), results are undefined if x < 0, we are choosing to set result to 0. // For sqrt(x), results are undefined if x < 0, we are choosing to set result to 0.
if (getType().getBasicType() == EbtFloat && unionArray[i].getFConst() < 0.0f) if (getType().getBasicType() == EbtFloat && operandArray[i].getFConst() < 0.0f)
UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &tempConstArray[i]); UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &resultArray[i]);
else if (!foldFloatTypeUnary(unionArray[i], &sqrtf, infoSink, &tempConstArray[i])) else if (!foldFloatTypeUnary(operandArray[i], &sqrtf, infoSink, &resultArray[i]))
return nullptr; return nullptr;
break; break;
...@@ -1520,18 +1531,18 @@ TIntermTyped *TIntermConstantUnion::foldUnary(TOperator op, TInfoSink &infoSink) ...@@ -1520,18 +1531,18 @@ TIntermTyped *TIntermConstantUnion::foldUnary(TOperator op, TInfoSink &infoSink)
// There is no stdlib built-in function equavalent for GLES built-in inversesqrt(), // There is no stdlib built-in function equavalent for GLES built-in inversesqrt(),
// so getting the square root first using builtin function sqrt() and then taking its inverse. // so getting the square root first using builtin function sqrt() and then taking its inverse.
// Also, for inversesqrt(x), results are undefined if x <= 0, we are choosing to set result to 0. // Also, for inversesqrt(x), results are undefined if x <= 0, we are choosing to set result to 0.
if (getType().getBasicType() == EbtFloat && unionArray[i].getFConst() <= 0.0f) if (getType().getBasicType() == EbtFloat && operandArray[i].getFConst() <= 0.0f)
UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &tempConstArray[i]); UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &resultArray[i]);
else if (!foldFloatTypeUnary(unionArray[i], &sqrtf, infoSink, &tempConstArray[i])) else if (!foldFloatTypeUnary(operandArray[i], &sqrtf, infoSink, &resultArray[i]))
return nullptr; return nullptr;
else else
tempConstArray[i].setFConst(1.0f / tempConstArray[i].getFConst()); resultArray[i].setFConst(1.0f / resultArray[i].getFConst());
break; break;
case EOpVectorLogicalNot: case EOpVectorLogicalNot:
if (getType().getBasicType() == EbtBool) if (getType().getBasicType() == EbtBool)
{ {
tempConstArray[i].setBConst(!unionArray[i].getBConst()); resultArray[i].setBConst(!operandArray[i].getBConst());
break; break;
} }
infoSink.info.message( infoSink.info.message(
...@@ -1542,12 +1553,13 @@ TIntermTyped *TIntermConstantUnion::foldUnary(TOperator op, TInfoSink &infoSink) ...@@ -1542,12 +1553,13 @@ TIntermTyped *TIntermConstantUnion::foldUnary(TOperator op, TInfoSink &infoSink)
case EOpNormalize: case EOpNormalize:
if (getType().getBasicType() == EbtFloat) if (getType().getBasicType() == EbtFloat)
{ {
float x = unionArray[i].getFConst(); float x = operandArray[i].getFConst();
float length = VectorLength(unionArray, objectSize); float length = VectorLength(operandArray, objectSize);
if (length) if (length)
tempConstArray[i].setFConst(x / length); resultArray[i].setFConst(x / length);
else else
UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &tempConstArray[i]); UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink,
&resultArray[i]);
break; break;
} }
infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant");
...@@ -1557,9 +1569,7 @@ TIntermTyped *TIntermConstantUnion::foldUnary(TOperator op, TInfoSink &infoSink) ...@@ -1557,9 +1569,7 @@ TIntermTyped *TIntermConstantUnion::foldUnary(TOperator op, TInfoSink &infoSink)
return nullptr; return nullptr;
} }
} }
newNode = new TIntermConstantUnion(tempConstArray, getType()); return resultArray;
newNode->setLine(getLine());
return newNode;
} }
} }
......
...@@ -300,7 +300,7 @@ class TIntermConstantUnion : public TIntermTyped ...@@ -300,7 +300,7 @@ class TIntermConstantUnion : public TIntermTyped
virtual bool replaceChildNode(TIntermNode *, TIntermNode *) { return false; } virtual bool replaceChildNode(TIntermNode *, TIntermNode *) { return false; }
TConstantUnion *foldBinary(TOperator op, TIntermConstantUnion *rightNode, TInfoSink &infoSink); TConstantUnion *foldBinary(TOperator op, TIntermConstantUnion *rightNode, TInfoSink &infoSink);
TIntermTyped *foldUnary(TOperator op, TInfoSink &infoSink); TConstantUnion *foldUnary(TOperator op, TInfoSink &infoSink);
static TIntermTyped *FoldAggregateBuiltIn(TOperator op, TIntermAggregate *aggregate, TInfoSink &infoSink); static TIntermTyped *FoldAggregateBuiltIn(TOperator op, TIntermAggregate *aggregate, TInfoSink &infoSink);
...@@ -404,6 +404,7 @@ class TIntermUnary : public TIntermOperator ...@@ -404,6 +404,7 @@ class TIntermUnary : public TIntermOperator
void setOperand(TIntermTyped *operand) { mOperand = operand; } void setOperand(TIntermTyped *operand) { mOperand = operand; }
TIntermTyped *getOperand() { return mOperand; } TIntermTyped *getOperand() { return mOperand; }
void promote(const TType *funcReturnType); void promote(const TType *funcReturnType);
TIntermTyped *fold(TInfoSink &infoSink);
void setUseEmulatedFunction() { mUseEmulatedFunction = true; } void setUseEmulatedFunction() { mUseEmulatedFunction = true; }
bool getUseEmulatedFunction() { return mUseEmulatedFunction; } bool getUseEmulatedFunction() { return mUseEmulatedFunction; }
......
...@@ -120,10 +120,6 @@ TIntermTyped *TIntermediate::addIndex( ...@@ -120,10 +120,6 @@ TIntermTyped *TIntermediate::addIndex(
TIntermTyped *TIntermediate::addUnaryMath( TIntermTyped *TIntermediate::addUnaryMath(
TOperator op, TIntermTyped *child, const TSourceLoc &line, const TType *funcReturnType) TOperator op, TIntermTyped *child, const TSourceLoc &line, const TType *funcReturnType)
{ {
TIntermConstantUnion *childTempConstant = 0;
if (child->getAsConstantUnion())
childTempConstant = child->getAsConstantUnion();
// //
// Make a new node for the operator. // Make a new node for the operator.
// //
...@@ -132,13 +128,9 @@ TIntermTyped *TIntermediate::addUnaryMath( ...@@ -132,13 +128,9 @@ TIntermTyped *TIntermediate::addUnaryMath(
node->setOperand(child); node->setOperand(child);
node->promote(funcReturnType); node->promote(funcReturnType);
if (childTempConstant) TIntermTyped *foldedNode = node->fold(mInfoSink);
{ if (foldedNode)
TIntermTyped *newChild = childTempConstant->foldUnary(op, mInfoSink); return foldedNode;
if (newChild)
return newChild;
}
return node; return node;
} }
......
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