Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(518)

Side by Side Diff: src/sksl/SkSLIRGenerator.cpp

Issue 2494523002: Revert of added constant folding & branch elimination to skslc (Closed)
Patch Set: Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/sksl/SkSLIRGenerator.h ('k') | tests/SkSLErrorTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2016 Google Inc. 2 * Copyright 2016 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkSLIRGenerator.h" 8 #include "SkSLIRGenerator.h"
9 9
10 #include "limits.h" 10 #include "limits.h"
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 if (!ifTrue) { 239 if (!ifTrue) {
240 return nullptr; 240 return nullptr;
241 } 241 }
242 std::unique_ptr<Statement> ifFalse; 242 std::unique_ptr<Statement> ifFalse;
243 if (s.fIfFalse) { 243 if (s.fIfFalse) {
244 ifFalse = this->convertStatement(*s.fIfFalse); 244 ifFalse = this->convertStatement(*s.fIfFalse);
245 if (!ifFalse) { 245 if (!ifFalse) {
246 return nullptr; 246 return nullptr;
247 } 247 }
248 } 248 }
249 if (test->fKind == Expression::kBoolLiteral_Kind) {
250 // static boolean value, fold down to a single branch
251 if (((BoolLiteral&) *test).fValue) {
252 return ifTrue;
253 } else if (s.fIfFalse) {
254 return ifFalse;
255 } else {
256 // False & no else clause. Not an error, so don't return null!
257 return std::unique_ptr<Statement>(new Block(s.fPosition, { }, fSymbo lTable));
258 }
259 }
260 return std::unique_ptr<Statement>(new IfStatement(s.fPosition, std::move(tes t), 249 return std::unique_ptr<Statement>(new IfStatement(s.fPosition, std::move(tes t),
261 std::move(ifTrue), std::mo ve(ifFalse))); 250 std::move(ifTrue), std::mo ve(ifFalse)));
262 } 251 }
263 252
264 std::unique_ptr<Statement> IRGenerator::convertFor(const ASTForStatement& f) { 253 std::unique_ptr<Statement> IRGenerator::convertFor(const ASTForStatement& f) {
265 AutoLoopLevel level(this); 254 AutoLoopLevel level(this);
266 AutoSymbolTable table(this); 255 AutoSymbolTable table(this);
267 std::unique_ptr<Statement> initializer; 256 std::unique_ptr<Statement> initializer;
268 if (f.fInitializer) { 257 if (f.fInitializer) {
269 initializer = this->convertStatement(*f.fInitializer); 258 initializer = this->convertStatement(*f.fInitializer);
(...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after
798 } 787 }
799 return false; 788 return false;
800 } 789 }
801 if (tryFlipped) { 790 if (tryFlipped) {
802 return determine_binary_type(context, op, right, left, outRightType, out LeftType, 791 return determine_binary_type(context, op, right, left, outRightType, out LeftType,
803 outResultType, false); 792 outResultType, false);
804 } 793 }
805 return false; 794 return false;
806 } 795 }
807 796
808 /**
809 * If both operands are compile-time constants and can be folded, returns an exp ression representing
810 * the folded value. Otherwise, returns null. Note that unlike most other functi ons here, null does
811 * not represent a compilation error.
812 */
813 std::unique_ptr<Expression> IRGenerator::constantFold(const Expression& left,
814 Token::Kind op,
815 const Expression& right) {
816 // Note that we expressly do not worry about precision and overflow here -- we use the maximum
817 // precision to calculate the results and hope the result makes sense. The p lan is to move the
818 // Skia caps into SkSL, so we have access to all of them including the preci sions of the various
819 // types, which will let us be more intelligent about this.
820 if (left.fKind == Expression::kBoolLiteral_Kind &&
821 right.fKind == Expression::kBoolLiteral_Kind) {
822 bool leftVal = ((BoolLiteral&) left).fValue;
823 bool rightVal = ((BoolLiteral&) right).fValue;
824 bool result;
825 switch (op) {
826 case Token::LOGICALAND: result = leftVal && rightVal; break;
827 case Token::LOGICALOR: result = leftVal || rightVal; break;
828 case Token::LOGICALXOR: result = leftVal ^ rightVal; break;
829 default: return nullptr;
830 }
831 return std::unique_ptr<Expression>(new BoolLiteral(fContext, left.fPosit ion, result));
832 }
833 #define RESULT(t, op) std::unique_ptr<Expression>(new t ## Literal(fContext, left.fPosition, \
834 leftVal o p rightVal))
835 if (left.fKind == Expression::kIntLiteral_Kind && right.fKind == Expression: :kIntLiteral_Kind) {
836 int64_t leftVal = ((IntLiteral&) left).fValue;
837 int64_t rightVal = ((IntLiteral&) right).fValue;
838 switch (op) {
839 case Token::PLUS: return RESULT(Int, +);
840 case Token::MINUS: return RESULT(Int, -);
841 case Token::STAR: return RESULT(Int, *);
842 case Token::SLASH: return RESULT(Int, /);
843 case Token::PERCENT: return RESULT(Int, %);
844 case Token::BITWISEAND: return RESULT(Int, &);
845 case Token::BITWISEOR: return RESULT(Int, |);
846 case Token::BITWISEXOR: return RESULT(Int, ^);
847 case Token::SHL: return RESULT(Int, <<);
848 case Token::SHR: return RESULT(Int, >>);
849 case Token::EQEQ: return RESULT(Bool, ==);
850 case Token::NEQ: return RESULT(Bool, !=);
851 case Token::GT: return RESULT(Bool, >);
852 case Token::GTEQ: return RESULT(Bool, >=);
853 case Token::LT: return RESULT(Bool, <);
854 case Token::LTEQ: return RESULT(Bool, <=);
855 default: return nullptr;
856 }
857 }
858 if (left.fKind == Expression::kFloatLiteral_Kind &&
859 right.fKind == Expression::kFloatLiteral_Kind) {
860 double leftVal = ((FloatLiteral&) left).fValue;
861 double rightVal = ((FloatLiteral&) right).fValue;
862 switch (op) {
863 case Token::PLUS: return RESULT(Float, +);
864 case Token::MINUS: return RESULT(Float, -);
865 case Token::STAR: return RESULT(Float, *);
866 case Token::SLASH: return RESULT(Float, /);
867 case Token::EQEQ: return RESULT(Bool, ==);
868 case Token::NEQ: return RESULT(Bool, !=);
869 case Token::GT: return RESULT(Bool, >);
870 case Token::GTEQ: return RESULT(Bool, >=);
871 case Token::LT: return RESULT(Bool, <);
872 case Token::LTEQ: return RESULT(Bool, <=);
873 default: return nullptr;
874 }
875 }
876 #undef RESULT
877 return nullptr;
878 }
879
880 std::unique_ptr<Expression> IRGenerator::convertBinaryExpression( 797 std::unique_ptr<Expression> IRGenerator::convertBinaryExpression(
881 const ASTBinaryExpre ssion& expression) { 798 const ASTBinaryExpre ssion& expression) {
882 std::unique_ptr<Expression> left = this->convertExpression(*expression.fLeft ); 799 std::unique_ptr<Expression> left = this->convertExpression(*expression.fLeft );
883 if (!left) { 800 if (!left) {
884 return nullptr; 801 return nullptr;
885 } 802 }
886 std::unique_ptr<Expression> right = this->convertExpression(*expression.fRig ht); 803 std::unique_ptr<Expression> right = this->convertExpression(*expression.fRig ht);
887 if (!right) { 804 if (!right) {
888 return nullptr; 805 return nullptr;
889 } 806 }
890 const Type* leftType; 807 const Type* leftType;
891 const Type* rightType; 808 const Type* rightType;
892 const Type* resultType; 809 const Type* resultType;
893 if (!determine_binary_type(fContext, expression.fOperator, left->fType, righ t->fType, &leftType, 810 if (!determine_binary_type(fContext, expression.fOperator, left->fType, righ t->fType, &leftType,
894 &rightType, &resultType, !is_assignment(expressio n.fOperator))) { 811 &rightType, &resultType, !is_assignment(expressio n.fOperator))) {
895 fErrors.error(expression.fPosition, "type mismatch: '" + 812 fErrors.error(expression.fPosition, "type mismatch: '" +
896 Token::OperatorName(expression.fOper ator) + 813 Token::OperatorName(expression.fOper ator) +
897 "' cannot operate on '" + left->fTyp e.fName + 814 "' cannot operate on '" + left->fTyp e.fName +
898 "', '" + right->fType.fName + "'"); 815 "', '" + right->fType.fName + "'");
899 return nullptr; 816 return nullptr;
900 } 817 }
901 if (is_assignment(expression.fOperator)) { 818 if (is_assignment(expression.fOperator)) {
902 this->markWrittenTo(*left); 819 this->markWrittenTo(*left);
903 } 820 }
904 left = this->coerce(std::move(left), *leftType); 821 left = this->coerce(std::move(left), *leftType);
905 right = this->coerce(std::move(right), *rightType); 822 right = this->coerce(std::move(right), *rightType);
906 if (!left || !right) { 823 if (!left || !right) {
907 return nullptr; 824 return nullptr;
908 } 825 }
909 std::unique_ptr<Expression> result = this->constantFold(*left.get(), express ion.fOperator, 826 return std::unique_ptr<Expression>(new BinaryExpression(expression.fPosition ,
910 *right.get()); 827 std::move(left),
911 if (!result) { 828 expression.fOperator ,
912 result = std::unique_ptr<Expression>(new BinaryExpression(expression.fPo sition, 829 std::move(right),
913 std::move(left ), 830 *resultType));
914 expression.fOp erator,
915 std::move(righ t),
916 *resultType));
917 }
918 return result;
919 } 831 }
920 832
921 std::unique_ptr<Expression> IRGenerator::convertTernaryExpression( 833 std::unique_ptr<Expression> IRGenerator::convertTernaryExpression(
922 const ASTTernaryExpre ssion& expression) { 834 const ASTTernaryExpre ssion& expression) {
923 std::unique_ptr<Expression> test = this->coerce(this->convertExpression(*exp ression.fTest), 835 std::unique_ptr<Expression> test = this->coerce(this->convertExpression(*exp ression.fTest),
924 *fContext.fBool_Type); 836 *fContext.fBool_Type);
925 if (!test) { 837 if (!test) {
926 return nullptr; 838 return nullptr;
927 } 839 }
928 std::unique_ptr<Expression> ifTrue = this->convertExpression(*expression.fIf True); 840 std::unique_ptr<Expression> ifTrue = this->convertExpression(*expression.fIf True);
(...skipping 10 matching lines...) Expand all
939 if (!determine_binary_type(fContext, Token::EQEQ, ifTrue->fType, ifFalse->fT ype, &trueType, 851 if (!determine_binary_type(fContext, Token::EQEQ, ifTrue->fType, ifFalse->fT ype, &trueType,
940 &falseType, &resultType, true)) { 852 &falseType, &resultType, true)) {
941 fErrors.error(expression.fPosition, "ternary operator result mismatch: ' " + 853 fErrors.error(expression.fPosition, "ternary operator result mismatch: ' " +
942 ifTrue->fType.fName + "', '" + 854 ifTrue->fType.fName + "', '" +
943 ifFalse->fType.fName + "'"); 855 ifFalse->fType.fName + "'");
944 return nullptr; 856 return nullptr;
945 } 857 }
946 ASSERT(trueType == falseType); 858 ASSERT(trueType == falseType);
947 ifTrue = this->coerce(std::move(ifTrue), *trueType); 859 ifTrue = this->coerce(std::move(ifTrue), *trueType);
948 ifFalse = this->coerce(std::move(ifFalse), *falseType); 860 ifFalse = this->coerce(std::move(ifFalse), *falseType);
949 if (test->fKind == Expression::kBoolLiteral_Kind) {
950 // static boolean test, just return one of the branches
951 if (((BoolLiteral&) *test).fValue) {
952 return ifTrue;
953 } else {
954 return ifFalse;
955 }
956 }
957 return std::unique_ptr<Expression>(new TernaryExpression(expression.fPositio n, 861 return std::unique_ptr<Expression>(new TernaryExpression(expression.fPositio n,
958 std::move(test), 862 std::move(test),
959 std::move(ifTrue), 863 std::move(ifTrue),
960 std::move(ifFalse)) ); 864 std::move(ifFalse)) );
961 } 865 }
962 866
963 std::unique_ptr<Expression> IRGenerator::call(Position position, 867 std::unique_ptr<Expression> IRGenerator::call(Position position,
964 const FunctionDeclaration& functio n, 868 const FunctionDeclaration& functio n,
965 std::vector<std::unique_ptr<Expres sion>> arguments) { 869 std::vector<std::unique_ptr<Expres sion>> arguments) {
966 if (function.fParameters.size() != arguments.size()) { 870 if (function.fParameters.size() != arguments.size()) {
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
1215 } 1119 }
1216 this->markWrittenTo(*base); 1120 this->markWrittenTo(*base);
1217 break; 1121 break;
1218 case Token::LOGICALNOT: 1122 case Token::LOGICALNOT:
1219 if (base->fType != *fContext.fBool_Type) { 1123 if (base->fType != *fContext.fBool_Type) {
1220 fErrors.error(expression.fPosition, 1124 fErrors.error(expression.fPosition,
1221 "'" + Token::OperatorName(expression.fOperator) + 1125 "'" + Token::OperatorName(expression.fOperator) +
1222 "' cannot operate on '" + base->fType.description( ) + "'"); 1126 "' cannot operate on '" + base->fType.description( ) + "'");
1223 return nullptr; 1127 return nullptr;
1224 } 1128 }
1225 if (base->fKind == Expression::kBoolLiteral_Kind) {
1226 return std::unique_ptr<Expression>(new BoolLiteral(fContext, bas e->fPosition,
1227 !((BoolLitera l&) *base).fValue));
1228 }
1229 break; 1129 break;
1230 case Token::BITWISENOT: 1130 case Token::BITWISENOT:
1231 if (base->fType != *fContext.fInt_Type) { 1131 if (base->fType != *fContext.fInt_Type) {
1232 fErrors.error(expression.fPosition, 1132 fErrors.error(expression.fPosition,
1233 "'" + Token::OperatorName(expression.fOperator) + 1133 "'" + Token::OperatorName(expression.fOperator) +
1234 "' cannot operate on '" + base->fType.description( ) + "'"); 1134 "' cannot operate on '" + base->fType.description( ) + "'");
1235 return nullptr; 1135 return nullptr;
1236 } 1136 }
1237 break; 1137 break;
1238 default: 1138 default:
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
1458 case Expression::kIndex_Kind: 1358 case Expression::kIndex_Kind:
1459 this->markWrittenTo(*((IndexExpression&) expr).fBase); 1359 this->markWrittenTo(*((IndexExpression&) expr).fBase);
1460 break; 1360 break;
1461 default: 1361 default:
1462 fErrors.error(expr.fPosition, "cannot assign to '" + expr.descriptio n() + "'"); 1362 fErrors.error(expr.fPosition, "cannot assign to '" + expr.descriptio n() + "'");
1463 break; 1363 break;
1464 } 1364 }
1465 } 1365 }
1466 1366
1467 } 1367 }
OLDNEW
« no previous file with comments | « src/sksl/SkSLIRGenerator.h ('k') | tests/SkSLErrorTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698