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:
parent
3401d5eb22
commit
708faba16b
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user