Allow multiple expressions on the same statement to be inlined.

This will allow the inliner to successfully do more work in a single
pass.

Change-Id: I26e8831737c10bdf9a35eebd94ea8b74f6487077
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/386916
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
This commit is contained in:
John Stiles 2021-03-19 09:43:23 -04:00 committed by Skia Commit-Bot
parent 3401d5eb22
commit 708faba16b
3 changed files with 29 additions and 19 deletions

View File

@ -928,7 +928,7 @@ public:
this->addInlineCandidate(expr);
break;
}
case Expression::Kind::kIndex:{
case Expression::Kind::kIndex: {
IndexExpression& indexExpr = (*expr)->as<IndexExpression>();
this->visitExpression(&indexExpr.base());
this->visitExpression(&indexExpr.index());
@ -1076,18 +1076,14 @@ bool Inliner::analyze(const std::vector<std::unique_ptr<ProgramElement>>& elemen
this->buildCandidateList(elements, symbols, usage, &candidateList);
// Inline the candidates where we've determined that it's safe to do so.
std::unordered_set<const std::unique_ptr<Statement>*> enclosingStmtSet;
using StatementRemappingTable = std::unordered_map<std::unique_ptr<Statement>*,
std::unique_ptr<Statement>*>;
StatementRemappingTable statementRemappingTable;
bool madeChanges = false;
for (const InlineCandidate& candidate : candidateList.fCandidates) {
FunctionCall& funcCall = (*candidate.fCandidateExpr)->as<FunctionCall>();
// Inlining two expressions using the same enclosing statement in the same inlining pass
// does not work properly. If this happens, skip it; we'll get it in the next pass.
auto [unusedIter, inserted] = enclosingStmtSet.insert(candidate.fEnclosingStmt);
if (!inserted) {
continue;
}
// Convert the function call to its inlined equivalent.
InlinedCall inlinedCall = this->inlineCall(&funcCall, candidate.fSymbols, *usage,
&candidate.fEnclosingFunction->declaration());
@ -1103,6 +1099,16 @@ bool Inliner::analyze(const std::vector<std::unique_ptr<ProgramElement>>& elemen
// Add references within the inlined body
usage->add(inlinedCall.fInlinedBody.get());
// Look up the enclosing statement; remap it if necessary.
std::unique_ptr<Statement>* enclosingStmt = candidate.fEnclosingStmt;
for (;;) {
auto iter = statementRemappingTable.find(enclosingStmt);
if (iter == statementRemappingTable.end()) {
break;
}
enclosingStmt = iter->second;
}
// Move the enclosing statement to the end of the unscoped Block containing the inlined
// function, then replace the enclosing statement with that Block.
// Before:
@ -1111,14 +1117,18 @@ bool Inliner::analyze(const std::vector<std::unique_ptr<ProgramElement>>& elemen
// After:
// fInlinedBody = null
// fEnclosingStmt = Block{ stmt1, stmt2, stmt3, stmt4 }
inlinedCall.fInlinedBody->children().push_back(std::move(*candidate.fEnclosingStmt));
*candidate.fEnclosingStmt = std::move(inlinedCall.fInlinedBody);
inlinedCall.fInlinedBody->children().push_back(std::move(*enclosingStmt));
*enclosingStmt = std::move(inlinedCall.fInlinedBody);
// Replace the candidate function call with our replacement expression.
usage->replace(candidate.fCandidateExpr->get(), inlinedCall.fReplacementExpr.get());
*candidate.fCandidateExpr = std::move(inlinedCall.fReplacementExpr);
madeChanges = true;
// If anything else pointed at our enclosing statement, it's now pointing at a Block
// containing many other statements as well. Maintain a fix-up table to account for this.
statementRemappingTable[enclosingStmt] = &(*enclosingStmt)->as<Block>().children().back();
// Stop inlining if we've reached our hard cap on new statements.
if (fInlinedStatementCounter >= kInlinedStatementLimit) {
break;

View File

@ -47,8 +47,8 @@ vec4 blend_hue(vec4 src, vec4 dst) {
return vec4((((_blend_set_color_luminance(_blend_set_color_saturation(sda, dsa), alpha, dsa) + dst.xyz) - dsa) + src.xyz) - sda, (src.w + dst.w) - alpha);
}
void main() {
float _0_c = color.x * color.y + color.z;
sk_FragColor = vec4(_0_c);
float _1_c = color.x * color.y + color.z;
sk_FragColor = vec4(_1_c);
sk_FragColor *= 1.25;
sk_FragColor *= color.xxyy * color.w;
sk_FragColor *= color.zzww * color.y;

View File

@ -2,11 +2,11 @@
out vec4 sk_FragColor;
uniform vec4 color;
vec4 main() {
float _0_c = color.x * color.y + color.z;
float a = _0_c;
float _1_c = color.y * color.z + color.w;
float b = _1_c;
float _2_c = color.z * color.w + color.x;
float c = _2_c;
float _1_c = color.x * color.y + color.z;
float a = _1_c;
float _2_c = color.y * color.z + color.w;
float b = _2_c;
float _3_c = color.z * color.w + color.x;
float c = _3_c;
return vec4(a, b, c * c, a * (b * c));
}