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(
bool TIntermUnary::replaceChildNode(
TIntermNode *original, TIntermNode *replacement)
{
ASSERT(original->getAsTyped()->getType() == replacement->getAsTyped()->getType());
REPLACE_IF_IS(mOperand, TIntermTyped, original, replacement);
return false;
}
......@@ -623,46 +624,66 @@ TOperator TIntermBinary::GetMulAssignOpBasedOnOperands(const TType &left, const
// Make sure the type of a unary operator is appropriate for its
// combination of operation and operand type.
//
void TIntermUnary::promote(const TType *funcReturnType)
void TIntermUnary::promote()
{
switch (mOp)
{
case EOpFloatBitsToInt:
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());
}
TQualifier resultQualifier = EvqTemporary;
if (mOperand->getQualifier() == EvqConst)
resultQualifier = EvqConst;
if (funcReturnType != nullptr)
unsigned char operandPrimarySize =
static_cast<unsigned char>(mOperand->getType().getNominalSize());
switch (mOp)
{
if (funcReturnType->getBasicType() == EbtBool)
{
// Bool types should not have precision.
setType(*funcReturnType);
}
else
{
// Precision of the node has been set based on the operand.
setTypePreservePrecision(*funcReturnType);
}
case EOpFloatBitsToInt:
setType(TType(EbtInt, EbpHigh, resultQualifier, operandPrimarySize));
break;
case EOpFloatBitsToUint:
setType(TType(EbtUInt, EbpHigh, resultQualifier, operandPrimarySize));
break;
case EOpIntBitsToFloat:
case EOpUintBitsToFloat:
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)
mType.setQualifier(EvqConst);
else
mType.setQualifier(EvqTemporary);
TIntermUnary::TIntermUnary(TOperator op, TIntermTyped *operand)
: TIntermOperator(op), mOperand(operand), mUseEmulatedFunction(false)
{
promote();
}
TIntermBinary::TIntermBinary(TOperator op, TIntermTyped *left, TIntermTyped *right)
......
......@@ -387,7 +387,6 @@ class TIntermOperator : public TIntermTyped
{
public:
TOperator getOp() const { return mOp; }
void setOp(TOperator op) { mOp = op; }
bool isAssignment() const;
bool isMultiplication() const;
......@@ -457,19 +456,7 @@ class TIntermBinary : public TIntermOperator
class TIntermUnary : public TIntermOperator
{
public:
TIntermUnary(TOperator op, const TType &type)
: 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)
{
}
TIntermUnary(TOperator op, TIntermTyped *operand);
TIntermTyped *deepCopy() const override { return new TIntermUnary(*this); }
......@@ -479,9 +466,7 @@ class TIntermUnary : public TIntermOperator
bool hasSideEffects() const override { return isAssignment() || mOperand->hasSideEffects(); }
void setOperand(TIntermTyped *operand) { mOperand = operand; }
TIntermTyped *getOperand() { return mOperand; }
void promote(const TType *funcReturnType);
TIntermTyped *fold(TDiagnostics *diagnostics);
void setUseEmulatedFunction() { mUseEmulatedFunction = true; }
......@@ -495,6 +480,8 @@ class TIntermUnary : public TIntermOperator
bool mUseEmulatedFunction;
private:
void promote();
TIntermUnary(const TIntermUnary &node); // note: not deleted, just private!
};
......@@ -528,6 +515,8 @@ class TIntermAggregate : public TIntermOperator
// Note: only supported for nodes that can be a part of an expression.
TIntermTyped *deepCopy() const override { return new TIntermAggregate(*this); }
void setOp(TOperator op) { mOp = op; }
TIntermAggregate *getAsAggregate() override { return this; }
void traverse(TIntermTraverser *it) override;
bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
......
......@@ -3212,7 +3212,6 @@ TIntermTyped *TParseContext::createUnaryMath(TOperator op,
TIntermUnary *node = new TIntermUnary(op, child);
node->setLine(loc);
node->promote(funcReturnType);
TIntermTyped *foldedNode = node->fold(&mDiagnostics);
if (foldedNode)
......
......@@ -55,19 +55,15 @@ bool RemovePowTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
TIntermTyped *x = node->getSequence()->at(0)->getAsTyped();
TIntermTyped *y = node->getSequence()->at(1)->getAsTyped();
TIntermUnary *log = new TIntermUnary(EOpLog2);
log->setOperand(x);
TIntermUnary *log = new TIntermUnary(EOpLog2, x);
log->setLine(node->getLine());
log->setType(x->getType());
TOperator op = TIntermBinary::GetMulOpBasedOnOperands(y->getType(), log->getType());
TIntermBinary *mul = new TIntermBinary(op, y, log);
mul->setLine(node->getLine());
TIntermUnary *exp = new TIntermUnary(EOpExp2);
exp->setOperand(mul);
TIntermUnary *exp = new TIntermUnary(EOpExp2, mul);
exp->setLine(node->getLine());
exp->setType(node->getType());
queueReplacement(node, exp, OriginalNode::IS_DROPPED);
......
......@@ -102,8 +102,8 @@ class DoWhileRewriter : public TIntermTraverser
TIntermAggregate *breakBlock = new TIntermAggregate(EOpSequence);
breakBlock->getSequence()->push_back(breakStatement);
TIntermUnary *negatedCondition = new TIntermUnary(EOpLogicalNot);
negatedCondition->setOperand(loop->getCondition());
TIntermUnary *negatedCondition =
new TIntermUnary(EOpLogicalNot, loop->getCondition());
TIntermSelection *innerIf =
new TIntermSelection(negatedCondition, breakBlock, nullptr);
......
......@@ -31,13 +31,6 @@ class ElseBlockRewriter : public TIntermTraverser
TIntermNode *rewriteSelection(TIntermSelection *selection);
};
TIntermUnary *MakeNewUnary(TOperator op, TIntermTyped *operand)
{
TIntermUnary *unary = new TIntermUnary(op, operand->getType());
unary->setOperand(operand);
return unary;
}
ElseBlockRewriter::ElseBlockRewriter()
: TIntermTraverser(true, false, true),
mFunctionType(NULL)
......@@ -113,7 +106,7 @@ TIntermNode *ElseBlockRewriter::rewriteSelection(TIntermSelection *selection)
}
TIntermSymbol *conditionSymbolElse = createTempSymbol(boolType);
TIntermUnary *negatedCondition = MakeNewUnary(EOpLogicalNot, conditionSymbolElse);
TIntermUnary *negatedCondition = new TIntermUnary(EOpLogicalNot, conditionSymbolElse);
falseBlock = new TIntermSelection(negatedCondition,
selection->getFalseBlock(), negatedElse);
}
......
......@@ -79,8 +79,7 @@ bool UnfoldShortCircuitTraverser::visitBinary(Visit visit, TIntermBinary *node)
ASSERT(node->getRight()->getType() == boolType);
assignRightBlock->getSequence()->push_back(createTempAssignment(node->getRight()));
TIntermUnary *notTempSymbol = new TIntermUnary(EOpLogicalNot, boolType);
notTempSymbol->setOperand(createTempSymbol(boolType));
TIntermUnary *notTempSymbol = new TIntermUnary(EOpLogicalNot, createTempSymbol(boolType));
TIntermSelection *ifNode = new TIntermSelection(notTempSymbol, assignRightBlock, nullptr);
insertions.push_back(ifNode);
......
......@@ -166,9 +166,8 @@ TEST_F(IntermNodeTest, DeepCopyUnaryNode)
{
TType type(EbtFloat, EbpHigh);
TIntermUnary *original = new TIntermUnary(EOpPreIncrement);
TIntermUnary *original = new TIntermUnary(EOpPreIncrement, createTestSymbol());
original->setLine(getTestSourceLoc());
original->setOperand(createTestSymbol());
TIntermTyped *copyTyped = original->deepCopy();
TIntermUnary *copy = copyTyped->getAsUnaryNode();
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