Refactor binary node creation
1. Simplify code by using asserts instead of adding internal errors to
log.
2. Add a TIntermBinary constructor that takes left and right operand
nodes as parameters.
3. Remove TIntermediate functions with trivial functionality.
BUG=angleproject:952
TEST=angle_unittests
Change-Id: I2e0e52160c9377d8efcf15f14fd59f01cb41bd83
Reviewed-on: https://chromium-review.googlesource.com/372720
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/compiler/translator/IntermNode.cpp b/src/compiler/translator/IntermNode.cpp
index 2ce85e0..83f8e00 100644
--- a/src/compiler/translator/IntermNode.cpp
+++ b/src/compiler/translator/IntermNode.cpp
@@ -17,6 +17,7 @@
#include "common/mathutil.h"
#include "common/matrix_utils.h"
+#include "compiler/translator/Diagnostics.h"
#include "compiler/translator/HashNames.h"
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/SymbolTable.h"
@@ -565,7 +566,7 @@
// For lots of operations it should already be established that the operand
// combination is valid, but returns false if operator can't work on operands.
//
-bool TIntermBinary::promote(TInfoSink &infoSink)
+bool TIntermBinary::promote()
{
ASSERT(mLeft->isArray() == mRight->isArray());
@@ -686,8 +687,7 @@
}
else
{
- infoSink.info.message(EPrefixInternalError, getLine(),
- "Missing elses");
+ UNREACHABLE();
return false;
}
@@ -744,8 +744,7 @@
}
else
{
- infoSink.info.message(EPrefixInternalError, getLine(),
- "Missing elses");
+ UNREACHABLE();
return false;
}
@@ -836,7 +835,7 @@
return true;
}
-TIntermTyped *TIntermBinary::fold(TInfoSink &infoSink)
+TIntermTyped *TIntermBinary::fold(TDiagnostics *diagnostics)
{
TIntermConstantUnion *leftConstant = mLeft->getAsConstantUnion();
TIntermConstantUnion *rightConstant = mRight->getAsConstantUnion();
@@ -844,7 +843,7 @@
{
return nullptr;
}
- TConstantUnion *constArray = leftConstant->foldBinary(mOp, rightConstant, infoSink);
+ TConstantUnion *constArray = leftConstant->foldBinary(mOp, rightConstant, diagnostics);
// Nodes may be constant folded without being qualified as constant.
TQualifier resultQualifier = EvqConst;
@@ -917,7 +916,9 @@
//
// Returns the constant value to keep using or nullptr.
//
-TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op, TIntermConstantUnion *rightNode, TInfoSink &infoSink)
+TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op,
+ TIntermConstantUnion *rightNode,
+ TDiagnostics *diagnostics)
{
const TConstantUnion *leftArray = getUnionArrayPointer();
const TConstantUnion *rightArray = rightNode->getUnionArrayPointer();
@@ -966,14 +967,7 @@
case EOpMatrixTimesMatrix:
{
- if (getType().getBasicType() != EbtFloat ||
- rightNode->getBasicType() != EbtFloat)
- {
- infoSink.info.message(
- EPrefixInternalError, getLine(),
- "Constant Folding cannot be done for matrix multiply");
- return nullptr;
- }
+ ASSERT(getType().getBasicType() == EbtFloat && rightNode->getBasicType() == EbtFloat);
const int leftCols = getCols();
const int leftRows = getRows();
@@ -1011,8 +1005,8 @@
case EbtFloat:
if (rightArray[i] == 0.0f)
{
- infoSink.info.message(EPrefixWarning, getLine(),
- "Divide by zero error during constant folding");
+ diagnostics->warning(
+ getLine(), "Divide by zero error during constant folding", "/", "");
resultArray[i].setFConst(leftArray[i].getFConst() < 0 ? -FLT_MAX : FLT_MAX);
}
else
@@ -1025,8 +1019,8 @@
case EbtInt:
if (rightArray[i] == 0)
{
- infoSink.info.message(EPrefixWarning, getLine(),
- "Divide by zero error during constant folding");
+ diagnostics->warning(
+ getLine(), "Divide by zero error during constant folding", "/", "");
resultArray[i].setIConst(INT_MAX);
}
else
@@ -1046,8 +1040,8 @@
case EbtUInt:
if (rightArray[i] == 0)
{
- infoSink.info.message(EPrefixWarning, getLine(),
- "Divide by zero error during constant folding");
+ diagnostics->warning(
+ getLine(), "Divide by zero error during constant folding", "/", "");
resultArray[i].setUConst(UINT_MAX);
}
else
@@ -1065,9 +1059,8 @@
break;
default:
- infoSink.info.message(EPrefixInternalError, getLine(),
- "Constant folding cannot be done for \"/\"");
- return nullptr;
+ UNREACHABLE();
+ return nullptr;
}
}
}
@@ -1075,12 +1068,7 @@
case EOpMatrixTimesVector:
{
- if (rightNode->getBasicType() != EbtFloat)
- {
- infoSink.info.message(EPrefixInternalError, getLine(),
- "Constant Folding cannot be done for matrix times vector");
- return nullptr;
- }
+ ASSERT(rightNode->getBasicType() == EbtFloat);
const int matrixCols = getCols();
const int matrixRows = getRows();
@@ -1102,12 +1090,7 @@
case EOpVectorTimesMatrix:
{
- if (getType().getBasicType() != EbtFloat)
- {
- infoSink.info.message(EPrefixInternalError, getLine(),
- "Constant Folding cannot be done for vector times matrix");
- return nullptr;
- }
+ ASSERT(getType().getBasicType() == EbtFloat);
const int matrixCols = rightNode->getType().getCols();
const int matrixRows = rightNode->getType().getRows();
@@ -1149,18 +1132,11 @@
case EOpLogicalXor:
{
+ ASSERT(getType().getBasicType() == EbtBool);
resultArray = new TConstantUnion[objectSize];
for (size_t i = 0; i < objectSize; i++)
{
- switch (getType().getBasicType())
- {
- case EbtBool:
- resultArray[i].setBConst(leftArray[i] != rightArray[i]);
- break;
- default:
- UNREACHABLE();
- break;
- }
+ resultArray[i].setBConst(leftArray[i] != rightArray[i]);
}
}
break;
@@ -1240,10 +1216,8 @@
break;
default:
- infoSink.info.message(
- EPrefixInternalError, getLine(),
- "Invalid operator for constant folding");
- return nullptr;
+ UNREACHABLE();
+ return nullptr;
}
return resultArray;
}
diff --git a/src/compiler/translator/IntermNode.h b/src/compiler/translator/IntermNode.h
index e06652f..7aae484 100644
--- a/src/compiler/translator/IntermNode.h
+++ b/src/compiler/translator/IntermNode.h
@@ -27,6 +27,8 @@
#include "compiler/translator/Operator.h"
#include "compiler/translator/Types.h"
+class TDiagnostics;
+
class TIntermTraverser;
class TIntermAggregate;
class TIntermBinary;
@@ -349,7 +351,9 @@
void traverse(TIntermTraverser *it) override;
bool replaceChildNode(TIntermNode *, TIntermNode *) override { return false; }
- TConstantUnion *foldBinary(TOperator op, TIntermConstantUnion *rightNode, TInfoSink &infoSink);
+ TConstantUnion *foldBinary(TOperator op,
+ TIntermConstantUnion *rightNode,
+ TDiagnostics *diagnostics);
TConstantUnion *foldUnaryWithDifferentReturnType(TOperator op, TInfoSink &infoSink);
TConstantUnion *foldUnaryWithSameReturnType(TOperator op, TInfoSink &infoSink);
@@ -406,6 +410,11 @@
: TIntermOperator(op),
mAddIndexClamp(false) {}
+ TIntermBinary(TOperator op, TIntermTyped *left, TIntermTyped *right)
+ : TIntermOperator(op), mLeft(left), mRight(right), mAddIndexClamp(false)
+ {
+ }
+
TIntermTyped *deepCopy() const override { return new TIntermBinary(*this); }
TIntermBinary *getAsBinaryNode() override { return this; };
@@ -421,8 +430,8 @@
void setRight(TIntermTyped *node) { mRight = node; }
TIntermTyped *getLeft() const { return mLeft; }
TIntermTyped *getRight() const { return mRight; }
- bool promote(TInfoSink &);
- TIntermTyped *fold(TInfoSink &infoSink);
+ bool promote();
+ TIntermTyped *fold(TDiagnostics *diagnostics);
void setAddIndexClamp() { mAddIndexClamp = true; }
bool getAddIndexClamp() { return mAddIndexClamp; }
diff --git a/src/compiler/translator/Intermediate.cpp b/src/compiler/translator/Intermediate.cpp
index 9a2e1c5..b6fefa4 100644
--- a/src/compiler/translator/Intermediate.cpp
+++ b/src/compiler/translator/Intermediate.cpp
@@ -38,53 +38,6 @@
}
//
-// Connect two nodes with a new parent that does a binary operation on the nodes.
-//
-// Returns the added node.
-//
-TIntermTyped *TIntermediate::addBinaryMath(
- TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &line)
-{
- //
- // Need a new node holding things together then. Make
- // one and promote it to the right type.
- //
- TIntermBinary *node = new TIntermBinary(op);
- node->setLine(line);
-
- node->setLeft(left);
- node->setRight(right);
- if (!node->promote(mInfoSink))
- return NULL;
-
- // See if we can fold constants.
- TIntermTyped *foldedNode = node->fold(mInfoSink);
- if (foldedNode)
- return foldedNode;
-
- return node;
-}
-
-//
-// Connect two nodes through an assignment.
-//
-// Returns the added node.
-//
-TIntermTyped *TIntermediate::addAssign(
- TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &line)
-{
- TIntermBinary *node = new TIntermBinary(op);
- node->setLine(line);
-
- node->setLeft(left);
- node->setRight(right);
- if (!node->promote(mInfoSink))
- return NULL;
-
- return node;
-}
-
-//
// Connect two nodes through an index operator, where the left node is the base
// of an array or struct, and the right node is a direct or indirect offset.
//
diff --git a/src/compiler/translator/Intermediate.h b/src/compiler/translator/Intermediate.h
index f723fc7..339daa3 100644
--- a/src/compiler/translator/Intermediate.h
+++ b/src/compiler/translator/Intermediate.h
@@ -28,10 +28,6 @@
TIntermSymbol *addSymbol(
int id, const TString &, const TType &, const TSourceLoc &);
- TIntermTyped *addBinaryMath(
- TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &);
- TIntermTyped *addAssign(
- TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &);
TIntermTyped *addIndex(
TOperator op, TIntermTyped *base, TIntermTyped *index, const TSourceLoc &);
TIntermTyped *addUnaryMath(
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index 5a79d2a..1561382 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -3631,7 +3631,18 @@
break;
}
- return intermediate.addBinaryMath(op, left, right, loc);
+ TIntermBinary *node = new TIntermBinary(op, left, right);
+ node->setLine(loc);
+
+ if (!node->promote())
+ return nullptr;
+
+ // See if we can fold constants.
+ TIntermTyped *foldedNode = node->fold(&mDiagnostics);
+ if (foldedNode)
+ return foldedNode;
+
+ return node;
}
TIntermTyped *TParseContext::addBinaryMath(TOperator op,
@@ -3674,7 +3685,13 @@
{
if (binaryOpCommonCheck(op, left, right, loc))
{
- return intermediate.addAssign(op, left, right, loc);
+ TIntermBinary *node = new TIntermBinary(op, left, right);
+ node->setLine(loc);
+
+ if (!node->promote())
+ return nullptr;
+
+ return node;
}
return nullptr;
}
diff --git a/src/compiler/translator/RemovePow.cpp b/src/compiler/translator/RemovePow.cpp
index d55e124..48fc1f9 100644
--- a/src/compiler/translator/RemovePow.cpp
+++ b/src/compiler/translator/RemovePow.cpp
@@ -52,8 +52,6 @@
{
if (IsProblematicPow(node))
{
- TInfoSink nullSink;
-
TIntermTyped *x = node->getSequence()->at(0)->getAsTyped();
TIntermTyped *y = node->getSequence()->at(1)->getAsTyped();
@@ -62,11 +60,9 @@
log->setLine(node->getLine());
log->setType(x->getType());
- TIntermBinary *mul = new TIntermBinary(EOpMul);
- mul->setLeft(y);
- mul->setRight(log);
+ TIntermBinary *mul = new TIntermBinary(EOpMul, y, log);
mul->setLine(node->getLine());
- bool valid = mul->promote(nullSink);
+ bool valid = mul->promote();
UNUSED_ASSERTION_VARIABLE(valid);
ASSERT(valid);