673 {
674
677
678
679
680
683 }
684
685
686 if (
left->isBoolLiteral() &&
right->isBoolLiteral()) {
687 bool leftVal =
left->as<Literal>().boolValue();
688 bool rightVal =
right->as<Literal>().boolValue();
690 switch (op.kind()) {
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;
697 }
699 }
700
701
702 if (
left->isBoolLiteral()) {
704 }
705
706
707 if (
right->isBoolLiteral()) {
708
710
712 }
713
714
716 }
717
719
720
722 }
723
725
726
728 }
729
731 return nullptr;
732 }
733
734
735 const Type& leftType =
left->type();
739
740 if (leftSideIsConstant && rightSideIsConstant) {
741
742 if (
left->isIntLiteral() &&
right->isIntLiteral()) {
743 using SKSL_UINT = uint64_t;
746
747
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)
752 switch (op.kind()) {
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) {
758 context.fErrors->error(
pos,
"arithmetic overflow");
759 return nullptr;
760 }
762 case Operator::Kind::PERCENT:
763 if (leftVal == std::numeric_limits<SKSL_INT>::min() && rightVal == -1) {
764 context.fErrors->error(
pos,
"arithmetic overflow");
765 return nullptr;
766 }
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) {
779
780
781
783 }
784 context.fErrors->error(
pos,
"shift value out of range");
785 return nullptr;
786 case Operator::Kind::SHR:
787 if (rightVal >= 0 && rightVal <= 31) {
789 }
790 context.fErrors->error(
pos,
"shift value out of range");
791 return nullptr;
792
793 default:
794 return nullptr;
795 }
796 #undef RESULT
797 #undef URESULT
798 }
799
800
801 if (
left->isFloatLiteral() &&
right->isFloatLiteral()) {
804
805 #define RESULT(Op) fold_expression(pos, leftVal Op rightVal, &resultType)
806 switch (op.kind()) {
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;
818 }
819 #undef RESULT
820 }
821
822
823 if (op.kind() == Operator::Kind::STAR) {
824 if (leftType.isMatrix() && rightType.isMatrix()) {
826 }
827 if (leftType.isVector() && rightType.isMatrix()) {
829 }
830 if (leftType.isMatrix() && rightType.isVector()) {
832 }
833 }
834
835
836 if (
is_vec_or_mat(leftType) && leftType.matches(rightType)) {
838 }
839
840
842 leftType.componentType().matches(rightType)) {
845 }
846
847
849 rightType.componentType().matches(leftType)) {
852 }
853
854
855 if ((leftType.isMatrix() && rightType.isMatrix()) ||
856 (leftType.isArray() && rightType.isArray()) ||
857 (leftType.isStruct() && rightType.isStruct())) {
859 }
860 }
861
862 if (context.fConfig->fSettings.fOptimize) {
863
864
865 if (leftSideIsConstant || rightSideIsConstant) {
867 *
right, resultType)) {
868 return expr;
869 }
870 }
871
872
874 *
right, resultType)) {
875 return expr;
876 }
877 }
878
879
880 return nullptr;
881}
static bool left(const SkPoint &p0, const SkPoint &p1)
static bool right(const SkPoint &p0, const SkPoint &p1)
static std::unique_ptr< Literal > MakeBool(const Context &context, Position pos, bool value)
bool IsSameExpressionTree(const Expression &left, const Expression &right)
bool HasSideEffects(const Expression &expr)
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 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 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 std::unique_ptr< Expression > simplify_matrix_times_vector(const Context &context, Position pos, const Expression &left, const Expression &right)
static std::unique_ptr< Expression > short_circuit_boolean(Position pos, const Expression &left, Operator op, 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 > simplify_arithmetic(const Context &context, Position pos, const Expression &left, Operator op, const Expression &right, const Type &resultType)