42 switch (
type.typeKind()) {
56 bool rightVal = right.as<
Literal>().boolValue();
59 if ((op.
kind() == Operator::Kind::LOGICALAND && rightVal) ||
60 (op.
kind() == Operator::Kind::LOGICALOR && !rightVal) ||
61 (op.
kind() == Operator::Kind::LOGICALXOR && !rightVal) ||
62 (op.
kind() == Operator::Kind::EQEQ && rightVal) ||
63 (op.
kind() == Operator::Kind::NEQ && !rightVal)) {
65 return left.clone(
pos);
75 bool leftVal = left.as<
Literal>().boolValue();
78 if ((op.
kind() == Operator::Kind::LOGICALAND && !leftVal) ||
79 (op.
kind() == Operator::Kind::LOGICALOR && leftVal)) {
81 return left.clone(
pos);
94 if (op.
kind() == Operator::Kind::EQEQ || op.
kind() == Operator::Kind::NEQ) {
95 bool equality = (op.
kind() == Operator::Kind::EQEQ);
97 switch (left.compareConstant(right)) {
120 const Type& componentType = left.type().componentType();
124 double leftVals[4][4];
125 for (
int c = 0; c < leftColumns; ++c) {
126 for (
int r = 0; r < leftRows; ++r) {
127 leftVals[c][r] = *left.getConstantValue((c * leftRows) + r);
131 double rightVals[4][4];
132 for (
int c = 0; c < rightColumns; ++c) {
133 for (
int r = 0; r < rightRows; ++r) {
134 rightVals[c][r] = *right.getConstantValue((c * rightRows) + r);
139 int outColumns = rightColumns,
144 for (
int c = 0; c < outColumns; ++c) {
145 for (
int r = 0; r < outRows; ++r) {
148 for (
int dotIdx = 0; dotIdx < leftColumns; ++dotIdx) {
149 val += leftVals[dotIdx][r] * rightVals[c][dotIdx];
152 if (val >= -FLT_MAX && val <= FLT_MAX) {
153 args[argIndex++] = val;
161 if (outColumns == 1) {
166 const Type& resultType = componentType.
toCompound(context, outColumns, outRows);
174 const Type& leftType = left.type();
175 const Type& rightType = right.type();
189 const Type& leftType = left.type();
190 const Type& rightType = right.type();
204 const Type& leftType = left.type();
205 const Type& rightType = right.type();
221 SkASSERT(left.type().matches(right.type()));
231 using FoldFn = double (*)(double, double);
235 case Operator::Kind::MINUS: foldFn = +[](
double a,
double b) {
return a -
b; };
break;
236 case Operator::Kind::STAR: foldFn = +[](
double a,
double b) {
return a *
b; };
break;
237 case Operator::Kind::SLASH: foldFn = +[](
double a,
double b) {
return a /
b; };
break;
242 const Type& componentType =
type.componentType();
249 int numSlots =
type.slotCount();
250 for (
int i = 0;
i < numSlots;
i++) {
251 double value = foldFn(*left.getConstantValue(
i), *right.getConstantValue(
i));
252 if (value < minimumValue || value > maximumValue) {
263 if (
type.isVector()) {
266 if (
type.isMatrix()) {
267 int numSlots =
type.slotCount();
270 for (
int index = 0; index < numSlots; ++index) {
285 if (
type.isMatrix()) {
288 if (
type.isVector()) {
303 if (
type.isScalar()) {
306 if (
type.isVector()) {
309 if (
type.isMatrix()) {
345 for (
int index = 0; index < numSlots; ++index) {
347 if (slotVal.has_value() && *slotVal == 0.0) {
356 for (
int index = 0; index < numSlots; ++index) {
358 if (!slotVal.has_value() || *slotVal !=
value) {
370 if (columns != rows) {
374 for (
int c = 0; c < columns; ++c) {
375 for (
int r = 0; r < rows; ++r) {
378 if (!slotVal.has_value() || *slotVal !=
expectation) {
398 if (right.type().isMatrix() || !right.type().componentType().isFloat()) {
403 int nslots = right.type().slotCount();
404 for (
int index = 0; index < nslots; ++index) {
405 std::optional<double>
value = right.getConstantValue(index);
426 case Operator::Kind::SLASH:
427 case Operator::Kind::SLASHEQ:
428 case Operator::Kind::PERCENT:
429 case Operator::Kind::PERCENTEQ:
463 return expr ? expr : &inExpr;
467 Position pos, std::unique_ptr<Expression> inExpr) {
469 return expr ? expr->
clone(
pos) : std::move(inExpr);
473 return left.type().isScalar() && right.type().isMatrix();
485 const Type& resultType) {
504 case Operator::Kind::STAR:
537 case Operator::Kind::MINUS:
554 case Operator::Kind::SLASH:
562 if (!left.type().isMatrix()) {
570 case Operator::Kind::PLUSEQ:
571 case Operator::Kind::MINUSEQ:
581 case Operator::Kind::STAREQ:
591 case Operator::Kind::SLASHEQ:
621 Operator::Kind::SLASH,
630 const Type& resultType) {
636 if (left.type().isMatrix() && right.type().isScalar()) {
655 const Type* resultType) {
673 const Type& resultType) {
676 const Type& leftType = left->type();
677 const Type& rightType = right->type();
680 if (left->isIntLiteral() && right->isIntLiteral()) {
681 using SKSL_UINT = uint64_t;
686 #define RESULT(Op) fold_expression(pos, (SKSL_INT)(leftVal) Op \
687 (SKSL_INT)(rightVal), &resultType)
688 #define URESULT(Op) fold_expression(pos, (SKSL_INT)((SKSL_UINT)(leftVal) Op \
689 (SKSL_UINT)(rightVal)), &resultType)
692 case Operator::Kind::MINUS:
return URESULT(-);
693 case Operator::Kind::STAR:
return URESULT(*);
694 case Operator::Kind::SLASH:
701 case Operator::Kind::PERCENT:
708 case Operator::Kind::BITWISEAND:
return RESULT(&);
709 case Operator::Kind::BITWISEOR:
return RESULT(|);
710 case Operator::Kind::BITWISEXOR:
return RESULT(^);
711 case Operator::Kind::EQEQ:
return RESULT(==);
712 case Operator::Kind::NEQ:
return RESULT(!=);
714 case Operator::Kind::GTEQ:
return RESULT(>=);
716 case Operator::Kind::LTEQ:
return RESULT(<=);
717 case Operator::Kind::SHL:
718 if (rightVal >= 0 && rightVal <= 31) {
727 case Operator::Kind::SHR:
728 if (rightVal >= 0 && rightVal <= 31) {
744 if (left->isFloatLiteral() && right->isFloatLiteral()) {
748 #define RESULT(Op) fold_expression(pos, leftVal Op rightVal, &resultType)
751 case Operator::Kind::MINUS:
return RESULT(-);
752 case Operator::Kind::STAR:
return RESULT(*);
753 case Operator::Kind::SLASH:
return RESULT(/);
754 case Operator::Kind::EQEQ:
return RESULT(==);
755 case Operator::Kind::NEQ:
return RESULT(!=);
757 case Operator::Kind::GTEQ:
return RESULT(>=);
759 case Operator::Kind::LTEQ:
return RESULT(<=);
768 if (op.
kind() == Operator::Kind::STAR) {
789 *left, op, *
splat_scalar(context, *right, left->type()));
796 *
splat_scalar(context, *left, right->type()), op, *right);
815 const Type& resultType) {
824 return right->clone(
pos);
828 if (left->isBoolLiteral() && right->isBoolLiteral()) {
829 bool leftVal = left->as<
Literal>().boolValue();
830 bool rightVal = right->as<
Literal>().boolValue();
833 case Operator::Kind::LOGICALAND:
result = leftVal && rightVal;
break;
834 case Operator::Kind::LOGICALOR:
result = leftVal || rightVal;
break;
835 case Operator::Kind::LOGICALXOR:
result = leftVal ^ rightVal;
break;
836 case Operator::Kind::EQEQ:
result = leftVal == rightVal;
break;
837 case Operator::Kind::NEQ:
result = leftVal != rightVal;
break;
838 default:
return nullptr;
844 if (left->isBoolLiteral()) {
849 if (right->isBoolLiteral()) {
879 if (leftSideIsConstant && rightSideIsConstant) {
886 if (leftSideIsConstant || rightSideIsConstant) {
888 *right, resultType)) {
895 *right, resultType)) {
#define SkDEBUGFAILF(fmt,...)
static constexpr double sk_ieee_double_divide(double numer, double denom)
void swap(sk_sp< T > &a, sk_sp< T > &b)
static std::unique_ptr< Expression > Make(const Context &context, Position pos, std::unique_ptr< Expression > left, Operator op, std::unique_ptr< Expression > right)
static bool GetConstantValue(const Expression &value, double *out)
static bool GetConstantInt(const Expression &value, SKSL_INT *out)
static std::unique_ptr< Expression > Simplify(const Context &context, Position pos, const Expression &left, Operator op, const Expression &right, const Type &resultType)
static bool IsConstantSplat(const Expression &expr, double value)
static const Expression * GetConstantValueOrNull(const Expression &value)
static const Expression * GetConstantValueForVariable(const Expression &value)
static std::unique_ptr< Expression > MakeConstantValueForVariable(Position pos, std::unique_ptr< Expression > expr)
static std::unique_ptr< Expression > MakeFromConstants(const Context &context, Position pos, const Type &type, const double values[])
static std::unique_ptr< Expression > Make(const Context &context, Position pos, const Type &type, ExpressionArray args)
static std::unique_ptr< Expression > Make(const Context &context, Position pos, const Type &type, std::unique_ptr< Expression > arg)
static std::unique_ptr< Expression > Make(const Context &context, Position pos, const Type &type, std::unique_ptr< Expression > arg)
void error(Position position, std::string_view msg)
bool isIntLiteral() const
virtual std::unique_ptr< Expression > clone(Position pos) const =0
const Type & type() const
virtual std::optional< double > getConstantValue(int n) const
static std::unique_ptr< Literal > MakeBool(const Context &context, Position pos, bool value)
static std::unique_ptr< Literal > Make(Position pos, double value, const Type *type)
bool isAssignment() const
static std::unique_ptr< Expression > Make(const Context &context, Position pos, Operator op, std::unique_ptr< Expression > base)
virtual bool isArray() const
virtual bool isVector() const
virtual const Type & componentType() const
bool matches(const Type &other) const
virtual bool isMatrix() const
virtual int columns() const
virtual size_t slotCount() const
virtual bool isScalar() const
virtual double maximumValue() const
const Type & toCompound(const Context &context, int columns, int rows) const
virtual bool isStruct() const
virtual double minimumValue() const
const Variable * variable() const
const Expression * initialValue() const
ModifierFlags modifierFlags() const
void reserve_exact(int n)
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
static float min(float r, float g, float b)
bool IsCompileTimeConstant(const Expression &expr)
bool IsSameExpressionTree(const Expression &left, const Expression &right)
bool HasSideEffects(const Expression &expr)
bool UpdateVariableRefKind(Expression *expr, VariableRefKind kind, ErrorReporter *errors=nullptr)
static std::unique_ptr< Expression > negate_expression(const Context &context, Position pos, const Expression &expr, const Type &type)
static std::unique_ptr< Expression > simplify_matrix_division(const Context &context, Position pos, const Expression &left, Operator op, const Expression &right, const Type &resultType)
static std::unique_ptr< Expression > simplify_matrix_multiplication(const Context &context, Position pos, const Expression &left, const Expression &right, int leftColumns, int leftRows, int rightColumns, int rightRows)
static bool error_on_divide_by_zero(const Context &context, Position pos, Operator op, const Expression &right)
static std::unique_ptr< Expression > eliminate_no_op_boolean(Position pos, const Expression &left, Operator op, const Expression &right)
static bool contains_constant_zero(const Expression &expr)
static std::unique_ptr< Expression > simplify_matrix_times_matrix(const Context &context, Position pos, const Expression &left, const Expression &right)
static bool is_vec_or_mat(const Type &type)
static bool is_matrix_op_scalar(const Expression &left, const Expression &right)
static std::unique_ptr< Expression > cast_expression(const Context &context, Position pos, const Expression &expr, const Type &type)
static bool is_constant_diagonal(const Expression &expr, double value)
static bool is_constant_value(const Expression &expr, double value)
static std::unique_ptr< Expression > simplify_matrix_times_vector(const Context &context, Position pos, const Expression &left, const Expression &right)
static std::unique_ptr< Expression > make_reciprocal_expression(const Context &context, const Expression &right)
static std::unique_ptr< Expression > short_circuit_boolean(Position pos, const Expression &left, Operator op, const Expression &right)
static bool is_scalar_op_matrix(const Expression &left, const Expression &right)
static std::unique_ptr< Expression > one_over_scalar(const Context &context, const Expression &right)
static std::unique_ptr< Expression > simplify_constant_equality(const Context &context, Position pos, const Expression &left, Operator op, const Expression &right)
static std::unique_ptr< Expression > fold_two_constants(const Context &context, Position pos, const Expression *left, Operator op, const Expression *right, const Type &resultType)
static std::unique_ptr< Expression > simplify_vector_times_matrix(const Context &context, Position pos, const Expression &left, const Expression &right)
static std::unique_ptr< Expression > simplify_componentwise(const Context &context, Position pos, const Expression &left, Operator op, const Expression &right)
static std::unique_ptr< Expression > splat_scalar(const Context &context, const Expression &scalar, const Type &type)
static std::unique_ptr< Expression > zero_expression(const Context &context, Position pos, const Type &type)
static std::unique_ptr< Expression > simplify_arithmetic(const Context &context, Position pos, const Expression &left, Operator op, const Expression &right, const Type &resultType)
static std::unique_ptr< Expression > fold_expression(Position pos, double result, const Type *resultType)
ProgramSettings fSettings