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); _inlineResulthalf4unpremulhalf40 = half4(inputColor.xyz / max(inputColor.w, 9.9999997473787516e-05), inputColor.w);
} }
inputColor = _inlineResulthalf4unpremulhalf40; inputColor = _inlineResulthalf4unpremulhalf40;
} }

View File

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

View File

@ -1993,9 +1993,9 @@ std::unique_ptr<Expression> IRGenerator::call(int offset,
if (fCanInline && fInliner.isSafeToInline(*funcCall, fSettings->fInlineThreshold)) { if (fCanInline && fInliner.isSafeToInline(*funcCall, fSettings->fInlineThreshold)) {
Inliner::InlinedCall inlinedCall = fInliner.inlineCall(std::move(funcCall), Inliner::InlinedCall inlinedCall = fInliner.inlineCall(std::move(funcCall),
fSymbolTable.get()); fSymbolTable.get());
fExtraStatements.insert(fExtraStatements.end(), if (inlinedCall.fInlinedBody) {
std::make_move_iterator(inlinedCall.fInlinedBody.begin()), fExtraStatements.push_back(std::move(inlinedCall.fInlinedBody));
std::make_move_iterator(inlinedCall.fInlinedBody.end())); }
return std::move(inlinedCall.fReplacementExpr); 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; std::vector<std::unique_ptr<Expression>>& arguments = call->fArguments;
const FunctionDefinition& function = *call->fFunction.fDefinition; const FunctionDefinition& function = *call->fFunction.fDefinition;
InlinedCall inlinedCall; InlinedCall inlinedCall;
std::vector<std::unique_ptr<Statement>> inlinedBody;
// Use unique variable names based on the function signature. Otherwise there are situations in // 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 // 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. // 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)))); std::make_unique<VarDeclarations>(offset, &type, std::move(variables))));
return variableSymbol; 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 // 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 // do { } while (false); and then use break statements to jump to the end in order to
// emulate a goto. // emulate a goto.
inlinedCall.fInlinedBody.push_back(std::make_unique<DoStatement>( inlinedBody.push_back(std::make_unique<DoStatement>(
/*offset=*/-1, /*offset=*/-1,
std::move(inlineBlock), std::move(inlineBlock),
std::make_unique<BoolLiteral>(*fContext, offset, /*value=*/false))); std::make_unique<BoolLiteral>(*fContext, offset, /*value=*/false)));
} else { } else {
// No early returns, so we can just dump the code in. We need to use a block so we don't get // 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. // 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. // Copy the values of `out` parameters into their destinations.
@ -547,7 +548,7 @@ Inliner::InlinedCall Inliner::inlineCall(std::unique_ptr<FunctionCall> call,
continue; continue;
} }
auto varRef = std::make_unique<VariableReference>(offset, *varMap[p]); 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, std::make_unique<BinaryExpression>(offset,
arguments[i]->clone(), arguments[i]->clone(),
Token::Kind::TK_EQ, Token::Kind::TK_EQ,
@ -566,6 +567,19 @@ Inliner::InlinedCall Inliner::inlineCall(std::unique_ptr<FunctionCall> call,
/*value=*/false); /*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; return inlinedCall;
} }

View File

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

View File

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

View File

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