Commit a223430c by Olli Etuaho Committed by Commit Bot

Promote unary nodes automatically

Unary nodes now get their type set automatically based on the operation and operand. The operand should only be changed to another of the same type after the node is constructed. The operation can't be changed on unary and binary nodes after they've been constructed. BUG=angleproject:1490 TEST=angle_unittests Change-Id: Ib1ea3dcb1162261966c02d5f03d8091cf647fac1 Reviewed-on: https://chromium-review.googlesource.com/378935Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
parent 3272a6d3
...@@ -192,6 +192,7 @@ bool TIntermBinary::replaceChildNode( ...@@ -192,6 +192,7 @@ bool TIntermBinary::replaceChildNode(
bool TIntermUnary::replaceChildNode( bool TIntermUnary::replaceChildNode(
TIntermNode *original, TIntermNode *replacement) TIntermNode *original, TIntermNode *replacement)
{ {
ASSERT(original->getAsTyped()->getType() == replacement->getAsTyped()->getType());
REPLACE_IF_IS(mOperand, TIntermTyped, original, replacement); REPLACE_IF_IS(mOperand, TIntermTyped, original, replacement);
return false; return false;
} }
...@@ -623,46 +624,66 @@ TOperator TIntermBinary::GetMulAssignOpBasedOnOperands(const TType &left, const ...@@ -623,46 +624,66 @@ TOperator TIntermBinary::GetMulAssignOpBasedOnOperands(const TType &left, const
// Make sure the type of a unary operator is appropriate for its // Make sure the type of a unary operator is appropriate for its
// combination of operation and operand type. // combination of operation and operand type.
// //
void TIntermUnary::promote(const TType *funcReturnType) void TIntermUnary::promote()
{ {
switch (mOp) TQualifier resultQualifier = EvqTemporary;
{ if (mOperand->getQualifier() == EvqConst)
case EOpFloatBitsToInt: resultQualifier = EvqConst;
case EOpFloatBitsToUint:
case EOpIntBitsToFloat:
case EOpUintBitsToFloat:
case EOpPackSnorm2x16:
case EOpPackUnorm2x16:
case EOpPackHalf2x16:
case EOpUnpackSnorm2x16:
case EOpUnpackUnorm2x16:
mType.setPrecision(EbpHigh);
break;
case EOpUnpackHalf2x16:
mType.setPrecision(EbpMedium);
break;
default:
setType(mOperand->getType());
}
if (funcReturnType != nullptr) unsigned char operandPrimarySize =
static_cast<unsigned char>(mOperand->getType().getNominalSize());
switch (mOp)
{ {
if (funcReturnType->getBasicType() == EbtBool) case EOpFloatBitsToInt:
{ setType(TType(EbtInt, EbpHigh, resultQualifier, operandPrimarySize));
// Bool types should not have precision. break;
setType(*funcReturnType); case EOpFloatBitsToUint:
} setType(TType(EbtUInt, EbpHigh, resultQualifier, operandPrimarySize));
else break;
{ case EOpIntBitsToFloat:
// Precision of the node has been set based on the operand. case EOpUintBitsToFloat:
setTypePreservePrecision(*funcReturnType); setType(TType(EbtFloat, EbpHigh, resultQualifier, operandPrimarySize));
} break;
case EOpPackSnorm2x16:
case EOpPackUnorm2x16:
case EOpPackHalf2x16:
setType(TType(EbtUInt, EbpHigh, resultQualifier));
break;
case EOpUnpackSnorm2x16:
case EOpUnpackUnorm2x16:
setType(TType(EbtFloat, EbpHigh, resultQualifier, 2));
break;
case EOpUnpackHalf2x16:
setType(TType(EbtFloat, EbpMedium, resultQualifier, 2));
break;
case EOpAny:
case EOpAll:
setType(TType(EbtBool, EbpUndefined, resultQualifier));
break;
case EOpLength:
case EOpDeterminant:
setType(TType(EbtFloat, mOperand->getType().getPrecision(), resultQualifier));
break;
case EOpTranspose:
setType(TType(EbtFloat, mOperand->getType().getPrecision(), resultQualifier,
static_cast<unsigned char>(mOperand->getType().getRows()),
static_cast<unsigned char>(mOperand->getType().getCols())));
break;
case EOpIsInf:
case EOpIsNan:
setType(TType(EbtBool, EbpUndefined, resultQualifier, operandPrimarySize));
break;
default:
setType(mOperand->getType());
mType.setQualifier(resultQualifier);
break;
} }
}
if (mOperand->getQualifier() == EvqConst) TIntermUnary::TIntermUnary(TOperator op, TIntermTyped *operand)
mType.setQualifier(EvqConst); : TIntermOperator(op), mOperand(operand), mUseEmulatedFunction(false)
else {
mType.setQualifier(EvqTemporary); promote();
} }
TIntermBinary::TIntermBinary(TOperator op, TIntermTyped *left, TIntermTyped *right) TIntermBinary::TIntermBinary(TOperator op, TIntermTyped *left, TIntermTyped *right)
......
...@@ -387,7 +387,6 @@ class TIntermOperator : public TIntermTyped ...@@ -387,7 +387,6 @@ class TIntermOperator : public TIntermTyped
{ {
public: public:
TOperator getOp() const { return mOp; } TOperator getOp() const { return mOp; }
void setOp(TOperator op) { mOp = op; }
bool isAssignment() const; bool isAssignment() const;
bool isMultiplication() const; bool isMultiplication() const;
...@@ -457,19 +456,7 @@ class TIntermBinary : public TIntermOperator ...@@ -457,19 +456,7 @@ class TIntermBinary : public TIntermOperator
class TIntermUnary : public TIntermOperator class TIntermUnary : public TIntermOperator
{ {
public: public:
TIntermUnary(TOperator op, const TType &type) TIntermUnary(TOperator op, TIntermTyped *operand);
: TIntermOperator(op, type),
mOperand(NULL),
mUseEmulatedFunction(false) {}
TIntermUnary(TOperator op)
: TIntermOperator(op),
mOperand(NULL),
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); }
...@@ -479,9 +466,7 @@ class TIntermUnary : public TIntermOperator ...@@ -479,9 +466,7 @@ class TIntermUnary : public TIntermOperator
bool hasSideEffects() const override { return isAssignment() || mOperand->hasSideEffects(); } bool hasSideEffects() const override { return isAssignment() || mOperand->hasSideEffects(); }
void setOperand(TIntermTyped *operand) { mOperand = operand; }
TIntermTyped *getOperand() { return mOperand; } TIntermTyped *getOperand() { return mOperand; }
void promote(const TType *funcReturnType);
TIntermTyped *fold(TDiagnostics *diagnostics); TIntermTyped *fold(TDiagnostics *diagnostics);
void setUseEmulatedFunction() { mUseEmulatedFunction = true; } void setUseEmulatedFunction() { mUseEmulatedFunction = true; }
...@@ -495,6 +480,8 @@ class TIntermUnary : public TIntermOperator ...@@ -495,6 +480,8 @@ class TIntermUnary : public TIntermOperator
bool mUseEmulatedFunction; bool mUseEmulatedFunction;
private: private:
void promote();
TIntermUnary(const TIntermUnary &node); // note: not deleted, just private! TIntermUnary(const TIntermUnary &node); // note: not deleted, just private!
}; };
...@@ -528,6 +515,8 @@ class TIntermAggregate : public TIntermOperator ...@@ -528,6 +515,8 @@ class TIntermAggregate : public TIntermOperator
// Note: only supported for nodes that can be a part of an expression. // Note: only supported for nodes that can be a part of an expression.
TIntermTyped *deepCopy() const override { return new TIntermAggregate(*this); } TIntermTyped *deepCopy() const override { return new TIntermAggregate(*this); }
void setOp(TOperator op) { mOp = op; }
TIntermAggregate *getAsAggregate() override { return this; } TIntermAggregate *getAsAggregate() override { return this; }
void traverse(TIntermTraverser *it) override; void traverse(TIntermTraverser *it) override;
bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override; bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
......
...@@ -3212,7 +3212,6 @@ TIntermTyped *TParseContext::createUnaryMath(TOperator op, ...@@ -3212,7 +3212,6 @@ TIntermTyped *TParseContext::createUnaryMath(TOperator op,
TIntermUnary *node = new TIntermUnary(op, child); TIntermUnary *node = new TIntermUnary(op, child);
node->setLine(loc); node->setLine(loc);
node->promote(funcReturnType);
TIntermTyped *foldedNode = node->fold(&mDiagnostics); TIntermTyped *foldedNode = node->fold(&mDiagnostics);
if (foldedNode) if (foldedNode)
......
...@@ -55,19 +55,15 @@ bool RemovePowTraverser::visitAggregate(Visit visit, TIntermAggregate *node) ...@@ -55,19 +55,15 @@ bool RemovePowTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
TIntermTyped *x = node->getSequence()->at(0)->getAsTyped(); TIntermTyped *x = node->getSequence()->at(0)->getAsTyped();
TIntermTyped *y = node->getSequence()->at(1)->getAsTyped(); TIntermTyped *y = node->getSequence()->at(1)->getAsTyped();
TIntermUnary *log = new TIntermUnary(EOpLog2); TIntermUnary *log = new TIntermUnary(EOpLog2, x);
log->setOperand(x);
log->setLine(node->getLine()); log->setLine(node->getLine());
log->setType(x->getType());
TOperator op = TIntermBinary::GetMulOpBasedOnOperands(y->getType(), log->getType()); TOperator op = TIntermBinary::GetMulOpBasedOnOperands(y->getType(), log->getType());
TIntermBinary *mul = new TIntermBinary(op, y, log); TIntermBinary *mul = new TIntermBinary(op, y, log);
mul->setLine(node->getLine()); mul->setLine(node->getLine());
TIntermUnary *exp = new TIntermUnary(EOpExp2); TIntermUnary *exp = new TIntermUnary(EOpExp2, mul);
exp->setOperand(mul);
exp->setLine(node->getLine()); exp->setLine(node->getLine());
exp->setType(node->getType());
queueReplacement(node, exp, OriginalNode::IS_DROPPED); queueReplacement(node, exp, OriginalNode::IS_DROPPED);
......
...@@ -102,8 +102,8 @@ class DoWhileRewriter : public TIntermTraverser ...@@ -102,8 +102,8 @@ class DoWhileRewriter : public TIntermTraverser
TIntermAggregate *breakBlock = new TIntermAggregate(EOpSequence); TIntermAggregate *breakBlock = new TIntermAggregate(EOpSequence);
breakBlock->getSequence()->push_back(breakStatement); breakBlock->getSequence()->push_back(breakStatement);
TIntermUnary *negatedCondition = new TIntermUnary(EOpLogicalNot); TIntermUnary *negatedCondition =
negatedCondition->setOperand(loop->getCondition()); new TIntermUnary(EOpLogicalNot, loop->getCondition());
TIntermSelection *innerIf = TIntermSelection *innerIf =
new TIntermSelection(negatedCondition, breakBlock, nullptr); new TIntermSelection(negatedCondition, breakBlock, nullptr);
......
...@@ -31,13 +31,6 @@ class ElseBlockRewriter : public TIntermTraverser ...@@ -31,13 +31,6 @@ class ElseBlockRewriter : public TIntermTraverser
TIntermNode *rewriteSelection(TIntermSelection *selection); TIntermNode *rewriteSelection(TIntermSelection *selection);
}; };
TIntermUnary *MakeNewUnary(TOperator op, TIntermTyped *operand)
{
TIntermUnary *unary = new TIntermUnary(op, operand->getType());
unary->setOperand(operand);
return unary;
}
ElseBlockRewriter::ElseBlockRewriter() ElseBlockRewriter::ElseBlockRewriter()
: TIntermTraverser(true, false, true), : TIntermTraverser(true, false, true),
mFunctionType(NULL) mFunctionType(NULL)
...@@ -113,7 +106,7 @@ TIntermNode *ElseBlockRewriter::rewriteSelection(TIntermSelection *selection) ...@@ -113,7 +106,7 @@ TIntermNode *ElseBlockRewriter::rewriteSelection(TIntermSelection *selection)
} }
TIntermSymbol *conditionSymbolElse = createTempSymbol(boolType); TIntermSymbol *conditionSymbolElse = createTempSymbol(boolType);
TIntermUnary *negatedCondition = MakeNewUnary(EOpLogicalNot, conditionSymbolElse); TIntermUnary *negatedCondition = new TIntermUnary(EOpLogicalNot, conditionSymbolElse);
falseBlock = new TIntermSelection(negatedCondition, falseBlock = new TIntermSelection(negatedCondition,
selection->getFalseBlock(), negatedElse); selection->getFalseBlock(), negatedElse);
} }
......
...@@ -79,8 +79,7 @@ bool UnfoldShortCircuitTraverser::visitBinary(Visit visit, TIntermBinary *node) ...@@ -79,8 +79,7 @@ bool UnfoldShortCircuitTraverser::visitBinary(Visit visit, TIntermBinary *node)
ASSERT(node->getRight()->getType() == boolType); ASSERT(node->getRight()->getType() == boolType);
assignRightBlock->getSequence()->push_back(createTempAssignment(node->getRight())); assignRightBlock->getSequence()->push_back(createTempAssignment(node->getRight()));
TIntermUnary *notTempSymbol = new TIntermUnary(EOpLogicalNot, boolType); TIntermUnary *notTempSymbol = new TIntermUnary(EOpLogicalNot, createTempSymbol(boolType));
notTempSymbol->setOperand(createTempSymbol(boolType));
TIntermSelection *ifNode = new TIntermSelection(notTempSymbol, assignRightBlock, nullptr); TIntermSelection *ifNode = new TIntermSelection(notTempSymbol, assignRightBlock, nullptr);
insertions.push_back(ifNode); insertions.push_back(ifNode);
......
...@@ -166,9 +166,8 @@ TEST_F(IntermNodeTest, DeepCopyUnaryNode) ...@@ -166,9 +166,8 @@ TEST_F(IntermNodeTest, DeepCopyUnaryNode)
{ {
TType type(EbtFloat, EbpHigh); TType type(EbtFloat, EbpHigh);
TIntermUnary *original = new TIntermUnary(EOpPreIncrement); TIntermUnary *original = new TIntermUnary(EOpPreIncrement, createTestSymbol());
original->setLine(getTestSourceLoc()); original->setLine(getTestSourceLoc());
original->setOperand(createTestSymbol());
TIntermTyped *copyTyped = original->deepCopy(); TIntermTyped *copyTyped = original->deepCopy();
TIntermUnary *copy = copyTyped->getAsUnaryNode(); TIntermUnary *copy = copyTyped->getAsUnaryNode();
ASSERT_NE(nullptr, copy); ASSERT_NE(nullptr, copy);
......
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