added SkSL OptimizationContext
This simplifies the signatures of several methods and makes it easier to ignore errors we have already reported. Change-Id: I767ca22a66e69fe72557c2560ef84f5dbe339eb8 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/329220 Commit-Queue: Ethan Nicholas <ethannicholas@google.com> Reviewed-by: John Stiles <johnstiles@google.com>
This commit is contained in:
parent
65674e4c2e
commit
cdeae8c0cc
@ -705,9 +705,8 @@ static bool is_constant(const Expression& expr, T value) {
|
||||
*/
|
||||
static void delete_left(BasicBlock* b,
|
||||
std::vector<BasicBlock::Node>::iterator* iter,
|
||||
bool* outUpdated,
|
||||
bool* outNeedsRescan) {
|
||||
*outUpdated = true;
|
||||
Compiler::OptimizationContext* optimizationContext) {
|
||||
optimizationContext->fUpdated = true;
|
||||
std::unique_ptr<Expression>* target = (*iter)->expression();
|
||||
BinaryExpression& bin = (*target)->as<BinaryExpression>();
|
||||
Expression& left = bin.left();
|
||||
@ -721,16 +720,16 @@ static void delete_left(BasicBlock* b,
|
||||
}
|
||||
*target = std::move(rightPointer);
|
||||
if (!result) {
|
||||
*outNeedsRescan = true;
|
||||
optimizationContext->fNeedsRescan = true;
|
||||
return;
|
||||
}
|
||||
if (*iter == b->fNodes.begin()) {
|
||||
*outNeedsRescan = true;
|
||||
optimizationContext->fNeedsRescan = true;
|
||||
return;
|
||||
}
|
||||
--(*iter);
|
||||
if (!(*iter)->isExpression() || (*iter)->expression() != &rightPointer) {
|
||||
*outNeedsRescan = true;
|
||||
optimizationContext->fNeedsRescan = true;
|
||||
return;
|
||||
}
|
||||
*iter = b->fNodes.erase(*iter);
|
||||
@ -743,9 +742,8 @@ static void delete_left(BasicBlock* b,
|
||||
*/
|
||||
static void delete_right(BasicBlock* b,
|
||||
std::vector<BasicBlock::Node>::iterator* iter,
|
||||
bool* outUpdated,
|
||||
bool* outNeedsRescan) {
|
||||
*outUpdated = true;
|
||||
Compiler::OptimizationContext* optimizationContext) {
|
||||
optimizationContext->fUpdated = true;
|
||||
std::unique_ptr<Expression>* target = (*iter)->expression();
|
||||
BinaryExpression& bin = (*target)->as<BinaryExpression>();
|
||||
std::unique_ptr<Expression>& leftPointer = bin.leftPointer();
|
||||
@ -753,17 +751,17 @@ static void delete_right(BasicBlock* b,
|
||||
SkASSERT(!right.hasSideEffects());
|
||||
if (!b->tryRemoveExpressionBefore(iter, &right)) {
|
||||
*target = std::move(leftPointer);
|
||||
*outNeedsRescan = true;
|
||||
optimizationContext->fNeedsRescan = true;
|
||||
return;
|
||||
}
|
||||
*target = std::move(leftPointer);
|
||||
if (*iter == b->fNodes.begin()) {
|
||||
*outNeedsRescan = true;
|
||||
optimizationContext->fNeedsRescan = true;
|
||||
return;
|
||||
}
|
||||
--(*iter);
|
||||
if ((!(*iter)->isExpression() || (*iter)->expression() != &leftPointer)) {
|
||||
*outNeedsRescan = true;
|
||||
optimizationContext->fNeedsRescan = true;
|
||||
return;
|
||||
}
|
||||
*iter = b->fNodes.erase(*iter);
|
||||
@ -788,20 +786,19 @@ static void vectorize(BasicBlock* b,
|
||||
std::vector<BasicBlock::Node>::iterator* iter,
|
||||
const Type& type,
|
||||
std::unique_ptr<Expression>* otherExpression,
|
||||
bool* outUpdated,
|
||||
bool* outNeedsRescan) {
|
||||
Compiler::OptimizationContext* optimizationContext) {
|
||||
SkASSERT((*(*iter)->expression())->kind() == Expression::Kind::kBinary);
|
||||
SkASSERT(type.typeKind() == Type::TypeKind::kVector);
|
||||
SkASSERT((*otherExpression)->type().typeKind() == Type::TypeKind::kScalar);
|
||||
*outUpdated = true;
|
||||
optimizationContext->fUpdated = true;
|
||||
std::unique_ptr<Expression>* target = (*iter)->expression();
|
||||
if (!b->tryRemoveExpression(iter)) {
|
||||
*target = construct(&type, std::move(*otherExpression));
|
||||
*outNeedsRescan = true;
|
||||
optimizationContext->fNeedsRescan = true;
|
||||
} else {
|
||||
*target = construct(&type, std::move(*otherExpression));
|
||||
if (!b->tryInsertExpression(iter, target)) {
|
||||
*outNeedsRescan = true;
|
||||
optimizationContext->fNeedsRescan = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -812,10 +809,9 @@ static void vectorize(BasicBlock* b,
|
||||
*/
|
||||
static void vectorize_left(BasicBlock* b,
|
||||
std::vector<BasicBlock::Node>::iterator* iter,
|
||||
bool* outUpdated,
|
||||
bool* outNeedsRescan) {
|
||||
Compiler::OptimizationContext* optimizationContext) {
|
||||
BinaryExpression& bin = (*(*iter)->expression())->as<BinaryExpression>();
|
||||
vectorize(b, iter, bin.right().type(), &bin.leftPointer(), outUpdated, outNeedsRescan);
|
||||
vectorize(b, iter, bin.right().type(), &bin.leftPointer(), optimizationContext);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -824,10 +820,9 @@ static void vectorize_left(BasicBlock* b,
|
||||
*/
|
||||
static void vectorize_right(BasicBlock* b,
|
||||
std::vector<BasicBlock::Node>::iterator* iter,
|
||||
bool* outUpdated,
|
||||
bool* outNeedsRescan) {
|
||||
Compiler::OptimizationContext* optimizationContext) {
|
||||
BinaryExpression& bin = (*(*iter)->expression())->as<BinaryExpression>();
|
||||
vectorize(b, iter, bin.left().type(), &bin.rightPointer(), outUpdated, outNeedsRescan);
|
||||
vectorize(b, iter, bin.left().type(), &bin.rightPointer(), optimizationContext);
|
||||
}
|
||||
|
||||
// Mark that an expression which we were writing to is no longer being written to
|
||||
@ -855,19 +850,18 @@ static void clear_write(Expression& expr) {
|
||||
void Compiler::simplifyExpression(DefinitionMap& definitions,
|
||||
BasicBlock& b,
|
||||
std::vector<BasicBlock::Node>::iterator* iter,
|
||||
std::unordered_set<const Variable*>* undefinedVariables,
|
||||
bool* outUpdated,
|
||||
bool* outNeedsRescan) {
|
||||
OptimizationContext* optimizationContext) {
|
||||
Expression* expr = (*iter)->expression()->get();
|
||||
SkASSERT(expr);
|
||||
if ((*iter)->fConstantPropagation) {
|
||||
std::unique_ptr<Expression> optimized = expr->constantPropagate(*fIRGenerator, definitions);
|
||||
std::unique_ptr<Expression> optimized = expr->constantPropagate(*fIRGenerator,
|
||||
definitions);
|
||||
if (optimized) {
|
||||
*outUpdated = true;
|
||||
optimizationContext->fUpdated = true;
|
||||
optimized = fIRGenerator->coerce(std::move(optimized), expr->type());
|
||||
SkASSERT(optimized);
|
||||
if (!try_replace_expression(&b, iter, &optimized)) {
|
||||
*outNeedsRescan = true;
|
||||
optimizationContext->fNeedsRescan = true;
|
||||
return;
|
||||
}
|
||||
SkASSERT((*iter)->isExpression());
|
||||
@ -881,8 +875,8 @@ void Compiler::simplifyExpression(DefinitionMap& definitions,
|
||||
if (ref.refKind() != VariableReference::RefKind::kWrite &&
|
||||
ref.refKind() != VariableReference::RefKind::kPointer &&
|
||||
var->storage() == Variable::Storage::kLocal && !definitions[var] &&
|
||||
(*undefinedVariables).find(var) == (*undefinedVariables).end()) {
|
||||
(*undefinedVariables).insert(var);
|
||||
optimizationContext->fSilences.find(var) == optimizationContext->fSilences.end()) {
|
||||
optimizationContext->fSilences.insert(var);
|
||||
this->error(expr->fOffset,
|
||||
"'" + var->name() + "' has not been assigned");
|
||||
}
|
||||
@ -898,15 +892,15 @@ void Compiler::simplifyExpression(DefinitionMap& definitions,
|
||||
} else {
|
||||
(*iter)->setExpression(std::move(t->ifFalse()));
|
||||
}
|
||||
*outUpdated = true;
|
||||
*outNeedsRescan = true;
|
||||
optimizationContext->fUpdated = true;
|
||||
optimizationContext->fNeedsRescan = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Expression::Kind::kBinary: {
|
||||
BinaryExpression* bin = &expr->as<BinaryExpression>();
|
||||
if (dead_assignment(*bin)) {
|
||||
delete_left(&b, iter, outUpdated, outNeedsRescan);
|
||||
delete_left(&b, iter, optimizationContext);
|
||||
break;
|
||||
}
|
||||
Expression& left = bin->left();
|
||||
@ -926,12 +920,12 @@ void Compiler::simplifyExpression(DefinitionMap& definitions,
|
||||
if (leftType.typeKind() == Type::TypeKind::kVector &&
|
||||
rightType.typeKind() == Type::TypeKind::kScalar) {
|
||||
// float4(1) * x -> float4(x)
|
||||
vectorize_right(&b, iter, outUpdated, outNeedsRescan);
|
||||
vectorize_right(&b, iter, optimizationContext);
|
||||
} else {
|
||||
// 1 * x -> x
|
||||
// 1 * float4(x) -> float4(x)
|
||||
// float4(1) * float4(x) -> float4(x)
|
||||
delete_left(&b, iter, outUpdated, outNeedsRescan);
|
||||
delete_left(&b, iter, optimizationContext);
|
||||
}
|
||||
}
|
||||
else if (is_constant(left, 0)) {
|
||||
@ -939,13 +933,13 @@ void Compiler::simplifyExpression(DefinitionMap& definitions,
|
||||
rightType.typeKind() == Type::TypeKind::kVector &&
|
||||
!right.hasSideEffects()) {
|
||||
// 0 * float4(x) -> float4(0)
|
||||
vectorize_left(&b, iter, outUpdated, outNeedsRescan);
|
||||
vectorize_left(&b, iter, optimizationContext);
|
||||
} else {
|
||||
// 0 * x -> 0
|
||||
// float4(0) * x -> float4(0)
|
||||
// float4(0) * float4(x) -> float4(0)
|
||||
if (!right.hasSideEffects()) {
|
||||
delete_right(&b, iter, outUpdated, outNeedsRescan);
|
||||
delete_right(&b, iter, optimizationContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -953,12 +947,12 @@ void Compiler::simplifyExpression(DefinitionMap& definitions,
|
||||
if (leftType.typeKind() == Type::TypeKind::kScalar &&
|
||||
rightType.typeKind() == Type::TypeKind::kVector) {
|
||||
// x * float4(1) -> float4(x)
|
||||
vectorize_left(&b, iter, outUpdated, outNeedsRescan);
|
||||
vectorize_left(&b, iter, optimizationContext);
|
||||
} else {
|
||||
// x * 1 -> x
|
||||
// float4(x) * 1 -> float4(x)
|
||||
// float4(x) * float4(1) -> float4(x)
|
||||
delete_right(&b, iter, outUpdated, outNeedsRescan);
|
||||
delete_right(&b, iter, optimizationContext);
|
||||
}
|
||||
}
|
||||
else if (is_constant(right, 0)) {
|
||||
@ -966,13 +960,13 @@ void Compiler::simplifyExpression(DefinitionMap& definitions,
|
||||
rightType.typeKind() == Type::TypeKind::kScalar &&
|
||||
!left.hasSideEffects()) {
|
||||
// float4(x) * 0 -> float4(0)
|
||||
vectorize_right(&b, iter, outUpdated, outNeedsRescan);
|
||||
vectorize_right(&b, iter, optimizationContext);
|
||||
} else {
|
||||
// x * 0 -> 0
|
||||
// x * float4(0) -> float4(0)
|
||||
// float4(x) * float4(0) -> float4(0)
|
||||
if (!left.hasSideEffects()) {
|
||||
delete_left(&b, iter, outUpdated, outNeedsRescan);
|
||||
delete_left(&b, iter, optimizationContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -982,23 +976,23 @@ void Compiler::simplifyExpression(DefinitionMap& definitions,
|
||||
if (leftType.typeKind() == Type::TypeKind::kVector &&
|
||||
rightType.typeKind() == Type::TypeKind::kScalar) {
|
||||
// float4(0) + x -> float4(x)
|
||||
vectorize_right(&b, iter, outUpdated, outNeedsRescan);
|
||||
vectorize_right(&b, iter, optimizationContext);
|
||||
} else {
|
||||
// 0 + x -> x
|
||||
// 0 + float4(x) -> float4(x)
|
||||
// float4(0) + float4(x) -> float4(x)
|
||||
delete_left(&b, iter, outUpdated, outNeedsRescan);
|
||||
delete_left(&b, iter, optimizationContext);
|
||||
}
|
||||
} else if (is_constant(right, 0)) {
|
||||
if (leftType.typeKind() == Type::TypeKind::kScalar &&
|
||||
rightType.typeKind() == Type::TypeKind::kVector) {
|
||||
// x + float4(0) -> float4(x)
|
||||
vectorize_left(&b, iter, outUpdated, outNeedsRescan);
|
||||
vectorize_left(&b, iter, optimizationContext);
|
||||
} else {
|
||||
// x + 0 -> x
|
||||
// float4(x) + 0 -> float4(x)
|
||||
// float4(x) + float4(0) -> float4(x)
|
||||
delete_right(&b, iter, outUpdated, outNeedsRescan);
|
||||
delete_right(&b, iter, optimizationContext);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1007,12 +1001,12 @@ void Compiler::simplifyExpression(DefinitionMap& definitions,
|
||||
if (leftType.typeKind() == Type::TypeKind::kScalar &&
|
||||
rightType.typeKind() == Type::TypeKind::kVector) {
|
||||
// x - float4(0) -> float4(x)
|
||||
vectorize_left(&b, iter, outUpdated, outNeedsRescan);
|
||||
vectorize_left(&b, iter, optimizationContext);
|
||||
} else {
|
||||
// x - 0 -> x
|
||||
// float4(x) - 0 -> float4(x)
|
||||
// float4(x) - float4(0) -> float4(x)
|
||||
delete_right(&b, iter, outUpdated, outNeedsRescan);
|
||||
delete_right(&b, iter, optimizationContext);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1021,25 +1015,25 @@ void Compiler::simplifyExpression(DefinitionMap& definitions,
|
||||
if (leftType.typeKind() == Type::TypeKind::kScalar &&
|
||||
rightType.typeKind() == Type::TypeKind::kVector) {
|
||||
// x / float4(1) -> float4(x)
|
||||
vectorize_left(&b, iter, outUpdated, outNeedsRescan);
|
||||
vectorize_left(&b, iter, optimizationContext);
|
||||
} else {
|
||||
// x / 1 -> x
|
||||
// float4(x) / 1 -> float4(x)
|
||||
// float4(x) / float4(1) -> float4(x)
|
||||
delete_right(&b, iter, outUpdated, outNeedsRescan);
|
||||
delete_right(&b, iter, optimizationContext);
|
||||
}
|
||||
} else if (is_constant(left, 0)) {
|
||||
if (leftType.typeKind() == Type::TypeKind::kScalar &&
|
||||
rightType.typeKind() == Type::TypeKind::kVector &&
|
||||
!right.hasSideEffects()) {
|
||||
// 0 / float4(x) -> float4(0)
|
||||
vectorize_left(&b, iter, outUpdated, outNeedsRescan);
|
||||
vectorize_left(&b, iter, optimizationContext);
|
||||
} else {
|
||||
// 0 / x -> 0
|
||||
// float4(0) / x -> float4(0)
|
||||
// float4(0) / float4(x) -> float4(0)
|
||||
if (!right.hasSideEffects()) {
|
||||
delete_right(&b, iter, outUpdated, outNeedsRescan);
|
||||
delete_right(&b, iter, optimizationContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1047,25 +1041,25 @@ void Compiler::simplifyExpression(DefinitionMap& definitions,
|
||||
case Token::Kind::TK_PLUSEQ:
|
||||
if (is_constant(right, 0)) {
|
||||
clear_write(left);
|
||||
delete_right(&b, iter, outUpdated, outNeedsRescan);
|
||||
delete_right(&b, iter, optimizationContext);
|
||||
}
|
||||
break;
|
||||
case Token::Kind::TK_MINUSEQ:
|
||||
if (is_constant(right, 0)) {
|
||||
clear_write(left);
|
||||
delete_right(&b, iter, outUpdated, outNeedsRescan);
|
||||
delete_right(&b, iter, optimizationContext);
|
||||
}
|
||||
break;
|
||||
case Token::Kind::TK_STAREQ:
|
||||
if (is_constant(right, 1)) {
|
||||
clear_write(left);
|
||||
delete_right(&b, iter, outUpdated, outNeedsRescan);
|
||||
delete_right(&b, iter, optimizationContext);
|
||||
}
|
||||
break;
|
||||
case Token::Kind::TK_SLASHEQ:
|
||||
if (is_constant(right, 1)) {
|
||||
clear_write(left);
|
||||
delete_right(&b, iter, outUpdated, outNeedsRescan);
|
||||
delete_right(&b, iter, optimizationContext);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -1085,9 +1079,9 @@ void Compiler::simplifyExpression(DefinitionMap& definitions,
|
||||
}
|
||||
}
|
||||
if (identity) {
|
||||
*outUpdated = true;
|
||||
optimizationContext->fUpdated = true;
|
||||
if (!try_replace_expression(&b, iter, &s.base())) {
|
||||
*outNeedsRescan = true;
|
||||
optimizationContext->fNeedsRescan = true;
|
||||
return;
|
||||
}
|
||||
SkASSERT((*iter)->isExpression());
|
||||
@ -1101,11 +1095,11 @@ void Compiler::simplifyExpression(DefinitionMap& definitions,
|
||||
for (int c : s.components()) {
|
||||
final.push_back(base.components()[c]);
|
||||
}
|
||||
*outUpdated = true;
|
||||
optimizationContext->fUpdated = true;
|
||||
std::unique_ptr<Expression> replacement(new Swizzle(*fContext, base.base()->clone(),
|
||||
std::move(final)));
|
||||
if (!try_replace_expression(&b, iter, &replacement)) {
|
||||
*outNeedsRescan = true;
|
||||
optimizationContext->fNeedsRescan = true;
|
||||
return;
|
||||
}
|
||||
SkASSERT((*iter)->isExpression());
|
||||
@ -1278,9 +1272,7 @@ static std::unique_ptr<Statement> block_for_case(SwitchStatement* switchStatemen
|
||||
void Compiler::simplifyStatement(DefinitionMap& definitions,
|
||||
BasicBlock& b,
|
||||
std::vector<BasicBlock::Node>::iterator* iter,
|
||||
std::unordered_set<const Variable*>* undefinedVariables,
|
||||
bool* outUpdated,
|
||||
bool* outNeedsRescan) {
|
||||
OptimizationContext* optimizationContext) {
|
||||
Statement* stmt = (*iter)->statement()->get();
|
||||
switch (stmt->kind()) {
|
||||
case Statement::Kind::kVarDeclaration: {
|
||||
@ -1291,11 +1283,11 @@ void Compiler::simplifyStatement(DefinitionMap& definitions,
|
||||
if (varDecl.value()) {
|
||||
SkASSERT((*iter)->statement()->get() == stmt);
|
||||
if (!b.tryRemoveExpressionBefore(iter, varDecl.value().get())) {
|
||||
*outNeedsRescan = true;
|
||||
optimizationContext->fNeedsRescan = true;
|
||||
}
|
||||
}
|
||||
(*iter)->setStatement(std::unique_ptr<Statement>(new Nop()));
|
||||
*outUpdated = true;
|
||||
optimizationContext->fUpdated = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1313,15 +1305,15 @@ void Compiler::simplifyStatement(DefinitionMap& definitions,
|
||||
(*iter)->setStatement(std::unique_ptr<Statement>(new Nop()));
|
||||
}
|
||||
}
|
||||
*outUpdated = true;
|
||||
*outNeedsRescan = true;
|
||||
optimizationContext->fUpdated = true;
|
||||
optimizationContext->fNeedsRescan = true;
|
||||
break;
|
||||
}
|
||||
if (i.ifFalse() && i.ifFalse()->isEmpty()) {
|
||||
// else block doesn't do anything, remove it
|
||||
i.ifFalse().reset();
|
||||
*outUpdated = true;
|
||||
*outNeedsRescan = true;
|
||||
optimizationContext->fUpdated = true;
|
||||
optimizationContext->fNeedsRescan = true;
|
||||
}
|
||||
if (!i.ifFalse() && i.ifTrue()->isEmpty()) {
|
||||
// if block doesn't do anything, no else block
|
||||
@ -1334,8 +1326,8 @@ void Compiler::simplifyStatement(DefinitionMap& definitions,
|
||||
// statement
|
||||
(*iter)->setStatement(std::unique_ptr<Statement>(new Nop()));
|
||||
}
|
||||
*outUpdated = true;
|
||||
*outNeedsRescan = true;
|
||||
optimizationContext->fUpdated = true;
|
||||
optimizationContext->fNeedsRescan = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1387,8 +1379,8 @@ void Compiler::simplifyStatement(DefinitionMap& definitions,
|
||||
(*iter)->setStatement(std::unique_ptr<Statement>(new Nop()));
|
||||
}
|
||||
}
|
||||
*outUpdated = true;
|
||||
*outNeedsRescan = true;
|
||||
optimizationContext->fUpdated = true;
|
||||
optimizationContext->fNeedsRescan = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1398,11 +1390,11 @@ void Compiler::simplifyStatement(DefinitionMap& definitions,
|
||||
if (!e.expression()->hasSideEffects()) {
|
||||
// Expression statement with no side effects, kill it
|
||||
if (!b.tryRemoveExpressionBefore(iter, e.expression().get())) {
|
||||
*outNeedsRescan = true;
|
||||
optimizationContext->fNeedsRescan = true;
|
||||
}
|
||||
SkASSERT((*iter)->statement()->get() == stmt);
|
||||
(*iter)->setStatement(std::unique_ptr<Statement>(new Nop()));
|
||||
*outUpdated = true;
|
||||
optimizationContext->fUpdated = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1443,17 +1435,15 @@ bool Compiler::scanCFG(FunctionDefinition& f) {
|
||||
}
|
||||
|
||||
// check for dead code & undefined variables, perform constant propagation
|
||||
std::unordered_set<const Variable*> undefinedVariables;
|
||||
bool updated;
|
||||
bool needsRescan = false;
|
||||
OptimizationContext optimizationContext;
|
||||
do {
|
||||
if (needsRescan) {
|
||||
if (optimizationContext.fNeedsRescan) {
|
||||
cfg = CFGGenerator().getCFG(f);
|
||||
this->computeDataFlow(&cfg);
|
||||
needsRescan = false;
|
||||
optimizationContext.fNeedsRescan = false;
|
||||
}
|
||||
|
||||
updated = false;
|
||||
optimizationContext.fUpdated = false;
|
||||
bool first = true;
|
||||
for (BasicBlock& b : cfg.fBlocks) {
|
||||
if (!first && !b.fIsReachable) {
|
||||
@ -1472,31 +1462,31 @@ bool Compiler::scanCFG(FunctionDefinition& f) {
|
||||
first = false;
|
||||
DefinitionMap definitions = b.fBefore;
|
||||
|
||||
for (auto iter = b.fNodes.begin(); iter != b.fNodes.end() && !needsRescan; ++iter) {
|
||||
for (auto iter = b.fNodes.begin(); iter != b.fNodes.end() &&
|
||||
!optimizationContext.fNeedsRescan; ++iter) {
|
||||
if (iter->isExpression()) {
|
||||
this->simplifyExpression(definitions, b, &iter, &undefinedVariables, &updated,
|
||||
&needsRescan);
|
||||
this->simplifyExpression(definitions, b, &iter, &optimizationContext);
|
||||
} else {
|
||||
this->simplifyStatement(definitions, b, &iter, &undefinedVariables, &updated,
|
||||
&needsRescan);
|
||||
this->simplifyStatement(definitions, b, &iter, &optimizationContext);
|
||||
}
|
||||
if (needsRescan) {
|
||||
if (optimizationContext.fNeedsRescan) {
|
||||
break;
|
||||
}
|
||||
this->addDefinitions(*iter, &definitions);
|
||||
}
|
||||
|
||||
if (needsRescan) {
|
||||
if (optimizationContext.fNeedsRescan) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
madeChanges |= updated;
|
||||
} while (updated);
|
||||
SkASSERT(!needsRescan);
|
||||
madeChanges |= optimizationContext.fUpdated;
|
||||
} while (optimizationContext.fUpdated);
|
||||
SkASSERT(!optimizationContext.fNeedsRescan);
|
||||
|
||||
// verify static ifs & switches, clean up dead variable decls
|
||||
for (BasicBlock& b : cfg.fBlocks) {
|
||||
for (auto iter = b.fNodes.begin(); iter != b.fNodes.end() && !needsRescan;) {
|
||||
for (auto iter = b.fNodes.begin(); iter != b.fNodes.end() &&
|
||||
!optimizationContext.fNeedsRescan;) {
|
||||
if (iter->isStatement()) {
|
||||
const Statement& s = **iter->statement();
|
||||
switch (s.kind()) {
|
||||
|
@ -107,6 +107,15 @@ public:
|
||||
String fCoords;
|
||||
};
|
||||
|
||||
struct OptimizationContext {
|
||||
// nodes we have already reported errors for and should not error on again
|
||||
std::unordered_set<const IRNode*> fSilences;
|
||||
// true if we have updated the CFG during this pass
|
||||
bool fUpdated = false;
|
||||
// true if we need to completely regenerate the CFG
|
||||
bool fNeedsRescan = false;
|
||||
};
|
||||
|
||||
#if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
|
||||
/**
|
||||
* Represents the arguments to GrGLSLShaderBuilder::emitFunction.
|
||||
@ -227,9 +236,7 @@ private:
|
||||
void simplifyExpression(DefinitionMap& definitions,
|
||||
BasicBlock& b,
|
||||
std::vector<BasicBlock::Node>::iterator* iter,
|
||||
std::unordered_set<const Variable*>* undefinedVariables,
|
||||
bool* outUpdated,
|
||||
bool* outNeedsRescan);
|
||||
OptimizationContext* context);
|
||||
|
||||
/**
|
||||
* Simplifies the statement pointed to by iter (in both the IR and CFG structures), if
|
||||
@ -238,9 +245,7 @@ private:
|
||||
void simplifyStatement(DefinitionMap& definitions,
|
||||
BasicBlock& b,
|
||||
std::vector<BasicBlock::Node>::iterator* iter,
|
||||
std::unordered_set<const Variable*>* undefinedVariables,
|
||||
bool* outUpdated,
|
||||
bool* outNeedsRescan);
|
||||
OptimizationContext* context);
|
||||
|
||||
/**
|
||||
* Optimizes a function based on control flow analysis. Returns true if changes were made.
|
||||
|
Loading…
Reference in New Issue
Block a user