Commit f119a263 by Olli Etuaho Committed by Commit Bot

Clean up unary and aggregate math folding

Prefer asserts instead of adding internal errors to the compiler log when types of arguments are not as expected or the folding function runs into an operation it can't handle. Neither of these cases should be possible, the checks for correct argument types are solid at this point. In the future, when new built-in functions are added, constant folding support for them should be added as well. foldUnaryWithDifferentReturnType and foldUnaryWithSameReturnType are renamed to foldUnaryNonComponentWise and foldUnaryComponentWise respectively. These names better reflect what these functions are doing. The info sink member is removed from TIntermediate, since TDiagnostics is now passed into the functions that may generate warnings instead. BUG=angleproject:1490 TEST=angle_unittests Change-Id: I6a08abbe29cf23f3a318032fdc46dd3dbaf4410e Reviewed-on: https://chromium-review.googlesource.com/377959 Commit-Queue: Olli Etuaho <oetuaho@nvidia.com> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org>
parent 9df01f8a
...@@ -219,8 +219,7 @@ TIntermNode *TCompiler::compileTreeImpl(const char *const shaderStrings[], ...@@ -219,8 +219,7 @@ TIntermNode *TCompiler::compileTreeImpl(const char *const shaderStrings[],
++firstSource; ++firstSource;
} }
TIntermediate intermediate(infoSink); TParseContext parseContext(symbolTable, extensionBehavior, shaderType, shaderSpec,
TParseContext parseContext(symbolTable, extensionBehavior, intermediate, shaderType, shaderSpec,
compileOptions, true, infoSink, getResources()); compileOptions, true, infoSink, getResources());
parseContext.setFragmentPrecisionHighOnESSL1(fragmentPrecisionHigh); parseContext.setFragmentPrecisionHighOnESSL1(fragmentPrecisionHigh);
...@@ -254,7 +253,7 @@ TIntermNode *TCompiler::compileTreeImpl(const char *const shaderStrings[], ...@@ -254,7 +253,7 @@ TIntermNode *TCompiler::compileTreeImpl(const char *const shaderStrings[],
mComputeShaderLocalSize = parseContext.getComputeShaderLocalSize(); mComputeShaderLocalSize = parseContext.getComputeShaderLocalSize();
root = parseContext.getTreeRoot(); root = parseContext.getTreeRoot();
root = intermediate.postProcess(root); root = TIntermediate::PostProcess(root);
// Highp might have been auto-enabled based on shader version // Highp might have been auto-enabled based on shader version
fragmentPrecisionHigh = parseContext.getFragmentPrecisionHigh(); fragmentPrecisionHigh = parseContext.getFragmentPrecisionHigh();
......
...@@ -319,6 +319,7 @@ class TIntermConstantUnion : public TIntermTyped ...@@ -319,6 +319,7 @@ class TIntermConstantUnion : public TIntermTyped
TIntermConstantUnion(const TConstantUnion *unionPointer, const TType &type) TIntermConstantUnion(const TConstantUnion *unionPointer, const TType &type)
: TIntermTyped(type), mUnionArrayPointer(unionPointer) : TIntermTyped(type), mUnionArrayPointer(unionPointer)
{ {
ASSERT(unionPointer);
} }
TIntermTyped *deepCopy() const override { return new TIntermConstantUnion(*this); } TIntermTyped *deepCopy() const override { return new TIntermConstantUnion(*this); }
...@@ -346,6 +347,7 @@ class TIntermConstantUnion : public TIntermTyped ...@@ -346,6 +347,7 @@ class TIntermConstantUnion : public TIntermTyped
void replaceConstantUnion(const TConstantUnion *safeConstantUnion) void replaceConstantUnion(const TConstantUnion *safeConstantUnion)
{ {
ASSERT(safeConstantUnion);
// Previous union pointer freed on pool deallocation. // Previous union pointer freed on pool deallocation.
mUnionArrayPointer = safeConstantUnion; mUnionArrayPointer = safeConstantUnion;
} }
...@@ -357,12 +359,12 @@ class TIntermConstantUnion : public TIntermTyped ...@@ -357,12 +359,12 @@ class TIntermConstantUnion : public TIntermTyped
TConstantUnion *foldBinary(TOperator op, TConstantUnion *foldBinary(TOperator op,
TIntermConstantUnion *rightNode, TIntermConstantUnion *rightNode,
TDiagnostics *diagnostics); TDiagnostics *diagnostics);
TConstantUnion *foldUnaryWithDifferentReturnType(TOperator op, TInfoSink &infoSink); TConstantUnion *foldUnaryNonComponentWise(TOperator op);
TConstantUnion *foldUnaryWithSameReturnType(TOperator op, TInfoSink &infoSink); TConstantUnion *foldUnaryComponentWise(TOperator op, TDiagnostics *diagnostics);
static TConstantUnion *FoldAggregateConstructor(TIntermAggregate *aggregate, static TConstantUnion *FoldAggregateConstructor(TIntermAggregate *aggregate);
TInfoSink &infoSink); static TConstantUnion *FoldAggregateBuiltIn(TIntermAggregate *aggregate,
static TConstantUnion *FoldAggregateBuiltIn(TIntermAggregate *aggregate, TInfoSink &infoSink); TDiagnostics *diagnostics);
protected: protected:
// Same data may be shared between multiple constant unions, so it can't be modified. // Same data may be shared between multiple constant unions, so it can't be modified.
...@@ -370,7 +372,9 @@ class TIntermConstantUnion : public TIntermTyped ...@@ -370,7 +372,9 @@ class TIntermConstantUnion : public TIntermTyped
private: private:
typedef float(*FloatTypeUnaryFunc) (float); typedef float(*FloatTypeUnaryFunc) (float);
bool foldFloatTypeUnary(const TConstantUnion &parameter, FloatTypeUnaryFunc builtinFunc, TInfoSink &infoSink, TConstantUnion *result) const; void foldFloatTypeUnary(const TConstantUnion &parameter,
FloatTypeUnaryFunc builtinFunc,
TConstantUnion *result) const;
TIntermConstantUnion(const TIntermConstantUnion &node); // Note: not deleted, just private! TIntermConstantUnion(const TIntermConstantUnion &node); // Note: not deleted, just private!
}; };
...@@ -468,6 +472,11 @@ class TIntermUnary : public TIntermOperator ...@@ -468,6 +472,11 @@ class TIntermUnary : public TIntermOperator
mOperand(NULL), mOperand(NULL),
mUseEmulatedFunction(false) {} mUseEmulatedFunction(false) {}
TIntermUnary(TOperator op, TIntermTyped *operand)
: TIntermOperator(op), mOperand(operand), mUseEmulatedFunction(false)
{
}
TIntermTyped *deepCopy() const override { return new TIntermUnary(*this); } TIntermTyped *deepCopy() const override { return new TIntermUnary(*this); }
void traverse(TIntermTraverser *it) override; void traverse(TIntermTraverser *it) override;
...@@ -479,7 +488,7 @@ class TIntermUnary : public TIntermOperator ...@@ -479,7 +488,7 @@ class TIntermUnary : public TIntermOperator
void setOperand(TIntermTyped *operand) { mOperand = operand; } void setOperand(TIntermTyped *operand) { mOperand = operand; }
TIntermTyped *getOperand() { return mOperand; } TIntermTyped *getOperand() { return mOperand; }
void promote(const TType *funcReturnType); void promote(const TType *funcReturnType);
TIntermTyped *fold(TInfoSink &infoSink); TIntermTyped *fold(TDiagnostics *diagnostics);
void setUseEmulatedFunction() { mUseEmulatedFunction = true; } void setUseEmulatedFunction() { mUseEmulatedFunction = true; }
bool getUseEmulatedFunction() { return mUseEmulatedFunction; } bool getUseEmulatedFunction() { return mUseEmulatedFunction; }
...@@ -532,7 +541,7 @@ class TIntermAggregate : public TIntermOperator ...@@ -532,7 +541,7 @@ class TIntermAggregate : public TIntermOperator
bool insertChildNodes(TIntermSequence::size_type position, TIntermSequence insertions); bool insertChildNodes(TIntermSequence::size_type position, TIntermSequence insertions);
// Conservatively assume function calls and other aggregate operators have side-effects // Conservatively assume function calls and other aggregate operators have side-effects
bool hasSideEffects() const override { return true; } bool hasSideEffects() const override { return true; }
TIntermTyped *fold(TInfoSink &infoSink); TIntermTyped *fold(TDiagnostics *diagnostics);
TIntermSequence *getSequence() { return &mSequence; } TIntermSequence *getSequence() { return &mSequence; }
const TIntermSequence *getSequence() const { return &mSequence; } const TIntermSequence *getSequence() const { return &mSequence; }
......
...@@ -58,29 +58,6 @@ TIntermTyped *TIntermediate::addIndex( ...@@ -58,29 +58,6 @@ TIntermTyped *TIntermediate::addIndex(
} }
// //
// Add one node as the parent of another that it operates on.
//
// Returns the added node.
//
TIntermTyped *TIntermediate::addUnaryMath(
TOperator op, TIntermTyped *child, const TSourceLoc &line, const TType *funcReturnType)
{
//
// Make a new node for the operator.
//
TIntermUnary *node = new TIntermUnary(op);
node->setLine(line);
node->setOperand(child);
node->promote(funcReturnType);
TIntermTyped *foldedNode = node->fold(mInfoSink);
if (foldedNode)
return foldedNode;
return node;
}
//
// This is the safe way to change the operator on an aggregate, as it // This is the safe way to change the operator on an aggregate, as it
// does lots of error checking and fixing. Especially for establishing // does lots of error checking and fixing. Especially for establishing
// a function call's operation on it's set of parameters. Sequences // a function call's operation on it's set of parameters. Sequences
...@@ -388,7 +365,7 @@ TIntermBranch* TIntermediate::addBranch( ...@@ -388,7 +365,7 @@ TIntermBranch* TIntermediate::addBranch(
// This is to be executed once the final root is put on top by the parsing // This is to be executed once the final root is put on top by the parsing
// process. // process.
// //
TIntermAggregate *TIntermediate::postProcess(TIntermNode *root) TIntermAggregate *TIntermediate::PostProcess(TIntermNode *root)
{ {
if (root == nullptr) if (root == nullptr)
return nullptr; return nullptr;
...@@ -411,7 +388,8 @@ TIntermAggregate *TIntermediate::postProcess(TIntermNode *root) ...@@ -411,7 +388,8 @@ TIntermAggregate *TIntermediate::postProcess(TIntermNode *root)
return aggRoot; return aggRoot;
} }
TIntermTyped *TIntermediate::foldAggregateBuiltIn(TIntermAggregate *aggregate) TIntermTyped *TIntermediate::foldAggregateBuiltIn(TIntermAggregate *aggregate,
TDiagnostics *diagnostics)
{ {
switch (aggregate->getOp()) switch (aggregate->getOp())
{ {
...@@ -438,12 +416,12 @@ TIntermTyped *TIntermediate::foldAggregateBuiltIn(TIntermAggregate *aggregate) ...@@ -438,12 +416,12 @@ TIntermTyped *TIntermediate::foldAggregateBuiltIn(TIntermAggregate *aggregate)
case EOpFaceForward: case EOpFaceForward:
case EOpReflect: case EOpReflect:
case EOpRefract: case EOpRefract:
return aggregate->fold(mInfoSink); return aggregate->fold(diagnostics);
default: default:
// TODO: Add support for folding array constructors // TODO: Add support for folding array constructors
if (aggregate->isConstructor() && !aggregate->isArray()) if (aggregate->isConstructor() && !aggregate->isArray())
{ {
return aggregate->fold(mInfoSink); return aggregate->fold(diagnostics);
} }
// Constant folding not supported for the built-in. // Constant folding not supported for the built-in.
return nullptr; return nullptr;
......
...@@ -16,15 +16,13 @@ struct TVectorFields ...@@ -16,15 +16,13 @@ struct TVectorFields
}; };
// //
// Set of helper functions to help parse and build the tree. // Set of helper functions to help build the tree.
// //
class TInfoSink;
class TIntermediate class TIntermediate
{ {
public: public:
POOL_ALLOCATOR_NEW_DELETE(); POOL_ALLOCATOR_NEW_DELETE();
TIntermediate(TInfoSink &i) TIntermediate() {}
: mInfoSink(i) { }
TIntermSymbol *addSymbol( TIntermSymbol *addSymbol(
int id, const TString &, const TType &, const TSourceLoc &); int id, const TString &, const TType &, const TSourceLoc &);
...@@ -56,16 +54,14 @@ class TIntermediate ...@@ -56,16 +54,14 @@ class TIntermediate
TIntermBranch *addBranch(TOperator, const TSourceLoc &); TIntermBranch *addBranch(TOperator, const TSourceLoc &);
TIntermBranch *addBranch(TOperator, TIntermTyped *, const TSourceLoc &); TIntermBranch *addBranch(TOperator, TIntermTyped *, const TSourceLoc &);
TIntermTyped *addSwizzle(TVectorFields &, const TSourceLoc &); TIntermTyped *addSwizzle(TVectorFields &, const TSourceLoc &);
TIntermAggregate *postProcess(TIntermNode *root); static TIntermAggregate *PostProcess(TIntermNode *root);
static void outputTree(TIntermNode *, TInfoSinkBase &); static void outputTree(TIntermNode *, TInfoSinkBase &);
TIntermTyped *foldAggregateBuiltIn(TIntermAggregate *aggregate); TIntermTyped *foldAggregateBuiltIn(TIntermAggregate *aggregate, TDiagnostics *diagnostics);
private: private:
void operator=(TIntermediate &); // prevent assignments void operator=(TIntermediate &); // prevent assignments
TInfoSink & mInfoSink;
}; };
#endif // COMPILER_TRANSLATOR_INTERMEDIATE_H_ #endif // COMPILER_TRANSLATOR_INTERMEDIATE_H_
...@@ -2376,7 +2376,7 @@ TIntermTyped *TParseContext::addConstructor(TIntermNode *arguments, ...@@ -2376,7 +2376,7 @@ TIntermTyped *TParseContext::addConstructor(TIntermNode *arguments,
constructor->setType(type); constructor->setType(type);
TIntermTyped *constConstructor = intermediate.foldAggregateBuiltIn(constructor); TIntermTyped *constConstructor = intermediate.foldAggregateBuiltIn(constructor, &mDiagnostics);
if (constConstructor) if (constConstructor)
{ {
return constConstructor; return constConstructor;
...@@ -3425,7 +3425,15 @@ TIntermTyped *TParseContext::createUnaryMath(TOperator op, ...@@ -3425,7 +3425,15 @@ TIntermTyped *TParseContext::createUnaryMath(TOperator op,
break; break;
} }
return intermediate.addUnaryMath(op, child, loc, funcReturnType); TIntermUnary *node = new TIntermUnary(op, child);
node->setLine(loc);
node->promote(funcReturnType);
TIntermTyped *foldedNode = 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)
...@@ -4054,7 +4062,8 @@ TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunction *fnCall, ...@@ -4054,7 +4062,8 @@ TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunction *fnCall,
// See if we can constant fold a built-in. Note that this may be possible even // See if we can constant fold a built-in. Note that this may be possible even
// if it is not const-qualified. // if it is not const-qualified.
TIntermTyped *foldedNode = intermediate.foldAggregateBuiltIn(aggregate); TIntermTyped *foldedNode =
intermediate.foldAggregateBuiltIn(aggregate, &mDiagnostics);
if (foldedNode) if (foldedNode)
{ {
callNode = foldedNode; callNode = foldedNode;
......
...@@ -31,14 +31,13 @@ class TParseContext : angle::NonCopyable ...@@ -31,14 +31,13 @@ class TParseContext : angle::NonCopyable
public: public:
TParseContext(TSymbolTable &symt, TParseContext(TSymbolTable &symt,
TExtensionBehavior &ext, TExtensionBehavior &ext,
TIntermediate &interm,
sh::GLenum type, sh::GLenum type,
ShShaderSpec spec, ShShaderSpec spec,
int options, int options,
bool checksPrecErrors, bool checksPrecErrors,
TInfoSink &is, TInfoSink &is,
const ShBuiltInResources &resources) const ShBuiltInResources &resources)
: intermediate(interm), : intermediate(),
symbolTable(symt), symbolTable(symt),
mDeferredSingleDeclarationErrorCheck(false), mDeferredSingleDeclarationErrorCheck(false),
mShaderType(type), mShaderType(type),
...@@ -367,7 +366,7 @@ class TParseContext : angle::NonCopyable ...@@ -367,7 +366,7 @@ class TParseContext : angle::NonCopyable
TIntermTyped *cond, TIntermTyped *trueBlock, TIntermTyped *falseBlock, const TSourceLoc &line); TIntermTyped *cond, TIntermTyped *trueBlock, TIntermTyped *falseBlock, const TSourceLoc &line);
// TODO(jmadill): make these private // TODO(jmadill): make these private
TIntermediate &intermediate; // to hold and build a parse tree TIntermediate intermediate; // to build a parse tree
TSymbolTable &symbolTable; // symbol table that goes with the language currently being parsed TSymbolTable &symbolTable; // symbol table that goes with the language currently being parsed
private: private:
......
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