Commit eb7f90fd by Olli Etuaho Committed by Commit Bot

Remove simple Intermediate.h functions

Most of the functions were just simple wrappers around node constructors. Dropping this extra redirection makes the code simpler. The fold() functions of node types are simplified, so that if the node can't be folded the pointer to the node itself is returned. This makes the code in ParseContext more straightforward. The few remaining functions in Intermediate are a bit more complex so they should be handled separately, but they'll be removed eventually as well. BUG=angleproject:1490 TEST=angle_unittests Change-Id: I85e11919d1f62358cfba9c011b841e32bc25402f Reviewed-on: https://chromium-review.googlesource.com/563393Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
parent 70c95fa6
...@@ -1043,6 +1043,24 @@ TQualifier TIntermTernary::DetermineQualifier(TIntermTyped *cond, ...@@ -1043,6 +1043,24 @@ TQualifier TIntermTernary::DetermineQualifier(TIntermTyped *cond,
return EvqTemporary; return EvqTemporary;
} }
TIntermTyped *TIntermTernary::fold()
{
if (mCondition->getAsConstantUnion())
{
if (mCondition->getAsConstantUnion()->getBConst(0))
{
mTrueExpression->getTypePointer()->setQualifier(mType.getQualifier());
return mTrueExpression;
}
else
{
mFalseExpression->getTypePointer()->setQualifier(mType.getQualifier());
return mFalseExpression;
}
}
return this;
}
void TIntermSwizzle::promote() void TIntermSwizzle::promote()
{ {
TQualifier resultQualifier = EvqTemporary; TQualifier resultQualifier = EvqTemporary;
...@@ -1116,7 +1134,8 @@ void TIntermBinary::promote() ...@@ -1116,7 +1134,8 @@ void TIntermBinary::promote()
ASSERT(!isMultiplication() || ASSERT(!isMultiplication() ||
mOp == GetMulOpBasedOnOperands(mLeft->getType(), mRight->getType())); mOp == GetMulOpBasedOnOperands(mLeft->getType(), mRight->getType()));
// Comma is handled as a special case. // Comma is handled as a special case. Note that the comma node qualifier depends on the shader
// version and so is not being set here.
if (mOp == EOpComma) if (mOp == EOpComma)
{ {
setType(mRight->getType()); setType(mRight->getType());
...@@ -1351,7 +1370,7 @@ TIntermTyped *TIntermSwizzle::fold() ...@@ -1351,7 +1370,7 @@ TIntermTyped *TIntermSwizzle::fold()
TIntermConstantUnion *operandConstant = mOperand->getAsConstantUnion(); TIntermConstantUnion *operandConstant = mOperand->getAsConstantUnion();
if (operandConstant == nullptr) if (operandConstant == nullptr)
{ {
return nullptr; return this;
} }
TConstantUnion *constArray = new TConstantUnion[mSwizzleOffsets.size()]; TConstantUnion *constArray = new TConstantUnion[mSwizzleOffsets.size()];
...@@ -1368,22 +1387,35 @@ TIntermTyped *TIntermBinary::fold(TDiagnostics *diagnostics) ...@@ -1368,22 +1387,35 @@ TIntermTyped *TIntermBinary::fold(TDiagnostics *diagnostics)
TIntermConstantUnion *rightConstant = mRight->getAsConstantUnion(); TIntermConstantUnion *rightConstant = mRight->getAsConstantUnion();
switch (mOp) switch (mOp)
{ {
case EOpComma:
{
if (mLeft->hasSideEffects())
{
return this;
}
mRight->getTypePointer()->setQualifier(mType.getQualifier());
return mRight;
}
case EOpIndexDirect: case EOpIndexDirect:
{ {
if (leftConstant == nullptr || rightConstant == nullptr) if (leftConstant == nullptr || rightConstant == nullptr)
{ {
return nullptr; return this;
} }
int index = rightConstant->getIConst(0); int index = rightConstant->getIConst(0);
const TConstantUnion *constArray = leftConstant->foldIndexing(index); const TConstantUnion *constArray = leftConstant->foldIndexing(index);
if (!constArray)
{
return this;
}
return CreateFoldedNode(constArray, this, mType.getQualifier()); return CreateFoldedNode(constArray, this, mType.getQualifier());
} }
case EOpIndexDirectStruct: case EOpIndexDirectStruct:
{ {
if (leftConstant == nullptr || rightConstant == nullptr) if (leftConstant == nullptr || rightConstant == nullptr)
{ {
return nullptr; return this;
} }
const TFieldList &fields = mLeft->getType().getStruct()->fields(); const TFieldList &fields = mLeft->getType().getStruct()->fields();
size_t index = static_cast<size_t>(rightConstant->getIConst(0)); size_t index = static_cast<size_t>(rightConstant->getIConst(0));
...@@ -1400,15 +1432,19 @@ TIntermTyped *TIntermBinary::fold(TDiagnostics *diagnostics) ...@@ -1400,15 +1432,19 @@ TIntermTyped *TIntermBinary::fold(TDiagnostics *diagnostics)
case EOpIndexIndirect: case EOpIndexIndirect:
case EOpIndexDirectInterfaceBlock: case EOpIndexDirectInterfaceBlock:
// Can never be constant folded. // Can never be constant folded.
return nullptr; return this;
default: default:
{ {
if (leftConstant == nullptr || rightConstant == nullptr) if (leftConstant == nullptr || rightConstant == nullptr)
{ {
return nullptr; return this;
} }
TConstantUnion *constArray = TConstantUnion *constArray =
leftConstant->foldBinary(mOp, rightConstant, diagnostics, mLeft->getLine()); leftConstant->foldBinary(mOp, rightConstant, diagnostics, mLeft->getLine());
if (!constArray)
{
return this;
}
// Nodes may be constant folded without being qualified as constant. // Nodes may be constant folded without being qualified as constant.
return CreateFoldedNode(constArray, this, mType.getQualifier()); return CreateFoldedNode(constArray, this, mType.getQualifier());
...@@ -1421,7 +1457,7 @@ TIntermTyped *TIntermUnary::fold(TDiagnostics *diagnostics) ...@@ -1421,7 +1457,7 @@ TIntermTyped *TIntermUnary::fold(TDiagnostics *diagnostics)
TIntermConstantUnion *operandConstant = mOperand->getAsConstantUnion(); TIntermConstantUnion *operandConstant = mOperand->getAsConstantUnion();
if (operandConstant == nullptr) if (operandConstant == nullptr)
{ {
return nullptr; return this;
} }
TConstantUnion *constArray = nullptr; TConstantUnion *constArray = nullptr;
...@@ -1449,6 +1485,10 @@ TIntermTyped *TIntermUnary::fold(TDiagnostics *diagnostics) ...@@ -1449,6 +1485,10 @@ TIntermTyped *TIntermUnary::fold(TDiagnostics *diagnostics)
constArray = operandConstant->foldUnaryComponentWise(mOp, diagnostics); constArray = operandConstant->foldUnaryComponentWise(mOp, diagnostics);
break; break;
} }
if (constArray == nullptr)
{
return this;
}
// Nodes may be constant folded without being qualified as constant. // Nodes may be constant folded without being qualified as constant.
return CreateFoldedNode(constArray, this, mType.getQualifier()); return CreateFoldedNode(constArray, this, mType.getQualifier());
...@@ -1461,7 +1501,7 @@ TIntermTyped *TIntermAggregate::fold(TDiagnostics *diagnostics) ...@@ -1461,7 +1501,7 @@ TIntermTyped *TIntermAggregate::fold(TDiagnostics *diagnostics)
{ {
if (param->getAsConstantUnion() == nullptr) if (param->getAsConstantUnion() == nullptr)
{ {
return nullptr; return this;
} }
} }
TConstantUnion *constArray = nullptr; TConstantUnion *constArray = nullptr;
...@@ -2617,6 +2657,42 @@ TConstantUnion *TIntermConstantUnion::FoldAggregateConstructor(TIntermAggregate ...@@ -2617,6 +2657,42 @@ TConstantUnion *TIntermConstantUnion::FoldAggregateConstructor(TIntermAggregate
return resultArray; return resultArray;
} }
bool TIntermAggregate::CanFoldAggregateBuiltInOp(TOperator op)
{
switch (op)
{
case EOpAtan:
case EOpPow:
case EOpMod:
case EOpMin:
case EOpMax:
case EOpClamp:
case EOpMix:
case EOpStep:
case EOpSmoothStep:
case EOpLdexp:
case EOpMulMatrixComponentWise:
case EOpOuterProduct:
case EOpEqualComponentWise:
case EOpNotEqualComponentWise:
case EOpLessThanComponentWise:
case EOpLessThanEqualComponentWise:
case EOpGreaterThanComponentWise:
case EOpGreaterThanEqualComponentWise:
case EOpDistance:
case EOpDot:
case EOpCross:
case EOpFaceforward:
case EOpReflect:
case EOpRefract:
case EOpBitfieldExtract:
case EOpBitfieldInsert:
return true;
default:
return false;
}
}
// static // static
TConstantUnion *TIntermConstantUnion::FoldAggregateBuiltIn(TIntermAggregate *aggregate, TConstantUnion *TIntermConstantUnion::FoldAggregateBuiltIn(TIntermAggregate *aggregate,
TDiagnostics *diagnostics) TDiagnostics *diagnostics)
......
...@@ -630,6 +630,7 @@ class TIntermAggregate : public TIntermOperator, public TIntermAggregateBase ...@@ -630,6 +630,7 @@ class TIntermAggregate : public TIntermOperator, public TIntermAggregateBase
bool hasSideEffects() const override; bool hasSideEffects() const override;
static bool CanFoldAggregateBuiltInOp(TOperator op);
TIntermTyped *fold(TDiagnostics *diagnostics); TIntermTyped *fold(TDiagnostics *diagnostics);
TIntermSequence *getSequence() override { return &mArguments; } TIntermSequence *getSequence() override { return &mArguments; }
...@@ -831,13 +832,15 @@ class TIntermTernary : public TIntermTyped ...@@ -831,13 +832,15 @@ class TIntermTernary : public TIntermTyped
mFalseExpression->hasSideEffects(); mFalseExpression->hasSideEffects();
} }
static TQualifier DetermineQualifier(TIntermTyped *cond, TIntermTyped *fold();
TIntermTyped *trueExpression,
TIntermTyped *falseExpression);
private: private:
TIntermTernary(const TIntermTernary &node); // Note: not deleted, just private! TIntermTernary(const TIntermTernary &node); // Note: not deleted, just private!
static TQualifier DetermineQualifier(TIntermTyped *cond,
TIntermTyped *trueExpression,
TIntermTyped *falseExpression);
TIntermTyped *mCondition; TIntermTyped *mCondition;
TIntermTyped *mTrueExpression; TIntermTyped *mTrueExpression;
TIntermTyped *mFalseExpression; TIntermTyped *mFalseExpression;
......
...@@ -26,47 +26,6 @@ namespace sh ...@@ -26,47 +26,6 @@ namespace sh
// //
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
//
// Add a terminal node for an identifier in an expression.
//
// Returns the added node.
//
TIntermSymbol *TIntermediate::addSymbol(int id,
const TString &name,
const TType &type,
const TSourceLoc &line)
{
TIntermSymbol *node = new TIntermSymbol(id, name, type);
node->setLine(line);
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.
//
// Returns the added node.
// The caller should set the type of the returned node.
//
TIntermTyped *TIntermediate::addIndex(TOperator op,
TIntermTyped *base,
TIntermTyped *index,
const TSourceLoc &line,
TDiagnostics *diagnostics)
{
TIntermBinary *node = new TIntermBinary(op, base, index);
node->setLine(line);
TIntermTyped *folded = node->fold(diagnostics);
if (folded)
{
return folded;
}
return node;
}
// If the input node is nullptr, return nullptr. // If the input node is nullptr, return nullptr.
// If the input node is a block node, return it. // If the input node is a block node, return it.
// If the input node is not a block node, put it inside a block node and return that. // If the input node is not a block node, put it inside a block node and return that.
...@@ -84,80 +43,6 @@ TIntermBlock *TIntermediate::EnsureBlock(TIntermNode *node) ...@@ -84,80 +43,6 @@ TIntermBlock *TIntermediate::EnsureBlock(TIntermNode *node)
return blockNode; return blockNode;
} }
TIntermTyped *TIntermediate::AddComma(TIntermTyped *left,
TIntermTyped *right,
const TSourceLoc &line,
int shaderVersion)
{
TIntermTyped *commaNode = nullptr;
if (!left->hasSideEffects())
{
commaNode = right;
}
else
{
commaNode = new TIntermBinary(EOpComma, left, right);
commaNode->setLine(line);
}
TQualifier resultQualifier = TIntermBinary::GetCommaQualifier(shaderVersion, left, right);
commaNode->getTypePointer()->setQualifier(resultQualifier);
return commaNode;
}
// For "?:" test nodes. There are three children; a condition,
// a true path, and a false path. The two paths are specified
// as separate parameters.
//
// Returns the ternary node created, or one of trueExpression and falseExpression if the expression
// could be folded.
TIntermTyped *TIntermediate::AddTernarySelection(TIntermTyped *cond,
TIntermTyped *trueExpression,
TIntermTyped *falseExpression,
const TSourceLoc &line)
{
// Note that the node resulting from here can be a constant union without being qualified as
// constant.
if (cond->getAsConstantUnion())
{
TQualifier resultQualifier =
TIntermTernary::DetermineQualifier(cond, trueExpression, falseExpression);
if (cond->getAsConstantUnion()->getBConst(0))
{
trueExpression->getTypePointer()->setQualifier(resultQualifier);
return trueExpression;
}
else
{
falseExpression->getTypePointer()->setQualifier(resultQualifier);
return falseExpression;
}
}
// Make a ternary node.
TIntermTernary *node = new TIntermTernary(cond, trueExpression, falseExpression);
node->setLine(line);
return node;
}
TIntermSwitch *TIntermediate::addSwitch(TIntermTyped *init,
TIntermBlock *statementList,
const TSourceLoc &line)
{
TIntermSwitch *node = new TIntermSwitch(init, statementList);
node->setLine(line);
return node;
}
TIntermCase *TIntermediate::addCase(TIntermTyped *condition, const TSourceLoc &line)
{
TIntermCase *node = new TIntermCase(condition);
node->setLine(line);
return node;
}
// //
// Constant terminal nodes. Has a union that contains bool, float or int constants // Constant terminal nodes. Has a union that contains bool, float or int constants
// //
...@@ -174,68 +59,4 @@ TIntermConstantUnion *TIntermediate::addConstantUnion(const TConstantUnion *cons ...@@ -174,68 +59,4 @@ TIntermConstantUnion *TIntermediate::addConstantUnion(const TConstantUnion *cons
return node; return node;
} }
TIntermTyped *TIntermediate::AddSwizzle(TIntermTyped *baseExpression,
const TVectorFields &fields,
const TSourceLoc &dotLocation)
{
TVector<int> fieldsVector;
for (int i = 0; i < fields.num; ++i)
{
fieldsVector.push_back(fields.offsets[i]);
}
TIntermSwizzle *node = new TIntermSwizzle(baseExpression, fieldsVector);
node->setLine(dotLocation);
TIntermTyped *folded = node->fold();
if (folded)
{
return folded;
}
return node;
}
TIntermTyped *TIntermediate::foldAggregateBuiltIn(TIntermAggregate *aggregate,
TDiagnostics *diagnostics)
{
switch (aggregate->getOp())
{
case EOpAtan:
case EOpPow:
case EOpMod:
case EOpMin:
case EOpMax:
case EOpClamp:
case EOpMix:
case EOpStep:
case EOpSmoothStep:
case EOpLdexp:
case EOpMulMatrixComponentWise:
case EOpOuterProduct:
case EOpEqualComponentWise:
case EOpNotEqualComponentWise:
case EOpLessThanComponentWise:
case EOpLessThanEqualComponentWise:
case EOpGreaterThanComponentWise:
case EOpGreaterThanEqualComponentWise:
case EOpDistance:
case EOpDot:
case EOpCross:
case EOpFaceforward:
case EOpReflect:
case EOpRefract:
case EOpBitfieldExtract:
case EOpBitfieldInsert:
return aggregate->fold(diagnostics);
default:
// TODO: Add support for folding array constructors
if (aggregate->isConstructor() && !aggregate->isArray())
{
return aggregate->fold(diagnostics);
}
// Constant folding not supported for the built-in.
return nullptr;
}
}
} // namespace sh } // namespace sh
...@@ -12,12 +12,6 @@ ...@@ -12,12 +12,6 @@
namespace sh namespace sh
{ {
struct TVectorFields
{
int offsets[4];
int num;
};
// //
// Set of helper functions to help build the tree. // Set of helper functions to help build the tree.
// //
...@@ -27,35 +21,11 @@ class TIntermediate ...@@ -27,35 +21,11 @@ class TIntermediate
POOL_ALLOCATOR_NEW_DELETE(); POOL_ALLOCATOR_NEW_DELETE();
TIntermediate() {} TIntermediate() {}
TIntermSymbol *addSymbol(int id, const TString &, const TType &, const TSourceLoc &);
TIntermTyped *addIndex(TOperator op,
TIntermTyped *base,
TIntermTyped *index,
const TSourceLoc &line,
TDiagnostics *diagnostics);
static TIntermBlock *EnsureBlock(TIntermNode *node); static TIntermBlock *EnsureBlock(TIntermNode *node);
static TIntermTyped *AddTernarySelection(TIntermTyped *cond,
TIntermTyped *trueExpression,
TIntermTyped *falseExpression,
const TSourceLoc &line);
TIntermSwitch *addSwitch(TIntermTyped *init,
TIntermBlock *statementList,
const TSourceLoc &line);
TIntermCase *addCase(TIntermTyped *condition, const TSourceLoc &line);
static TIntermTyped *AddComma(TIntermTyped *left,
TIntermTyped *right,
const TSourceLoc &line,
int shaderVersion);
TIntermConstantUnion *addConstantUnion(const TConstantUnion *constantUnion, TIntermConstantUnion *addConstantUnion(const TConstantUnion *constantUnion,
const TType &type, const TType &type,
const TSourceLoc &line); const TSourceLoc &line);
static TIntermTyped *AddSwizzle(TIntermTyped *baseExpression,
const TVectorFields &fields,
const TSourceLoc &dotLocation);
TIntermTyped *foldAggregateBuiltIn(TIntermAggregate *aggregate, TDiagnostics *diagnostics);
private: private:
void operator=(TIntermediate &); // prevent assignments void operator=(TIntermediate &); // prevent assignments
}; };
......
...@@ -176,21 +176,19 @@ TParseContext::~TParseContext() ...@@ -176,21 +176,19 @@ TParseContext::~TParseContext()
{ {
} }
// bool TParseContext::parseVectorFields(const TSourceLoc &line,
// Look at a '.' field selector string and change it into offsets const TString &compString,
// for a vector.
//
bool TParseContext::parseVectorFields(const TString &compString,
int vecSize, int vecSize,
TVectorFields &fields, TVector<int> *fieldOffsets)
const TSourceLoc &line)
{ {
fields.num = (int)compString.size(); ASSERT(fieldOffsets);
if (fields.num > 4) size_t fieldCount = compString.size();
if (fieldCount > 4u)
{ {
error(line, "illegal vector field selection", compString.c_str()); error(line, "illegal vector field selection", compString.c_str());
return false; return false;
} }
fieldOffsets->resize(fieldCount);
enum enum
{ {
...@@ -199,57 +197,57 @@ bool TParseContext::parseVectorFields(const TString &compString, ...@@ -199,57 +197,57 @@ bool TParseContext::parseVectorFields(const TString &compString,
estpq estpq
} fieldSet[4]; } fieldSet[4];
for (int i = 0; i < fields.num; ++i) for (unsigned int i = 0u; i < fieldOffsets->size(); ++i)
{ {
switch (compString[i]) switch (compString[i])
{ {
case 'x': case 'x':
fields.offsets[i] = 0; (*fieldOffsets)[i] = 0;
fieldSet[i] = exyzw; fieldSet[i] = exyzw;
break; break;
case 'r': case 'r':
fields.offsets[i] = 0; (*fieldOffsets)[i] = 0;
fieldSet[i] = ergba; fieldSet[i] = ergba;
break; break;
case 's': case 's':
fields.offsets[i] = 0; (*fieldOffsets)[i] = 0;
fieldSet[i] = estpq; fieldSet[i] = estpq;
break; break;
case 'y': case 'y':
fields.offsets[i] = 1; (*fieldOffsets)[i] = 1;
fieldSet[i] = exyzw; fieldSet[i] = exyzw;
break; break;
case 'g': case 'g':
fields.offsets[i] = 1; (*fieldOffsets)[i] = 1;
fieldSet[i] = ergba; fieldSet[i] = ergba;
break; break;
case 't': case 't':
fields.offsets[i] = 1; (*fieldOffsets)[i] = 1;
fieldSet[i] = estpq; fieldSet[i] = estpq;
break; break;
case 'z': case 'z':
fields.offsets[i] = 2; (*fieldOffsets)[i] = 2;
fieldSet[i] = exyzw; fieldSet[i] = exyzw;
break; break;
case 'b': case 'b':
fields.offsets[i] = 2; (*fieldOffsets)[i] = 2;
fieldSet[i] = ergba; fieldSet[i] = ergba;
break; break;
case 'p': case 'p':
fields.offsets[i] = 2; (*fieldOffsets)[i] = 2;
fieldSet[i] = estpq; fieldSet[i] = estpq;
break; break;
case 'w': case 'w':
fields.offsets[i] = 3; (*fieldOffsets)[i] = 3;
fieldSet[i] = exyzw; fieldSet[i] = exyzw;
break; break;
case 'a': case 'a':
fields.offsets[i] = 3; (*fieldOffsets)[i] = 3;
fieldSet[i] = ergba; fieldSet[i] = ergba;
break; break;
case 'q': case 'q':
fields.offsets[i] = 3; (*fieldOffsets)[i] = 3;
fieldSet[i] = estpq; fieldSet[i] = estpq;
break; break;
default: default:
...@@ -258,9 +256,9 @@ bool TParseContext::parseVectorFields(const TString &compString, ...@@ -258,9 +256,9 @@ bool TParseContext::parseVectorFields(const TString &compString,
} }
} }
for (int i = 0; i < fields.num; ++i) for (unsigned int i = 0u; i < fieldOffsets->size(); ++i)
{ {
if (fields.offsets[i] >= vecSize) if ((*fieldOffsets)[i] >= vecSize)
{ {
error(line, "vector field selection out of range", compString.c_str()); error(line, "vector field selection out of range", compString.c_str());
return false; return false;
...@@ -1682,8 +1680,10 @@ TIntermTyped *TParseContext::parseVariableIdentifier(const TSourceLoc &location, ...@@ -1682,8 +1680,10 @@ TIntermTyped *TParseContext::parseVariableIdentifier(const TSourceLoc &location,
} }
else else
{ {
return intermediate.addSymbol(variable->getUniqueId(), variable->getName(), TIntermSymbol *symbolNode =
variable->getType(), location); new TIntermSymbol(variable->getUniqueId(), variable->getName(), variable->getType());
symbolNode->setLine(location);
return symbolNode;
} }
} }
...@@ -1800,8 +1800,9 @@ bool TParseContext::executeInitializer(const TSourceLoc &line, ...@@ -1800,8 +1800,9 @@ bool TParseContext::executeInitializer(const TSourceLoc &line,
} }
} }
TIntermSymbol *intermSymbol = intermediate.addSymbol( TIntermSymbol *intermSymbol =
variable->getUniqueId(), variable->getName(), variable->getType(), line); new TIntermSymbol(variable->getUniqueId(), variable->getName(), variable->getType());
intermSymbol->setLine(line);
*initNode = createAssign(EOpInitialize, intermSymbol, initializer, line); *initNode = createAssign(EOpInitialize, intermSymbol, initializer, line);
if (*initNode == nullptr) if (*initNode == nullptr)
{ {
...@@ -2188,7 +2189,7 @@ TIntermDeclaration *TParseContext::parseSingleDeclaration( ...@@ -2188,7 +2189,7 @@ TIntermDeclaration *TParseContext::parseSingleDeclaration(
// But if the empty declaration is declaring a struct type, the symbol node will store that. // But if the empty declaration is declaring a struct type, the symbol node will store that.
if (type.getBasicType() == EbtStruct) if (type.getBasicType() == EbtStruct)
{ {
symbol = intermediate.addSymbol(0, "", type, identifierOrTypeLocation); symbol = new TIntermSymbol(0, "", type);
} }
else if (IsAtomicCounter(publicType.getBasicType())) else if (IsAtomicCounter(publicType.getBasicType()))
{ {
...@@ -2213,8 +2214,7 @@ TIntermDeclaration *TParseContext::parseSingleDeclaration( ...@@ -2213,8 +2214,7 @@ TIntermDeclaration *TParseContext::parseSingleDeclaration(
if (variable) if (variable)
{ {
symbol = intermediate.addSymbol(variable->getUniqueId(), identifier, type, symbol = new TIntermSymbol(variable->getUniqueId(), identifier, type);
identifierOrTypeLocation);
} }
} }
...@@ -2222,6 +2222,7 @@ TIntermDeclaration *TParseContext::parseSingleDeclaration( ...@@ -2222,6 +2222,7 @@ TIntermDeclaration *TParseContext::parseSingleDeclaration(
declaration->setLine(identifierOrTypeLocation); declaration->setLine(identifierOrTypeLocation);
if (symbol) if (symbol)
{ {
symbol->setLine(identifierOrTypeLocation);
declaration->appendDeclarator(symbol); declaration->appendDeclarator(symbol);
} }
return declaration; return declaration;
...@@ -2263,10 +2264,10 @@ TIntermDeclaration *TParseContext::parseSingleArrayDeclaration(TPublicType &publ ...@@ -2263,10 +2264,10 @@ TIntermDeclaration *TParseContext::parseSingleArrayDeclaration(TPublicType &publ
TIntermDeclaration *declaration = new TIntermDeclaration(); TIntermDeclaration *declaration = new TIntermDeclaration();
declaration->setLine(identifierLocation); declaration->setLine(identifierLocation);
TIntermSymbol *symbol = intermediate.addSymbol(0, identifier, arrayType, identifierLocation); if (variable)
if (variable && symbol)
{ {
symbol->setId(variable->getUniqueId()); TIntermSymbol *symbol = new TIntermSymbol(variable->getUniqueId(), identifier, arrayType);
symbol->setLine(identifierLocation);
declaration->appendDeclarator(symbol); declaration->appendDeclarator(symbol);
} }
...@@ -2394,8 +2395,8 @@ TIntermInvariantDeclaration *TParseContext::parseInvariantDeclaration( ...@@ -2394,8 +2395,8 @@ TIntermInvariantDeclaration *TParseContext::parseInvariantDeclaration(
symbolTable.addInvariantVarying(std::string(identifier->c_str())); symbolTable.addInvariantVarying(std::string(identifier->c_str()));
TIntermSymbol *intermSymbol = TIntermSymbol *intermSymbol = new TIntermSymbol(variable->getUniqueId(), *identifier, type);
intermediate.addSymbol(variable->getUniqueId(), *identifier, type, identifierLoc); intermSymbol->setLine(identifierLoc);
return new TIntermInvariantDeclaration(intermSymbol, identifierLoc); return new TIntermInvariantDeclaration(intermSymbol, identifierLoc);
} }
...@@ -2426,10 +2427,10 @@ void TParseContext::parseDeclarator(TPublicType &publicType, ...@@ -2426,10 +2427,10 @@ void TParseContext::parseDeclarator(TPublicType &publicType,
} }
declareVariable(identifierLocation, identifier, type, &variable); declareVariable(identifierLocation, identifier, type, &variable);
TIntermSymbol *symbol = intermediate.addSymbol(0, identifier, type, identifierLocation); if (variable)
if (variable && symbol)
{ {
symbol->setId(variable->getUniqueId()); TIntermSymbol *symbol = new TIntermSymbol(variable->getUniqueId(), identifier, type);
symbol->setLine(identifierLocation);
declarationOut->appendDeclarator(symbol); declarationOut->appendDeclarator(symbol);
} }
} }
...@@ -2468,9 +2469,9 @@ void TParseContext::parseArrayDeclarator(TPublicType &publicType, ...@@ -2468,9 +2469,9 @@ void TParseContext::parseArrayDeclarator(TPublicType &publicType,
TVariable *variable = nullptr; TVariable *variable = nullptr;
declareVariable(identifierLocation, identifier, arrayType, &variable); declareVariable(identifierLocation, identifier, arrayType, &variable);
TIntermSymbol *symbol = TIntermSymbol *symbol = new TIntermSymbol(0, identifier, arrayType);
intermediate.addSymbol(0, identifier, arrayType, identifierLocation); symbol->setLine(identifierLocation);
if (variable && symbol) if (variable)
symbol->setId(variable->getUniqueId()); symbol->setId(variable->getUniqueId());
declarationOut->appendDeclarator(symbol); declarationOut->appendDeclarator(symbol);
...@@ -2744,6 +2745,8 @@ TIntermFunctionPrototype *TParseContext::createPrototypeNodeFromFunction( ...@@ -2744,6 +2745,8 @@ TIntermFunctionPrototype *TParseContext::createPrototypeNodeFromFunction(
{ {
const TConstParameter &param = function.getParam(i); const TConstParameter &param = function.getParam(i);
TIntermSymbol *symbol = nullptr;
// If the parameter has no name, it's not an error, just don't add it to symbol table (could // If the parameter has no name, it's not an error, just don't add it to symbol table (could
// be used for unused args). // be used for unused args).
if (param.name != nullptr) if (param.name != nullptr)
...@@ -2751,20 +2754,27 @@ TIntermFunctionPrototype *TParseContext::createPrototypeNodeFromFunction( ...@@ -2751,20 +2754,27 @@ TIntermFunctionPrototype *TParseContext::createPrototypeNodeFromFunction(
TVariable *variable = new TVariable(param.name, *param.type); TVariable *variable = new TVariable(param.name, *param.type);
// Insert the parameter in the symbol table. // Insert the parameter in the symbol table.
if (insertParametersToSymbolTable && !symbolTable.declare(variable)) if (insertParametersToSymbolTable)
{
if (symbolTable.declare(variable))
{
symbol = new TIntermSymbol(variable->getUniqueId(), variable->getName(),
variable->getType());
}
else
{ {
error(location, "redefinition", variable->getName().c_str()); error(location, "redefinition", variable->getName().c_str());
prototype->appendParameter(intermediate.addSymbol(0, "", *param.type, location));
continue;
} }
TIntermSymbol *symbol = intermediate.addSymbol(
variable->getUniqueId(), variable->getName(), variable->getType(), location);
prototype->appendParameter(symbol);
} }
else }
if (!symbol)
{ {
prototype->appendParameter(intermediate.addSymbol(0, "", *param.type, location)); // The parameter had no name or declaring the symbol failed - either way, add a nameless
// symbol.
symbol = new TIntermSymbol(0, "", *param.type);
} }
symbol->setLine(location);
prototype->appendParameter(symbol);
} }
return prototype; return prototype;
} }
...@@ -3075,13 +3085,11 @@ TIntermTyped *TParseContext::addConstructor(TIntermSequence *arguments, ...@@ -3075,13 +3085,11 @@ TIntermTyped *TParseContext::addConstructor(TIntermSequence *arguments,
TIntermAggregate *constructorNode = TIntermAggregate::CreateConstructor(type, arguments); TIntermAggregate *constructorNode = TIntermAggregate::CreateConstructor(type, arguments);
constructorNode->setLine(line); constructorNode->setLine(line);
TIntermTyped *constConstructor = // TODO(oetuaho@nvidia.com): Add support for folding array constructors.
intermediate.foldAggregateBuiltIn(constructorNode, mDiagnostics); if (!constructorNode->isArray())
if (constConstructor)
{ {
return constConstructor; return constructorNode->fold(mDiagnostics);
} }
return constructorNode; return constructorNode;
} }
...@@ -3259,8 +3267,8 @@ TIntermDeclaration *TParseContext::addInterfaceBlock( ...@@ -3259,8 +3267,8 @@ TIntermDeclaration *TParseContext::addInterfaceBlock(
symbolName = instanceTypeDef->getName(); symbolName = instanceTypeDef->getName();
} }
TIntermSymbol *blockSymbol = TIntermSymbol *blockSymbol = new TIntermSymbol(symbolId, symbolName, interfaceBlockType);
intermediate.addSymbol(symbolId, symbolName, interfaceBlockType, typeQualifier.line); blockSymbol->setLine(typeQualifier.line);
TIntermDeclaration *declaration = new TIntermDeclaration(); TIntermDeclaration *declaration = new TIntermDeclaration();
declaration->appendDeclarator(blockSymbol); declaration->appendDeclarator(blockSymbol);
declaration->setLine(nameLine); declaration->setLine(nameLine);
...@@ -3427,13 +3435,16 @@ TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression, ...@@ -3427,13 +3435,16 @@ TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression,
indexConstantUnion->replaceConstantUnion(safeConstantUnion); indexConstantUnion->replaceConstantUnion(safeConstantUnion);
} }
return intermediate.addIndex(EOpIndexDirect, baseExpression, indexExpression, location, TIntermBinary *node = new TIntermBinary(EOpIndexDirect, baseExpression, indexExpression);
mDiagnostics); node->setLine(location);
return node->fold(mDiagnostics);
} }
else else
{ {
return intermediate.addIndex(EOpIndexIndirect, baseExpression, indexExpression, location, TIntermBinary *node = new TIntermBinary(EOpIndexIndirect, baseExpression, indexExpression);
mDiagnostics); node->setLine(location);
// Indirect indexing can never be constant folded.
return node;
} }
} }
...@@ -3474,15 +3485,17 @@ TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre ...@@ -3474,15 +3485,17 @@ TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre
if (baseExpression->isVector()) if (baseExpression->isVector())
{ {
TVectorFields fields; TVector<int> fieldOffsets;
if (!parseVectorFields(fieldString, baseExpression->getNominalSize(), fields, if (!parseVectorFields(fieldLocation, fieldString, baseExpression->getNominalSize(),
fieldLocation)) &fieldOffsets))
{ {
fields.num = 1; fieldOffsets.resize(1);
fields.offsets[0] = 0; fieldOffsets[0] = 0;
} }
TIntermSwizzle *node = new TIntermSwizzle(baseExpression, fieldOffsets);
node->setLine(dotLocation);
return TIntermediate::AddSwizzle(baseExpression, fields, dotLocation); return node->fold();
} }
else if (baseExpression->getBasicType() == EbtStruct) else if (baseExpression->getBasicType() == EbtStruct)
{ {
...@@ -3508,8 +3521,10 @@ TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre ...@@ -3508,8 +3521,10 @@ TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre
{ {
TIntermTyped *index = TIntermTyped::CreateIndexNode(i); TIntermTyped *index = TIntermTyped::CreateIndexNode(i);
index->setLine(fieldLocation); index->setLine(fieldLocation);
return intermediate.addIndex(EOpIndexDirectStruct, baseExpression, index, TIntermBinary *node =
dotLocation, mDiagnostics); new TIntermBinary(EOpIndexDirectStruct, baseExpression, index);
node->setLine(dotLocation);
return node->fold(mDiagnostics);
} }
else else
{ {
...@@ -3542,8 +3557,11 @@ TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre ...@@ -3542,8 +3557,11 @@ TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre
{ {
TIntermTyped *index = TIntermTyped::CreateIndexNode(i); TIntermTyped *index = TIntermTyped::CreateIndexNode(i);
index->setLine(fieldLocation); index->setLine(fieldLocation);
return intermediate.addIndex(EOpIndexDirectInterfaceBlock, baseExpression, index, TIntermBinary *node =
dotLocation, mDiagnostics); new TIntermBinary(EOpIndexDirectInterfaceBlock, baseExpression, index);
node->setLine(dotLocation);
// Indexing interface blocks can never be constant folded.
return node;
} }
else else
{ {
...@@ -4065,12 +4083,8 @@ TIntermSwitch *TParseContext::addSwitch(TIntermTyped *init, ...@@ -4065,12 +4083,8 @@ TIntermSwitch *TParseContext::addSwitch(TIntermTyped *init,
} }
} }
TIntermSwitch *node = intermediate.addSwitch(init, statementList, loc); TIntermSwitch *node = new TIntermSwitch(init, statementList);
if (node == nullptr) node->setLine(loc);
{
error(loc, "erroneous switch statement", "switch");
return nullptr;
}
return node; return node;
} }
...@@ -4099,12 +4113,8 @@ TIntermCase *TParseContext::addCase(TIntermTyped *condition, const TSourceLoc &l ...@@ -4099,12 +4113,8 @@ TIntermCase *TParseContext::addCase(TIntermTyped *condition, const TSourceLoc &l
{ {
error(condition->getLine(), "case label must be constant", "case"); error(condition->getLine(), "case label must be constant", "case");
} }
TIntermCase *node = intermediate.addCase(condition, loc); TIntermCase *node = new TIntermCase(condition);
if (node == nullptr) node->setLine(loc);
{
error(loc, "erroneous case statement", "case");
return nullptr;
}
return node; return node;
} }
...@@ -4115,12 +4125,8 @@ TIntermCase *TParseContext::addDefault(const TSourceLoc &loc) ...@@ -4115,12 +4125,8 @@ TIntermCase *TParseContext::addDefault(const TSourceLoc &loc)
error(loc, "default labels need to be inside switch statements", "default"); error(loc, "default labels need to be inside switch statements", "default");
return nullptr; return nullptr;
} }
TIntermCase *node = intermediate.addCase(nullptr, loc); TIntermCase *node = new TIntermCase(nullptr);
if (node == nullptr) node->setLine(loc);
{
error(loc, "erroneous default statement", "default");
return nullptr;
}
return node; return node;
} }
...@@ -4169,11 +4175,7 @@ TIntermTyped *TParseContext::createUnaryMath(TOperator op, ...@@ -4169,11 +4175,7 @@ TIntermTyped *TParseContext::createUnaryMath(TOperator op,
TIntermUnary *node = new TIntermUnary(op, child); TIntermUnary *node = new TIntermUnary(op, child);
node->setLine(loc); node->setLine(loc);
TIntermTyped *foldedNode = node->fold(mDiagnostics); return node->fold(mDiagnostics);
if (foldedNode)
return foldedNode;
return node;
} }
TIntermTyped *TParseContext::addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc) TIntermTyped *TParseContext::addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc)
...@@ -4529,11 +4531,7 @@ TIntermTyped *TParseContext::addBinaryMathInternal(TOperator op, ...@@ -4529,11 +4531,7 @@ TIntermTyped *TParseContext::addBinaryMathInternal(TOperator op,
node->setLine(loc); node->setLine(loc);
// See if we can fold constants. // See if we can fold constants.
TIntermTyped *foldedNode = node->fold(mDiagnostics); return node->fold(mDiagnostics);
if (foldedNode)
return foldedNode;
return node;
} }
TIntermTyped *TParseContext::addBinaryMath(TOperator op, TIntermTyped *TParseContext::addBinaryMath(TOperator op,
...@@ -4623,7 +4621,10 @@ TIntermTyped *TParseContext::addComma(TIntermTyped *left, ...@@ -4623,7 +4621,10 @@ TIntermTyped *TParseContext::addComma(TIntermTyped *left,
","); ",");
} }
return TIntermediate::AddComma(left, right, loc, mShaderVersion); TIntermBinary *commaNode = new TIntermBinary(EOpComma, left, right);
TQualifier resultQualifier = TIntermBinary::GetCommaQualifier(mShaderVersion, left, right);
commaNode->getTypePointer()->setQualifier(resultQualifier);
return commaNode->fold(mDiagnostics);
} }
TIntermBranch *TParseContext::addBranch(TOperator op, const TSourceLoc &loc) TIntermBranch *TParseContext::addBranch(TOperator op, const TSourceLoc &loc)
...@@ -4948,17 +4949,18 @@ TIntermTyped *TParseContext::addNonConstructorFunctionCall(TFunction *fnCall, ...@@ -4948,17 +4949,18 @@ TIntermTyped *TParseContext::addNonConstructorFunctionCall(TFunction *fnCall,
// Some built-in functions have out parameters too. // Some built-in functions have out parameters too.
functionCallLValueErrorCheck(fnCandidate, callNode); functionCallLValueErrorCheck(fnCandidate, callNode);
// See if we can constant fold a built-in. Note that this may be possible even if (TIntermAggregate::CanFoldAggregateBuiltInOp(callNode->getOp()))
// if it is not const-qualified.
TIntermTyped *foldedNode =
intermediate.foldAggregateBuiltIn(callNode, mDiagnostics);
if (foldedNode)
{ {
return foldedNode; // See if we can constant fold a built-in. Note that this may be possible
// even if it is not const-qualified.
return callNode->fold(mDiagnostics);
} }
else
{
return callNode; return callNode;
} }
} }
}
else else
{ {
// This is a real function call // This is a real function call
...@@ -5002,8 +5004,12 @@ TIntermTyped *TParseContext::addTernarySelection(TIntermTyped *cond, ...@@ -5002,8 +5004,12 @@ TIntermTyped *TParseContext::addTernarySelection(TIntermTyped *cond,
if (trueExpression->getType() != falseExpression->getType()) if (trueExpression->getType() != falseExpression->getType())
{ {
binaryOpError(loc, "?:", trueExpression->getCompleteString(), std::stringstream reasonStream;
falseExpression->getCompleteString()); reasonStream << "mismatching ternary operator operand types '"
<< trueExpression->getCompleteString() << " and '"
<< falseExpression->getCompleteString() << "'";
std::string reason = reasonStream.str();
error(loc, reason.c_str(), "?:");
return falseExpression; return falseExpression;
} }
if (IsOpaqueType(trueExpression->getBasicType())) if (IsOpaqueType(trueExpression->getBasicType()))
...@@ -5042,7 +5048,12 @@ TIntermTyped *TParseContext::addTernarySelection(TIntermTyped *cond, ...@@ -5042,7 +5048,12 @@ TIntermTyped *TParseContext::addTernarySelection(TIntermTyped *cond,
return falseExpression; return falseExpression;
} }
return TIntermediate::AddTernarySelection(cond, trueExpression, falseExpression, loc); // Note that the node resulting from here can be a constant union without being qualified as
// constant.
TIntermTernary *node = new TIntermTernary(cond, trueExpression, falseExpression);
node->setLine(loc);
return node->fold();
} }
// //
......
...@@ -98,7 +98,11 @@ class TParseContext : angle::NonCopyable ...@@ -98,7 +98,11 @@ class TParseContext : angle::NonCopyable
const TString *name, const TString *name,
const TSymbol *symbol); const TSymbol *symbol);
bool parseVectorFields(const TString &, int vecSize, TVectorFields &, const TSourceLoc &line); // Look at a '.' field selector string and change it into offsets for a vector.
bool parseVectorFields(const TSourceLoc &line,
const TString &compString,
int vecSize,
TVector<int> *fieldOffsets);
void assignError(const TSourceLoc &line, const char *op, TString left, TString right); void assignError(const TSourceLoc &line, const char *op, TString left, TString right);
void unaryOpError(const TSourceLoc &line, const char *op, TString operand); void unaryOpError(const TSourceLoc &line, const char *op, TString operand);
......
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