The inlined function body is now returned as a single Statement.

If only a single statement is necessary, it is returned as-is.
If multiple statements are needed, they are wrapped in a non-scoped
Block statement. If no statements at all are needed (!), null will be
returned.

Change-Id: I6ba373f73d339b8c2e7b8d39dfb28f13655e3d03
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/313911
Commit-Queue: John Stiles <johnstiles@google.com>
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
This commit is contained in:
John Stiles 2020-08-31 14:16:06 -04:00 committed by Skia Commit-Bot
parent 44e96bee4b
commit 39616ec7c9
7 changed files with 38 additions and 10 deletions

View File

@ -47,6 +47,7 @@ public:
{
_inlineResulthalf4unpremulhalf40 = half4(inputColor.xyz / max(inputColor.w, 9.9999997473787516e-05), inputColor.w);
}
inputColor = _inlineResulthalf4unpremulhalf40;
}

View File

@ -56,6 +56,7 @@ half4 _inlineResulthalf4unpremulhalf40;
{
_inlineResulthalf4unpremulhalf40 = half4(inColor.xyz / max(inColor.w, 9.9999997473787516e-05), inColor.w);
}
half4 color = _inlineResulthalf4unpremulhalf40;
@if (%s) {

View File

@ -1993,9 +1993,9 @@ std::unique_ptr<Expression> IRGenerator::call(int offset,
if (fCanInline && fInliner.isSafeToInline(*funcCall, fSettings->fInlineThreshold)) {
Inliner::InlinedCall inlinedCall = fInliner.inlineCall(std::move(funcCall),
fSymbolTable.get());
fExtraStatements.insert(fExtraStatements.end(),
std::make_move_iterator(inlinedCall.fInlinedBody.begin()),
std::make_move_iterator(inlinedCall.fInlinedBody.end()));
if (inlinedCall.fInlinedBody) {
fExtraStatements.push_back(std::move(inlinedCall.fInlinedBody));
}
return std::move(inlinedCall.fReplacementExpr);
}

View File

@ -434,6 +434,7 @@ Inliner::InlinedCall Inliner::inlineCall(std::unique_ptr<FunctionCall> call,
std::vector<std::unique_ptr<Expression>>& arguments = call->fArguments;
const FunctionDefinition& function = *call->fFunction.fDefinition;
InlinedCall inlinedCall;
std::vector<std::unique_ptr<Statement>> inlinedBody;
// Use unique variable names based on the function signature. Otherwise there are situations in
// which an inlined function is later inlined into another function, and we end up with
@ -474,7 +475,7 @@ Inliner::InlinedCall Inliner::inlineCall(std::unique_ptr<FunctionCall> call,
}
// Add the new variable-declaration statement to our block of extra statements.
inlinedCall.fInlinedBody.push_back(std::make_unique<VarDeclarationsStatement>(
inlinedBody.push_back(std::make_unique<VarDeclarationsStatement>(
std::make_unique<VarDeclarations>(offset, &type, std::move(variables))));
return variableSymbol;
@ -525,14 +526,14 @@ Inliner::InlinedCall Inliner::inlineCall(std::unique_ptr<FunctionCall> call,
// used to perform an early return), we fake it by wrapping the function in a
// do { } while (false); and then use break statements to jump to the end in order to
// emulate a goto.
inlinedCall.fInlinedBody.push_back(std::make_unique<DoStatement>(
inlinedBody.push_back(std::make_unique<DoStatement>(
/*offset=*/-1,
std::move(inlineBlock),
std::make_unique<BoolLiteral>(*fContext, offset, /*value=*/false)));
} else {
// No early returns, so we can just dump the code in. We need to use a block so we don't get
// name conflicts with locals.
inlinedCall.fInlinedBody.push_back(std::move(inlineBlock));
inlinedBody.push_back(std::move(inlineBlock));
}
// Copy the values of `out` parameters into their destinations.
@ -547,7 +548,7 @@ Inliner::InlinedCall Inliner::inlineCall(std::unique_ptr<FunctionCall> call,
continue;
}
auto varRef = std::make_unique<VariableReference>(offset, *varMap[p]);
inlinedCall.fInlinedBody.push_back(std::make_unique<ExpressionStatement>(
inlinedBody.push_back(std::make_unique<ExpressionStatement>(
std::make_unique<BinaryExpression>(offset,
arguments[i]->clone(),
Token::Kind::TK_EQ,
@ -566,6 +567,19 @@ Inliner::InlinedCall Inliner::inlineCall(std::unique_ptr<FunctionCall> call,
/*value=*/false);
}
switch (inlinedBody.size()) {
case 0:
break;
case 1:
inlinedCall.fInlinedBody = std::move(inlinedBody.front());
break;
default:
inlinedCall.fInlinedBody = std::make_unique<Block>(offset, std::move(inlinedBody),
/*symbols=*/nullptr,
/*isScope=*/false);
break;
}
return inlinedCall;
}

View File

@ -36,11 +36,11 @@ public:
/**
* Processes the passed-in FunctionCall expression. The FunctionCall expression should be
* replaced with `fReplacementExpr`. Any statements in `fInlinedBody` should be inserted
* immediately above the statement containing the inlined expression.
* replaced with `fReplacementExpr`. If non-null, `fInlinedBody` should be inserted immediately
* above the statement containing the inlined expression.
*/
struct InlinedCall {
std::vector<std::unique_ptr<Statement>> fInlinedBody;
std::unique_ptr<Statement> fInlinedBody;
std::unique_ptr<Expression> fReplacementExpr;
};
InlinedCall inlineCall(std::unique_ptr<FunctionCall>, SymbolTable*);

View File

@ -1049,6 +1049,7 @@ R"SkSL(half4 _inlineResulthalf4fliphalf40;
{
_inlineResulthalf4fliphalf40 = %s.wzyx;
}
%s = _inlineResulthalf4fliphalf40;
)SkSL"
@ -1150,6 +1151,7 @@ R"SkSL(half4 _inlineResulthalf4switchyhalf40;
result = %s.zzzz;
_inlineResulthalf4switchyhalf40 = result;
}
%s = _inlineResulthalf4switchyhalf40;
)SkSL"
@ -1221,6 +1223,7 @@ R"SkSL(half4 _inlineResulthalf4switchyhalf40;
}
_inlineResulthalf4switchyhalf40 = result;
}
%s = _inlineResulthalf4switchyhalf40;
)SkSL"
@ -1257,6 +1260,7 @@ R"SkSL(half4 _inlineResulthalf4loopyhalf40;
pix = %s.zzzz;
_inlineResulthalf4loopyhalf40 = pix;
}
%s = _inlineResulthalf4loopyhalf40;
)SkSL"
@ -1284,6 +1288,7 @@ R"SkSL(half4 _inlineResulthalf4branchyhalf40;
{
if (%s.z == %s.w) _inlineResulthalf4branchyhalf40 = %s.yyyy; else _inlineResulthalf4branchyhalf40 = %s.zzzz;
}
%s = _inlineResulthalf4branchyhalf40;
)SkSL"
@ -1315,6 +1320,7 @@ R"SkSL(half4 _inlineResulthalf4blockyhalf40;
_inlineResulthalf4blockyhalf40 = %s;
}
}
%s = _inlineResulthalf4blockyhalf40;
)SkSL"
@ -1354,6 +1360,7 @@ do {
break;
}
} while (false);
%s = _inlineResulthalf4returnyhalf40;
)SkSL"
@ -1404,6 +1411,7 @@ half4 _inlineArghalf4branchyhalf41_0 = %s;
_inlineArghalf4branchyhalf41_0 *= 0.5;
if (_inlineArghalf4branchyhalf41_0.x > 0.0) _inlineResulthalf4branchyhalf40 = _inlineArghalf4branchyhalf41_0.xxxx; else if (_inlineArghalf4branchyhalf41_0.y > 0.0) _inlineResulthalf4branchyhalf40 = _inlineArghalf4branchyhalf41_0.yyyy; else if (_inlineArghalf4branchyhalf41_0.z > 0.0) _inlineResulthalf4branchyhalf40 = _inlineArghalf4branchyhalf41_0.zzzz; else _inlineResulthalf4branchyhalf40 = _inlineArghalf4branchyhalf41_0.wwww;
}
half4 _inlineResulthalf4branchyAndBlockyhalf42;
{
{
@ -1425,6 +1433,7 @@ half4 _inlineResulthalf4branchyAndBlockyhalf42;
}
}
}
%s = _inlineResulthalf4branchyhalf40 * _inlineResulthalf4branchyAndBlockyhalf42;
)SkSL"

View File

@ -114,6 +114,7 @@ DEF_TEST(SkSLFunctions, r) {
" {\n"
" _inlineResultfloatfoofloat20 = y[0] * y[1];\n"
" }\n"
"\n"
" z = _inlineResultfloatfoofloat20;\n"
"\n"
" x = z;\n"
@ -274,6 +275,7 @@ DEF_TEST(SkSLFunctionInlineArguments, r) {
" _inlineArghalfparameterWritehalf1_0 *= 2.0;\n"
" _inlineResulthalfparameterWritehalf0 = _inlineArghalfparameterWritehalf1_0;\n"
" }\n"
"\n"
" sk_FragColor.x = _inlineResulthalfparameterWritehalf0;\n"
"\n"
"}\n");
@ -329,6 +331,7 @@ DEF_TEST(SkSLFunctionInlineArguments, r) {
" foo(_inlineArghalfbarhalf1_0);\n"
" }\n"
"\n"
"\n"
" sk_FragColor.x = 0.0;\n"
"}\n");
}