42 switch (
type.typeKind()) {
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)) {
78 if ((op.
kind() == Operator::Kind::LOGICALAND && !leftVal) ||
79 (op.
kind() == Operator::Kind::LOGICALOR && leftVal)) {
94 if (op.
kind() == Operator::Kind::EQEQ || op.
kind() == Operator::Kind::NEQ) {
95 bool equality = (op.
kind() == Operator::Kind::EQEQ);
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) {
163 std::swap(outColumns, outRows);
166 const Type& resultType = componentType.
toCompound(context, outColumns, outRows);
231 using FoldFn = double (*)(double, double);
234 case Operator::Kind::PLUS: foldFn = +[](
double a,
double b) {
return a +
b; };
break;
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) {
376 double expectation = (c == r) ?
value : 0;
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);
412 values[index] = *
value;
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) {
487 case Operator::Kind::PLUS:
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) {
686 if (
left->isBoolLiteral() &&
right->isBoolLiteral()) {
691 case Operator::Kind::LOGICALAND:
result = leftVal && rightVal;
break;
692 case Operator::Kind::LOGICALOR:
result = leftVal || rightVal;
break;
693 case Operator::Kind::LOGICALXOR:
result = leftVal ^ rightVal;
break;
694 case Operator::Kind::EQEQ:
result = leftVal == rightVal;
break;
695 case Operator::Kind::NEQ:
result = leftVal != rightVal;
break;
696 default:
return nullptr;
702 if (
left->isBoolLiteral()) {
707 if (
right->isBoolLiteral()) {
735 const Type& leftType =
left->type();
740 if (leftSideIsConstant && rightSideIsConstant) {
742 if (
left->isIntLiteral() &&
right->isIntLiteral()) {
743 using SKSL_UINT = uint64_t;
748 #define RESULT(Op) fold_expression(pos, (SKSL_INT)(leftVal) Op \
749 (SKSL_INT)(rightVal), &resultType)
750 #define URESULT(Op) fold_expression(pos, (SKSL_INT)((SKSL_UINT)(leftVal) Op \
751 (SKSL_UINT)(rightVal)), &resultType)
753 case Operator::Kind::PLUS:
return URESULT(+);
754 case Operator::Kind::MINUS:
return URESULT(-);
755 case Operator::Kind::STAR:
return URESULT(*);
756 case Operator::Kind::SLASH:
757 if (leftVal == std::numeric_limits<SKSL_INT>::min() && rightVal == -1) {
762 case Operator::Kind::PERCENT:
763 if (leftVal == std::numeric_limits<SKSL_INT>::min() && rightVal == -1) {
768 case Operator::Kind::BITWISEAND:
return RESULT(&);
769 case Operator::Kind::BITWISEOR:
return RESULT(|);
770 case Operator::Kind::BITWISEXOR:
return RESULT(^);
771 case Operator::Kind::EQEQ:
return RESULT(==);
772 case Operator::Kind::NEQ:
return RESULT(!=);
773 case Operator::Kind::GT:
return RESULT(>);
774 case Operator::Kind::GTEQ:
return RESULT(>=);
775 case Operator::Kind::LT:
return RESULT(<);
776 case Operator::Kind::LTEQ:
return RESULT(<=);
777 case Operator::Kind::SHL:
778 if (rightVal >= 0 && rightVal <= 31) {
786 case Operator::Kind::SHR:
787 if (rightVal >= 0 && rightVal <= 31) {
801 if (
left->isFloatLiteral() &&
right->isFloatLiteral()) {
805 #define RESULT(Op) fold_expression(pos, leftVal Op rightVal, &resultType)
807 case Operator::Kind::PLUS:
return RESULT(+);
808 case Operator::Kind::MINUS:
return RESULT(-);
809 case Operator::Kind::STAR:
return RESULT(*);
810 case Operator::Kind::SLASH:
return RESULT(/);
811 case Operator::Kind::EQEQ:
return RESULT(==);
812 case Operator::Kind::NEQ:
return RESULT(!=);
813 case Operator::Kind::GT:
return RESULT(>);
814 case Operator::Kind::GTEQ:
return RESULT(>=);
815 case Operator::Kind::LT:
return RESULT(<);
816 case Operator::Kind::LTEQ:
return RESULT(<=);
817 default:
return nullptr;
823 if (op.
kind() == Operator::Kind::STAR) {
865 if (leftSideIsConstant || rightSideIsConstant) {
867 *
right, resultType)) {
874 *
right, resultType)) {
#define SkDEBUGFAILF(fmt,...)
static constexpr double sk_ieee_double_divide(double numer, double denom)
static bool left(const SkPoint &p0, const SkPoint &p1)
static bool right(const SkPoint &p0, const SkPoint &p1)
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)
virtual const Type & type() const
bool isIntLiteral() const
virtual std::unique_ptr< Expression > clone(Position pos) const =0
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
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 > 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