Commit 3272a6d3 by Olli Etuaho Committed by Commit Bot

Promote and fold indexing nodes similarly to other binary ops

Indexing nodes now get their type set in TIntermBinary::promote, same as math and logic ops. They are also constant folded through TIntermBinary::fold() instead of having special functions for constant folding them in ParseContext. Index nodes for struct and interface block member access now always have integer type, instead of sometimes having the type of the field they were used to access. Usage of TIntermBinary constructor is cleaned up so only the constructor that takes in left and right operands is used. The type of TIntermBinary nodes is always determined automatically. Together these changes make the code considerably cleaner. Note that the code for constant folding for array indexing is actually never hit because constant folding array constructors is still intentionally disabled in the code. BUG=angleproject:1490 TEST=angle_unittests Change-Id: Ifcec45257476cdb0d495c7d72e3cf2f83388e8c5 Reviewed-on: https://chromium-review.googlesource.com/377961Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
parent 57b9424f
...@@ -167,12 +167,11 @@ bool ArrayReturnValueToOutParameterTraverser::visitBranch(Visit visit, TIntermBr ...@@ -167,12 +167,11 @@ bool ArrayReturnValueToOutParameterTraverser::visitBranch(Visit visit, TIntermBr
// Instead of returning a value, assign to the out parameter and then return. // Instead of returning a value, assign to the out parameter and then return.
TIntermSequence replacements; TIntermSequence replacements;
TIntermBinary *replacementAssignment = new TIntermBinary(EOpAssign);
TIntermTyped *expression = node->getExpression(); TIntermTyped *expression = node->getExpression();
ASSERT(expression != nullptr); ASSERT(expression != nullptr);
replacementAssignment->setLeft(CreateReturnValueSymbol(expression->getType())); TIntermSymbol *returnValueSymbol = CreateReturnValueSymbol(expression->getType());
replacementAssignment->setRight(node->getExpression()); TIntermBinary *replacementAssignment =
replacementAssignment->setType(expression->getType()); new TIntermBinary(EOpAssign, returnValueSymbol, expression);
replacementAssignment->setLine(expression->getLine()); replacementAssignment->setLine(expression->getLine());
replacements.push_back(replacementAssignment); replacements.push_back(replacementAssignment);
......
...@@ -68,7 +68,7 @@ class AliasingBreaker : public TIntermTraverser ...@@ -68,7 +68,7 @@ class AliasingBreaker : public TIntermTraverser
TIntermBinary *bPlusZero = new TIntermBinary(EOpAdd, B, TIntermTyped::CreateZero(type)); TIntermBinary *bPlusZero = new TIntermBinary(EOpAdd, B, TIntermTyped::CreateZero(type));
bPlusZero->setLine(B->getLine()); bPlusZero->setLine(B->getLine());
binary->setRight(bPlusZero); binary->replaceChildNode(B, bPlusZero);
return true; return true;
} }
......
...@@ -101,10 +101,8 @@ bool DeferGlobalInitializersTraverser::visitBinary(Visit visit, TIntermBinary *n ...@@ -101,10 +101,8 @@ bool DeferGlobalInitializersTraverser::visitBinary(Visit visit, TIntermBinary *n
// Deferral is done also in any cases where the variable has not been constant folded, // Deferral is done also in any cases where the variable has not been constant folded,
// since otherwise there's a chance that HLSL output will generate extra statements // since otherwise there's a chance that HLSL output will generate extra statements
// from the initializer expression. // from the initializer expression.
TIntermBinary *deferredInit = new TIntermBinary(EOpAssign); TIntermBinary *deferredInit =
deferredInit->setLeft(symbolNode->deepCopy()); new TIntermBinary(EOpAssign, symbolNode->deepCopy(), node->getRight());
deferredInit->setRight(node->getRight());
deferredInit->setType(node->getType());
mDeferredInitializers.push_back(deferredInit); mDeferredInitializers.push_back(deferredInit);
// Change const global to a regular global if its initialization is deferred. // Change const global to a regular global if its initialization is deferred.
......
...@@ -47,17 +47,13 @@ class GLFragColorBroadcastTraverser : public TIntermTraverser ...@@ -47,17 +47,13 @@ class GLFragColorBroadcastTraverser : public TIntermTraverser
TIntermBinary *GLFragColorBroadcastTraverser::constructGLFragDataNode(int index) const TIntermBinary *GLFragColorBroadcastTraverser::constructGLFragDataNode(int index) const
{ {
TType gl_FragDataElementType = TType(EbtFloat, 4); TType gl_FragDataType = TType(EbtFloat, EbpMedium, EvqFragData, 4);
TType gl_FragDataType = gl_FragDataElementType;
gl_FragDataType.setArraySize(mMaxDrawBuffers); gl_FragDataType.setArraySize(mMaxDrawBuffers);
TIntermSymbol *symbol = new TIntermSymbol(0, "gl_FragData", gl_FragDataType); TIntermSymbol *symbol = new TIntermSymbol(0, "gl_FragData", gl_FragDataType);
TIntermTyped *indexNode = TIntermTyped::CreateIndexNode(index); TIntermTyped *indexNode = TIntermTyped::CreateIndexNode(index);
TIntermBinary *binary = new TIntermBinary(EOpIndexDirect); TIntermBinary *binary = new TIntermBinary(EOpIndexDirect, symbol, indexNode);
binary->setLeft(symbol);
binary->setRight(indexNode);
binary->setType(gl_FragDataElementType);
return binary; return binary;
} }
......
...@@ -124,10 +124,7 @@ bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node) ...@@ -124,10 +124,7 @@ bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node)
// Create a chain of n-1 multiples. // Create a chain of n-1 multiples.
for (int i = 1; i < n; ++i) for (int i = 1; i < n; ++i)
{ {
TIntermBinary *mul = new TIntermBinary(EOpMul); TIntermBinary *mul = new TIntermBinary(EOpMul, current, createTempSymbol(lhs->getType()));
mul->setLeft(current);
mul->setRight(createTempSymbol(lhs->getType()));
mul->setType(node->getType());
mul->setLine(node->getLine()); mul->setLine(node->getLine());
current = mul; current = mul;
} }
...@@ -138,9 +135,7 @@ bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node) ...@@ -138,9 +135,7 @@ bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node)
TConstantUnion *oneVal = new TConstantUnion(); TConstantUnion *oneVal = new TConstantUnion();
oneVal->setFConst(1.0f); oneVal->setFConst(1.0f);
TIntermConstantUnion *oneNode = new TIntermConstantUnion(oneVal, node->getType()); TIntermConstantUnion *oneNode = new TIntermConstantUnion(oneVal, node->getType());
TIntermBinary *div = new TIntermBinary(EOpDiv); TIntermBinary *div = new TIntermBinary(EOpDiv, oneNode, current);
div->setLeft(oneNode);
div->setRight(current);
current = div; current = div;
} }
......
...@@ -99,10 +99,9 @@ void VariableInitializer::insertInitCode(TIntermSequence *sequence) ...@@ -99,10 +99,9 @@ void VariableInitializer::insertInitCode(TIntermSequence *sequence)
for (unsigned int i = 0; i < var.arraySize; ++i) for (unsigned int i = 0; i < var.arraySize; ++i)
{ {
TIntermBinary *element = new TIntermBinary(EOpIndexDirect); TIntermSymbol *arraySymbol = new TIntermSymbol(0, name, type);
element->setLeft(new TIntermSymbol(0, name, type)); TIntermBinary *element = new TIntermBinary(EOpIndexDirect, arraySymbol,
element->setRight(TIntermTyped::CreateIndexNode(i)); TIntermTyped::CreateIndexNode(i));
element->setType(elementType);
TIntermTyped *zero = TIntermTyped::CreateZero(elementType); TIntermTyped *zero = TIntermTyped::CreateZero(elementType);
TIntermBinary *assignment = new TIntermBinary(EOpAssign, element, zero); TIntermBinary *assignment = new TIntermBinary(EOpAssign, element, zero);
......
...@@ -93,7 +93,7 @@ float VectorDotProduct(const TConstantUnion *paramArray1, ...@@ -93,7 +93,7 @@ float VectorDotProduct(const TConstantUnion *paramArray1,
return result; return result;
} }
TIntermTyped *CreateFoldedNode(TConstantUnion *constArray, TIntermTyped *CreateFoldedNode(const TConstantUnion *constArray,
const TIntermTyped *originalNode, const TIntermTyped *originalNode,
TQualifier qualifier) TQualifier qualifier)
{ {
...@@ -680,8 +680,6 @@ TIntermBinary::TIntermBinary(TOperator op, TIntermTyped *left, TIntermTyped *rig ...@@ -680,8 +680,6 @@ TIntermBinary::TIntermBinary(TOperator op, TIntermTyped *left, TIntermTyped *rig
// //
void TIntermBinary::promote() void TIntermBinary::promote()
{ {
ASSERT(mLeft->isArray() == mRight->isArray());
ASSERT(!isMultiplication() || ASSERT(!isMultiplication() ||
mOp == GetMulOpBasedOnOperands(mLeft->getType(), mRight->getType())); mOp == GetMulOpBasedOnOperands(mLeft->getType(), mRight->getType()));
...@@ -689,11 +687,6 @@ void TIntermBinary::promote() ...@@ -689,11 +687,6 @@ void TIntermBinary::promote()
// operand. Then only deviations from this need be coded. // operand. Then only deviations from this need be coded.
setType(mLeft->getType()); setType(mLeft->getType());
// The result gets promoted to the highest precision.
TPrecision higherPrecision = GetHigherPrecision(
mLeft->getPrecision(), mRight->getPrecision());
getTypePointer()->setPrecision(higherPrecision);
TQualifier resultQualifier = EvqConst; TQualifier resultQualifier = EvqConst;
// Binary operations results in temporary variables unless both // Binary operations results in temporary variables unless both
// operands are const. // operands are const.
...@@ -703,6 +696,62 @@ void TIntermBinary::promote() ...@@ -703,6 +696,62 @@ void TIntermBinary::promote()
getTypePointer()->setQualifier(EvqTemporary); getTypePointer()->setQualifier(EvqTemporary);
} }
// Handle indexing ops.
switch (mOp)
{
case EOpIndexDirect:
case EOpIndexIndirect:
if (mLeft->isArray())
{
mType.clearArrayness();
}
else if (mLeft->isMatrix())
{
setType(TType(mLeft->getBasicType(), mLeft->getPrecision(), resultQualifier,
static_cast<unsigned char>(mLeft->getRows())));
}
else if (mLeft->isVector())
{
setType(TType(mLeft->getBasicType(), mLeft->getPrecision(), resultQualifier));
}
else
{
UNREACHABLE();
}
return;
case EOpIndexDirectStruct:
{
const TFieldList &fields = mLeft->getType().getStruct()->fields();
const int i = mRight->getAsConstantUnion()->getIConst(0);
setType(*fields[i]->type());
getTypePointer()->setQualifier(resultQualifier);
return;
}
case EOpIndexDirectInterfaceBlock:
{
const TFieldList &fields = mLeft->getType().getInterfaceBlock()->fields();
const int i = mRight->getAsConstantUnion()->getIConst(0);
setType(*fields[i]->type());
getTypePointer()->setQualifier(resultQualifier);
return;
}
case EOpVectorSwizzle:
{
auto numFields = mRight->getAsAggregate()->getSequence()->size();
setType(TType(mLeft->getBasicType(), mLeft->getPrecision(), resultQualifier,
static_cast<unsigned char>(numFields)));
return;
}
default:
break;
}
ASSERT(mLeft->isArray() == mRight->isArray());
// The result gets promoted to the highest precision.
TPrecision higherPrecision = GetHigherPrecision(mLeft->getPrecision(), mRight->getPrecision());
getTypePointer()->setPrecision(higherPrecision);
const int nominalSize = const int nominalSize =
std::max(mLeft->getNominalSize(), mRight->getNominalSize()); std::max(mLeft->getNominalSize(), mRight->getNominalSize());
...@@ -722,8 +771,8 @@ void TIntermBinary::promote() ...@@ -722,8 +771,8 @@ void TIntermBinary::promote()
case EOpGreaterThan: case EOpGreaterThan:
case EOpLessThanEqual: case EOpLessThanEqual:
case EOpGreaterThanEqual: case EOpGreaterThanEqual:
setType(TType(EbtBool, EbpUndefined, resultQualifier)); setType(TType(EbtBool, EbpUndefined, resultQualifier));
break; break;
// //
// And and Or operate on conditionals // And and Or operate on conditionals
...@@ -828,8 +877,8 @@ void TIntermBinary::promote() ...@@ -828,8 +877,8 @@ void TIntermBinary::promote()
case EOpIndexIndirect: case EOpIndexIndirect:
case EOpIndexDirectInterfaceBlock: case EOpIndexDirectInterfaceBlock:
case EOpIndexDirectStruct: case EOpIndexDirectStruct:
// TODO (oetuaho): These ops could be handled here as well (should be done closer to the case EOpVectorSwizzle:
// top of the function). // These ops should be already fully handled.
UNREACHABLE(); UNREACHABLE();
break; break;
default: default:
...@@ -838,18 +887,103 @@ void TIntermBinary::promote() ...@@ -838,18 +887,103 @@ void TIntermBinary::promote()
} }
} }
TIntermTyped *TIntermBinary::fold(TDiagnostics *diagnostics) const TConstantUnion *TIntermConstantUnion::foldIndexing(int index)
{ {
TIntermConstantUnion *leftConstant = mLeft->getAsConstantUnion(); if (isArray())
TIntermConstantUnion *rightConstant = mRight->getAsConstantUnion();
if (leftConstant == nullptr || rightConstant == nullptr)
{ {
ASSERT(index < static_cast<int>(getType().getArraySize()));
TType arrayElementType = getType();
arrayElementType.clearArrayness();
size_t arrayElementSize = arrayElementType.getObjectSize();
return &mUnionArrayPointer[arrayElementSize * index];
}
else if (isMatrix())
{
ASSERT(index < getType().getCols());
int size = getType().getRows();
return &mUnionArrayPointer[size * index];
}
else if (isVector())
{
ASSERT(index < getType().getNominalSize());
return &mUnionArrayPointer[index];
}
else
{
UNREACHABLE();
return nullptr; return nullptr;
} }
TConstantUnion *constArray = leftConstant->foldBinary(mOp, rightConstant, diagnostics); }
// Nodes may be constant folded without being qualified as constant. TIntermTyped *TIntermBinary::fold(TDiagnostics *diagnostics)
return CreateFoldedNode(constArray, this, mType.getQualifier()); {
TIntermConstantUnion *leftConstant = mLeft->getAsConstantUnion();
TIntermConstantUnion *rightConstant = mRight->getAsConstantUnion();
switch (mOp)
{
case EOpIndexDirect:
{
if (leftConstant == nullptr || rightConstant == nullptr)
{
return nullptr;
}
int index = rightConstant->getIConst(0);
const TConstantUnion *constArray = leftConstant->foldIndexing(index);
return CreateFoldedNode(constArray, this, mType.getQualifier());
}
case EOpIndexDirectStruct:
{
if (leftConstant == nullptr || rightConstant == nullptr)
{
return nullptr;
}
const TFieldList &fields = mLeft->getType().getStruct()->fields();
size_t index = static_cast<size_t>(rightConstant->getIConst(0));
size_t previousFieldsSize = 0;
for (size_t i = 0; i < index; ++i)
{
previousFieldsSize += fields[i]->type()->getObjectSize();
}
const TConstantUnion *constArray = leftConstant->getUnionArrayPointer();
return CreateFoldedNode(constArray + previousFieldsSize, this, mType.getQualifier());
}
case EOpIndexIndirect:
case EOpIndexDirectInterfaceBlock:
// Can never be constant folded.
return nullptr;
case EOpVectorSwizzle:
{
if (leftConstant == nullptr)
{
return nullptr;
}
TIntermAggregate *fieldsAgg = mRight->getAsAggregate();
TIntermSequence *fieldsSequence = fieldsAgg->getSequence();
size_t numFields = fieldsSequence->size();
TConstantUnion *constArray = new TConstantUnion[numFields];
for (size_t i = 0; i < numFields; i++)
{
int fieldOffset = fieldsSequence->at(i)->getAsConstantUnion()->getIConst(0);
constArray[i] = *leftConstant->foldIndexing(fieldOffset);
}
return CreateFoldedNode(constArray, this, mType.getQualifier());
}
default:
{
if (leftConstant == nullptr || rightConstant == nullptr)
{
return nullptr;
}
TConstantUnion *constArray = leftConstant->foldBinary(mOp, rightConstant, diagnostics);
// Nodes may be constant folded without being qualified as constant.
return CreateFoldedNode(constArray, this, mType.getQualifier());
}
}
} }
TIntermTyped *TIntermUnary::fold(TDiagnostics *diagnostics) TIntermTyped *TIntermUnary::fold(TDiagnostics *diagnostics)
......
...@@ -359,6 +359,7 @@ class TIntermConstantUnion : public TIntermTyped ...@@ -359,6 +359,7 @@ class TIntermConstantUnion : public TIntermTyped
TConstantUnion *foldBinary(TOperator op, TConstantUnion *foldBinary(TOperator op,
TIntermConstantUnion *rightNode, TIntermConstantUnion *rightNode,
TDiagnostics *diagnostics); TDiagnostics *diagnostics);
const TConstantUnion *foldIndexing(int index);
TConstantUnion *foldUnaryNonComponentWise(TOperator op); TConstantUnion *foldUnaryNonComponentWise(TOperator op);
TConstantUnion *foldUnaryComponentWise(TOperator op, TDiagnostics *diagnostics); TConstantUnion *foldUnaryComponentWise(TOperator op, TDiagnostics *diagnostics);
...@@ -413,12 +414,7 @@ class TIntermOperator : public TIntermTyped ...@@ -413,12 +414,7 @@ class TIntermOperator : public TIntermTyped
class TIntermBinary : public TIntermOperator class TIntermBinary : public TIntermOperator
{ {
public: public:
TIntermBinary(TOperator op)
: TIntermOperator(op),
mAddIndexClamp(false) {}
// This constructor determines the type of the binary node based on the operands and op. // This constructor determines the type of the binary node based on the operands and op.
// This is only supported for math/logical ops, not indexing.
TIntermBinary(TOperator op, TIntermTyped *left, TIntermTyped *right); TIntermBinary(TOperator op, TIntermTyped *left, TIntermTyped *right);
TIntermTyped *deepCopy() const override { return new TIntermBinary(*this); } TIntermTyped *deepCopy() const override { return new TIntermBinary(*this); }
...@@ -435,8 +431,6 @@ class TIntermBinary : public TIntermOperator ...@@ -435,8 +431,6 @@ class TIntermBinary : public TIntermOperator
return isAssignment() || mLeft->hasSideEffects() || mRight->hasSideEffects(); return isAssignment() || mLeft->hasSideEffects() || mRight->hasSideEffects();
} }
void setLeft(TIntermTyped *node) { mLeft = node; }
void setRight(TIntermTyped *node) { mRight = node; }
TIntermTyped *getLeft() const { return mLeft; } TIntermTyped *getLeft() const { return mLeft; }
TIntermTyped *getRight() const { return mRight; } TIntermTyped *getRight() const { return mRight; }
TIntermTyped *fold(TDiagnostics *diagnostics); TIntermTyped *fold(TDiagnostics *diagnostics);
......
...@@ -147,10 +147,7 @@ TIntermAggregate *TIntermTraverser::createTempInitDeclaration(TIntermTyped *init ...@@ -147,10 +147,7 @@ TIntermAggregate *TIntermTraverser::createTempInitDeclaration(TIntermTyped *init
ASSERT(initializer != nullptr); ASSERT(initializer != nullptr);
TIntermSymbol *tempSymbol = createTempSymbol(initializer->getType(), qualifier); TIntermSymbol *tempSymbol = createTempSymbol(initializer->getType(), qualifier);
TIntermAggregate *tempDeclaration = new TIntermAggregate(EOpDeclaration); TIntermAggregate *tempDeclaration = new TIntermAggregate(EOpDeclaration);
TIntermBinary *tempInit = new TIntermBinary(EOpInitialize); TIntermBinary *tempInit = new TIntermBinary(EOpInitialize, tempSymbol, initializer);
tempInit->setLeft(tempSymbol);
tempInit->setRight(initializer);
tempInit->setType(tempSymbol->getType());
tempDeclaration->getSequence()->push_back(tempInit); tempDeclaration->getSequence()->push_back(tempInit);
return tempDeclaration; return tempDeclaration;
} }
...@@ -164,10 +161,7 @@ TIntermBinary *TIntermTraverser::createTempAssignment(TIntermTyped *rightNode) ...@@ -164,10 +161,7 @@ TIntermBinary *TIntermTraverser::createTempAssignment(TIntermTyped *rightNode)
{ {
ASSERT(rightNode != nullptr); ASSERT(rightNode != nullptr);
TIntermSymbol *tempSymbol = createTempSymbol(rightNode->getType()); TIntermSymbol *tempSymbol = createTempSymbol(rightNode->getType());
TIntermBinary *assignment = new TIntermBinary(EOpAssign); TIntermBinary *assignment = new TIntermBinary(EOpAssign, tempSymbol, rightNode);
assignment->setLeft(tempSymbol);
assignment->setRight(rightNode);
assignment->setType(tempSymbol->getType());
return assignment; return assignment;
} }
......
...@@ -44,15 +44,20 @@ TIntermSymbol *TIntermediate::addSymbol( ...@@ -44,15 +44,20 @@ TIntermSymbol *TIntermediate::addSymbol(
// Returns the added node. // Returns the added node.
// The caller should set the type of the returned node. // The caller should set the type of the returned node.
// //
TIntermTyped *TIntermediate::addIndex( TIntermTyped *TIntermediate::addIndex(TOperator op,
TOperator op, TIntermTyped *base, TIntermTyped *index, const TSourceLoc &line) TIntermTyped *base,
TIntermTyped *index,
const TSourceLoc &line,
TDiagnostics *diagnostics)
{ {
TIntermBinary *node = new TIntermBinary(op); TIntermBinary *node = new TIntermBinary(op, base, index);
node->setLine(line); node->setLine(line);
node->setLeft(base);
node->setRight(index);
// caller should set the type TIntermTyped *folded = node->fold(diagnostics);
if (folded)
{
return folded;
}
return node; return node;
} }
...@@ -312,6 +317,7 @@ TIntermTyped *TIntermediate::addSwizzle( ...@@ -312,6 +317,7 @@ TIntermTyped *TIntermediate::addSwizzle(
{ {
TIntermAggregate *node = new TIntermAggregate(EOpSequence); TIntermAggregate *node = new TIntermAggregate(EOpSequence);
node->getTypePointer()->setQualifier(EvqConst);
node->setLine(line); node->setLine(line);
TIntermConstantUnion *constIntNode; TIntermConstantUnion *constIntNode;
......
...@@ -26,8 +26,11 @@ class TIntermediate ...@@ -26,8 +26,11 @@ class TIntermediate
TIntermSymbol *addSymbol( TIntermSymbol *addSymbol(
int id, const TString &, const TType &, const TSourceLoc &); int id, const TString &, const TType &, const TSourceLoc &);
TIntermTyped *addIndex( TIntermTyped *addIndex(TOperator op,
TOperator op, TIntermTyped *base, TIntermTyped *index, const TSourceLoc &); TIntermTyped *base,
TIntermTyped *index,
const TSourceLoc &line,
TDiagnostics *diagnostics);
TIntermTyped *addUnaryMath( TIntermTyped *addUnaryMath(
TOperator op, TIntermTyped *child, const TSourceLoc &line, const TType *funcReturnType); TOperator op, TIntermTyped *child, const TSourceLoc &line, const TType *funcReturnType);
TIntermAggregate *growAggregate( TIntermAggregate *growAggregate(
......
...@@ -2385,98 +2385,6 @@ TIntermTyped *TParseContext::addConstructor(TIntermNode *arguments, ...@@ -2385,98 +2385,6 @@ TIntermTyped *TParseContext::addConstructor(TIntermNode *arguments,
return constructor; return constructor;
} }
// This function returns vector field(s) being accessed from a constant vector.
TIntermConstantUnion *TParseContext::foldVectorSwizzle(TVectorFields &fields,
TIntermConstantUnion *baseNode,
const TSourceLoc &location)
{
const TConstantUnion *unionArray = baseNode->getUnionArrayPointer();
ASSERT(unionArray);
TConstantUnion *constArray = new TConstantUnion[fields.num];
const auto &type = baseNode->getType();
for (int i = 0; i < fields.num; i++)
{
// Out-of-range indices should already be checked.
ASSERT(fields.offsets[i] < type.getNominalSize());
constArray[i] = unionArray[fields.offsets[i]];
}
return intermediate.addConstantUnion(constArray, type, location);
}
// This function returns the column vector being accessed from a constant matrix.
TIntermConstantUnion *TParseContext::foldMatrixSubscript(int index,
TIntermConstantUnion *baseNode,
const TSourceLoc &location)
{
ASSERT(index < baseNode->getType().getCols());
const TConstantUnion *unionArray = baseNode->getUnionArrayPointer();
int size = baseNode->getType().getRows();
return intermediate.addConstantUnion(&unionArray[size * index], baseNode->getType(), location);
}
// This function returns an element of an array accessed from a constant array.
TIntermConstantUnion *TParseContext::foldArraySubscript(int index,
TIntermConstantUnion *baseNode,
const TSourceLoc &location)
{
ASSERT(index < static_cast<int>(baseNode->getArraySize()));
TType arrayElementType = baseNode->getType();
arrayElementType.clearArrayness();
size_t arrayElementSize = arrayElementType.getObjectSize();
const TConstantUnion *unionArray = baseNode->getUnionArrayPointer();
return intermediate.addConstantUnion(&unionArray[arrayElementSize * index], baseNode->getType(),
location);
}
//
// This function returns the value of a particular field inside a constant structure from the symbol
// table.
// If there is an embedded/nested struct, it appropriately calls addConstStructNested or
// addConstStructFromAggr function and returns the parse-tree with the values of the embedded/nested
// struct.
//
TIntermTyped *TParseContext::addConstStruct(const TString &identifier,
TIntermTyped *node,
const TSourceLoc &line)
{
const TFieldList &fields = node->getType().getStruct()->fields();
size_t instanceSize = 0;
for (size_t index = 0; index < fields.size(); ++index)
{
if (fields[index]->name() == identifier)
{
break;
}
else
{
instanceSize += fields[index]->type()->getObjectSize();
}
}
TIntermTyped *typedNode;
TIntermConstantUnion *tempConstantNode = node->getAsConstantUnion();
if (tempConstantNode)
{
const TConstantUnion *constArray = tempConstantNode->getUnionArrayPointer();
// type will be changed in the calling function
typedNode = intermediate.addConstantUnion(constArray + instanceSize,
tempConstantNode->getType(), line);
}
else
{
error(line, "Cannot offset into the structure", "Error");
return nullptr;
}
return typedNode;
}
// //
// Interface/uniform blocks // Interface/uniform blocks
// //
...@@ -2697,8 +2605,6 @@ TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression, ...@@ -2697,8 +2605,6 @@ TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression,
const TSourceLoc &location, const TSourceLoc &location,
TIntermTyped *indexExpression) TIntermTyped *indexExpression)
{ {
TIntermTyped *indexedExpression = NULL;
if (!baseExpression->isArray() && !baseExpression->isMatrix() && !baseExpression->isVector()) if (!baseExpression->isArray() && !baseExpression->isMatrix() && !baseExpression->isVector())
{ {
if (baseExpression->getAsSymbolNode()) if (baseExpression->getAsSymbolNode())
...@@ -2710,6 +2616,11 @@ TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression, ...@@ -2710,6 +2616,11 @@ TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression,
{ {
error(location, " left of '[' is not of type array, matrix, or vector ", "expression"); error(location, " left of '[' is not of type array, matrix, or vector ", "expression");
} }
TConstantUnion *unionArray = new TConstantUnion[1];
unionArray->setFConst(0.0f);
return intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConst),
location);
} }
TIntermConstantUnion *indexConstantUnion = indexExpression->getAsConstantUnion(); TIntermConstantUnion *indexConstantUnion = indexExpression->getAsConstantUnion();
...@@ -2739,151 +2650,78 @@ TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression, ...@@ -2739,151 +2650,78 @@ TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression,
if (indexConstantUnion) if (indexConstantUnion)
{ {
// If the index is not qualified as constant, the behavior in the spec is undefined. This // If an out-of-range index is not qualified as constant, the behavior in the spec is
// applies even if ANGLE has been able to constant fold it (ANGLE may constant fold // undefined. This applies even if ANGLE has been able to constant fold it (ANGLE may
// expressions that are not constant expressions). The most compatible way to handle this // constant fold expressions that are not constant expressions). The most compatible way to
// case is to report a warning instead of an error and force the index to be in the // handle this case is to report a warning instead of an error and force the index to be in
// correct range. // the correct range.
bool outOfRangeIndexIsError = indexExpression->getQualifier() == EvqConst; bool outOfRangeIndexIsError = indexExpression->getQualifier() == EvqConst;
int index = indexConstantUnion->getIConst(0); int index = indexConstantUnion->getIConst(0);
if (!baseExpression->isArray())
{
// Array checks are done later because a different error message might be generated
// based on the index in some cases.
if (baseExpression->isVector())
{
index = checkIndexOutOfRange(outOfRangeIndexIsError, location, index,
baseExpression->getType().getNominalSize(),
"vector field selection out of range", "[]");
}
else if (baseExpression->isMatrix())
{
index = checkIndexOutOfRange(outOfRangeIndexIsError, location, index,
baseExpression->getType().getCols(),
"matrix field selection out of range", "[]");
}
}
TIntermConstantUnion *baseConstantUnion = baseExpression->getAsConstantUnion(); int safeIndex = -1;
if (baseConstantUnion)
{
if (baseExpression->isArray())
{
index = checkIndexOutOfRange(outOfRangeIndexIsError, location, index,
baseExpression->getArraySize(),
"array index out of range", "[]");
// Constant folding for array indexing.
indexedExpression = foldArraySubscript(index, baseConstantUnion, location);
}
else if (baseExpression->isVector())
{
// Constant folding for vector indexing - reusing vector swizzle folding.
TVectorFields fields;
fields.num = 1;
fields.offsets[0] = index;
indexedExpression = foldVectorSwizzle(fields, baseConstantUnion, location);
}
else if (baseExpression->isMatrix())
{
// Constant folding for matrix indexing.
indexedExpression = foldMatrixSubscript(index, baseConstantUnion, location);
}
}
else
{
int safeIndex = -1;
if (baseExpression->isArray()) if (baseExpression->isArray())
{
if (baseExpression->getQualifier() == EvqFragData && index > 0)
{ {
if (baseExpression->getQualifier() == EvqFragData && index > 0) if (mShaderSpec == SH_WEBGL2_SPEC)
{ {
if (mShaderSpec == SH_WEBGL2_SPEC) // Error has been already generated if index is not const.
if (indexExpression->getQualifier() == EvqConst)
{ {
// Error has been already generated if index is not const. error(location, "", "[",
if (indexExpression->getQualifier() == EvqConst) "array index for gl_FragData must be constant zero");
{
error(location, "", "[",
"array index for gl_FragData must be constant zero");
}
safeIndex = 0;
}
else if (!isExtensionEnabled("GL_EXT_draw_buffers"))
{
outOfRangeError(outOfRangeIndexIsError, location, "", "[",
"array index for gl_FragData must be zero when "
"GL_EXT_draw_buffers is disabled");
safeIndex = 0;
} }
safeIndex = 0;
} }
// Only do generic out-of-range check if similar error hasn't already been reported. else if (!isExtensionEnabled("GL_EXT_draw_buffers"))
if (safeIndex < 0)
{ {
safeIndex = checkIndexOutOfRange(outOfRangeIndexIsError, location, index, outOfRangeError(outOfRangeIndexIsError, location, "", "[",
baseExpression->getArraySize(), "array index for gl_FragData must be zero when "
"array index out of range", "[]"); "GL_EXT_draw_buffers is disabled");
safeIndex = 0;
} }
} }
// Only do generic out-of-range check if similar error hasn't already been reported.
// Data of constant unions can't be changed, because it may be shared with other if (safeIndex < 0)
// constant unions or even builtins, like gl_MaxDrawBuffers. Instead use a new
// sanitized object.
if (safeIndex != -1)
{ {
TConstantUnion *safeConstantUnion = new TConstantUnion(); safeIndex = checkIndexOutOfRange(outOfRangeIndexIsError, location, index,
safeConstantUnion->setIConst(safeIndex); baseExpression->getArraySize(),
indexConstantUnion->replaceConstantUnion(safeConstantUnion); "array index out of range", "[]");
} }
indexedExpression =
intermediate.addIndex(EOpIndexDirect, baseExpression, indexExpression, location);
} }
} else if (baseExpression->isMatrix())
else {
{ safeIndex = checkIndexOutOfRange(outOfRangeIndexIsError, location, index,
indexedExpression = baseExpression->getType().getCols(),
intermediate.addIndex(EOpIndexIndirect, baseExpression, indexExpression, location); "matrix field selection out of range", "[]");
} }
else if (baseExpression->isVector())
{
safeIndex = checkIndexOutOfRange(outOfRangeIndexIsError, location, index,
baseExpression->getType().getNominalSize(),
"vector field selection out of range", "[]");
}
if (indexedExpression == 0) ASSERT(safeIndex >= 0);
{ // Data of constant unions can't be changed, because it may be shared with other
TConstantUnion *unionArray = new TConstantUnion[1]; // constant unions or even builtins, like gl_MaxDrawBuffers. Instead use a new
unionArray->setFConst(0.0f); // sanitized object.
indexedExpression = if (safeIndex != index)
intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConst), location); {
} TConstantUnion *safeConstantUnion = new TConstantUnion();
else if (baseExpression->isArray()) safeConstantUnion->setIConst(safeIndex);
{ indexConstantUnion->replaceConstantUnion(safeConstantUnion);
TType indexedType = baseExpression->getType(); }
indexedType.clearArrayness();
indexedExpression->setType(indexedType);
}
else if (baseExpression->isMatrix())
{
indexedExpression->setType(TType(baseExpression->getBasicType(),
baseExpression->getPrecision(), EvqTemporary,
static_cast<unsigned char>(baseExpression->getRows())));
}
else if (baseExpression->isVector())
{
indexedExpression->setType(
TType(baseExpression->getBasicType(), baseExpression->getPrecision(), EvqTemporary));
}
else
{
indexedExpression->setType(baseExpression->getType());
}
if (baseExpression->getType().getQualifier() == EvqConst && return intermediate.addIndex(EOpIndexDirect, baseExpression, indexExpression, location,
indexExpression->getType().getQualifier() == EvqConst) &mDiagnostics);
{
indexedExpression->getTypePointer()->setQualifier(EvqConst);
} }
else else
{ {
indexedExpression->getTypePointer()->setQualifier(EvqTemporary); return intermediate.addIndex(EOpIndexIndirect, baseExpression, indexExpression, location,
&mDiagnostics);
} }
return indexedExpression;
} }
int TParseContext::checkIndexOutOfRange(bool outOfRangeIndexIsError, int TParseContext::checkIndexOutOfRange(bool outOfRangeIndexIsError,
...@@ -2916,11 +2754,10 @@ TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre ...@@ -2916,11 +2754,10 @@ TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre
const TString &fieldString, const TString &fieldString,
const TSourceLoc &fieldLocation) const TSourceLoc &fieldLocation)
{ {
TIntermTyped *indexedExpression = NULL;
if (baseExpression->isArray()) if (baseExpression->isArray())
{ {
error(fieldLocation, "cannot apply dot operator to an array", "."); error(fieldLocation, "cannot apply dot operator to an array", ".");
return baseExpression;
} }
if (baseExpression->isVector()) if (baseExpression->isVector())
...@@ -2933,41 +2770,21 @@ TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre ...@@ -2933,41 +2770,21 @@ TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre
fields.offsets[0] = 0; fields.offsets[0] = 0;
} }
if (baseExpression->getAsConstantUnion()) TIntermTyped *index = intermediate.addSwizzle(fields, fieldLocation);
{ return intermediate.addIndex(EOpVectorSwizzle, baseExpression, index, dotLocation,
// constant folding for vector fields &mDiagnostics);
indexedExpression =
foldVectorSwizzle(fields, baseExpression->getAsConstantUnion(), fieldLocation);
}
else
{
TIntermTyped *index = intermediate.addSwizzle(fields, fieldLocation);
indexedExpression =
intermediate.addIndex(EOpVectorSwizzle, baseExpression, index, dotLocation);
}
if (indexedExpression == nullptr)
{
indexedExpression = baseExpression;
}
else
{
// Note that the qualifier set here will be corrected later.
indexedExpression->setType(TType(baseExpression->getBasicType(),
baseExpression->getPrecision(), EvqTemporary,
static_cast<unsigned char>(fields.num)));
}
} }
else if (baseExpression->getBasicType() == EbtStruct) else if (baseExpression->getBasicType() == EbtStruct)
{ {
bool fieldFound = false;
const TFieldList &fields = baseExpression->getType().getStruct()->fields(); const TFieldList &fields = baseExpression->getType().getStruct()->fields();
if (fields.empty()) if (fields.empty())
{ {
error(dotLocation, "structure has no fields", "Internal Error"); error(dotLocation, "structure has no fields", "Internal Error");
indexedExpression = baseExpression; return baseExpression;
} }
else else
{ {
bool fieldFound = false;
unsigned int i; unsigned int i;
for (i = 0; i < fields.size(); ++i) for (i = 0; i < fields.size(); ++i)
{ {
...@@ -2979,47 +2796,29 @@ TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre ...@@ -2979,47 +2796,29 @@ TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre
} }
if (fieldFound) if (fieldFound)
{ {
if (baseExpression->getAsConstantUnion()) TIntermTyped *index = TIntermTyped::CreateIndexNode(i);
{ index->setLine(fieldLocation);
indexedExpression = addConstStruct(fieldString, baseExpression, dotLocation); return intermediate.addIndex(EOpIndexDirectStruct, baseExpression, index,
if (indexedExpression == 0) dotLocation, &mDiagnostics);
{
indexedExpression = baseExpression;
}
else
{
indexedExpression->setType(*fields[i]->type());
}
}
else
{
TConstantUnion *unionArray = new TConstantUnion[1];
unionArray->setIConst(i);
TIntermTyped *index = intermediate.addConstantUnion(
unionArray, *fields[i]->type(), fieldLocation);
indexedExpression = intermediate.addIndex(EOpIndexDirectStruct, baseExpression,
index, dotLocation);
indexedExpression->setType(*fields[i]->type());
}
} }
else else
{ {
error(dotLocation, " no such field in structure", fieldString.c_str()); error(dotLocation, " no such field in structure", fieldString.c_str());
indexedExpression = baseExpression; return baseExpression;
} }
} }
} }
else if (baseExpression->isInterfaceBlock()) else if (baseExpression->isInterfaceBlock())
{ {
bool fieldFound = false;
const TFieldList &fields = baseExpression->getType().getInterfaceBlock()->fields(); const TFieldList &fields = baseExpression->getType().getInterfaceBlock()->fields();
if (fields.empty()) if (fields.empty())
{ {
error(dotLocation, "interface block has no fields", "Internal Error"); error(dotLocation, "interface block has no fields", "Internal Error");
indexedExpression = baseExpression; return baseExpression;
} }
else else
{ {
bool fieldFound = false;
unsigned int i; unsigned int i;
for (i = 0; i < fields.size(); ++i) for (i = 0; i < fields.size(); ++i)
{ {
...@@ -3031,18 +2830,15 @@ TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre ...@@ -3031,18 +2830,15 @@ TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre
} }
if (fieldFound) if (fieldFound)
{ {
TConstantUnion *unionArray = new TConstantUnion[1]; TIntermTyped *index = TIntermTyped::CreateIndexNode(i);
unionArray->setIConst(i); index->setLine(fieldLocation);
TIntermTyped *index = return intermediate.addIndex(EOpIndexDirectInterfaceBlock, baseExpression, index,
intermediate.addConstantUnion(unionArray, *fields[i]->type(), fieldLocation); dotLocation, &mDiagnostics);
indexedExpression = intermediate.addIndex(EOpIndexDirectInterfaceBlock,
baseExpression, index, dotLocation);
indexedExpression->setType(*fields[i]->type());
} }
else else
{ {
error(dotLocation, " no such field in interface block", fieldString.c_str()); error(dotLocation, " no such field in interface block", fieldString.c_str());
indexedExpression = baseExpression; return baseExpression;
} }
} }
} }
...@@ -3060,19 +2856,8 @@ TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre ...@@ -3060,19 +2856,8 @@ TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre
"side", "side",
fieldString.c_str()); fieldString.c_str());
} }
indexedExpression = baseExpression; return baseExpression;
} }
if (baseExpression->getQualifier() == EvqConst)
{
indexedExpression->getTypePointer()->setQualifier(EvqConst);
}
else
{
indexedExpression->getTypePointer()->setQualifier(EvqTemporary);
}
return indexedExpression;
} }
TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierType, TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierType,
......
...@@ -284,8 +284,6 @@ class TParseContext : angle::NonCopyable ...@@ -284,8 +284,6 @@ class TParseContext : angle::NonCopyable
TFunction *fnCall, TFunction *fnCall,
const TSourceLoc &line); const TSourceLoc &line);
TIntermTyped *addConstStruct(
const TString &identifier, TIntermTyped *node, const TSourceLoc& line);
TIntermTyped *addIndexExpression(TIntermTyped *baseExpression, TIntermTyped *addIndexExpression(TIntermTyped *baseExpression,
const TSourceLoc& location, const TSourceLoc& location,
TIntermTyped *indexExpression); TIntermTyped *indexExpression);
...@@ -378,18 +376,6 @@ class TParseContext : angle::NonCopyable ...@@ -378,18 +376,6 @@ class TParseContext : angle::NonCopyable
const char *reason, const char *reason,
const char *token); const char *token);
// Constant folding for element access. Note that the returned node does not have the correct
// type - it is expected to be fixed later.
TIntermConstantUnion *foldVectorSwizzle(TVectorFields &fields,
TIntermConstantUnion *baseNode,
const TSourceLoc &location);
TIntermConstantUnion *foldMatrixSubscript(int index,
TIntermConstantUnion *baseNode,
const TSourceLoc &location);
TIntermConstantUnion *foldArraySubscript(int index,
TIntermConstantUnion *baseNode,
const TSourceLoc &location);
bool declareVariable(const TSourceLoc &line, const TString &identifier, const TType &type, TVariable **variable); bool declareVariable(const TSourceLoc &line, const TString &identifier, const TType &type, TVariable **variable);
void checkCanBeDeclaredWithoutInitializer(const TSourceLoc &line, void checkCanBeDeclaredWithoutInitializer(const TSourceLoc &line,
......
...@@ -92,21 +92,15 @@ TIntermBinary *CreateIndexDirectBaseSymbolNode(const TType &indexedType, ...@@ -92,21 +92,15 @@ TIntermBinary *CreateIndexDirectBaseSymbolNode(const TType &indexedType,
const int index, const int index,
TQualifier baseQualifier) TQualifier baseQualifier)
{ {
TIntermBinary *indexNode = new TIntermBinary(EOpIndexDirect);
indexNode->setType(fieldType);
TIntermSymbol *baseSymbol = CreateBaseSymbol(indexedType, baseQualifier); TIntermSymbol *baseSymbol = CreateBaseSymbol(indexedType, baseQualifier);
indexNode->setLeft(baseSymbol); TIntermBinary *indexNode =
indexNode->setRight(CreateIntConstantNode(index)); new TIntermBinary(EOpIndexDirect, baseSymbol, TIntermTyped::CreateIndexNode(index));
return indexNode; return indexNode;
} }
TIntermBinary *CreateAssignValueSymbolNode(TIntermTyped *targetNode, const TType &assignedValueType) TIntermBinary *CreateAssignValueSymbolNode(TIntermTyped *targetNode, const TType &assignedValueType)
{ {
TIntermBinary *assignNode = new TIntermBinary(EOpAssign); return new TIntermBinary(EOpAssign, targetNode, CreateValueSymbol(assignedValueType));
assignNode->setType(assignedValueType);
assignNode->setLeft(targetNode);
assignNode->setRight(CreateValueSymbol(assignedValueType));
return assignNode;
} }
TIntermTyped *EnsureSignedInt(TIntermTyped *node) TIntermTyped *EnsureSignedInt(TIntermTyped *node)
...@@ -256,10 +250,9 @@ TIntermAggregate *GetIndexFunctionDefinition(TType type, bool write) ...@@ -256,10 +250,9 @@ TIntermAggregate *GetIndexFunctionDefinition(TType type, bool write)
TIntermAggregate *bodyNode = new TIntermAggregate(EOpSequence); TIntermAggregate *bodyNode = new TIntermAggregate(EOpSequence);
bodyNode->getSequence()->push_back(switchNode); bodyNode->getSequence()->push_back(switchNode);
TIntermBinary *cond = new TIntermBinary(EOpLessThan); TIntermBinary *cond =
new TIntermBinary(EOpLessThan, CreateIndexSymbol(), CreateIntConstantNode(0));
cond->setType(TType(EbtBool, EbpUndefined)); cond->setType(TType(EbtBool, EbpUndefined));
cond->setLeft(CreateIndexSymbol());
cond->setRight(CreateIntConstantNode(0));
// Two blocks: one accesses (either reads or writes) the first element and returns, // Two blocks: one accesses (either reads or writes) the first element and returns,
// the other accesses the last element. // the other accesses the last element.
......
...@@ -113,16 +113,11 @@ bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node) ...@@ -113,16 +113,11 @@ bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node)
// sampler // sampler
newsequence.push_back(sequence->at(0)); newsequence.push_back(sequence->at(0));
// Position+offset
TIntermBinary *add = new TIntermBinary(EOpAdd);
add->setType(node->getType());
// Position // Position
TIntermTyped *texCoordNode = sequence->at(1)->getAsTyped(); TIntermTyped *texCoordNode = sequence->at(1)->getAsTyped();
ASSERT(texCoordNode); ASSERT(texCoordNode);
add->setLine(texCoordNode->getLine());
add->setType(texCoordNode->getType());
add->setLeft(texCoordNode);
// offset // offset
TIntermTyped *offsetNode = nullptr;
ASSERT(sequence->at(3)->getAsTyped()); ASSERT(sequence->at(3)->getAsTyped());
if (is2DArray) if (is2DArray)
{ {
...@@ -143,12 +138,16 @@ bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node) ...@@ -143,12 +138,16 @@ bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node)
ivec3Sequence.push_back(zeroNode); ivec3Sequence.push_back(zeroNode);
constructIVec3Node->insertChildNodes(0, ivec3Sequence); constructIVec3Node->insertChildNodes(0, ivec3Sequence);
add->setRight(constructIVec3Node); offsetNode = constructIVec3Node;
} }
else else
{ {
add->setRight(sequence->at(3)->getAsTyped()); offsetNode = sequence->at(3)->getAsTyped();
} }
// Position+offset
TIntermBinary *add = new TIntermBinary(EOpAdd, texCoordNode, offsetNode);
add->setLine(texCoordNode->getLine());
newsequence.push_back(add); newsequence.push_back(add);
// lod // lod
......
...@@ -39,11 +39,7 @@ bool ContainsVectorNode(const TIntermSequence &sequence) ...@@ -39,11 +39,7 @@ bool ContainsVectorNode(const TIntermSequence &sequence)
TIntermBinary *ConstructVectorIndexBinaryNode(TIntermSymbol *symbolNode, int index) TIntermBinary *ConstructVectorIndexBinaryNode(TIntermSymbol *symbolNode, int index)
{ {
TIntermBinary *binary = new TIntermBinary(EOpIndexDirect); return new TIntermBinary(EOpIndexDirect, symbolNode, TIntermTyped::CreateIndexNode(index));
binary->setLeft(symbolNode);
TIntermTyped *indexNode = TIntermTyped::CreateIndexNode(index);
binary->setRight(indexNode);
return binary;
} }
TIntermBinary *ConstructMatrixIndexBinaryNode( TIntermBinary *ConstructMatrixIndexBinaryNode(
...@@ -52,11 +48,8 @@ TIntermBinary *ConstructMatrixIndexBinaryNode( ...@@ -52,11 +48,8 @@ TIntermBinary *ConstructMatrixIndexBinaryNode(
TIntermBinary *colVectorNode = TIntermBinary *colVectorNode =
ConstructVectorIndexBinaryNode(symbolNode, colIndex); ConstructVectorIndexBinaryNode(symbolNode, colIndex);
TIntermBinary *binary = new TIntermBinary(EOpIndexDirect); return new TIntermBinary(EOpIndexDirect, colVectorNode,
binary->setLeft(colVectorNode); TIntermTyped::CreateIndexNode(rowIndex));
TIntermTyped *rowIndexNode = TIntermTyped::CreateIndexNode(rowIndex);
binary->setRight(rowIndexNode);
return binary;
} }
} // namespace anonymous } // namespace anonymous
...@@ -268,11 +261,8 @@ TString ScalarizeVecAndMatConstructorArgs::createTempVariable(TIntermTyped *orig ...@@ -268,11 +261,8 @@ TString ScalarizeVecAndMatConstructorArgs::createTempVariable(TIntermTyped *orig
type.setPrecision(mFragmentPrecisionHigh ? EbpHigh : EbpMedium); type.setPrecision(mFragmentPrecisionHigh ? EbpHigh : EbpMedium);
} }
TIntermBinary *init = new TIntermBinary(EOpInitialize);
TIntermSymbol *symbolNode = new TIntermSymbol(-1, tempVarName, type); TIntermSymbol *symbolNode = new TIntermSymbol(-1, tempVarName, type);
init->setLeft(symbolNode); TIntermBinary *init = new TIntermBinary(EOpInitialize, symbolNode, original);
init->setRight(original);
init->setType(type);
TIntermAggregate *decl = new TIntermAggregate(EOpDeclaration); TIntermAggregate *decl = new TIntermAggregate(EOpDeclaration);
decl->getSequence()->push_back(init); decl->getSequence()->push_back(init);
......
...@@ -69,10 +69,8 @@ bool SeparateArrayInitTraverser::visitAggregate(Visit, TIntermAggregate *node) ...@@ -69,10 +69,8 @@ bool SeparateArrayInitTraverser::visitAggregate(Visit, TIntermAggregate *node)
replacementDeclaration->setLine(symbol->getLine()); replacementDeclaration->setLine(symbol->getLine());
replacements.push_back(replacementDeclaration); replacements.push_back(replacementDeclaration);
TIntermBinary *replacementAssignment = new TIntermBinary(EOpAssign); TIntermBinary *replacementAssignment =
replacementAssignment->setLeft(symbol); new TIntermBinary(EOpAssign, symbol, initializer);
replacementAssignment->setRight(initializer);
replacementAssignment->setType(initializer->getType());
replacementAssignment->setLine(symbol->getLine()); replacementAssignment->setLine(symbol->getLine());
replacements.push_back(replacementAssignment); replacements.push_back(replacementAssignment);
......
...@@ -49,11 +49,7 @@ SeparateExpressionsTraverser::SeparateExpressionsTraverser() ...@@ -49,11 +49,7 @@ SeparateExpressionsTraverser::SeparateExpressionsTraverser()
// and also needs to be replaced in its original location by a different node. // and also needs to be replaced in its original location by a different node.
TIntermBinary *CopyAssignmentNode(TIntermBinary *node) TIntermBinary *CopyAssignmentNode(TIntermBinary *node)
{ {
TIntermBinary *copyNode = new TIntermBinary(node->getOp()); return new TIntermBinary(node->getOp(), node->getLeft(), node->getRight());
copyNode->setLeft(node->getLeft());
copyNode->setRight(node->getRight());
copyNode->setType(node->getType());
return copyNode;
} }
// Performs a shallow copy of a constructor/function call node. // Performs a shallow copy of a constructor/function call node.
......
...@@ -147,10 +147,8 @@ TEST_F(IntermNodeTest, DeepCopyBinaryNode) ...@@ -147,10 +147,8 @@ TEST_F(IntermNodeTest, DeepCopyBinaryNode)
{ {
TType type(EbtFloat, EbpHigh); TType type(EbtFloat, EbpHigh);
TIntermBinary *original = new TIntermBinary(EOpAdd); TIntermBinary *original = new TIntermBinary(EOpAdd, createTestSymbol(), createTestSymbol());
original->setLine(getTestSourceLoc()); original->setLine(getTestSourceLoc());
original->setLeft(createTestSymbol());
original->setRight(createTestSymbol());
TIntermTyped *copyTyped = original->deepCopy(); TIntermTyped *copyTyped = original->deepCopy();
TIntermBinary *copy = copyTyped->getAsBinaryNode(); TIntermBinary *copy = copyTyped->getAsBinaryNode();
ASSERT_NE(nullptr, copy); ASSERT_NE(nullptr, copy);
......
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