Handle constant expressions that have not been constant folded.
Change-Id: I7dd1e6db9a4cee64cb10fb27373d77038b2af63e
Reviewed-on: https://swiftshader-review.googlesource.com/5078
Tested-by: Nicolas Capens <capn@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
diff --git a/src/OpenGL/compiler/ParseHelper.cpp b/src/OpenGL/compiler/ParseHelper.cpp
index eb41738..d8efe5d 100644
--- a/src/OpenGL/compiler/ParseHelper.cpp
+++ b/src/OpenGL/compiler/ParseHelper.cpp
@@ -228,7 +228,7 @@
void TParseContext::binaryOpError(const TSourceLoc &line, const char* op, TString left, TString right)
{
std::stringstream extraInfoStream;
- extraInfoStream << "no operation '" << op << "' exists that takes a left-hand operand of type '" << left
+ extraInfoStream << "no operation '" << op << "' exists that takes a left-hand operand of type '" << left
<< "' and a right operand of type '" << right << "' (or there is no acceptable conversion)";
std::string extraInfo = extraInfoStream.str();
error(line, " wrong operand types ", op, extraInfo.c_str());
@@ -1191,11 +1191,12 @@
ASSERT(intermNode != nullptr);
TType type = TType(pType);
- TVariable *variable = nullptr;
if(type.isArray() && (type.getArraySize() == 0))
{
type.setArraySize(initializer->getArraySize());
}
+
+ TVariable *variable = nullptr;
if(!declareVariable(line, identifier, type, &variable))
{
return true;
@@ -1218,7 +1219,7 @@
//
// identifier must be of type constant, a global, or a temporary
//
- TQualifier qualifier = variable->getType().getQualifier();
+ TQualifier qualifier = type.getQualifier();
if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal) && (qualifier != EvqConstExpr)) {
error(line, " cannot initialize this type of qualifier ", variable->getType().getQualifierString());
return true;
@@ -1228,7 +1229,7 @@
//
if (qualifier == EvqConstExpr) {
- if (qualifier != initializer->getType().getQualifier()) {
+ if (qualifier != initializer->getQualifier()) {
std::stringstream extraInfoStream;
extraInfoStream << "'" << variable->getType().getCompleteString() << "'";
std::string extraInfo = extraInfoStream.str();
@@ -1236,12 +1237,14 @@
variable->getType().setQualifier(EvqTemporary);
return true;
}
+
if (type != initializer->getType()) {
error(line, " non-matching types for const initializer ",
variable->getType().getQualifierString());
variable->getType().setQualifier(EvqTemporary);
return true;
}
+
if (initializer->getAsConstantUnion()) {
variable->shareConstPointer(initializer->getAsConstantUnion()->getUnionArrayPointer());
} else if (initializer->getAsSymbolNode()) {
@@ -1250,17 +1253,10 @@
ConstantUnion* constArray = tVar->getConstPointer();
variable->shareConstPointer(constArray);
- } else {
- std::stringstream extraInfoStream;
- extraInfoStream << "'" << variable->getType().getCompleteString() << "'";
- std::string extraInfo = extraInfoStream.str();
- error(line, " cannot assign to", "=", extraInfo.c_str());
- variable->getType().setQualifier(EvqTemporary);
- return true;
}
}
- if (qualifier != EvqConstExpr) {
+ if (!variable->isConstant()) {
TIntermSymbol* intermSymbol = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), line);
*intermNode = createAssign(EOpInitialize, intermSymbol, initializer, line);
if(*intermNode == nullptr) {
@@ -1273,25 +1269,6 @@
return false;
}
-bool TParseContext::areAllChildConst(TIntermAggregate* aggrNode)
-{
- ASSERT(aggrNode != NULL);
- if (!aggrNode->isConstructor())
- return false;
-
- bool allConstant = true;
-
- // check if all the child nodes are constants so that they can be inserted into
- // the parent node
- TIntermSequence &sequence = aggrNode->getSequence() ;
- for (TIntermSequence::iterator p = sequence.begin(); p != sequence.end(); ++p) {
- if (!(*p)->getAsTyped()->getAsConstantUnion())
- return false;
- }
-
- return allConstant;
-}
-
TPublicType TParseContext::addFullySpecifiedType(TQualifier qualifier, bool invariant, TLayoutQualifier layoutQualifier, const TPublicType &typeSpecifier)
{
TPublicType returnType = typeSpecifier;
@@ -1818,12 +1795,12 @@
aggregate->setName(function.getMangledName().c_str());
aggregate->setType(function.getReturnType());
- // store the pragma information for debug and optimize and other vendor specific
- // information. This information can be queried from the parse tree
- aggregate->setOptimize(pragma().optimize);
+ // store the pragma information for debug and optimize and other vendor specific
+ // information. This information can be queried from the parse tree
+ aggregate->setOptimize(pragma().optimize);
aggregate->setDebug(pragma().debug);
- if(functionBody && functionBody->getAsAggregate())
+ if(functionBody && functionBody->getAsAggregate())
aggregate->setEndLine(functionBody->getAsAggregate()->getEndLine());
symbolTable.pop();
@@ -2117,8 +2094,8 @@
}
// Turn the argument list itself into a constructor
- TIntermTyped *constructor = intermediate.setAggregateOperator(aggregateArguments, op, line);
- TIntermTyped *constConstructor = foldConstConstructor(constructor->getAsAggregate(), *type);
+ TIntermAggregate *constructor = intermediate.setAggregateOperator(aggregateArguments, op, line);
+ TIntermTyped *constConstructor = foldConstConstructor(constructor, *type);
if(constConstructor)
{
return constConstructor;
@@ -2129,9 +2106,8 @@
TIntermTyped* TParseContext::foldConstConstructor(TIntermAggregate* aggrNode, const TType& type)
{
- bool canBeFolded = areAllChildConst(aggrNode);
aggrNode->setType(type);
- if (canBeFolded) {
+ if (aggrNode->isConstantFoldable()) {
bool returnVal = false;
ConstantUnion* unionArray = new ConstantUnion[type.getObjectSize()];
if (aggrNode->getSequence().size() == 1) {
@@ -2153,7 +2129,7 @@
// This function returns the tree representation for the vector field(s) being accessed from contant vector.
// If only one component of vector is accessed (v.x or v[0] where v is a contant vector), then a contant node is
// returned, else an aggregate node is returned (for v.xy). The input to this function could either be the symbol
-// node or it could be the intermediate tree representation of accessing fields in a constant structure or column of
+// node or it could be the intermediate tree representation of accessing fields in a constant structure or column of
// a constant matrix.
//
TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTyped* node, const TSourceLoc &line)
@@ -2625,7 +2601,7 @@
recover();
}
- if(baseExpression->getType().getQualifier() == EvqConstExpr)
+ if(baseExpression->getAsConstantUnion())
{
// constant folding for vector fields
indexedExpression = addConstVectorNode(fields, baseExpression, fieldLocation);