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[],
++firstSource;
}
TIntermediate intermediate(infoSink);
TParseContext parseContext(symbolTable, extensionBehavior, intermediate, shaderType, shaderSpec,
TParseContext parseContext(symbolTable, extensionBehavior, shaderType, shaderSpec,
compileOptions, true, infoSink, getResources());
parseContext.setFragmentPrecisionHighOnESSL1(fragmentPrecisionHigh);
......@@ -254,7 +253,7 @@ TIntermNode *TCompiler::compileTreeImpl(const char *const shaderStrings[],
mComputeShaderLocalSize = parseContext.getComputeShaderLocalSize();
root = parseContext.getTreeRoot();
root = intermediate.postProcess(root);
root = TIntermediate::PostProcess(root);
// Highp might have been auto-enabled based on shader version
fragmentPrecisionHigh = parseContext.getFragmentPrecisionHigh();
......
......@@ -319,6 +319,7 @@ class TIntermConstantUnion : public TIntermTyped
TIntermConstantUnion(const TConstantUnion *unionPointer, const TType &type)
: TIntermTyped(type), mUnionArrayPointer(unionPointer)
{
ASSERT(unionPointer);
}
TIntermTyped *deepCopy() const override { return new TIntermConstantUnion(*this); }
......@@ -346,6 +347,7 @@ class TIntermConstantUnion : public TIntermTyped
void replaceConstantUnion(const TConstantUnion *safeConstantUnion)
{
ASSERT(safeConstantUnion);
// Previous union pointer freed on pool deallocation.
mUnionArrayPointer = safeConstantUnion;
}
......@@ -357,12 +359,12 @@ class TIntermConstantUnion : public TIntermTyped
TConstantUnion *foldBinary(TOperator op,
TIntermConstantUnion *rightNode,
TDiagnostics *diagnostics);
TConstantUnion *foldUnaryWithDifferentReturnType(TOperator op, TInfoSink &infoSink);
TConstantUnion *foldUnaryWithSameReturnType(TOperator op, TInfoSink &infoSink);
TConstantUnion *foldUnaryNonComponentWise(TOperator op);
TConstantUnion *foldUnaryComponentWise(TOperator op, TDiagnostics *diagnostics);
static TConstantUnion *FoldAggregateConstructor(TIntermAggregate *aggregate,
TInfoSink &infoSink);
static TConstantUnion *FoldAggregateBuiltIn(TIntermAggregate *aggregate, TInfoSink &infoSink);
static TConstantUnion *FoldAggregateConstructor(TIntermAggregate *aggregate);
static TConstantUnion *FoldAggregateBuiltIn(TIntermAggregate *aggregate,
TDiagnostics *diagnostics);
protected:
// Same data may be shared between multiple constant unions, so it can't be modified.
......@@ -370,7 +372,9 @@ class TIntermConstantUnion : public TIntermTyped
private:
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!
};
......@@ -468,6 +472,11 @@ class TIntermUnary : public TIntermOperator
mOperand(NULL),
mUseEmulatedFunction(false) {}
TIntermUnary(TOperator op, TIntermTyped *operand)
: TIntermOperator(op), mOperand(operand), mUseEmulatedFunction(false)
{
}
TIntermTyped *deepCopy() const override { return new TIntermUnary(*this); }
void traverse(TIntermTraverser *it) override;
......@@ -479,7 +488,7 @@ class TIntermUnary : public TIntermOperator
void setOperand(TIntermTyped *operand) { mOperand = operand; }
TIntermTyped *getOperand() { return mOperand; }
void promote(const TType *funcReturnType);
TIntermTyped *fold(TInfoSink &infoSink);
TIntermTyped *fold(TDiagnostics *diagnostics);
void setUseEmulatedFunction() { mUseEmulatedFunction = true; }
bool getUseEmulatedFunction() { return mUseEmulatedFunction; }
......@@ -532,7 +541,7 @@ class TIntermAggregate : public TIntermOperator
bool insertChildNodes(TIntermSequence::size_type position, TIntermSequence insertions);
// Conservatively assume function calls and other aggregate operators have side-effects
bool hasSideEffects() const override { return true; }
TIntermTyped *fold(TInfoSink &infoSink);
TIntermTyped *fold(TDiagnostics *diagnostics);
TIntermSequence *getSequence() { return &mSequence; }
const TIntermSequence *getSequence() const { return &mSequence; }
......
......@@ -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
// does lots of error checking and fixing. Especially for establishing
// a function call's operation on it's set of parameters. Sequences
......@@ -388,7 +365,7 @@ TIntermBranch* TIntermediate::addBranch(
// This is to be executed once the final root is put on top by the parsing
// process.
//
TIntermAggregate *TIntermediate::postProcess(TIntermNode *root)
TIntermAggregate *TIntermediate::PostProcess(TIntermNode *root)
{
if (root == nullptr)
return nullptr;
......@@ -411,7 +388,8 @@ TIntermAggregate *TIntermediate::postProcess(TIntermNode *root)
return aggRoot;
}
TIntermTyped *TIntermediate::foldAggregateBuiltIn(TIntermAggregate *aggregate)
TIntermTyped *TIntermediate::foldAggregateBuiltIn(TIntermAggregate *aggregate,
TDiagnostics *diagnostics)
{
switch (aggregate->getOp())
{
......@@ -438,12 +416,12 @@ TIntermTyped *TIntermediate::foldAggregateBuiltIn(TIntermAggregate *aggregate)
case EOpFaceForward:
case EOpReflect:
case EOpRefract:
return aggregate->fold(mInfoSink);
return aggregate->fold(diagnostics);
default:
// TODO: Add support for folding array constructors
if (aggregate->isConstructor() && !aggregate->isArray())
{
return aggregate->fold(mInfoSink);
return aggregate->fold(diagnostics);
}
// Constant folding not supported for the built-in.
return nullptr;
......
......@@ -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
{
public:
POOL_ALLOCATOR_NEW_DELETE();
TIntermediate(TInfoSink &i)
: mInfoSink(i) { }
TIntermediate() {}
TIntermSymbol *addSymbol(
int id, const TString &, const TType &, const TSourceLoc &);
......@@ -56,16 +54,14 @@ class TIntermediate
TIntermBranch *addBranch(TOperator, const TSourceLoc &);
TIntermBranch *addBranch(TOperator, TIntermTyped *, const TSourceLoc &);
TIntermTyped *addSwizzle(TVectorFields &, const TSourceLoc &);
TIntermAggregate *postProcess(TIntermNode *root);
static TIntermAggregate *PostProcess(TIntermNode *root);
static void outputTree(TIntermNode *, TInfoSinkBase &);
TIntermTyped *foldAggregateBuiltIn(TIntermAggregate *aggregate);
TIntermTyped *foldAggregateBuiltIn(TIntermAggregate *aggregate, TDiagnostics *diagnostics);
private:
void operator=(TIntermediate &); // prevent assignments
TInfoSink & mInfoSink;
};
#endif // COMPILER_TRANSLATOR_INTERMEDIATE_H_
......@@ -2376,7 +2376,7 @@ TIntermTyped *TParseContext::addConstructor(TIntermNode *arguments,
constructor->setType(type);
TIntermTyped *constConstructor = intermediate.foldAggregateBuiltIn(constructor);
TIntermTyped *constConstructor = intermediate.foldAggregateBuiltIn(constructor, &mDiagnostics);
if (constConstructor)
{
return constConstructor;
......@@ -3425,7 +3425,15 @@ TIntermTyped *TParseContext::createUnaryMath(TOperator op,
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)
......@@ -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
// if it is not const-qualified.
TIntermTyped *foldedNode = intermediate.foldAggregateBuiltIn(aggregate);
TIntermTyped *foldedNode =
intermediate.foldAggregateBuiltIn(aggregate, &mDiagnostics);
if (foldedNode)
{
callNode = foldedNode;
......
......@@ -31,14 +31,13 @@ class TParseContext : angle::NonCopyable
public:
TParseContext(TSymbolTable &symt,
TExtensionBehavior &ext,
TIntermediate &interm,
sh::GLenum type,
ShShaderSpec spec,
int options,
bool checksPrecErrors,
TInfoSink &is,
const ShBuiltInResources &resources)
: intermediate(interm),
: intermediate(),
symbolTable(symt),
mDeferredSingleDeclarationErrorCheck(false),
mShaderType(type),
......@@ -367,7 +366,7 @@ class TParseContext : angle::NonCopyable
TIntermTyped *cond, TIntermTyped *trueBlock, TIntermTyped *falseBlock, const TSourceLoc &line);
// 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
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