Optimize function call return value temporaries (#7152)

This commit is contained in:
Geza Lore 2026-02-28 14:54:39 +00:00 committed by GitHub
parent 1af7fa92c2
commit 139bdc1ae3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 28 additions and 3 deletions

View File

@ -642,6 +642,15 @@ class TaskVisitor final : public VNVisitor {
}
}
bool hasRefArgument(AstNodeFTask* nodep) {
for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp = stmtp->nextp()) {
if (AstVar* const varp = VN_CAST(stmtp, Var)) {
if (varp->isRef() || varp->isConstRef()) return true;
}
}
return false;
}
AstNode* createInlinedFTask(AstNodeFTaskRef* refp, const string& namePrefix,
AstVarScope* outvscp) {
// outvscp is the variable for functions only, if nullptr, it's a task
@ -1543,9 +1552,25 @@ class TaskVisitor final : public VNVisitor {
// Create output variable
AstVarScope* outvscp = nullptr;
if (nodep->taskp()->isFunction()) {
// Not that it's a FUNCREF, but that we're calling a function (perhaps as a task)
outvscp
= createVarScope(VN_AS(nodep->taskp()->fvarp(), Var), namePrefix + "__Vfuncout");
AstVar* const fvarp = VN_AS(nodep->taskp()->fvarp(), Var);
// If the call is on the RHS of a simple assignment 'lhs = call()',
// the LHS variable can be reused as the output variable iff it has
// the same type, and the function does not read the output variable itself.
// This can be proven cheaply if the LHS is an automatic variable and the
// function does not have any ref arguments. This arises a lot after V3LiftExpr.
if (AstAssign* const assignp = VN_CAST(nodep->backp(), Assign)) {
if (AstVarRef* const lhsp = VN_CAST(assignp->lhsp(), VarRef)) {
AstVarScope* const vscp = lhsp->varScopep();
if (vscp->varp()->lifetime().isAutomatic()
&& vscp->varp()->dtypep()->skipRefp()->sameTree(
fvarp->dtypep()->skipRefp())
&& !hasRefArgument(nodep->taskp())) {
outvscp = vscp;
}
}
}
// Otherwise create a new variable for the result
if (!outvscp) outvscp = createVarScope(fvarp, namePrefix + "__Vfuncout");
}
// Create cloned statements
AstNode* beginp;