Commit 5c0e023c by Olli Etuaho

Qualify stored constant union data with const

This prevents accidentally changing data that may be shared between multiple TIntermConstantUnion nodes. Besides making the code less prone to bugs in general, this will make it easier to implement constant folding of array constructors. BUG=541551 TEST=angle_unittests, WebGL conformance tests Change-Id: I4f3059f70b841d9dd0cf20fea4d37684da9cd47e Reviewed-on: https://chromium-review.googlesource.com/312440Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Tryjob-Request: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Tested-by: 's avatarOlli Etuaho <oetuaho@nvidia.com>
parent 36b0514a
...@@ -169,7 +169,7 @@ void UndefinedConstantFoldingError(const TSourceLoc &loc, TOperator op, TBasicTy ...@@ -169,7 +169,7 @@ void UndefinedConstantFoldingError(const TSourceLoc &loc, TOperator op, TBasicTy
} }
} }
float VectorLength(TConstantUnion *paramArray, size_t paramArraySize) float VectorLength(const TConstantUnion *paramArray, size_t paramArraySize)
{ {
float result = 0.0f; float result = 0.0f;
for (size_t i = 0; i < paramArraySize; i++) for (size_t i = 0; i < paramArraySize; i++)
...@@ -180,7 +180,9 @@ float VectorLength(TConstantUnion *paramArray, size_t paramArraySize) ...@@ -180,7 +180,9 @@ float VectorLength(TConstantUnion *paramArray, size_t paramArraySize)
return sqrtf(result); return sqrtf(result);
} }
float VectorDotProduct(TConstantUnion *paramArray1, TConstantUnion *paramArray2, size_t paramArraySize) float VectorDotProduct(const TConstantUnion *paramArray1,
const TConstantUnion *paramArray2,
size_t paramArraySize)
{ {
float result = 0.0f; float result = 0.0f;
for (size_t i = 0; i < paramArraySize; i++) for (size_t i = 0; i < paramArraySize; i++)
...@@ -202,7 +204,9 @@ TIntermTyped *CreateFoldedNode(TConstantUnion *constArray, ...@@ -202,7 +204,9 @@ TIntermTyped *CreateFoldedNode(TConstantUnion *constArray,
return folded; return folded;
} }
angle::Matrix<float> GetMatrix(TConstantUnion *paramArray, const unsigned int &rows, const unsigned int &cols) angle::Matrix<float> GetMatrix(const TConstantUnion *paramArray,
const unsigned int &rows,
const unsigned int &cols)
{ {
std::vector<float> elements; std::vector<float> elements;
for (size_t i = 0; i < rows * cols; i++) for (size_t i = 0; i < rows * cols; i++)
...@@ -212,7 +216,7 @@ angle::Matrix<float> GetMatrix(TConstantUnion *paramArray, const unsigned int &r ...@@ -212,7 +216,7 @@ angle::Matrix<float> GetMatrix(TConstantUnion *paramArray, const unsigned int &r
return angle::Matrix<float>(elements, rows, cols).transpose(); return angle::Matrix<float>(elements, rows, cols).transpose();
} }
angle::Matrix<float> GetMatrix(TConstantUnion *paramArray, const unsigned int &size) angle::Matrix<float> GetMatrix(const TConstantUnion *paramArray, const unsigned int &size)
{ {
std::vector<float> elements; std::vector<float> elements;
for (size_t i = 0; i < size * size; i++) for (size_t i = 0; i < size * size; i++)
...@@ -416,12 +420,7 @@ TIntermTyped::TIntermTyped(const TIntermTyped &node) : TIntermNode(), mType(node ...@@ -416,12 +420,7 @@ TIntermTyped::TIntermTyped(const TIntermTyped &node) : TIntermNode(), mType(node
TIntermConstantUnion::TIntermConstantUnion(const TIntermConstantUnion &node) : TIntermTyped(node) TIntermConstantUnion::TIntermConstantUnion(const TIntermConstantUnion &node) : TIntermTyped(node)
{ {
size_t arraySize = mType.getObjectSize(); mUnionArrayPointer = node.mUnionArrayPointer;
mUnionArrayPointer = new TConstantUnion[arraySize];
for (size_t i = 0u; i < arraySize; ++i)
{
mUnionArrayPointer[i] = node.mUnionArrayPointer[i];
}
} }
TIntermAggregate::TIntermAggregate(const TIntermAggregate &node) TIntermAggregate::TIntermAggregate(const TIntermAggregate &node)
...@@ -969,8 +968,8 @@ TIntermTyped *TIntermAggregate::fold(TInfoSink &infoSink) ...@@ -969,8 +968,8 @@ TIntermTyped *TIntermAggregate::fold(TInfoSink &infoSink)
// //
TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op, TIntermConstantUnion *rightNode, TInfoSink &infoSink) TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op, TIntermConstantUnion *rightNode, TInfoSink &infoSink)
{ {
TConstantUnion *leftArray = getUnionArrayPointer(); const TConstantUnion *leftArray = getUnionArrayPointer();
TConstantUnion *rightArray = rightNode->getUnionArrayPointer(); const TConstantUnion *rightArray = rightNode->getUnionArrayPointer();
if (!leftArray) if (!leftArray)
return nullptr; return nullptr;
...@@ -1317,7 +1316,7 @@ TConstantUnion *TIntermConstantUnion::foldUnaryWithDifferentReturnType(TOperator ...@@ -1317,7 +1316,7 @@ TConstantUnion *TIntermConstantUnion::foldUnaryWithDifferentReturnType(TOperator
// Do operations where the return type has a different number of components compared to the operand type. // Do operations where the return type has a different number of components compared to the operand type.
// //
TConstantUnion *operandArray = getUnionArrayPointer(); const TConstantUnion *operandArray = getUnionArrayPointer();
if (!operandArray) if (!operandArray)
return nullptr; return nullptr;
...@@ -1530,7 +1529,7 @@ TConstantUnion *TIntermConstantUnion::foldUnaryWithSameReturnType(TOperator op, ...@@ -1530,7 +1529,7 @@ TConstantUnion *TIntermConstantUnion::foldUnaryWithSameReturnType(TOperator op,
// Do unary operations where the return type is the same as operand type. // Do unary operations where the return type is the same as operand type.
// //
TConstantUnion *operandArray = getUnionArrayPointer(); const TConstantUnion *operandArray = getUnionArrayPointer();
if (!operandArray) if (!operandArray)
return nullptr; return nullptr;
...@@ -2082,7 +2081,7 @@ TConstantUnion *TIntermConstantUnion::FoldAggregateBuiltIn(TIntermAggregate *agg ...@@ -2082,7 +2081,7 @@ TConstantUnion *TIntermConstantUnion::FoldAggregateBuiltIn(TIntermAggregate *agg
TOperator op = aggregate->getOp(); TOperator op = aggregate->getOp();
TIntermSequence *sequence = aggregate->getSequence(); TIntermSequence *sequence = aggregate->getSequence();
unsigned int paramsCount = static_cast<unsigned int>(sequence->size()); unsigned int paramsCount = static_cast<unsigned int>(sequence->size());
std::vector<TConstantUnion *> unionArrays(paramsCount); std::vector<const TConstantUnion *> unionArrays(paramsCount);
std::vector<size_t> objectSizes(paramsCount); std::vector<size_t> objectSizes(paramsCount);
size_t maxObjectSize = 0; size_t maxObjectSize = 0;
TBasicType basicType = EbtVoid; TBasicType basicType = EbtVoid;
......
...@@ -302,16 +302,16 @@ class TIntermRaw : public TIntermTyped ...@@ -302,16 +302,16 @@ class TIntermRaw : public TIntermTyped
class TIntermConstantUnion : public TIntermTyped class TIntermConstantUnion : public TIntermTyped
{ {
public: public:
TIntermConstantUnion(TConstantUnion *unionPointer, const TType &type) TIntermConstantUnion(const TConstantUnion *unionPointer, const TType &type)
: TIntermTyped(type), : TIntermTyped(type), mUnionArrayPointer(unionPointer)
mUnionArrayPointer(unionPointer) { } {
}
TIntermTyped *deepCopy() const override { return new TIntermConstantUnion(*this); } TIntermTyped *deepCopy() const override { return new TIntermConstantUnion(*this); }
bool hasSideEffects() const override { return false; } bool hasSideEffects() const override { return false; }
const TConstantUnion *getUnionArrayPointer() const { return mUnionArrayPointer; } const TConstantUnion *getUnionArrayPointer() const { return mUnionArrayPointer; }
TConstantUnion *getUnionArrayPointer() { return mUnionArrayPointer; }
int getIConst(size_t index) const int getIConst(size_t index) const
{ {
...@@ -330,7 +330,7 @@ class TIntermConstantUnion : public TIntermTyped ...@@ -330,7 +330,7 @@ class TIntermConstantUnion : public TIntermTyped
return mUnionArrayPointer ? mUnionArrayPointer[index].getBConst() : false; return mUnionArrayPointer ? mUnionArrayPointer[index].getBConst() : false;
} }
void replaceConstantUnion(TConstantUnion *safeConstantUnion) void replaceConstantUnion(const TConstantUnion *safeConstantUnion)
{ {
// Previous union pointer freed on pool deallocation. // Previous union pointer freed on pool deallocation.
mUnionArrayPointer = safeConstantUnion; mUnionArrayPointer = safeConstantUnion;
...@@ -349,7 +349,8 @@ class TIntermConstantUnion : public TIntermTyped ...@@ -349,7 +349,8 @@ class TIntermConstantUnion : public TIntermTyped
static TConstantUnion *FoldAggregateBuiltIn(TIntermAggregate *aggregate, TInfoSink &infoSink); static TConstantUnion *FoldAggregateBuiltIn(TIntermAggregate *aggregate, TInfoSink &infoSink);
protected: protected:
TConstantUnion *mUnionArrayPointer; // Same data may be shared between multiple constant unions, so it can't be modified.
const TConstantUnion *mUnionArrayPointer;
private: private:
typedef float(*FloatTypeUnaryFunc) (float); typedef float(*FloatTypeUnaryFunc) (float);
......
...@@ -375,8 +375,9 @@ TIntermCase *TIntermediate::addCase( ...@@ -375,8 +375,9 @@ TIntermCase *TIntermediate::addCase(
// Returns the constant union node created. // Returns the constant union node created.
// //
TIntermConstantUnion *TIntermediate::addConstantUnion( TIntermConstantUnion *TIntermediate::addConstantUnion(const TConstantUnion *constantUnion,
TConstantUnion *constantUnion, const TType &type, const TSourceLoc &line) const TType &type,
const TSourceLoc &line)
{ {
TIntermConstantUnion *node = new TIntermConstantUnion(constantUnion, type); TIntermConstantUnion *node = new TIntermConstantUnion(constantUnion, type);
node->setLine(line); node->setLine(line);
......
...@@ -52,8 +52,9 @@ class TIntermediate ...@@ -52,8 +52,9 @@ class TIntermediate
TIntermTyped *right, TIntermTyped *right,
const TSourceLoc &line, const TSourceLoc &line,
int shaderVersion); int shaderVersion);
TIntermConstantUnion *addConstantUnion( TIntermConstantUnion *addConstantUnion(const TConstantUnion *constantUnion,
TConstantUnion *constantUnion, const TType &type, const TSourceLoc &line); const TType &type,
const TSourceLoc &line);
TIntermNode *addLoop(TLoopType, TIntermNode *, TIntermTyped *, TIntermTyped *, TIntermNode *addLoop(TLoopType, TIntermNode *, TIntermTyped *, TIntermTyped *,
TIntermNode *, const TSourceLoc &); TIntermNode *, const TSourceLoc &);
TIntermBranch *addBranch(TOperator, const TSourceLoc &); TIntermBranch *addBranch(TOperator, const TSourceLoc &);
......
...@@ -1216,7 +1216,7 @@ TIntermTyped *TParseContext::parseVariableIdentifier(const TSourceLoc &location, ...@@ -1216,7 +1216,7 @@ TIntermTyped *TParseContext::parseVariableIdentifier(const TSourceLoc &location,
if (variable->getConstPointer()) if (variable->getConstPointer())
{ {
TConstantUnion *constArray = variable->getConstPointer(); const TConstantUnion *constArray = variable->getConstPointer();
return intermediate.addConstantUnion(constArray, variable->getType(), location); return intermediate.addConstantUnion(constArray, variable->getType(), location);
} }
else else
...@@ -1353,7 +1353,7 @@ bool TParseContext::executeInitializer(const TSourceLoc &line, ...@@ -1353,7 +1353,7 @@ bool TParseContext::executeInitializer(const TSourceLoc &line,
symbolTable.find(initializer->getAsSymbolNode()->getSymbol(), 0); symbolTable.find(initializer->getAsSymbolNode()->getSymbol(), 0);
const TVariable *tVar = static_cast<const TVariable *>(symbol); const TVariable *tVar = static_cast<const TVariable *>(symbol);
TConstantUnion *constArray = tVar->getConstPointer(); const TConstantUnion *constArray = tVar->getConstPointer();
if (constArray) if (constArray)
{ {
variable->shareConstPointer(constArray); variable->shareConstPointer(constArray);
...@@ -2373,7 +2373,7 @@ TIntermTyped *TParseContext::addConstMatrixNode(int index, ...@@ -2373,7 +2373,7 @@ TIntermTyped *TParseContext::addConstMatrixNode(int index,
index = node->getType().getCols() - 1; index = node->getType().getCols() - 1;
} }
TConstantUnion *unionArray = node->getUnionArrayPointer(); const TConstantUnion *unionArray = node->getUnionArrayPointer();
int size = node->getType().getCols(); int size = node->getType().getCols();
return intermediate.addConstantUnion(&unionArray[size * index], node->getType(), line); return intermediate.addConstantUnion(&unionArray[size * index], node->getType(), line);
} }
...@@ -2401,8 +2401,8 @@ TIntermTyped *TParseContext::addConstArrayNode(int index, ...@@ -2401,8 +2401,8 @@ TIntermTyped *TParseContext::addConstArrayNode(int index,
outOfRangeError(outOfRangeIndexIsError, line, "", "[", extraInfo.c_str()); outOfRangeError(outOfRangeIndexIsError, line, "", "[", extraInfo.c_str());
index = node->getType().getArraySize() - 1; index = node->getType().getArraySize() - 1;
} }
size_t arrayElementSize = arrayElementType.getObjectSize(); size_t arrayElementSize = arrayElementType.getObjectSize();
TConstantUnion *unionArray = node->getUnionArrayPointer(); const TConstantUnion *unionArray = node->getUnionArrayPointer();
return intermediate.addConstantUnion(&unionArray[arrayElementSize * index], node->getType(), return intermediate.addConstantUnion(&unionArray[arrayElementSize * index], node->getType(),
line); line);
} }
...@@ -2437,7 +2437,7 @@ TIntermTyped *TParseContext::addConstStruct(const TString &identifier, ...@@ -2437,7 +2437,7 @@ TIntermTyped *TParseContext::addConstStruct(const TString &identifier,
TIntermConstantUnion *tempConstantNode = node->getAsConstantUnion(); TIntermConstantUnion *tempConstantNode = node->getAsConstantUnion();
if (tempConstantNode) if (tempConstantNode)
{ {
TConstantUnion *constArray = tempConstantNode->getUnionArrayPointer(); const TConstantUnion *constArray = tempConstantNode->getUnionArrayPointer();
// type will be changed in the calling function // type will be changed in the calling function
typedNode = intermediate.addConstantUnion(constArray + instanceSize, typedNode = intermediate.addConstantUnion(constArray + instanceSize,
...@@ -2796,8 +2796,9 @@ TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression, ...@@ -2796,8 +2796,9 @@ TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression,
safeIndex = baseExpression->getType().getNominalSize() - 1; safeIndex = baseExpression->getType().getNominalSize() - 1;
} }
// Don't modify the data of the previous constant union, because it can point // Data of constant unions can't be changed, because it may be shared with other
// to builtins, like gl_MaxDrawBuffers. Instead use a new sanitized object. // constant unions or even builtins, like gl_MaxDrawBuffers. Instead use a new
// sanitized object.
if (safeIndex != -1) if (safeIndex != -1)
{ {
TConstantUnion *safeConstantUnion = new TConstantUnion(); TConstantUnion *safeConstantUnion = new TConstantUnion();
......
...@@ -128,34 +128,16 @@ class TVariable : public TSymbol ...@@ -128,34 +128,16 @@ class TVariable : public TSymbol
type.setQualifier(qualifier); type.setQualifier(qualifier);
} }
TConstantUnion *getConstPointer() const TConstantUnion *getConstPointer() const { return unionArray; }
{
if (!unionArray)
unionArray = new TConstantUnion[type.getObjectSize()];
return unionArray; void shareConstPointer(const TConstantUnion *constArray) { unionArray = constArray; }
}
TConstantUnion *getConstPointer() const
{
return unionArray;
}
void shareConstPointer(TConstantUnion *constArray)
{
if (unionArray == constArray)
return;
delete[] unionArray;
unionArray = constArray;
}
private: private:
TType type; TType type;
bool userType; bool userType;
// we are assuming that Pool Allocator will free the memory // we are assuming that Pool Allocator will free the memory
// allocated to unionArray when this object is destroyed. // allocated to unionArray when this object is destroyed.
TConstantUnion *unionArray; const TConstantUnion *unionArray;
}; };
// Immutable version of TParameter. // Immutable version of TParameter.
...@@ -400,7 +382,9 @@ class TSymbolTable : angle::NonCopyable ...@@ -400,7 +382,9 @@ class TSymbolTable : angle::NonCopyable
{ {
TVariable *constant = new TVariable( TVariable *constant = new TVariable(
NewPoolTString(name), TType(EbtInt, EbpUndefined, EvqConst, 1)); NewPoolTString(name), TType(EbtInt, EbpUndefined, EvqConst, 1));
constant->getConstPointer()->setIConst(value); TConstantUnion *unionArray = new TConstantUnion[1];
unionArray[0].setIConst(value);
constant->shareConstPointer(unionArray);
return insert(level, constant); return insert(level, constant);
} }
...@@ -408,7 +392,9 @@ class TSymbolTable : angle::NonCopyable ...@@ -408,7 +392,9 @@ class TSymbolTable : angle::NonCopyable
{ {
TVariable *constant = TVariable *constant =
new TVariable(NewPoolTString(name), TType(EbtInt, EbpUndefined, EvqConst, 1)); new TVariable(NewPoolTString(name), TType(EbtInt, EbpUndefined, EvqConst, 1));
constant->getConstPointer()->setIConst(value); TConstantUnion *unionArray = new TConstantUnion[1];
unionArray[0].setIConst(value);
constant->shareConstPointer(unionArray);
return insert(level, ext, constant); return insert(level, ext, constant);
} }
......
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