From b16b9e4656e7199c2aec74a4c8ebc7a875d3ba73 Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Mon, 2 Feb 2015 15:02:49 +0100 Subject: massive reduction of unneeded files --- .../slang/MachineIndependent/Intermediate.cpp | 2110 -------------------- 1 file changed, 2110 deletions(-) delete mode 100755 nx-X11/extras/Mesa/src/mesa/shader/slang/MachineIndependent/Intermediate.cpp (limited to 'nx-X11/extras/Mesa/src/mesa/shader/slang/MachineIndependent/Intermediate.cpp') diff --git a/nx-X11/extras/Mesa/src/mesa/shader/slang/MachineIndependent/Intermediate.cpp b/nx-X11/extras/Mesa/src/mesa/shader/slang/MachineIndependent/Intermediate.cpp deleted file mode 100755 index 056fe17de..000000000 --- a/nx-X11/extras/Mesa/src/mesa/shader/slang/MachineIndependent/Intermediate.cpp +++ /dev/null @@ -1,2110 +0,0 @@ -// -//Copyright (C) 2002-2005 3Dlabs Inc. Ltd. -//All rights reserved. -// -//Redistribution and use in source and binary forms, with or without -//modification, are permitted provided that the following conditions -//are met: -// -// Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// -// Neither the name of 3Dlabs Inc. Ltd. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -//POSSIBILITY OF SUCH DAMAGE. -// - -// -// Build the intermediate representation. -// - -#include "../Include/ShHandle.h" -#include "localintermediate.h" -#include "QualifierAlive.h" -#include "RemoveTree.h" -#include - -//////////////////////////////////////////////////////////////////////////// -// -// First set of functions are to help build the intermediate representation. -// These functions are not member functions of the nodes. -// They are called from parser productions. -// -///////////////////////////////////////////////////////////////////////////// - -// -// Add a terminal node for an identifier in an expression. -// -// Returns the added node. -// -TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType& type, TSourceLoc line) -{ - TIntermSymbol* node = new TIntermSymbol(id, name, type); - node->setLine(line); - - return node; -} - -// -// Connect two nodes with a new parent that does a binary operation on the nodes. -// -// Returns the added node. -// -TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc line, TSymbolTable& symbolTable) -{ - switch (op) { - case EOpLessThan: - case EOpGreaterThan: - case EOpLessThanEqual: - case EOpGreaterThanEqual: - if (left->getType().isMatrix() || left->getType().isArray() || left->getType().isVector() || left->getType().getBasicType() == EbtStruct) { - return 0; - } - break; - case EOpLogicalOr: - case EOpLogicalXor: - case EOpLogicalAnd: - if (left->getType().getBasicType() != EbtBool || left->getType().isMatrix() || left->getType().isArray() || left->getType().isVector()) { - return 0; - } - break; - case EOpAdd: - case EOpSub: - case EOpDiv: - case EOpMul: - if (left->getType().getBasicType() == EbtStruct || left->getType().getBasicType() == EbtBool) - return 0; - default: break; - } - - // - // First try converting the children to compatible types. - // - - if (!(left->getType().getStruct() && right->getType().getStruct())) { - TIntermTyped* child = addConversion(op, left->getType(), right); - if (child) - right = child; - else { - child = addConversion(op, right->getType(), left); - if (child) - left = child; - else - return 0; - } - } else { - if (left->getType() != right->getType()) - return 0; - } - - - // - // Need a new node holding things together then. Make - // one and promote it to the right type. - // - TIntermBinary* node = new TIntermBinary(op); - if (line == 0) - line = right->getLine(); - node->setLine(line); - - node->setLeft(left); - node->setRight(right); - if (! node->promote(infoSink)) - return 0; - - TIntermConstantUnion *leftTempConstant = left->getAsConstantUnion(); - TIntermConstantUnion *rightTempConstant = right->getAsConstantUnion(); - - if (leftTempConstant) - leftTempConstant = copyConstUnion(left->getAsConstantUnion())->getAsConstantUnion(); - - if (rightTempConstant) - rightTempConstant = copyConstUnion(right->getAsConstantUnion())->getAsConstantUnion(); - - if (right->getType().getQualifier() == EvqConst && left->getType().getQualifier() == EvqConst) { - if (right->getAsAggregate()) { - rightTempConstant = changeAggrToTempConst(right->getAsAggregate(), symbolTable, line); - if (rightTempConstant->getUnionArrayPointer() == 0) - return 0; - } - - if (left->getAsAggregate()) { - leftTempConstant = changeAggrToTempConst(left->getAsAggregate(), symbolTable, line); - if (leftTempConstant->getUnionArrayPointer() == 0) - return 0; - } - } - - // - // See if we can fold constants. - // - - TIntermTyped* typedReturnNode = 0; - if ( leftTempConstant && rightTempConstant) { - if (leftTempConstant->getSize() == 1 && rightTempConstant->getSize() > 1) - typedReturnNode = rightTempConstant->fold(node->getOp(), leftTempConstant, infoSink, false); - else - typedReturnNode = leftTempConstant->fold(node->getOp(), rightTempConstant, infoSink, true); - - if (typedReturnNode) - return typedReturnNode; - else { - node->setLeft(leftTempConstant); - node->setRight(rightTempConstant); - } - } else if (leftTempConstant) { - node->setLeft(copyConstUnion(leftTempConstant)); - } else if (rightTempConstant) { - node->setRight(rightTempConstant); - } - - return node; -} - -// -// Connect two nodes through an assignment. -// -// Returns the added node. -// -TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc line) -{ - // - // Like adding binary math, except the conversion can only go - // from right to left. - // - TIntermBinary* node = new TIntermBinary(op); - if (line == 0) - line = left->getLine(); - node->setLine(line); - - if (right->getAsConstantUnion()) { // if the right node of assignment is a TempConstant node, allocate its own new space and remove the pointer to the symbol table value - right = copyConstUnion(right->getAsConstantUnion()) ; - if (right == 0) - return 0; - } - - TIntermTyped* child = addConversion(op, left->getType(), right); - if (child == 0) - return 0; - - node->setLeft(left); - node->setRight(child); - if (! node->promote(infoSink)) - return 0; - - return node; -} - -// -// Connect two nodes through an index operator, where the left node is the base -// of an array or struct, and the right node is a direct or indirect offset. -// -// Returns the added node. -// The caller should set the type of the returned node. -// -TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc line) -{ - TIntermBinary* node = new TIntermBinary(op); - if (line == 0) - line = index->getLine(); - node->setLine(line); - node->setLeft(base); - node->setRight(index); - - // 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, TIntermNode* childNode, TSourceLoc line, TSymbolTable& symbolTable) -{ - TIntermUnary* node; - TIntermTyped* child = childNode->getAsTyped(); - - if (child == 0) { - infoSink.info.message(EPrefixInternalError, "Bad type in AddUnaryMath", line); - return 0; - } - - switch (op) { - case EOpLogicalNot: - if (child->getType().getBasicType() != EbtBool || child->getType().isMatrix() || child->getType().isArray() || child->getType().isVector()) { - return 0; - } - break; - - case EOpPostIncrement: - case EOpPreIncrement: - case EOpPostDecrement: - case EOpPreDecrement: - case EOpNegative: - if (child->getType().getBasicType() == EbtStruct) - return 0; - default: break; - } - - // - // Do we need to promote the operand? - // - // Note: Implicit promotions were removed from the language. - // - TBasicType newType = EbtVoid; - switch (op) { - case EOpConstructInt: newType = EbtInt; break; - case EOpConstructBool: newType = EbtBool; break; - case EOpConstructFloat: newType = EbtFloat; break; - default: break; - } - - if (newType != EbtVoid) { - child = addConversion(op, TType(newType, EvqTemporary, child->getNominalSize(), - child->isMatrix(), - child->isArray()), - child); - if (child == 0) - return 0; - } - - // - // For constructors, we are now done, it's all in the conversion. - // - switch (op) { - case EOpConstructInt: - case EOpConstructBool: - case EOpConstructFloat: - return child; - default: break; - } - - if (child->getAsConstantUnion()) - child = copyConstUnion(child->getAsConstantUnion()); - - if (child->getAsAggregate() && child->getType().getQualifier() == EvqConst) { - child = changeAggrToTempConst(child->getAsAggregate(), symbolTable, line); - if (child->getAsConstantUnion()->getUnionArrayPointer() == 0) - return 0; - } - - TIntermConstantUnion *childTempConstant = child->getAsConstantUnion(); - - // - // Make a new node for the operator. - // - node = new TIntermUnary(op); - if (line == 0) - line = child->getLine(); - node->setLine(line); - node->setOperand(child); - - if (! node->promote(infoSink)) - return 0; - - if (childTempConstant) { - TIntermTyped* newChild = childTempConstant->fold(op, 0, infoSink, true); - - if (newChild) { - return newChild; - } - } - - 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 -// 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. -// -TIntermAggregate* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator op, TSourceLoc line) -{ - TIntermAggregate* aggNode; - - // - // Make sure we have an aggregate. If not turn it into one. - // - if (node) { - aggNode = node->getAsAggregate(); - if (aggNode == 0 || aggNode->getOp() != EOpNull) { - // - // Make an aggregate containing this node. - // - aggNode = new TIntermAggregate(); - aggNode->getSequence().push_back(node); - if (line == 0) - line = node->getLine(); - } - } else - aggNode = new TIntermAggregate(); - - // - // Set the operator. - // - aggNode->setOperator(op); - if (line != 0) - aggNode->setLine(line); - - return aggNode; -} - -// -// Convert one type to another. -// -// Returns the node representing the conversion, which could be the same -// node passed in if no conversion was needed. -// -// Return 0 if a conversion can't be done. -// -TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TIntermTyped* node) -{ - // - // Does the base type allow operation? - // - switch (node->getBasicType()) { - case EbtVoid: - case EbtSampler1D: - case EbtSampler2D: - case EbtSampler3D: - case EbtSamplerCube: - case EbtSampler1DShadow: - case EbtSampler2DShadow: - return 0; - default: break; - } - - // - // Otherwise, if types are identical, no problem - // - if (type == node->getType()) - return node; - - // - // If one's a structure, then no conversions. - // - if (type.getStruct() || node->getType().getStruct()) - return 0; - - TBasicType promoteTo; - - switch (op) { - // - // Explicit conversions - // - case EOpConstructBool: - promoteTo = EbtBool; - break; - case EOpConstructFloat: - promoteTo = EbtFloat; - break; - case EOpConstructInt: - promoteTo = EbtInt; - break; - default: - // - // implicit conversions were removed from the language. - // - if (type.getBasicType() != node->getType().getBasicType()) - return 0; - // - // Size and structure could still differ, but that's - // handled by operator promotion. - // - return node; - } - - // - // Do conversion. - // - bool allConstant = true; - // check to see if there is an aggregate node - if (node->getAsAggregate()) { - if (node->getAsAggregate()->getOp() != EOpFunctionCall) { - // if the aggregate node is a constructor or a comma operator, look at its children, if they are constant - // convert them into the right type - TIntermSequence &sequenceVector = node->getAsAggregate()->getSequence() ; - for (TIntermSequence::iterator p = sequenceVector.begin(); - p != sequenceVector.end(); p++) { - if (!(*p)->getAsTyped()->getAsConstantUnion()) - allConstant = false; - } - } else - allConstant = false; - } - if (allConstant && node->getAsAggregate()) { // we can do the constant folding here as all the nodes of the aggregate are const - TIntermSequence &sequenceVector = node->getAsAggregate()->getSequence() ; - for (TIntermSequence::iterator p = sequenceVector.begin(); - p != sequenceVector.end(); p++) { - TIntermTyped* newNode = 0; - constUnion *unionArray = new constUnion[1]; - - switch (promoteTo) { - case EbtFloat: - switch ((*p)->getAsTyped()->getType().getBasicType()) { - - case EbtInt: - unionArray->fConst = static_cast((*p)->getAsTyped()->getAsConstantUnion()->getUnionArrayPointer()->iConst); - newNode = addConstantUnion(unionArray, TType(EbtFloat, EvqConst), node->getLine()); break; - case EbtBool: - unionArray->fConst = static_cast((*p)->getAsTyped()->getAsConstantUnion()->getUnionArrayPointer()->bConst); - newNode = newNode = addConstantUnion(unionArray, TType(EbtFloat, EvqConst), node->getLine()); break; - default: - infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine()); - return 0; - } - break; - case EbtInt: - switch ((*p)->getAsTyped()->getType().getBasicType()) { - case EbtFloat: - unionArray->iConst = static_cast((*p)->getAsTyped()->getAsConstantUnion()->getUnionArrayPointer()->fConst); - newNode = addConstantUnion(unionArray, TType(EbtInt, EvqConst), node->getLine()); - break; - case EbtBool: - unionArray->iConst = static_cast((*p)->getAsTyped()->getAsConstantUnion()->getUnionArrayPointer()->bConst); - newNode = addConstantUnion(unionArray, TType(EbtInt, EvqConst), node->getLine()); - break; - default: - infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine()); - return 0; - } - break; - case EbtBool: - switch ((*p)->getAsTyped()->getType().getBasicType()) { - case EbtFloat: - unionArray->bConst = (*p)->getAsTyped()->getAsConstantUnion()->getUnionArrayPointer()->fConst != 0.0 ; - newNode = addConstantUnion(unionArray, TType(EbtBool, EvqConst), node->getLine()); - break; - case EbtInt: - unionArray->bConst = (*p)->getAsTyped()->getAsConstantUnion()->getUnionArrayPointer()->iConst != 0 ; - newNode = addConstantUnion(unionArray, TType(EbtBool, EvqConst), node->getLine()); - break; - default: - infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine()); - return 0; - } - break; - default: - infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine()); - return 0; - } - if (newNode) { - sequenceVector.erase(p); - sequenceVector.insert(p, newNode); - } - } - return node->getAsAggregate(); - } else if (node->getAsConstantUnion()) { - - return (promoteConstantUnion(promoteTo, node->getAsConstantUnion())); - } else { - - // - // Add a new newNode for the conversion. - // - TIntermUnary* newNode = 0; - - TOperator newOp = EOpNull; - switch (promoteTo) { - case EbtFloat: - switch (node->getBasicType()) { - case EbtInt: newOp = EOpConvIntToFloat; break; - case EbtBool: newOp = EOpConvBoolToFloat; break; - default: - infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine()); - return 0; - } - break; - case EbtBool: - switch (node->getBasicType()) { - case EbtInt: newOp = EOpConvIntToBool; break; - case EbtFloat: newOp = EOpConvFloatToBool; break; - default: - infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine()); - return 0; - } - break; - case EbtInt: - switch (node->getBasicType()) { - case EbtBool: newOp = EOpConvBoolToInt; break; - case EbtFloat: newOp = EOpConvFloatToInt; break; - default: - infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine()); - return 0; - } - break; - default: - infoSink.info.message(EPrefixInternalError, "Bad promotion type", node->getLine()); - return 0; - } - - TType type(promoteTo, EvqTemporary, node->getNominalSize(), node->isMatrix(), node->isArray()); - newNode = new TIntermUnary(newOp, type); - newNode->setLine(node->getLine()); - newNode->setOperand(node); - - return newNode; - } -} - -// -// Safe way to combine two nodes into an aggregate. Works with null pointers, -// a node that's not a aggregate yet, etc. -// -// Returns the resulting aggregate, unless 0 was passed in for -// both existing nodes. -// -TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* right, TSourceLoc line) -{ - if (left == 0 && right == 0) - return 0; - - TIntermAggregate* aggNode = 0; - if (left) - aggNode = left->getAsAggregate(); - if (!aggNode || aggNode->getOp() != EOpNull) { - aggNode = new TIntermAggregate; - if (left) - aggNode->getSequence().push_back(left); - } - - if (right) - aggNode->getSequence().push_back(right); - - if (line != 0) - aggNode->setLine(line); - - return aggNode; -} - -// -// Turn an existing node into an aggregate. -// -// Returns an aggregate, unless 0 was passed in for the existing node. -// -TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node, TSourceLoc line) -{ - if (node == 0) - return 0; - - TIntermAggregate* aggNode = new TIntermAggregate; - aggNode->getSequence().push_back(node); - - if (line != 0) - aggNode->setLine(line); - else - aggNode->setLine(node->getLine()); - - 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 selection node created. -// -TIntermNode* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nodePair, TSourceLoc line) -{ - // - // For compile time constant selections, prune the code and - // test now. - // - - if (cond->getAsTyped() && cond->getAsTyped()->getAsConstantUnion()) { - if (cond->getAsTyped()->getAsConstantUnion()->getUnionArrayPointer()->bConst) - return nodePair.node1; - else - return nodePair.node2; - } - - TIntermSelection* node = new TIntermSelection(cond, nodePair.node1, nodePair.node2); - node->setLine(line); - - return node; -} - - -TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, TSourceLoc line) -{ - if (left->getType().getQualifier() == EvqConst && right->getType().getQualifier() == EvqConst) { - return right; - } else { - TIntermTyped *commaAggregate = growAggregate(left, right, line); - commaAggregate->getAsAggregate()->setOperator(EOpComma); - commaAggregate->setType(right->getType()); - commaAggregate->getTypePointer()->changeQualifier(EvqTemporary); - return commaAggregate; - } -} - -// -// 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 selection node created, or 0 if one could not be. -// -TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, TSourceLoc line) -{ - // - // Get compatible types. - // - TIntermTyped* child = addConversion(EOpSequence, trueBlock->getType(), falseBlock); - if (child) - falseBlock = child; - else { - child = addConversion(EOpSequence, falseBlock->getType(), trueBlock); - if (child) - trueBlock = child; - else - return 0; - } - - // - // See if condition is constant, and select now. - // - - if (cond->getAsConstantUnion()) { - if (cond->getAsConstantUnion()->getUnionArrayPointer()->bConst) - return trueBlock; - else - return falseBlock; - } - - // - // Make a selection node. - // - TIntermSelection* node = new TIntermSelection(cond, trueBlock, falseBlock, trueBlock->getType()); - node->setLine(line); - - return node; -} - -// -// Constant terminal nodes. Has a union that contains bool, float or int constants -// -// Returns the constant union node created. -// - -TIntermConstantUnion* TIntermediate::addConstantUnion(constUnion* unionArrayPointer, const TType& t, TSourceLoc line) -{ - TIntermConstantUnion* node = new TIntermConstantUnion(unionArrayPointer, t); - node->setLine(line); - - return node; -} - -TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, TSourceLoc line) -{ - - TIntermAggregate* node = new TIntermAggregate(EOpSequence); - - node->setLine(line); - TIntermConstantUnion* constIntNode; - TIntermSequence &sequenceVector = node->getSequence(); - constUnion* unionArray; - - for (int i = 0; i < fields.num; i++) { - unionArray = new constUnion[1]; - unionArray->iConst = fields.offsets[i]; - constIntNode = addConstantUnion(unionArray, TType(EbtInt, EvqConst), line); - sequenceVector.push_back(constIntNode); - } - - return node; -} - -// -// Create loop nodes. -// -TIntermNode* TIntermediate::addLoop(TIntermNode* body, TIntermTyped* test, TIntermTyped* terminal, bool testFirst, TSourceLoc line) -{ - TIntermNode* node = new TIntermLoop(body, test, terminal, testFirst); - node->setLine(line); - - return node; -} - -// -// Add branches. -// -TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TSourceLoc line) -{ - return addBranch(branchOp, 0, line); -} - -TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TIntermTyped* expression, TSourceLoc line) -{ - TIntermBranch* node = new TIntermBranch(branchOp, expression); - node->setLine(line); - - return node; -} - -// -// This is to be executed once the final root is put on top by the parsing -// process. -// -bool TIntermediate::postProcess(TIntermNode* root, EShLanguage language) -{ - if (root == 0) - return true; - - // - // First, finish off the top level sequence, if any - // - TIntermAggregate* aggRoot = root->getAsAggregate(); - if (aggRoot && aggRoot->getOp() == EOpNull) - aggRoot->setOperator(EOpSequence); - - return true; -} - -// -// This deletes the tree. -// -void TIntermediate::remove(TIntermNode* root) -{ - if (root) - RemoveAllTreeNodes(root); -} - -//////////////////////////////////////////////////////////////// -// -// Member functions of the nodes used for building the tree. -// -//////////////////////////////////////////////////////////////// - -// -// Say whether or not an operation node changes the value of a variable. -// -// Returns true if state is modified. -// -bool TIntermOperator::modifiesState() const -{ - switch (op) { - case EOpPostIncrement: - case EOpPostDecrement: - case EOpPreIncrement: - case EOpPreDecrement: - case EOpAssign: - case EOpAddAssign: - case EOpSubAssign: - case EOpMulAssign: - case EOpVectorTimesMatrixAssign: - case EOpVectorTimesScalarAssign: - case EOpMatrixTimesScalarAssign: - case EOpMatrixTimesMatrixAssign: - case EOpDivAssign: - case EOpModAssign: - case EOpAndAssign: - case EOpInclusiveOrAssign: - case EOpExclusiveOrAssign: - case EOpLeftShiftAssign: - case EOpRightShiftAssign: - return true; - default: - return false; - } -} - -// -// returns true if the operator is for one of the constructors -// -bool TIntermOperator::isConstructor() const -{ - switch (op) { - case EOpConstructVec2: - case EOpConstructVec3: - case EOpConstructVec4: - case EOpConstructMat2: - case EOpConstructMat3: - case EOpConstructMat4: - case EOpConstructFloat: - case EOpConstructIVec2: - case EOpConstructIVec3: - case EOpConstructIVec4: - case EOpConstructInt: - case EOpConstructBVec2: - case EOpConstructBVec3: - case EOpConstructBVec4: - case EOpConstructBool: - case EOpConstructStruct: - return true; - default: - return false; - } -} -// -// Make sure the type of a unary operator is appropriate for its -// combination of operation and operand type. -// -// Returns false in nothing makes sense. -// -bool TIntermUnary::promote(TInfoSink&) -{ - switch (op) { - case EOpLogicalNot: - if (operand->getBasicType() != EbtBool) - return false; - break; - case EOpBitwiseNot: - if (operand->getBasicType() != EbtInt) - return false; - break; - case EOpNegative: - case EOpPostIncrement: - case EOpPostDecrement: - case EOpPreIncrement: - case EOpPreDecrement: - if (operand->getBasicType() == EbtBool) - return false; - break; - - // operators for built-ins are already type checked against their prototype - case EOpAny: - case EOpAll: - case EOpVectorLogicalNot: - return true; - - default: - if (operand->getBasicType() != EbtFloat) - return false; - } - - setType(operand->getType()); - - return true; -} - -// -// Establishes the type of the resultant operation, as well as -// makes the operator the correct one for the operands. -// -// Returns false if operator can't work on operands. -// -bool TIntermBinary::promote(TInfoSink& infoSink) -{ - int size = left->getNominalSize(); - if (right->getNominalSize() > size) - size = right->getNominalSize(); - - TBasicType type = left->getBasicType(); - - // - // Don't operate on arrays. - // - if (left->isArray() || right->isArray()) - return false; - - // - // Base assumption: just make the type the same as the left - // operand. Then only deviations from this need be coded. - // - setType(TType(type, EvqTemporary, left->getNominalSize(), left->isMatrix())); - - // - // All scalars. Code after this test assumes this case is removed! - // - if (size == 1) { - - switch (op) { - - // - // Promote to conditional - // - case EOpEqual: - case EOpNotEqual: - case EOpLessThan: - case EOpGreaterThan: - case EOpLessThanEqual: - case EOpGreaterThanEqual: - setType(TType(EbtBool)); - break; - - // - // And and Or operate on conditionals - // - case EOpLogicalAnd: - case EOpLogicalOr: - if (left->getBasicType() != EbtBool || right->getBasicType() != EbtBool) - return false; - setType(TType(EbtBool)); - break; - - // - // Check for integer only operands. - // - case EOpMod: - case EOpRightShift: - case EOpLeftShift: - case EOpAnd: - case EOpInclusiveOr: - case EOpExclusiveOr: - if (left->getBasicType() != EbtInt || right->getBasicType() != EbtInt) - return false; - break; - case EOpModAssign: - case EOpAndAssign: - case EOpInclusiveOrAssign: - case EOpExclusiveOrAssign: - case EOpLeftShiftAssign: - case EOpRightShiftAssign: - if (left->getBasicType() != EbtInt || right->getBasicType() != EbtInt) - return false; - // fall through - - // - // Everything else should have matching types - // - default: - if (left->getBasicType() != right->getBasicType() || - left->isMatrix() != right->isMatrix()) - return false; - } - - return true; - } - - // - // Are the sizes compatible? - // - if ( left->getNominalSize() != size && left->getNominalSize() != 1 || - right->getNominalSize() != size && right->getNominalSize() != 1) - return false; - - // - // Can these two operands be combined? - // - switch (op) { - case EOpMul: - if (!left->isMatrix() && right->isMatrix()) { - if (left->isVector()) - op = EOpVectorTimesMatrix; - else { - op = EOpMatrixTimesScalar; - setType(TType(type, EvqTemporary, size, true)); - } - } else if (left->isMatrix() && !right->isMatrix()) { - if (right->isVector()) { - op = EOpMatrixTimesVector; - setType(TType(type, EvqTemporary, size, false)); - } else { - op = EOpMatrixTimesScalar; - } - } else if (left->isMatrix() && right->isMatrix()) { - op = EOpMatrixTimesMatrix; - } else if (!left->isMatrix() && !right->isMatrix()) { - if (left->isVector() && right->isVector()) { - // leave as component product - } else if (left->isVector() || right->isVector()) { - op = EOpVectorTimesScalar; - setType(TType(type, EvqTemporary, size, false)); - } - } else { - infoSink.info.message(EPrefixInternalError, "Missing elses", getLine()); - return false; - } - break; - case EOpMulAssign: - if (!left->isMatrix() && right->isMatrix()) { - if (left->isVector()) - op = EOpVectorTimesMatrixAssign; - else { - return false; - } - } else if (left->isMatrix() && !right->isMatrix()) { - if (right->isVector()) { - return false; - } else { - op = EOpMatrixTimesScalarAssign; - } - } else if (left->isMatrix() && right->isMatrix()) { - op = EOpMatrixTimesMatrixAssign; - } else if (!left->isMatrix() && !right->isMatrix()) { - if (left->isVector() && right->isVector()) { - // leave as component product - } else if (left->isVector() || right->isVector()) { - if (! left->isVector()) - return false; - op = EOpVectorTimesScalarAssign; - setType(TType(type, EvqTemporary, size, false)); - } - } else { - infoSink.info.message(EPrefixInternalError, "Missing elses", getLine()); - return false; - } - break; - case EOpAssign: - if (left->getNominalSize() != right->getNominalSize()) - return false; - // fall through - case EOpAdd: - case EOpSub: - case EOpDiv: - case EOpMod: - case EOpAddAssign: - case EOpSubAssign: - case EOpDivAssign: - case EOpModAssign: - if (left->isMatrix() && right->isVector() || - left->isVector() && right->isMatrix() || - left->getBasicType() != right->getBasicType()) - return false; - setType(TType(type, EvqTemporary, size, left->isMatrix() || right->isMatrix())); - break; - - case EOpEqual: - case EOpNotEqual: - case EOpLessThan: - case EOpGreaterThan: - case EOpLessThanEqual: - case EOpGreaterThanEqual: - if (left->isMatrix() && right->isVector() || - left->isVector() && right->isMatrix() || - left->getBasicType() != right->getBasicType()) - return false; - setType(TType(EbtBool)); - break; - -default: - return false; - } - - // - // One more check for assignment. The Resulting type has to match the left operand. - // - switch (op) { - case EOpAssign: - case EOpAddAssign: - case EOpSubAssign: - case EOpMulAssign: - case EOpDivAssign: - case EOpModAssign: - case EOpAndAssign: - case EOpInclusiveOrAssign: - case EOpExclusiveOrAssign: - case EOpLeftShiftAssign: - case EOpRightShiftAssign: - if (getType() != left->getType()) - return false; - break; - default: - break; - } - - return true; -} - -bool compareStructure(const TType& leftNodeType, constUnion* rightUnionArray, constUnion* leftUnionArray, int& index) -{ - TTypeList* fields = leftNodeType.getStruct(); - - size_t structSize = fields->size(); - - for (size_t j = 0; j < structSize; j++) { - int size = (*fields)[j].type->getInstanceSize(); - for (int i = 0; i < size; i++) { - switch ((*fields)[j].type->getBasicType()) { - case EbtFloat: - if (leftUnionArray[index].fConst != rightUnionArray[index].fConst) - return false; - index++; - break; - case EbtInt: - if (leftUnionArray[index].iConst != rightUnionArray[index].iConst) - return false; - index++; - break; - case EbtBool: - if (leftUnionArray[index].bConst != rightUnionArray[index].bConst) - return false; - index++; - break; - case EbtStruct: - if (!compareStructure(*(*fields)[j].type, rightUnionArray, leftUnionArray, index)) - return false; - break; - default: - assert(true && "Cannot compare"); - break; - } - - } - } - return true; -} - -// -// The fold functions see if an operation on a constant can be done in place, -// without generating run-time code. -// -// Returns the node to keep using, which may or may not be the node passed in. -// - -TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNode, TInfoSink& infoSink, bool leftOperand) -{ - constUnion *unionArray = this->getUnionArrayPointer(); - - if (constantNode) { - if (constantNode->getAsConstantUnion() && constantNode->getSize() == 1 && constantNode->getType().getBasicType() != EbtStruct - && this->getSize() > 1) { - TIntermConstantUnion *node = constantNode->getAsConstantUnion(); - TIntermConstantUnion *newNode; - constUnion* tempConstArray; - switch(op) { - case EOpAdd: - tempConstArray = new constUnion[this->getSize()]; - {// support MSVC++6.0 - for (int i = 0; i < this->getSize(); i++) { - switch (this->getType().getBasicType()) { - case EbtFloat: tempConstArray[i].fConst = unionArray[i].fConst + node->getUnionArrayPointer()->fConst; break; - case EbtInt: tempConstArray[i].iConst = unionArray[i].iConst + node->getUnionArrayPointer()->iConst; break; - default: - infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"+\"", this->getLine()); - return 0; - } - } - } - break; - case EOpMatrixTimesScalar: - case EOpVectorTimesScalar: - tempConstArray = new constUnion[this->getSize()]; - {// support MSVC++6.0 - for (int i = 0; i < this->getSize(); i++) { - switch (this->getType().getBasicType()) { - case EbtFloat: tempConstArray[i].fConst = unionArray[i].fConst * node->getUnionArrayPointer()->fConst; break; - case EbtInt: tempConstArray[i].iConst = unionArray[i].iConst * node->getUnionArrayPointer()->iConst; break; - default: - infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"*\"", this->getLine()); - return 0; - } - } - } - break; - case EOpSub: - tempConstArray = new constUnion[this->getSize()]; - {// support MSVC++6.0 - for (int i = 0; i < this->getSize(); i++) { - switch (this->getType().getBasicType()) { - case EbtFloat: - if (leftOperand) - tempConstArray[i].fConst = unionArray[i].fConst - node->getUnionArrayPointer()->fConst; - else - tempConstArray[i].fConst = node->getUnionArrayPointer()->fConst - unionArray[i].fConst; - break; - - case EbtInt: - if (leftOperand) - tempConstArray[i].iConst = unionArray[i].iConst - node->getUnionArrayPointer()->iConst; - else - tempConstArray[i].iConst = node->getUnionArrayPointer()->iConst - unionArray[i].iConst; - break; - default: - infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"-\"", this->getLine()); - return 0; - } - } - } - break; - - case EOpDiv: - tempConstArray = new constUnion[this->getSize()]; - {// support MSVC++6.0 - for (int i = 0; i < this->getSize(); i++) { - switch (this->getType().getBasicType()) { - case EbtFloat: - if (leftOperand) { - if (node->getUnionArrayPointer()->fConst == 0.0) { - infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", this->getLine()); - tempConstArray[i].fConst = FLT_MAX; - } else - tempConstArray[i].fConst = unionArray[i].fConst / node->getUnionArrayPointer()->fConst; - } else { - if (unionArray[i].fConst == 0.0) { - infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", this->getLine()); - tempConstArray[i].fConst = FLT_MAX; - } else - tempConstArray[i].fConst = node->getUnionArrayPointer()->fConst / unionArray[i].fConst; - } - break; - - case EbtInt: - if (leftOperand) { - if (node->getUnionArrayPointer()->iConst == 0) { - infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", this->getLine()); - tempConstArray[i].iConst = INT_MAX; - } else - tempConstArray[i].iConst = unionArray[i].iConst / node->getUnionArrayPointer()->iConst; - } else { - if (unionArray[i].iConst == 0) { - infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", this->getLine()); - tempConstArray[i].iConst = INT_MAX; - } else - tempConstArray[i].iConst = node->getUnionArrayPointer()->iConst / unionArray[i].iConst; - } - break; - default: - infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"/\"", this->getLine()); - return 0; - } - } - } - break; - - case EOpLogicalAnd: // this code is written for possible future use, will not get executed currently - tempConstArray = new constUnion[this->getSize()]; - {// support MSVC++6.0 - for (int i = 0; i < this->getSize(); i++) { - switch (this->getType().getBasicType()) { - case EbtBool: tempConstArray[i].bConst = unionArray[i].bConst && node->getUnionArrayPointer()->bConst; break; - default: - infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"&&\"", this->getLine()); - return 0; - } - } - } - break; - - case EOpLogicalXor: // this code is written for possible future use, will not get executed currently - tempConstArray = new constUnion[this->getSize()]; - {// support MSVC++6.0 - for (int i = 0; i < this->getSize(); i++) { - switch (this->getType().getBasicType()) { - case EbtBool: tempConstArray[i].bConst = unionArray[i].bConst ^ node->getUnionArrayPointer()->bConst; break; - default: - infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"^^\"", this->getLine()); - return 0; - } - } - } - break; - - case EOpLogicalOr: // this code is written for possible future use, will not get executed currently - tempConstArray = new constUnion[this->getSize()]; - {// support MSVC++6.0 - for (int i = 0; i < this->getSize(); i++) { - switch (this->getType().getBasicType()) { - case EbtBool: tempConstArray[i].bConst = unionArray[i].bConst || node->getUnionArrayPointer()->bConst; break; - default: - infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"||\"", this->getLine()); - return 0; - } - } - } - break; - - default: - infoSink.info.message(EPrefixInternalError, "Invalid operator for constant folding", this->getLine()); - return 0; - } - newNode = new TIntermConstantUnion(tempConstArray, this->getType()); - newNode->setLine(this->getLine()); - - return newNode; - } else if (constantNode->getAsConstantUnion() && (this->getSize() > 1 || this->getType().getBasicType() == EbtStruct)) { - TIntermConstantUnion *node = constantNode->getAsConstantUnion(); - constUnion *rightUnionArray = node->getUnionArrayPointer(); - constUnion* tempConstArray = 0; - TIntermConstantUnion *tempNode; - int index = 0; - bool boolNodeFlag = false; - switch(op) { - case EOpAdd: - tempConstArray = new constUnion[this->getSize()]; - {// support MSVC++6.0 - for (int i = 0; i < this->getSize(); i++) { - switch (this->getType().getBasicType()) { - case EbtFloat: tempConstArray[i].fConst = unionArray[i].fConst + rightUnionArray[i].fConst; break; - case EbtInt: tempConstArray[i].iConst = unionArray[i].iConst + rightUnionArray[i].iConst; break; - default: - infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"+\"", this->getLine()); - return 0; - } - } - } - break; - case EOpSub: - tempConstArray = new constUnion[this->getSize()]; - {// support MSVC++6.0 - for (int i = 0; i < this->getSize(); i++) { - switch (this->getType().getBasicType()) { - case EbtFloat: - if (leftOperand) - tempConstArray[i].fConst = unionArray[i].fConst - rightUnionArray[i].fConst; - else - tempConstArray[i].fConst = rightUnionArray[i].fConst - unionArray[i].fConst; - break; - - case EbtInt: - if (leftOperand) - tempConstArray[i].iConst = unionArray[i].iConst - rightUnionArray[i].iConst; - else - tempConstArray[i].iConst = rightUnionArray[i].iConst - unionArray[i].iConst; - break; - - default: - infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"-\"", this->getLine()); - return 0; - } - } - } - break; - case EOpMul: - if (this->isVector()) { // two vectors multiplied together - int size = this->getSize(); - tempConstArray = new constUnion[size]; - - for (int i = 0; i < size; i++) { - switch (this->getType().getBasicType()) { - case EbtFloat: tempConstArray[i].fConst = unionArray[i].fConst * rightUnionArray[i].fConst; break; - case EbtInt: tempConstArray[i].iConst = unionArray[i].iConst * rightUnionArray[i].iConst; break; - default: - infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for vector multiply", this->getLine()); - return 0; - } - } - } - break; - case EOpMatrixTimesMatrix: - if (this->getType().getBasicType() != EbtFloat || node->getBasicType() != EbtFloat) { - infoSink.info.message(EPrefixInternalError, "Constant Folding cannot be done for matrix multiply", this->getLine()); - return 0; - } - {// support MSVC++6.0 - int size = this->getNominalSize(); - tempConstArray = new constUnion[size*size]; - for (int row = 0; row < size; row++) { - for (int column = 0; column < size; column++) { - tempConstArray[size * column + row].fConst = 0.0; - for (int i = 0; i < size; i++) { - tempConstArray[size * column + row].fConst += unionArray[i * size + row].fConst * (rightUnionArray[column * size + i].fConst); - } - } - } - } - break; - case EOpDiv: - tempConstArray = new constUnion[this->getSize()]; - {// support MSVC++6.0 - for (int i = 0; i < this->getSize(); i++) { - switch (this->getType().getBasicType()) { - case EbtFloat: - if (leftOperand) { - if (rightUnionArray[i].fConst == 0.0) { - infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", this->getLine()); - tempConstArray[i].fConst = FLT_MAX; - } else - tempConstArray[i].fConst = unionArray[i].fConst / rightUnionArray[i].fConst; - } else { - if (unionArray[i].fConst == 0.0) { - infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", this->getLine()); - tempConstArray[i].fConst = FLT_MAX; - } else - tempConstArray[i].fConst = rightUnionArray[i].fConst / unionArray[i].fConst; - } - break; - - case EbtInt: - if (leftOperand) { - if (rightUnionArray[i].iConst == 0) { - infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", this->getLine()); - tempConstArray[i].iConst = INT_MAX; - } else - tempConstArray[i].iConst = unionArray[i].iConst / rightUnionArray[i].iConst; - } else { - if (unionArray[i].iConst == 0) { - infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", this->getLine()); - tempConstArray[i].iConst = INT_MAX; - } else - tempConstArray[i].iConst = rightUnionArray[i].iConst / unionArray[i].iConst; - } - break; - default: - infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"/\"", this->getLine()); - return 0; - } - } - } - break; - - case EOpMatrixTimesVector: - if (node->getBasicType() != EbtFloat) { - infoSink.info.message(EPrefixInternalError, "Constant Folding cannot be done for matrix times vector", this->getLine()); - return 0; - } - tempConstArray = new constUnion[this->getNominalSize()]; - - {// support MSVC++6.0 - for (int size = this->getNominalSize(), i = 0; i < size; i++) { - tempConstArray[i].fConst = 0.0; - for (int j = 0; j < size; j++) { - tempConstArray[i].fConst += ((unionArray[j*size + i].fConst) * rightUnionArray[j].fConst); - } - } - } - - tempNode = new TIntermConstantUnion(tempConstArray, node->getType()); - tempNode->setLine(this->getLine()); - - return tempNode; - - case EOpVectorTimesMatrix: - if (this->getType().getBasicType() != EbtFloat) { - infoSink.info.message(EPrefixInternalError, "Constant Folding cannot be done for vector times matrix", this->getLine()); - return 0; - } - - tempConstArray = new constUnion[this->getNominalSize()]; - {// support MSVC++6.0 - for (int size = this->getNominalSize(), i = 0; i < size; i++) { - tempConstArray[i].fConst = 0.0; - for (int j = 0; j < size; j++) { - tempConstArray[i].fConst += ((unionArray[j].fConst) * rightUnionArray[i*size + j].fConst); - } - } - } - break; - - case EOpLogicalAnd: // this code is written for possible future use, will not get executed currently - tempConstArray = new constUnion[this->getSize()]; - {// support MSVC++6.0 - for (int i = 0; i < this->getSize(); i++) { - switch (this->getType().getBasicType()) { - case EbtBool: tempConstArray[i].bConst = unionArray[i].bConst && rightUnionArray[i].bConst; break; - default: - infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"&&\"", this->getLine()); - return 0; - } - } - } - break; - - case EOpLogicalXor: // this code is written for possible future use, will not get executed currently - tempConstArray = new constUnion[this->getSize()]; - {// support MSVC++6.0 - for (int i = 0; i < this->getSize(); i++) { - switch (this->getType().getBasicType()) { - case EbtBool: tempConstArray[i].bConst = unionArray[i].bConst ^ rightUnionArray[i].bConst; break; - default: - infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"^^\"", this->getLine()); - return 0; - } - } - } - break; - - case EOpLogicalOr: // this code is written for possible future use, will not get executed currently - tempConstArray = new constUnion[this->getSize()]; - {// support MSVC++6.0 - for (int i = 0; i < this->getSize(); i++) { - switch (this->getType().getBasicType()) { - case EbtBool: tempConstArray[i].bConst = unionArray[i].bConst || rightUnionArray[i].bConst; break; - default: - infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"||\"", this->getLine()); - return 0; - } - } - } - break; - - case EOpEqual: - - switch (this->getType().getBasicType()) { - case EbtFloat: - {// support MSVC++6.0 - for (int i = 0; i < this->getSize(); i++) { - if (unionArray[i].fConst != rightUnionArray[i].fConst) { - boolNodeFlag = true; - break; // break out of for loop - } - } - } - break; - - case EbtInt: - {// support MSVC++6.0 - for (int i = 0; i < this->getSize(); i++) { - if (unionArray[i].iConst != rightUnionArray[i].iConst) { - boolNodeFlag = true; - break; // break out of for loop - } - } - } - break; - case EbtBool: - {// support MSVC++6.0 - for (int i = 0; i < this->getSize(); i++) { - if (unionArray[i].bConst != rightUnionArray[i].bConst) { - boolNodeFlag = true; - break; // break out of for loop - } - } - } - break; - case EbtStruct: - if (!compareStructure(node->getType(), node->getUnionArrayPointer(), unionArray, index)) - boolNodeFlag = true; - break; - - default: - infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"==\"", this->getLine()); - return 0; - } - - tempConstArray = new constUnion[1]; - if (!boolNodeFlag) { - tempConstArray->bConst = true; - } - else { - tempConstArray->bConst = false; - } - - tempNode = new TIntermConstantUnion(tempConstArray, TType(EbtBool, EvqConst)); - tempNode->setLine(this->getLine()); - - return tempNode; - - case EOpNotEqual: - switch (this->getType().getBasicType()) { - case EbtFloat: - {// support MSVC++6.0 - for (int i = 0; i < this->getSize(); i++) { - if (unionArray[i].fConst == rightUnionArray[i].fConst) { - boolNodeFlag = true; - break; // break out of for loop - } - } - } - break; - - case EbtInt: - {// support MSVC++6.0 - for (int i = 0; i < this->getSize(); i++) { - if (unionArray[i].iConst == rightUnionArray[i].iConst) { - boolNodeFlag = true; - break; // break out of for loop - } - } - } - break; - case EbtBool: - {// support MSVC++6.0 - for (int i = 0; i < this->getSize(); i++) { - if (unionArray[i].bConst == rightUnionArray[i].bConst) { - boolNodeFlag = true; - break; // break out of for loop - } - } - } - break; - case EbtStruct: - if (compareStructure(node->getType(), node->getUnionArrayPointer(), unionArray, index)) - boolNodeFlag = true; - break; - default: - infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"!=\"", this->getLine()); - return 0; - } - - tempConstArray = new constUnion[1]; - if (!boolNodeFlag) { - tempConstArray->bConst = true; - } - else { - tempConstArray->bConst = false; - } - - tempNode = new TIntermConstantUnion(tempConstArray, TType(EbtBool, EvqConst)); - tempNode->setLine(this->getLine()); - - return tempNode; - - default: - infoSink.info.message(EPrefixInternalError, "Invalid operator for constant folding", this->getLine()); - return 0; - } - tempNode = new TIntermConstantUnion(tempConstArray, this->getType()); - tempNode->setLine(this->getLine()); - - return tempNode; - } else if (this->getSize() == 1 && this->getType().getBasicType() != EbtStruct - && constantNode->getSize() == 1 && constantNode->getType().getBasicType() != EbtStruct ) { // scalar constant folding - constUnion *unionArray = new constUnion[1]; - TIntermConstantUnion* newNode = 0; - - switch (this->getType().getBasicType()) { - case EbtInt: - { - // - // Dealing with two operands, us and constant. - // - // Do Binary operations. - // - int rightValue = constantNode->getAsConstantUnion()->getUnionArrayPointer()->iConst; - int leftValue = this->getUnionArrayPointer()->iConst; - //int line = this->getLine(); - - switch(op) { - //?? add constant intrinsics - case EOpAdd: unionArray->iConst = leftValue + rightValue; break; - case EOpSub: unionArray->iConst = leftValue - rightValue; break; - case EOpMul: unionArray->iConst = leftValue * rightValue; break; - case EOpDiv: - if (rightValue == 0) { - infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", this->getLine()); - unionArray->iConst = INT_MAX; - } else - unionArray->iConst = leftValue / rightValue; break; - - case EOpMod: unionArray->iConst = leftValue % rightValue; break; - - case EOpRightShift: unionArray->iConst = leftValue >> rightValue; break; - case EOpLeftShift: unionArray->iConst = leftValue << rightValue; break; - - case EOpAnd: unionArray->iConst = leftValue & rightValue; break; - case EOpInclusiveOr: unionArray->iConst = leftValue | rightValue; break; - case EOpExclusiveOr: unionArray->iConst = leftValue ^ rightValue; break; - - // the following assume it's okay to have memory leaks - case EOpEqual: - unionArray->bConst = leftValue == rightValue; - newNode = new TIntermConstantUnion(unionArray, TType(EbtBool, EvqConst)); - break; - case EOpNotEqual: - unionArray->bConst = leftValue != rightValue; - newNode = new TIntermConstantUnion(unionArray, TType(EbtBool, EvqConst)); - break; - case EOpLessThan: - unionArray->bConst = leftValue < rightValue; - newNode = new TIntermConstantUnion(unionArray, TType(EbtBool, EvqConst)); - break; - case EOpGreaterThan: - unionArray->bConst = leftValue > rightValue; - newNode = new TIntermConstantUnion(unionArray, TType(EbtBool, EvqConst)); - break; - case EOpLessThanEqual: - unionArray->bConst = leftValue <= rightValue; - newNode = new TIntermConstantUnion(unionArray, TType(EbtBool, EvqConst)); - break; - case EOpGreaterThanEqual: - unionArray->bConst = leftValue >= rightValue; - newNode = new TIntermConstantUnion(unionArray, TType(EbtBool, EvqConst)); - break; - - default: - //infoSink.info.message(EPrefixInternalError, "Binary operation not folded into constant int", line); - return 0; - } - if (!newNode) { - newNode = new TIntermConstantUnion(unionArray, TType(EbtInt, EvqConst)); - } - newNode->setLine(constantNode->getLine()); - return newNode; - } - case EbtFloat: - { - float rightValue = constantNode->getAsConstantUnion()->getUnionArrayPointer()->fConst; - float leftValue = this->getUnionArrayPointer()->fConst; - - switch(op) { - //?? add constant intrinsics - case EOpAdd: unionArray->fConst = leftValue + rightValue; break; - case EOpSub: unionArray->fConst = leftValue - rightValue; break; - case EOpMul: unionArray->fConst = leftValue * rightValue; break; - case EOpDiv: - if (rightValue == 0.0) { - infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", this->getLine()); - unionArray->fConst = FLT_MAX; - } else - unionArray->fConst = leftValue / rightValue; break; - - // the following assume it's okay to have memory leaks (cleaned up by pool allocator) - case EOpEqual: - unionArray->bConst = leftValue == rightValue; - newNode = new TIntermConstantUnion(unionArray, TType(EbtBool, EvqConst)); - break; - case EOpNotEqual: - unionArray->bConst = leftValue != rightValue; - newNode = new TIntermConstantUnion(unionArray, TType(EbtBool, EvqConst)); - break; - case EOpLessThan: - unionArray->bConst = leftValue < rightValue; - newNode = new TIntermConstantUnion(unionArray, TType(EbtBool, EvqConst)); - break; - case EOpGreaterThan: - unionArray->bConst = leftValue > rightValue; - newNode = new TIntermConstantUnion(unionArray, TType(EbtBool, EvqConst)); - break; - case EOpLessThanEqual: - unionArray->bConst = leftValue <= rightValue; - newNode = new TIntermConstantUnion(unionArray, TType(EbtBool, EvqConst)); - break; - case EOpGreaterThanEqual: - unionArray->bConst = leftValue >= rightValue; - newNode = new TIntermConstantUnion(unionArray, TType(EbtBool, EvqConst)); - break; - - default: - //infoSink.info.message(EPrefixInternalError, "Binary operation not folded into constant float", line); - return 0; - } - if (!newNode) { - newNode = new TIntermConstantUnion(unionArray, TType(EbtFloat, EvqConst)); - } - newNode->setLine(constantNode->getLine()); - return newNode; - } - case EbtBool: - { - bool rightValue = constantNode->getAsConstantUnion()->getUnionArrayPointer()->bConst; - bool leftValue = this->getUnionArrayPointer()->bConst; - - switch(op) { - //?? add constant intrinsics - case EOpLogicalAnd: unionArray->bConst = leftValue & rightValue; break; - case EOpLogicalXor: unionArray->bConst = leftValue ^ rightValue; break; - case EOpLogicalOr: unionArray->bConst = leftValue | rightValue; break; - default: - infoSink.info.message(EPrefixInternalError, "Binary operator cannot be folded into constant bool", line); - return 0; - } - newNode = new TIntermConstantUnion(unionArray, TType(EbtBool, EvqConst)); - newNode->setLine(constantNode->getLine()); - return newNode; - } - default: - infoSink.info.message(EPrefixInternalError, "Cannot fold constant", this->getLine()); - return 0; - } - } - } else { - // - // Do unary operations - // - TIntermConstantUnion *newNode = 0; - constUnion* tempConstArray = new constUnion[this->getSize()]; - if (this->getSize() > 1) { - for (int i = 0; i < this->getSize(); i++) { - switch(op) { - case EOpNegative: - switch (this->getType().getBasicType()) { - case EbtFloat: tempConstArray[i].fConst = -(unionArray[i].fConst); break; - case EbtInt: tempConstArray[i].iConst = -(unionArray[i].iConst); break; - default: - infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", this->getLine()); - return 0; - } - break; - case EOpLogicalNot: // this code is written for possible future use, will not get executed currently - switch (this->getType().getBasicType()) { - case EbtBool: tempConstArray[i].bConst = !(unionArray[i].bConst); break; - default: - infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", this->getLine()); - return 0; - } - break; - default: - return 0; - } - } - newNode = new TIntermConstantUnion(tempConstArray, this->getType()); - newNode->setLine(this->getLine()); - return newNode; - } else { - switch(op) { - //?? add constant intrinsics - case EOpNegative: - switch (this->getType().getBasicType()) { - case EbtInt: - tempConstArray->iConst = -(this->getUnionArrayPointer()->iConst); - newNode = new TIntermConstantUnion(tempConstArray, TType(EbtInt, EvqConst)); - break; - case EbtFloat: - tempConstArray->fConst = -(this->getUnionArrayPointer()->fConst); - newNode = new TIntermConstantUnion(tempConstArray, TType(EbtFloat, EvqConst)); - break; - default: - infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", line); - return 0; - } - break; - case EOpLogicalNot: - switch (this->getType().getBasicType()) { - case EbtBool: - tempConstArray->bConst = !this->getUnionArrayPointer()->bConst; - newNode = new TIntermConstantUnion(tempConstArray, TType(EbtBool, EvqConst)); - break; - default: - infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", line); - return 0; - } - break; - default: - return 0; - } - newNode->setLine(this->getLine()); - return newNode; - - } - } - - return this; -} - -TIntermConstantUnion* TIntermediate::changeAggrToTempConst(TIntermAggregate* node, TSymbolTable& symbolTable, TSourceLoc line) -{ - constUnion* unionArray = new constUnion[node->getType().getInstanceSize()]; - bool returnVal; - - if (node->getSequence().size() == 1 && node->getSequence()[0]->getAsTyped()->getAsConstantUnion()) { - returnVal = parseConstTree(line, node, unionArray, node->getOp(), symbolTable, node->getType(), true); - } - else { - returnVal = parseConstTree(line, node, unionArray, node->getOp(), symbolTable, node->getType()); - } - - if (returnVal) - unionArray = 0; - - return (addConstantUnion(unionArray, node->getType(), node->getLine())); -} - -TIntermTyped* TIntermediate::copyConstUnion(TIntermConstantUnion* node) -{ - constUnion *unionArray = node->getUnionArrayPointer(); - - if (!unionArray) - return 0; - - int size; - if (node->getType().getBasicType() == EbtStruct) - //?? We should actually be calling getStructSize() function and not setStructSize. This problem occurs in case - // of nested/embedded structs. - size = node->getType().setStructSize(node->getType().getStruct()); - //size = node->getType().getStructSize(); - else - size = node->getType().getInstanceSize(); - - constUnion *newSpace = new constUnion[size]; - - for (int i = 0; i < size; i++) - newSpace[i] = unionArray[i]; - - node->setUnionArrayPointer(newSpace); - return node; -} - -TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermConstantUnion* node) -{ - constUnion *rightUnionArray = node->getUnionArrayPointer(); - int size = node->getType().getInstanceSize(); - - constUnion *leftUnionArray = new constUnion[size]; - - for (int i=0; i < size; i++) { - - switch (promoteTo) { - case EbtFloat: - switch (node->getType().getBasicType()) { - case EbtInt: - (leftUnionArray[i]).fConst = static_cast(rightUnionArray[i].iConst); - break; - case EbtBool: - (leftUnionArray[i]).fConst = static_cast(rightUnionArray[i].bConst); - break; - case EbtFloat: - (leftUnionArray[i]).fConst = rightUnionArray[i].fConst; - break; - default: - infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine()); - return 0; - } - break; - case EbtInt: - switch (node->getType().getBasicType()) { - case EbtInt: - (leftUnionArray[i]).iConst = rightUnionArray[i].iConst; - break; - case EbtBool: - (leftUnionArray[i]).iConst = static_cast(rightUnionArray[i].bConst); - break; - case EbtFloat: - (leftUnionArray[i]).iConst = static_cast(rightUnionArray[i].fConst); - break; - default: - infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine()); - return 0; - } - break; - case EbtBool: - switch (node->getType().getBasicType()) { - case EbtInt: - (leftUnionArray[i]).bConst = rightUnionArray[i].iConst != 0; - break; - case EbtBool: - (leftUnionArray[i]).bConst = rightUnionArray[i].bConst; - break; - case EbtFloat: - (leftUnionArray[i]).bConst = rightUnionArray[i].fConst != 0.0; - break; - default: - infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine()); - return 0; - } - - break; - default: - infoSink.info.message(EPrefixInternalError, "Incorrect data type found", node->getLine()); - return 0; - } - - } - - const TType& t = node->getType(); - - return addConstantUnion(leftUnionArray, TType(promoteTo, t.getQualifier(), t.getNominalSize(), t.isMatrix(), t.isArray()), node->getLine()); -} - -// -// This method inserts the child nodes into the parent node at the given location specified -// by parentNodeIter. offset tells the integer offset into the parent vector that points to -// the child node. sequenceVector is the parent vector. -// Returns reference to the last inserted child node -// increments the offset based on the number of child nodes added -// -void TIntermediate::removeChildNode(TIntermSequence &parentSequence, TType& parentType, int& offset, TIntermSequence::iterator& parentNodeIter, TIntermAggregate* child) -{ - if (!child) - return; - - parentNodeIter = parentSequence.begin() + offset; - - TIntermSequence& childSequence = child->getSequence(); - int oldSize = static_cast(parentSequence.size()); - if (childSequence.size() == 1) { - if (!removeMatrixConstNode(parentSequence, parentType, child, offset)) { - for (int i = 0; i < child->getType().getInstanceSize(); i++) { - constUnion* constantUnion = new constUnion[1]; - *constantUnion = *(childSequence[0]->getAsConstantUnion()->getUnionArrayPointer()); - TIntermConstantUnion *constant = new TIntermConstantUnion(constantUnion, - childSequence[0]->getAsConstantUnion()->getType()); - constant->setLine(child->getLine()); - parentNodeIter = parentSequence.begin() + offset; - parentSequence.insert(parentNodeIter, constant); - } - } - } else - parentSequence.insert(parentNodeIter, childSequence.begin(), childSequence.end()); - - int newSize = static_cast(parentSequence.size()); - offset = offset + newSize - oldSize; - parentNodeIter = parentSequence.begin() + offset; - parentNodeIter = parentSequence.erase(parentNodeIter); - offset--; - parentNodeIter--; -} - -// -// The parent has only one child node. This method is not implemented -// for parent that is a structure -// -TIntermTyped* TIntermediate::removeChildNode(TIntermTyped* parent, TType* parentType, TIntermAggregate* child) -{ - TIntermTyped* resultNode = 0; - - if (parentType->getInstanceSize() == 1) { - resultNode = child->getSequence()[0]->getAsTyped(); - } else { - int size = parentType->getInstanceSize(); - TIntermSequence& parentSequence = parent->getAsAggregate()->getSequence(); - TIntermSequence& childSequence = child->getSequence(); - - if (childSequence.size() == 1) { - if (!removeMatrixConstNode(parentSequence, *parentType, child, 1)) - parentSequence.push_back(child->getSequence()[0]); - } else { - for (int i = 0; i < size; i++) { - parentSequence.push_back(child->getSequence()[i]); - } - } - parentSequence.erase(parentSequence.begin()); - - return parent; - } - - return resultNode; -} - -bool TIntermediate::removeMatrixConstNode(TIntermSequence &parentSequence, TType& parentType, TIntermAggregate* child, int offset) -{ - if (!child) - return false; - - TIntermSequence::iterator parentNodeIter; - TIntermSequence &childSequence = child->getSequence(); - - switch (child->getOp()) { - case EOpConstructMat2: - case EOpConstructMat3: - case EOpConstructMat4: - {// support MSVC++6.0 - for (int i = 0; i < child->getType().getInstanceSize(); i++) { - constUnion* constantUnion = new constUnion[1]; - if (i % (child->getType().getNominalSize() + 1) == 0) { - *constantUnion = *(childSequence[0]->getAsConstantUnion()->getUnionArrayPointer()); - } else { - switch (parentType.getBasicType()) { - case EbtInt: constantUnion->iConst = 0; break; - case EbtFloat: constantUnion->fConst = 0.0; break; - case EbtBool: constantUnion->bConst = false; break; - default: ; /* default added by BrianP */ - } - } - TIntermConstantUnion *constant = new TIntermConstantUnion(constantUnion, - childSequence[0]->getAsConstantUnion()->getType()); - constant->setLine(child->getLine()); - parentNodeIter = parentSequence.begin() + offset + i; - parentSequence.insert(parentNodeIter, constant); - } - } - return true; - default: - return false; - } -} - -void TIntermAggregate::addToPragmaTable(const TPragmaTable& pTable) -{ - assert (!pragmaTable); - pragmaTable = new TPragmaTable(); - *pragmaTable = pTable; -} - -- cgit v1.2.3