diff options
Diffstat (limited to 'gfx/angle/src/compiler/translator/Intermediate.cpp')
-rwxr-xr-x | gfx/angle/src/compiler/translator/Intermediate.cpp | 222 |
1 files changed, 143 insertions, 79 deletions
diff --git a/gfx/angle/src/compiler/translator/Intermediate.cpp b/gfx/angle/src/compiler/translator/Intermediate.cpp index 9e3e455ae..b6fefa45e 100755 --- a/gfx/angle/src/compiler/translator/Intermediate.cpp +++ b/gfx/angle/src/compiler/translator/Intermediate.cpp @@ -15,9 +15,6 @@ #include "compiler/translator/Intermediate.h" #include "compiler/translator/SymbolTable.h" -namespace sh -{ - //////////////////////////////////////////////////////////////////////////// // // First set of functions are to help build the intermediate representation. @@ -47,30 +44,52 @@ TIntermSymbol *TIntermediate::addSymbol( // 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) +TIntermTyped *TIntermediate::addIndex( + TOperator op, TIntermTyped *base, TIntermTyped *index, const TSourceLoc &line) { - TIntermBinary *node = new TIntermBinary(op, base, index); + TIntermBinary *node = new TIntermBinary(op); node->setLine(line); + node->setLeft(base); + node->setRight(index); - TIntermTyped *folded = node->fold(diagnostics); - if (folded) - { - return folded; - } + // caller should set the type return node; } +// +// 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. +// a function call's operation on it's set of parameters. Sequences +// of instructions are also aggregates, but they just direnctly set +// their operator to EOpSequence. // // Returns an aggregate node, which could be the one passed in if // it was already an aggregate but no operator was set. +// TIntermAggregate *TIntermediate::setAggregateOperator( TIntermNode *node, TOperator op, const TSourceLoc &line) { @@ -141,10 +160,11 @@ TIntermAggregate *TIntermediate::growAggregate( // // Returns an aggregate, unless NULL was passed in for the existing node. // -TIntermAggregate *TIntermediate::MakeAggregate(TIntermNode *node, const TSourceLoc &line) +TIntermAggregate *TIntermediate::makeAggregate( + TIntermNode *node, const TSourceLoc &line) { - if (node == nullptr) - return nullptr; + if (node == NULL) + return NULL; TIntermAggregate *aggNode = new TIntermAggregate; aggNode->getSequence()->push_back(node); @@ -155,57 +175,70 @@ TIntermAggregate *TIntermediate::MakeAggregate(TIntermNode *node, const TSourceL } // If the input node is nullptr, return nullptr. -// 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. -TIntermBlock *TIntermediate::EnsureBlock(TIntermNode *node) +// If the input node is a sequence (block) node, return it. +// If the input node is not a sequence node, put it inside a sequence node and return that. +TIntermAggregate *TIntermediate::ensureSequence(TIntermNode *node) { if (node == nullptr) return nullptr; - TIntermBlock *blockNode = node->getAsBlock(); - if (blockNode != nullptr) - return blockNode; - - blockNode = new TIntermBlock(); - blockNode->setLine(node->getLine()); - blockNode->getSequence()->push_back(node); - return blockNode; + TIntermAggregate *aggNode = node->getAsAggregate(); + if (aggNode != nullptr && aggNode->getOp() == EOpSequence) + return aggNode; + + aggNode = makeAggregate(node, node->getLine()); + aggNode->setOp(EOpSequence); + return aggNode; } +// // For "if" test nodes. There are three children; a condition, // a true path, and a false path. The two paths are in the // nodePair. // -// Returns the node created. -TIntermNode *TIntermediate::addIfElse(TIntermTyped *cond, - TIntermNodePair nodePair, - const TSourceLoc &line) +// Returns the selection node created. +// +TIntermNode *TIntermediate::addSelection( + TIntermTyped *cond, TIntermNodePair nodePair, const TSourceLoc &line) { - // For compile time constant conditions, prune the code now. + // + // For compile time constant selections, prune the code and + // test now. + // if (cond->getAsConstantUnion()) { if (cond->getAsConstantUnion()->getBConst(0) == true) { - return EnsureBlock(nodePair.node1); + return nodePair.node1 ? setAggregateOperator( + nodePair.node1, EOpSequence, nodePair.node1->getLine()) : NULL; } else { - return EnsureBlock(nodePair.node2); + return nodePair.node2 ? setAggregateOperator( + nodePair.node2, EOpSequence, nodePair.node2->getLine()) : NULL; } } - TIntermIfElse *node = - new TIntermIfElse(cond, EnsureBlock(nodePair.node1), EnsureBlock(nodePair.node2)); + TIntermSelection *node = new TIntermSelection( + cond, ensureSequence(nodePair.node1), ensureSequence(nodePair.node2)); node->setLine(line); return node; } -TIntermTyped *TIntermediate::AddComma(TIntermTyped *left, +TIntermTyped *TIntermediate::addComma(TIntermTyped *left, TIntermTyped *right, const TSourceLoc &line, int shaderVersion) { + TQualifier resultQualifier = EvqConst; + // ESSL3.00 section 12.43: The result of a sequence operator is not a constant-expression. + if (shaderVersion >= 300 || left->getQualifier() != EvqConst || + right->getQualifier() != EvqConst) + { + resultQualifier = EvqTemporary; + } + TIntermTyped *commaNode = nullptr; if (!left->hasSideEffects()) { @@ -213,53 +246,58 @@ TIntermTyped *TIntermediate::AddComma(TIntermTyped *left, } else { - commaNode = new TIntermBinary(EOpComma, left, right); - commaNode->setLine(line); + commaNode = growAggregate(left, right, line); + commaNode->getAsAggregate()->setOp(EOpComma); + commaNode->setType(right->getType()); } - 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) +// Returns the selection node created, or one of trueBlock and falseBlock if the expression could be folded. +// +TIntermTyped *TIntermediate::addSelection(TIntermTyped *cond, TIntermTyped *trueBlock, TIntermTyped *falseBlock, + const TSourceLoc &line) { + TQualifier resultQualifier = EvqTemporary; + if (cond->getQualifier() == EvqConst && trueBlock->getQualifier() == EvqConst && + falseBlock->getQualifier() == EvqConst) + { + resultQualifier = EvqConst; + } // 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; + trueBlock->getTypePointer()->setQualifier(resultQualifier); + return trueBlock; } else { - falseExpression->getTypePointer()->setQualifier(resultQualifier); - return falseExpression; + falseBlock->getTypePointer()->setQualifier(resultQualifier); + return falseBlock; } } - // Make a ternary node. - TIntermTernary *node = new TIntermTernary(cond, trueExpression, falseExpression); + // + // Make a selection node. + // + TIntermSelection *node = new TIntermSelection(cond, trueBlock, falseBlock, trueBlock->getType()); + node->getTypePointer()->setQualifier(resultQualifier); node->setLine(line); return node; } -TIntermSwitch *TIntermediate::addSwitch(TIntermTyped *init, - TIntermBlock *statementList, - const TSourceLoc &line) +TIntermSwitch *TIntermediate::addSwitch( + TIntermTyped *init, TIntermAggregate *statementList, const TSourceLoc &line) { TIntermSwitch *node = new TIntermSwitch(init, statementList); node->setLine(line); @@ -292,22 +330,24 @@ TIntermConstantUnion *TIntermediate::addConstantUnion(const TConstantUnion *cons return node; } -TIntermTyped *TIntermediate::AddSwizzle(TIntermTyped *baseExpression, - const TVectorFields &fields, - const TSourceLoc &dotLocation) +TIntermTyped *TIntermediate::addSwizzle( + TVectorFields &fields, const TSourceLoc &line) { - 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) + TIntermAggregate *node = new TIntermAggregate(EOpSequence); + + node->setLine(line); + TIntermConstantUnion *constIntNode; + TIntermSequence *sequenceVector = node->getSequence(); + TConstantUnion *unionArray; + + for (int i = 0; i < fields.num; i++) { - return folded; + unionArray = new TConstantUnion[1]; + unionArray->setIConst(fields.offsets[i]); + constIntNode = addConstantUnion( + unionArray, TType(EbtInt, EbpUndefined, EvqConst), line); + sequenceVector->push_back(constIntNode); } return node; @@ -320,7 +360,7 @@ TIntermNode *TIntermediate::addLoop( TLoopType type, TIntermNode *init, TIntermTyped *cond, TIntermTyped *expr, TIntermNode *body, const TSourceLoc &line) { - TIntermNode *node = new TIntermLoop(type, init, cond, expr, EnsureBlock(body)); + TIntermNode *node = new TIntermLoop(type, init, cond, expr, ensureSequence(body)); node->setLine(line); return node; @@ -344,8 +384,34 @@ TIntermBranch* TIntermediate::addBranch( return node; } -TIntermTyped *TIntermediate::foldAggregateBuiltIn(TIntermAggregate *aggregate, - TDiagnostics *diagnostics) +// +// This is to be executed once the final root is put on top by the parsing +// process. +// +TIntermAggregate *TIntermediate::postProcess(TIntermNode *root) +{ + if (root == nullptr) + return nullptr; + + // + // Finish off the top level sequence, if any + // + TIntermAggregate *aggRoot = root->getAsAggregate(); + if (aggRoot != nullptr && aggRoot->getOp() == EOpNull) + { + aggRoot->setOp(EOpSequence); + } + else if (aggRoot == nullptr || aggRoot->getOp() != EOpSequence) + { + aggRoot = new TIntermAggregate(EOpSequence); + aggRoot->setLine(root->getLine()); + aggRoot->getSequence()->push_back(root); + } + + return aggRoot; +} + +TIntermTyped *TIntermediate::foldAggregateBuiltIn(TIntermAggregate *aggregate) { switch (aggregate->getOp()) { @@ -372,16 +438,14 @@ TIntermTyped *TIntermediate::foldAggregateBuiltIn(TIntermAggregate *aggregate, case EOpFaceForward: case EOpReflect: case EOpRefract: - return aggregate->fold(diagnostics); + return aggregate->fold(mInfoSink); default: // TODO: Add support for folding array constructors if (aggregate->isConstructor() && !aggregate->isArray()) { - return aggregate->fold(diagnostics); + return aggregate->fold(mInfoSink); } // Constant folding not supported for the built-in. return nullptr; } } - -} // namespace sh |