From 9ce80f71de026a1e1f9875ee5da55742e4fd3b53 Mon Sep 17 00:00:00 2001 From: John Stiles Date: Thu, 11 Mar 2021 22:35:19 -0500 Subject: [PATCH] Add Make factory functions to literal types. This is mostly for consistency with other IRNode types; there isn't any optimization opportunity or error checking for literals. Change-Id: I0e6a55cddbd814585ecafeddab4e591fe5113911 Bug: skia:11342 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/383996 Auto-Submit: John Stiles Commit-Queue: Brian Osman Reviewed-by: Brian Osman --- src/sksl/SkSLConstantFolder.cpp | 22 +++++++------- src/sksl/SkSLGLSLCodeGenerator.cpp | 6 ++-- src/sksl/SkSLIRGenerator.cpp | 20 +++++-------- src/sksl/SkSLInliner.cpp | 12 ++++---- src/sksl/SkSLRehydrator.cpp | 8 ++--- src/sksl/SkSLSPIRVCodeGenerator.cpp | 45 ++++++++++++++-------------- src/sksl/dsl/DSLExpression.cpp | 18 +++++------ src/sksl/ir/SkSLBoolLiteral.h | 15 ++++++++-- src/sksl/ir/SkSLConstructor.cpp | 20 ++++++------- src/sksl/ir/SkSLFloatLiteral.h | 14 +++++++-- src/sksl/ir/SkSLIntLiteral.h | 16 +++++++--- src/sksl/ir/SkSLPrefixExpression.cpp | 14 ++++----- src/sksl/ir/SkSLSetting.cpp | 4 +-- src/sksl/ir/SkSLSwizzle.cpp | 4 +-- 14 files changed, 117 insertions(+), 101 deletions(-) diff --git a/src/sksl/SkSLConstantFolder.cpp b/src/sksl/SkSLConstantFolder.cpp index c397cab5b5..8bd721d230 100644 --- a/src/sksl/SkSLConstantFolder.cpp +++ b/src/sksl/SkSLConstantFolder.cpp @@ -84,7 +84,7 @@ static std::unique_ptr simplify_vector(const Context& context, [[fallthrough]]; case Expression::ComparisonResult::kEqual: - return std::make_unique(context, left.fOffset, equality); + return BoolLiteral::Make(context, left.fOffset, equality); case Expression::ComparisonResult::kUnknown: return nullptr; @@ -98,7 +98,7 @@ static std::unique_ptr simplify_vector(const Context& context, args.reserve_back(type.columns()); for (int i = 0; i < type.columns(); i++) { U value = foldFn(left.getVecComponent(i), right.getVecComponent(i)); - args.push_back(std::make_unique>(left.fOffset, value, &componentType)); + args.push_back(Literal::Make(left.fOffset, value, &componentType)); } auto foldedCtor = Constructor::Convert(context, left.fOffset, type, std::move(args)); SkASSERT(foldedCtor); @@ -349,7 +349,7 @@ std::unique_ptr ConstantFolder::Simplify(const Context& context, case Token::Kind::TK_NEQ: result = leftVal != rightVal; break; default: return nullptr; } - return std::make_unique(context, offset, result); + return BoolLiteral::Make(context, offset, result); } // If the left side is a Boolean literal, apply short-circuit optimizations. @@ -372,13 +372,13 @@ std::unique_ptr ConstantFolder::Simplify(const Context& context, if (op.kind() == Token::Kind::TK_EQEQ && Analysis::IsSameExpressionTree(*left, *right)) { // With == comparison, if both sides are the same trivial expression, this is self- // comparison and is always true. (We are not concerned with NaN.) - return std::make_unique(context, leftExpr.fOffset, /*value=*/true); + return BoolLiteral::Make(context, leftExpr.fOffset, /*value=*/true); } if (op.kind() == Token::Kind::TK_NEQ && Analysis::IsSameExpressionTree(*left, *right)) { // With != comparison, if both sides are the same trivial expression, this is self- // comparison and is always false. (We are not concerned with NaN.) - return std::make_unique(context, leftExpr.fOffset, /*value=*/false); + return BoolLiteral::Make(context, leftExpr.fOffset, /*value=*/false); } if (ErrorOnDivideByZero(context, offset, op, *right)) { @@ -404,13 +404,11 @@ std::unique_ptr ConstantFolder::Simplify(const Context& context, // Note that we expressly do not worry about precision and overflow here -- we use the maximum // precision to calculate the results and hope the result makes sense. - // TODO: detect and handle integer overflow properly. + // TODO(skia:10932): detect and handle integer overflow properly. using SKSL_UINT = uint64_t; - #define RESULT(t, op) std::make_unique(context, offset, \ - leftVal op rightVal) - #define URESULT(t, op) std::make_unique(context, offset, \ - (SKSL_UINT) leftVal op \ - (SKSL_UINT) rightVal) + #define RESULT(t, op) t ## Literal::Make(context, offset, leftVal op rightVal) + #define URESULT(t, op) t ## Literal::Make(context, offset, (SKSL_UINT) leftVal op \ + (SKSL_UINT) rightVal) if (left->is() && right->is()) { SKSL_INT leftVal = left->as().value(); SKSL_INT rightVal = right->as().value(); @@ -535,7 +533,7 @@ std::unique_ptr ConstantFolder::Simplify(const Context& context, [[fallthrough]]; case Expression::ComparisonResult::kEqual: - return std::make_unique(context, offset, equality); + return BoolLiteral::Make(context, offset, equality); case Expression::ComparisonResult::kUnknown: return nullptr; diff --git a/src/sksl/SkSLGLSLCodeGenerator.cpp b/src/sksl/SkSLGLSLCodeGenerator.cpp index 87d91be02b..8868aa6541 100644 --- a/src/sksl/SkSLGLSLCodeGenerator.cpp +++ b/src/sksl/SkSLGLSLCodeGenerator.cpp @@ -909,12 +909,12 @@ void GLSLCodeGenerator::writeShortCircuitWorkaroundExpression(const BinaryExpres if (b.getOperator().kind() == Token::Kind::TK_LOGICALAND) { this->writeExpression(*b.right(), Precedence::kTernary); } else { - BoolLiteral boolTrue(fContext, -1, true); + BoolLiteral boolTrue(/*offset=*/-1, /*value=*/true, fContext.fTypes.fBool.get()); this->writeBoolLiteral(boolTrue); } this->write(" : "); if (b.getOperator().kind() == Token::Kind::TK_LOGICALAND) { - BoolLiteral boolFalse(fContext, -1, false); + BoolLiteral boolFalse(/*offset=*/-1, /*value=*/false, fContext.fTypes.fBool.get()); this->writeBoolLiteral(boolFalse); } else { this->writeExpression(*b.right(), Precedence::kTernary); @@ -1289,7 +1289,7 @@ void GLSLCodeGenerator::writeForStatement(const ForStatement& f) { if (this->caps().addAndTrueToLoopCondition()) { std::unique_ptr and_true(new BinaryExpression( /*offset=*/-1, f.test()->clone(), Token::Kind::TK_LOGICALAND, - std::make_unique(fContext, -1, true), + BoolLiteral::Make(fContext, /*offset=*/-1, /*value=*/true), fContext.fTypes.fBool.get())); this->writeExpression(*and_true, Precedence::kTopLevel); } else { diff --git a/src/sksl/SkSLIRGenerator.cpp b/src/sksl/SkSLIRGenerator.cpp index 8b6c61dad8..d285f0e73d 100644 --- a/src/sksl/SkSLIRGenerator.cpp +++ b/src/sksl/SkSLIRGenerator.cpp @@ -775,7 +775,7 @@ std::unique_ptr IRGenerator::applyInvocationIDWorkaround(std::unique_ptr< fContext, std::make_unique(/*offset=*/-1, loopIdx), Token::Kind::TK_LT, - std::make_unique(fContext, /*offset=*/-1, fInvocations)); + IntLiteral::Make(fContext, /*offset=*/-1, fInvocations)); auto next = PostfixExpression::Make( fContext, std::make_unique(/*offset=*/-1, loopIdx,VariableRefKind::kReadWrite), @@ -796,7 +796,7 @@ std::unique_ptr IRGenerator::applyInvocationIDWorkaround(std::unique_ptr< fContext, std::make_unique(/*offset=*/-1, loopIdx, VariableRefKind::kWrite), Token::Kind::TK_EQ, - std::make_unique(fContext, /*offset=*/-1, /*value=*/0)); + IntLiteral::Make(fContext, /*offset=*/-1, /*value=*/0)); auto initializer = ExpressionStatement::Make(fContext, std::move(assignment)); auto loop = ForStatement::Make( fContext, /*offset=*/-1, std::move(initializer), std::move(test), std::move(next), @@ -858,7 +858,7 @@ std::unique_ptr IRGenerator::getNormalizeSkPositionCode() { Op(Swizzle(Pos(), kXYIndices), Token::Kind::TK_STAR, Swizzle(Adjust(), kXZIndices)), Token::Kind::TK_PLUS, Op(Swizzle(Pos(), kWWIndices), Token::Kind::TK_STAR, Swizzle(Adjust(), kYWIndices)))); - children.push_back(std::make_unique(fContext, /*offset=*/-1, /*value=*/0.0)); + children.push_back(FloatLiteral::Make(fContext, /*offset=*/-1, /*value=*/0.0)); children.push_back(Swizzle(Pos(), kWIndex)); std::unique_ptr result = Op(Pos(), Token::Kind::TK_EQ, @@ -1421,7 +1421,7 @@ void IRGenerator::convertEnum(const ASTNode& e) { return; } } - value = std::make_unique(fContext, e.fOffset, currentValue); + value = IntLiteral::Make(fContext, e.fOffset, currentValue); ++currentValue; auto var = std::make_unique(e.fOffset, fModifiers->addToPool(modifiers), child.getString(), type, fIsBuiltinCode, @@ -1491,22 +1491,19 @@ std::unique_ptr IRGenerator::convertExpression(const ASTNode& expr) case ASTNode::Kind::kBinary: return this->convertBinaryExpression(expr); case ASTNode::Kind::kBool: - return std::unique_ptr(new BoolLiteral(fContext, expr.fOffset, - expr.getBool())); + return BoolLiteral::Make(fContext, expr.fOffset, expr.getBool()); case ASTNode::Kind::kCall: return this->convertCallExpression(expr); case ASTNode::Kind::kField: return this->convertFieldExpression(expr); case ASTNode::Kind::kFloat: - return std::unique_ptr(new FloatLiteral(fContext, expr.fOffset, - expr.getFloat())); + return FloatLiteral::Make(fContext, expr.fOffset, expr.getFloat()); case ASTNode::Kind::kIdentifier: return this->convertIdentifier(expr); case ASTNode::Kind::kIndex: return this->convertIndexExpression(expr); case ASTNode::Kind::kInt: - return std::unique_ptr(new IntLiteral(fContext, expr.fOffset, - expr.getInt())); + return IntLiteral::Make(fContext, expr.fOffset, expr.getInt()); case ASTNode::Kind::kPostfix: return this->convertPostfixExpression(expr); case ASTNode::Kind::kPrefix: @@ -1971,8 +1968,7 @@ std::unique_ptr IRGenerator::convertTypeField(int offset, const Type if (result) { const Variable& v = *result->as().variable(); SkASSERT(v.initialValue()); - result = std::make_unique(offset, v.initialValue()->as().value(), - &type); + result = IntLiteral::Make(offset, v.initialValue()->as().value(), &type); } else { this->errorReporter().error( offset, "type '" + type.name() + "' does not contain enumerator '" + field + "'"); diff --git a/src/sksl/SkSLInliner.cpp b/src/sksl/SkSLInliner.cpp index b10b0f5917..d30cbcaef0 100644 --- a/src/sksl/SkSLInliner.cpp +++ b/src/sksl/SkSLInliner.cpp @@ -691,9 +691,9 @@ Inliner::InlinedCall Inliner::inlineCall(FunctionCall* call, // int _1_loop = 0; symbolTable = std::make_shared(std::move(symbolTable), caller->isBuiltin()); const Type* intType = fContext->fTypes.fInt.get(); - std::unique_ptr initialValue = std::make_unique(/*offset=*/-1, - /*value=*/0, - intType); + std::unique_ptr initialValue = IntLiteral::Make(/*offset=*/-1, + /*value=*/0, + intType); InlineVariable loopVar = this->makeInlineVariable("loop", intType, symbolTable.get(), Modifiers{}, caller->isBuiltin(), &initialValue); @@ -703,7 +703,7 @@ Inliner::InlinedCall Inliner::inlineCall(FunctionCall* call, *fContext, std::make_unique(/*offset=*/-1, loopVar.fVarSymbol), Token::Kind::TK_LT, - std::make_unique(/*offset=*/-1, /*value=*/1, intType)); + IntLiteral::Make(/*offset=*/-1, /*value=*/1, intType)); // _1_loop++ std::unique_ptr increment = PostfixExpression::Make( @@ -754,9 +754,7 @@ Inliner::InlinedCall Inliner::inlineCall(FunctionCall* call, } else if (function.declaration().returnType() == *fContext->fTypes.fVoid) { // It's a void function, so it doesn't actually result in anything, but we have to return // something non-null as a standin. - inlinedCall.fReplacementExpr = std::make_unique(*fContext, - offset, - /*value=*/false); + inlinedCall.fReplacementExpr = BoolLiteral::Make(*fContext, offset, /*value=*/false); } else { // It's a non-void function, but it never created a result expression--that is, it never // returned anything on any path! This should have been detected in the function finalizer. diff --git a/src/sksl/SkSLRehydrator.cpp b/src/sksl/SkSLRehydrator.cpp index 9f15deb573..ce02ed39fc 100644 --- a/src/sksl/SkSLRehydrator.cpp +++ b/src/sksl/SkSLRehydrator.cpp @@ -288,7 +288,7 @@ std::unique_ptr Rehydrator::element() { int value = this->readS32(); // enum variables aren't really 'declared', but we have to create a declaration to // store the value - auto valueLiteral = std::make_unique(fContext, /*offset=*/-1, value); + auto valueLiteral = IntLiteral::Make(fContext, /*offset=*/-1, value); auto declaration = std::make_unique(&v, &v.type(), /*arraySize=*/0, std::move(valueLiteral)); v.setDeclaration(declaration.get()); @@ -446,7 +446,7 @@ std::unique_ptr Rehydrator::expression() { } case Rehydrator::kBoolLiteral_Command: { bool value = this->readU8(); - return std::make_unique(fContext, -1, value); + return BoolLiteral::Make(fContext, /*offset=*/-1, value); } case Rehydrator::kConstructor_Command: { const Type* type = this->type(); @@ -470,7 +470,7 @@ std::unique_ptr Rehydrator::expression() { const Type* type = this->type(); FloatIntUnion u; u.fInt = this->readS32(); - return std::make_unique(-1, u.fFloat, type); + return FloatLiteral::Make(/*offset=*/-1, u.fFloat, type); } case Rehydrator::kFunctionCall_Command: { const Type* type = this->type(); @@ -492,7 +492,7 @@ std::unique_ptr Rehydrator::expression() { case Rehydrator::kIntLiteral_Command: { const Type* type = this->type(); int value = this->readS32(); - return std::make_unique(-1, value, type); + return IntLiteral::Make(/*offset=*/-1, value, type); } case Rehydrator::kPostfix_Command: { Token::Kind op = (Token::Kind) this->readU8(); diff --git a/src/sksl/SkSLSPIRVCodeGenerator.cpp b/src/sksl/SkSLSPIRVCodeGenerator.cpp index 12240c705e..8b7b662324 100644 --- a/src/sksl/SkSLSPIRVCodeGenerator.cpp +++ b/src/sksl/SkSLSPIRVCodeGenerator.cpp @@ -549,7 +549,8 @@ SpvId SPIRVCodeGenerator::getType(const Type& rawType, const MemoryLayout& layou } if (type.columns() > 0) { SpvId typeId = this->getType(type.componentType(), layout); - IntLiteral countLiteral(fContext, /*offset=*/-1, type.columns()); + IntLiteral countLiteral(/*offset=*/-1, type.columns(), + fContext.fTypes.fInt.get()); SpvId countId = this->writeIntLiteral(countLiteral); this->writeInstruction(SpvOpTypeArray, result, typeId, countId, fConstantBuffer); @@ -903,8 +904,8 @@ SpvId SPIRVCodeGenerator::writeSpecialIntrinsic(const FunctionCall& c, SpecialIn SpvId img = this->writeExpression(*arguments[0], out); ExpressionArray args; args.reserve_back(2); - args.push_back(std::make_unique(fContext, /*offset=*/-1, /*value=*/0)); - args.push_back(std::make_unique(fContext, /*offset=*/-1, /*value=*/0)); + args.push_back(IntLiteral::Make(fContext, /*offset=*/-1, /*value=*/0)); + args.push_back(IntLiteral::Make(fContext, /*offset=*/-1, /*value=*/0)); Constructor ctor(/*offset=*/-1, *fContext.fTypes.fInt2, std::move(args)); SpvId coords = this->writeConstantVector(ctor); if (arguments.size() == 1) { @@ -970,7 +971,8 @@ SpvId SPIRVCodeGenerator::writeSpecialIntrinsic(const FunctionCall& c, SpecialIn } else { SkASSERT(arguments.size() == 2); if (fProgram.fConfig->fSettings.fSharpenTextures) { - FloatLiteral lodBias(fContext, -1, -0.5); + FloatLiteral lodBias(/*offset=*/-1, /*value=*/-0.5, + fContext.fTypes.fFloat.get()); this->writeInstruction(op, type, result, sampler, uv, SpvImageOperandsBiasMask, this->writeFloatLiteral(lodBias), @@ -1053,10 +1055,8 @@ SpvId SPIRVCodeGenerator::writeSpecialIntrinsic(const FunctionCall& c, SpecialIn ExpressionArray finalArgs; finalArgs.reserve_back(3); finalArgs.push_back(arguments[0]->clone()); - finalArgs.push_back(std::make_unique(fContext, /*offset=*/-1, - /*value=*/0)); - finalArgs.push_back(std::make_unique(fContext, /*offset=*/-1, - /*value=*/1)); + finalArgs.push_back(FloatLiteral::Make(fContext, /*offset=*/-1, /*value=*/0)); + finalArgs.push_back(FloatLiteral::Make(fContext, /*offset=*/-1, /*value=*/1)); std::vector spvArgs = this->vectorize(finalArgs, out); this->writeGLSLExtendedInstruction(callType, result, GLSLstd450FClamp, GLSLstd450SClamp, GLSLstd450UClamp, spvArgs, out); @@ -1225,9 +1225,9 @@ SpvId SPIRVCodeGenerator::castScalarToFloat(SpvId inputId, const Type& inputType SpvId result = this->nextId(); if (inputType.isBoolean()) { // Use OpSelect to convert the boolean argument to a literal 1.0 or 0.0. - FloatLiteral one(fContext, /*offset=*/-1, /*value=*/1); + FloatLiteral one(/*offset=*/-1, /*value=*/1, fContext.fTypes.fFloat.get()); SpvId oneID = this->writeFloatLiteral(one); - FloatLiteral zero(fContext, /*offset=*/-1, /*value=*/0); + FloatLiteral zero(/*offset=*/-1, /*value=*/0, fContext.fTypes.fFloat.get()); SpvId zeroID = this->writeFloatLiteral(zero); this->writeInstruction(SpvOpSelect, this->getType(outputType), result, inputId, oneID, zeroID, out); @@ -1360,7 +1360,7 @@ SpvId SPIRVCodeGenerator::castScalarToBoolean(SpvId inputId, const Type& inputTy void SPIRVCodeGenerator::writeUniformScaleMatrix(SpvId id, SpvId diagonal, const Type& type, OutputStream& out) { - FloatLiteral zero(fContext, -1, 0); + FloatLiteral zero(/*offset=*/-1, /*value=*/0, fContext.fTypes.fFloat.get()); SpvId zeroId = this->writeFloatLiteral(zero); std::vector columnIds; for (int column = 0; column < type.columns(); column++) { @@ -1399,10 +1399,10 @@ void SPIRVCodeGenerator::writeMatrixCopy(SpvId id, SpvId src, const Type& srcTyp 1)); SpvId zeroId; if (dstType.componentType() == *fContext.fTypes.fFloat) { - FloatLiteral zero(fContext, -1, 0.0); + FloatLiteral zero(/*offset=*/-1, /*value=*/0.0, fContext.fTypes.fFloat.get()); zeroId = this->writeFloatLiteral(zero); } else if (dstType.componentType() == *fContext.fTypes.fInt) { - IntLiteral zero(fContext, -1, 0); + IntLiteral zero(/*offset=*/-1, /*value=*/0, fContext.fTypes.fInt.get()); zeroId = this->writeIntLiteral(zero); } else { SK_ABORT("unsupported matrix component type"); @@ -1745,7 +1745,7 @@ std::vector SPIRVCodeGenerator::getAccessChain(const Expression& expr, Ou case Expression::Kind::kFieldAccess: { const FieldAccess& fieldExpr = expr.as(); chain = this->getAccessChain(*fieldExpr.base(), out); - IntLiteral index(fContext, /*offset=*/-1, fieldExpr.fieldIndex()); + IntLiteral index(/*offset=*/-1, fieldExpr.fieldIndex(), fContext.fTypes.fInt.get()); chain.push_back(this->writeIntLiteral(index)); break; } @@ -1894,7 +1894,7 @@ std::unique_ptr SPIRVCodeGenerator::getLValue(const const Variable& var = *expr.as().variable(); int uniformIdx = this->findUniformFieldIndex(var); if (uniformIdx >= 0) { - IntLiteral uniformIdxLiteral{fContext, /*offset=*/-1, uniformIdx}; + IntLiteral uniformIdxLiteral{/*offset=*/-1, uniformIdx, fContext.fTypes.fInt.get()}; SpvId memberId = this->nextId(); SpvId typeId = this->getPointerType(type, SpvStorageClassUniform); SpvId uniformIdxId = this->writeIntLiteral(uniformIdxLiteral); @@ -1939,7 +1939,8 @@ std::unique_ptr SPIRVCodeGenerator::getLValue(const if (swizzle.components().size() == 1) { SpvId member = this->nextId(); SpvId typeId = this->getPointerType(type, get_storage_class(*swizzle.base())); - IntLiteral index(fContext, /*offset=*/-1, swizzle.components()[0]); + IntLiteral index(/*offset=*/-1, swizzle.components()[0], + fContext.fTypes.fInt.get()); SpvId indexId = this->writeIntLiteral(index); this->writeInstruction(SpvOpAccessChain, typeId, member, base, indexId, out); return std::make_unique(*this, member, this->getType(type), @@ -2038,7 +2039,7 @@ SpvId SPIRVCodeGenerator::writeVariableReference(const VariableReference& ref, O } SkASSERT(fRTHeightFieldIndex != (SpvId)-1); - IntLiteral fieldIndex(fContext, -1, fRTHeightFieldIndex); + IntLiteral fieldIndex(/*offset=*/-1, fRTHeightFieldIndex, fContext.fTypes.fInt.get()); SpvId fieldIndexId = this->writeIntLiteral(fieldIndex); SpvId heightPtr = this->nextId(); this->writeOpCode(SpvOpAccessChain, 5, out); @@ -2057,7 +2058,7 @@ SpvId SPIRVCodeGenerator::writeVariableReference(const VariableReference& ref, O } // The z component will always be zero so we just get an id to the 0 literal - FloatLiteral zero(fContext, -1, 0.0); + FloatLiteral zero(/*offset=*/-1, /*value=*/0.0, fContext.fTypes.fFloat.get()); SpvId zeroId = writeFloatLiteral(zero); // Calculate the w component @@ -2233,10 +2234,10 @@ SpvId SPIRVCodeGenerator::writeComponentwiseMatrixBinary(const Type& operandType static std::unique_ptr create_literal_1(const Context& context, const Type& type) { if (type.isInteger()) { - return std::unique_ptr(new IntLiteral(-1, 1, &type)); + return IntLiteral::Make(/*offset=*/-1, /*value=*/1, &type); } else if (type.isFloat()) { - return std::unique_ptr(new FloatLiteral(-1, 1.0, &type)); + return FloatLiteral::Make(/*offset=*/-1, /*value=*/1.0, &type); } else { SK_ABORT("math is unsupported on type '%s'", String(type.name()).c_str()); } @@ -2483,7 +2484,7 @@ SpvId SPIRVCodeGenerator::writeBinaryExpression(const BinaryExpression& b, Outpu SpvId SPIRVCodeGenerator::writeLogicalAnd(const BinaryExpression& a, OutputStream& out) { SkASSERT(a.getOperator().kind() == Token::Kind::TK_LOGICALAND); - BoolLiteral falseLiteral(fContext, -1, false); + BoolLiteral falseLiteral(/*offset=*/-1, /*value=*/false, fContext.fTypes.fBool.get()); SpvId falseConstant = this->writeBoolLiteral(falseLiteral); SpvId lhs = this->writeExpression(*a.left(), out); SpvId rhsLabel = this->nextId(); @@ -2504,7 +2505,7 @@ SpvId SPIRVCodeGenerator::writeLogicalAnd(const BinaryExpression& a, OutputStrea SpvId SPIRVCodeGenerator::writeLogicalOr(const BinaryExpression& o, OutputStream& out) { SkASSERT(o.getOperator().kind() == Token::Kind::TK_LOGICALOR); - BoolLiteral trueLiteral(fContext, -1, true); + BoolLiteral trueLiteral(/*offset=*/-1, /*value=*/true, fContext.fTypes.fBool.get()); SpvId trueConstant = this->writeBoolLiteral(trueLiteral); SpvId lhs = this->writeExpression(*o.left(), out); SpvId rhsLabel = this->nextId(); diff --git a/src/sksl/dsl/DSLExpression.cpp b/src/sksl/dsl/DSLExpression.cpp index 7611457b20..356d86f371 100644 --- a/src/sksl/dsl/DSLExpression.cpp +++ b/src/sksl/dsl/DSLExpression.cpp @@ -41,9 +41,9 @@ DSLExpression::DSLExpression(std::unique_ptr expression) } DSLExpression::DSLExpression(float value) - : fExpression(std::make_unique(DSLWriter::Context(), - /*offset=*/-1, - value)) { + : fExpression(SkSL::FloatLiteral::Make(DSLWriter::Context(), + /*offset=*/-1, + value)) { if (!isfinite(value)) { if (isinf(value)) { DSLWriter::ReportError("error: floating point value is infinite\n"); @@ -54,14 +54,14 @@ DSLExpression::DSLExpression(float value) } DSLExpression::DSLExpression(int value) - : fExpression(std::make_unique(DSLWriter::Context(), - /*offset=*/-1, - value)) {} + : fExpression(SkSL::IntLiteral::Make(DSLWriter::Context(), + /*offset=*/-1, + value)) {} DSLExpression::DSLExpression(bool value) - : fExpression(std::make_unique(DSLWriter::Context(), - /*offset=*/-1, - value)) {} + : fExpression(SkSL::BoolLiteral::Make(DSLWriter::Context(), + /*offset=*/-1, + value)) {} DSLExpression::DSLExpression(const DSLVar& var) : fExpression(std::make_unique( diff --git a/src/sksl/ir/SkSLBoolLiteral.h b/src/sksl/ir/SkSLBoolLiteral.h index be3ab93937..bb086eb663 100644 --- a/src/sksl/ir/SkSLBoolLiteral.h +++ b/src/sksl/ir/SkSLBoolLiteral.h @@ -25,13 +25,22 @@ class Literal final : public Expression { public: static constexpr Kind kExpressionKind = Kind::kBoolLiteral; - Literal(const Context& context, int offset, bool value) - : Literal(offset, value, context.fTypes.fBool.get()) {} - Literal(int offset, bool value, const Type* type) : INHERITED(offset, kExpressionKind, type) , fValue(value) {} + // Makes a literal of boolean type. + static std::unique_ptr Make(const Context& context, int offset, float value) { + return std::make_unique(offset, value, context.fTypes.fBool.get()); + } + + // Makes a literal of boolean type. (Functionally identical to the above, but useful if you + // don't have access to the Context.) + static std::unique_ptr Make(int offset, float value, const Type* type) { + SkASSERT(type->isBoolean()); + return std::make_unique(offset, value, type); + } + bool value() const { return fValue; } diff --git a/src/sksl/ir/SkSLConstructor.cpp b/src/sksl/ir/SkSLConstructor.cpp index a0e1afd41f..8b09f4eedb 100644 --- a/src/sksl/ir/SkSLConstructor.cpp +++ b/src/sksl/ir/SkSLConstructor.cpp @@ -212,39 +212,37 @@ std::unique_ptr Constructor::SimplifyConversion(const Type& construc SKSL_INT value = expr.as().value(); if (constructorType.isFloat()) { // promote float(1) to 1.0 - return std::make_unique(expr.fOffset, (SKSL_FLOAT)value, - &constructorType); + return FloatLiteral::Make(expr.fOffset, (SKSL_FLOAT)value, &constructorType); } else if (constructorType.isInteger()) { // promote uint(1) to 1u - return std::make_unique(expr.fOffset, value, &constructorType); + return IntLiteral::Make(expr.fOffset, value, &constructorType); } else if (constructorType.isBoolean()) { // promote bool(1) to true/false - return std::make_unique(expr.fOffset, value != 0, &constructorType); + return BoolLiteral::Make(expr.fOffset, value != 0, &constructorType); } } else if (expr.is()) { float value = expr.as().value(); if (constructorType.isFloat()) { // promote float(1.23) to 1.23 - return std::make_unique(expr.fOffset, value, &constructorType); + return FloatLiteral::Make(expr.fOffset, value, &constructorType); } else if (constructorType.isInteger()) { // promote uint(1.23) to 1u - return std::make_unique(expr.fOffset, (SKSL_INT)value, &constructorType); + return IntLiteral::Make(expr.fOffset, (SKSL_INT)value, &constructorType); } else if (constructorType.isBoolean()) { // promote bool(1.23) to true/false - return std::make_unique(expr.fOffset, value != 0.0f, &constructorType); + return BoolLiteral::Make(expr.fOffset, value != 0.0f, &constructorType); } } else if (expr.is()) { bool value = expr.as().value(); if (constructorType.isFloat()) { // promote float(true) to 1.0 - return std::make_unique(expr.fOffset, value ? 1.0f : 0.0f, - &constructorType); + return FloatLiteral::Make(expr.fOffset, value ? 1.0f : 0.0f, &constructorType); } else if (constructorType.isInteger()) { // promote uint(true) to 1u - return std::make_unique(expr.fOffset, value ? 1 : 0, &constructorType); + return IntLiteral::Make(expr.fOffset, value ? 1 : 0, &constructorType); } else if (constructorType.isBoolean()) { // promote bool(true) to true/false - return std::make_unique(expr.fOffset, value, &constructorType); + return BoolLiteral::Make(expr.fOffset, value, &constructorType); } } return nullptr; diff --git a/src/sksl/ir/SkSLFloatLiteral.h b/src/sksl/ir/SkSLFloatLiteral.h index 48d796db51..4cc8eb948e 100644 --- a/src/sksl/ir/SkSLFloatLiteral.h +++ b/src/sksl/ir/SkSLFloatLiteral.h @@ -25,13 +25,21 @@ class Literal final : public Expression { public: static constexpr Kind kExpressionKind = Kind::kFloatLiteral; - Literal(const Context& context, int offset, float value) - : Literal(offset, value, context.fTypes.fFloatLiteral.get()) {} - Literal(int offset, float value, const Type* type) : INHERITED(offset, kExpressionKind, type) , fValue(value) {} + // Makes a literal of $intLiteral type. + static std::unique_ptr Make(const Context& context, int offset, float value) { + return std::make_unique(offset, value, context.fTypes.fFloatLiteral.get()); + } + + // Makes a literal of the specified floating-point type. + static std::unique_ptr Make(int offset, float value, const Type* type) { + SkASSERT(type->isFloat()); + return std::make_unique(offset, value, type); + } + float value() const { return fValue; } diff --git a/src/sksl/ir/SkSLIntLiteral.h b/src/sksl/ir/SkSLIntLiteral.h index 04aad407c8..35050790fd 100644 --- a/src/sksl/ir/SkSLIntLiteral.h +++ b/src/sksl/ir/SkSLIntLiteral.h @@ -27,13 +27,21 @@ public: // We will need to revisit this if we want full support for unsigned 64-bit integers, // but for now an SKSL_INT (int64_t) will hold every value we care about. - Literal(const Context& context, int offset, SKSL_INT value) - : Literal(offset, value, context.fTypes.fIntLiteral.get()) {} - - Literal(int offset, int64_t value, const Type* type) + Literal(int offset, SKSL_INT value, const Type* type) : INHERITED(offset, kExpressionKind, type) , fValue(value) {} + // Makes a literal of $intLiteral type. + static std::unique_ptr Make(const Context& context, int offset, SKSL_INT value) { + return std::make_unique(offset, value, context.fTypes.fIntLiteral.get()); + } + + // Makes a literal of the specified integer type. + static std::unique_ptr Make(int offset, SKSL_INT value, const Type* type) { + SkASSERT(type->isInteger() || type->isEnum()); + return std::make_unique(offset, value, type); + } + SKSL_INT value() const { return fValue; } diff --git a/src/sksl/ir/SkSLPrefixExpression.cpp b/src/sksl/ir/SkSLPrefixExpression.cpp index c7fefeebeb..a06fccfaee 100644 --- a/src/sksl/ir/SkSLPrefixExpression.cpp +++ b/src/sksl/ir/SkSLPrefixExpression.cpp @@ -21,15 +21,15 @@ static std::unique_ptr negate_operand(const Context& context, switch (value->kind()) { case Expression::Kind::kFloatLiteral: // Convert -floatLiteral(1) to floatLiteral(-1). - return std::make_unique(operand->fOffset, - -value->as().value(), - &value->type()); + return FloatLiteral::Make(operand->fOffset, + -value->as().value(), + &value->type()); case Expression::Kind::kIntLiteral: // Convert -intLiteral(1) to intLiteral(-1). - return std::make_unique(operand->fOffset, - -value->as().value(), - &value->type()); + return IntLiteral::Make(operand->fOffset, + -value->as().value(), + &value->type()); case Expression::Kind::kPrefix: if (context.fConfig->fSettings.fOptimize) { @@ -81,7 +81,7 @@ static std::unique_ptr logical_not_operand(const Context& context, case Expression::Kind::kBoolLiteral: { // Convert !boolLiteral(true) to boolLiteral(false). const BoolLiteral& b = value->as(); - return std::make_unique(operand->fOffset, !b.value(), &operand->type()); + return BoolLiteral::Make(operand->fOffset, !b.value(), &operand->type()); } case Expression::Kind::kPrefix: if (context.fConfig->fSettings.fOptimize) { diff --git a/src/sksl/ir/SkSLSetting.cpp b/src/sksl/ir/SkSLSetting.cpp index b89bbae2b5..806c227dd9 100644 --- a/src/sksl/ir/SkSLSetting.cpp +++ b/src/sksl/ir/SkSLSetting.cpp @@ -31,7 +31,7 @@ public: return context.fTypes.fBool.get(); } std::unique_ptr value(const Context& context) const override { - return std::make_unique(context, /*offset=*/-1, (context.fCaps.*fGetCap)()); + return BoolLiteral::Make(context, /*offset=*/-1, (context.fCaps.*fGetCap)()); } private: @@ -48,7 +48,7 @@ public: return context.fTypes.fInt.get(); } std::unique_ptr value(const Context& context) const override { - return std::make_unique(context, /*offset=*/-1, (context.fCaps.*fGetCap)()); + return IntLiteral::Make(context, /*offset=*/-1, (context.fCaps.*fGetCap)()); } private: diff --git a/src/sksl/ir/SkSLSwizzle.cpp b/src/sksl/ir/SkSLSwizzle.cpp index b76d3c969c..655a4c3009 100644 --- a/src/sksl/ir/SkSLSwizzle.cpp +++ b/src/sksl/ir/SkSLSwizzle.cpp @@ -95,7 +95,7 @@ std::unique_ptr Swizzle::Convert(const Context& context, if (constantZeroIdx == -1) { // Synthesize a 'type(0)' argument at the end of the constructor. ExpressionArray zeroArgs; - zeroArgs.push_back(std::make_unique(context, offset,/*fValue=*/0)); + zeroArgs.push_back(IntLiteral::Make(context, offset, /*value=*/0)); constructorArgs.push_back(Constructor::Convert(context, offset, *numberType, std::move(zeroArgs))); constantZeroIdx = constantFieldIdx++; @@ -106,7 +106,7 @@ std::unique_ptr Swizzle::Convert(const Context& context, if (constantOneIdx == -1) { // Synthesize a 'type(1)' argument at the end of the constructor. ExpressionArray oneArgs; - oneArgs.push_back(std::make_unique(context, offset, /*fValue=*/1)); + oneArgs.push_back(IntLiteral::Make(context, offset, /*value=*/1)); constructorArgs.push_back(Constructor::Convert(context, offset, *numberType, std::move(oneArgs))); constantOneIdx = constantFieldIdx++;