Add GetConstantValue, fix const-variable ES2 loop bounds
Prior to this fix, the new test cases would report that the various loop terms needed to be constant expressions. Bug: skia:12472 Change-Id: Ic377ed0c4598136ae38fb2b65c93b6d8609d54cb Reviewed-on: https://skia-review.googlesource.com/c/skia/+/452276 Commit-Queue: Brian Osman <brianosman@google.com> Reviewed-by: John Stiles <johnstiles@google.com>
This commit is contained in:
parent
e405d7c8e5
commit
448b2d5795
@ -1,17 +1,19 @@
|
||||
uniform half4 colorRed, colorGreen;
|
||||
|
||||
// Should return 5
|
||||
const float kZero = 0;
|
||||
float return_loop() {
|
||||
for (float i = 0; i < 10; ++i) {
|
||||
for (float i = kZero; i < 10; ++i) {
|
||||
if (i == 5) { return i; }
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Should return 35
|
||||
const float kTen = kZero + 10;
|
||||
float continue_loop() {
|
||||
float sum = 0;
|
||||
for (float i = 0; i < 10; ++i) {
|
||||
for (float i = 0; i < kTen; ++i) {
|
||||
if (i < 5) { continue; }
|
||||
sum += i;
|
||||
}
|
||||
@ -21,7 +23,8 @@ float continue_loop() {
|
||||
// Should return 15
|
||||
float break_loop() {
|
||||
float sum = 0;
|
||||
for (float i = 0; i < 10; ++i) {
|
||||
const float kOne = 1;
|
||||
for (float i = 0; i < 10; i += kOne) {
|
||||
if (i > 5) { break; }
|
||||
sum += i;
|
||||
}
|
||||
|
@ -1,17 +1,19 @@
|
||||
uniform half4 colorRed, colorGreen;
|
||||
|
||||
// Should return 5
|
||||
const int kZero = 0;
|
||||
int return_loop() {
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
for (int i = kZero; i < 10; ++i) {
|
||||
if (i == 5) { return i; }
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Should return 35
|
||||
const int kTen = kZero + 10;
|
||||
int continue_loop() {
|
||||
int sum = 0;
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
for (int i = 0; i < kTen; ++i) {
|
||||
if (i < 5) { continue; }
|
||||
sum += i;
|
||||
}
|
||||
@ -21,7 +23,8 @@ int continue_loop() {
|
||||
// Should return 15
|
||||
int break_loop() {
|
||||
int sum = 0;
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
const int kOne = 1;
|
||||
for (int i = 0; i < 10; i += kOne) {
|
||||
if (i > 5) { break; }
|
||||
sum += i;
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "include/sksl/SkSLErrorReporter.h"
|
||||
#include "src/core/SkSafeMath.h"
|
||||
#include "src/sksl/SkSLCompiler.h"
|
||||
#include "src/sksl/SkSLConstantFolder.h"
|
||||
#include "src/sksl/ir/SkSLExpression.h"
|
||||
#include "src/sksl/ir/SkSLProgram.h"
|
||||
|
||||
@ -1009,19 +1010,6 @@ bool Analysis::IsSameExpressionTree(const Expression& left, const Expression& ri
|
||||
}
|
||||
}
|
||||
|
||||
static bool get_constant_value(const Expression& expr, double* val) {
|
||||
const Expression* valExpr = expr.getConstantSubexpression(0);
|
||||
if (!valExpr) {
|
||||
return false;
|
||||
}
|
||||
if (valExpr->is<Literal>()) {
|
||||
*val = valExpr->as<Literal>().value();
|
||||
return true;
|
||||
}
|
||||
SkDEBUGFAILF("unexpected constant type (%s)", expr.type().description().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
static const char* invalid_for_ES2(int offset,
|
||||
const Statement* loopInitializer,
|
||||
const Expression* loopTest,
|
||||
@ -1047,7 +1035,7 @@ static const char* invalid_for_ES2(int offset,
|
||||
if (!initDecl.value()) {
|
||||
return "missing loop index initializer";
|
||||
}
|
||||
if (!get_constant_value(*initDecl.value(), &loopInfo.fStart)) {
|
||||
if (!ConstantFolder::GetConstantValue(*initDecl.value(), &loopInfo.fStart)) {
|
||||
return "loop index initializer must be a constant expression";
|
||||
}
|
||||
|
||||
@ -1084,7 +1072,7 @@ static const char* invalid_for_ES2(int offset,
|
||||
return "invalid relational operator";
|
||||
}
|
||||
double loopEnd = 0;
|
||||
if (!get_constant_value(*cond.right(), &loopEnd)) {
|
||||
if (!ConstantFolder::GetConstantValue(*cond.right(), &loopEnd)) {
|
||||
return "loop index must be compared with a constant expression";
|
||||
}
|
||||
|
||||
@ -1106,7 +1094,7 @@ static const char* invalid_for_ES2(int offset,
|
||||
if (!is_loop_index(next.left())) {
|
||||
return "expected loop index in loop expression";
|
||||
}
|
||||
if (!get_constant_value(*next.right(), &loopInfo.fDelta)) {
|
||||
if (!ConstantFolder::GetConstantValue(*next.right(), &loopInfo.fDelta)) {
|
||||
return "loop index must be modified by a constant expression";
|
||||
}
|
||||
switch (next.getOperator().kind()) {
|
||||
|
@ -145,6 +145,15 @@ bool ConstantFolder::GetConstantInt(const Expression& value, SKSL_INT* out) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ConstantFolder::GetConstantValue(const Expression& value, double* out) {
|
||||
const Expression* expr = GetConstantValueForVariable(value);
|
||||
if (!expr->is<Literal>()) {
|
||||
return false;
|
||||
}
|
||||
*out = expr->as<Literal>().value();
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool is_constant_scalar_value(const Expression& inExpr, double match) {
|
||||
const Expression* expr = ConstantFolder::GetConstantValueForVariable(inExpr);
|
||||
return (expr->is<Literal>() && expr->as<Literal>().value() == match);
|
||||
|
@ -30,6 +30,12 @@ public:
|
||||
*/
|
||||
static bool GetConstantInt(const Expression& value, SKSL_INT* out);
|
||||
|
||||
/**
|
||||
* If value is a literal or const scalar variable with a known value, returns true and stores
|
||||
* the value in out. Otherwise returns false.
|
||||
*/
|
||||
static bool GetConstantValue(const Expression& value, double* out);
|
||||
|
||||
/**
|
||||
* If the expression is a const variable with a known compile-time-constant value, returns that
|
||||
* value. If not, returns the original expression as-is.
|
||||
|
@ -1,8 +1,10 @@
|
||||
uniform half4 colorRed;
|
||||
uniform half4 colorGreen;
|
||||
const float kZero_0 = 0.0;
|
||||
const float kTen_0 = 10.0;
|
||||
float return_loop_0()
|
||||
{
|
||||
for (float i = 0.0;i < 10.0; ++i)
|
||||
for (float i = kZero_0;i < 10.0; ++i)
|
||||
{
|
||||
if (i == 5.0)
|
||||
{
|
||||
@ -14,7 +16,7 @@ float return_loop_0()
|
||||
float continue_loop_0()
|
||||
{
|
||||
float sum = 0.0;
|
||||
for (float i = 0.0;i < 10.0; ++i)
|
||||
for (float i = 0.0;i < kTen_0; ++i)
|
||||
{
|
||||
if (i < 5.0)
|
||||
{
|
||||
@ -27,7 +29,8 @@ float continue_loop_0()
|
||||
float break_loop_0()
|
||||
{
|
||||
float sum = 0.0;
|
||||
for (float i = 0.0;i < 10.0; ++i)
|
||||
const float kOne = 1.0;
|
||||
for (float i = 0.0;i < 10.0; i += kOne)
|
||||
{
|
||||
if (i > 5.0)
|
||||
{
|
||||
|
@ -1,8 +1,10 @@
|
||||
uniform half4 colorRed;
|
||||
uniform half4 colorGreen;
|
||||
const int kZero_0 = 0;
|
||||
const int kTen_0 = 10;
|
||||
int return_loop_0()
|
||||
{
|
||||
for (int i = 0;i < 10; ++i)
|
||||
for (int i = kZero_0;i < 10; ++i)
|
||||
{
|
||||
if (i == 5)
|
||||
{
|
||||
@ -14,7 +16,7 @@ int return_loop_0()
|
||||
int continue_loop_0()
|
||||
{
|
||||
int sum = 0;
|
||||
for (int i = 0;i < 10; ++i)
|
||||
for (int i = 0;i < kTen_0; ++i)
|
||||
{
|
||||
if (i < 5)
|
||||
{
|
||||
@ -27,7 +29,8 @@ int continue_loop_0()
|
||||
int break_loop_0()
|
||||
{
|
||||
int sum = 0;
|
||||
for (int i = 0;i < 10; ++i)
|
||||
const int kOne = 1;
|
||||
for (int i = 0;i < 10; i += kOne)
|
||||
{
|
||||
if (i > 5)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user