Fix inline function ref port persistence
This commit is contained in:
parent
d2dfcbca53
commit
1e3c7a5496
|
|
@ -198,7 +198,22 @@ private:
|
|||
}
|
||||
// We make multiple edges if a task is called multiple times from another task.
|
||||
UASSERT_OBJ(nodep->taskp(), nodep, "Unlinked task");
|
||||
new TaskEdge{&m_callGraph, m_curVxp, getFTaskVertex(nodep->taskp())};
|
||||
TaskFTaskVertex* const taskVtxp = getFTaskVertex(nodep->taskp());
|
||||
new TaskEdge{&m_callGraph, m_curVxp, taskVtxp};
|
||||
// Do we have to disable inlining the function?
|
||||
const V3TaskConnects tconnects = V3Task::taskConnects(nodep, nodep->taskp()->stmtsp());
|
||||
if (!taskVtxp->noInline()) { // Else short-circuit below
|
||||
for (const auto& itr : tconnects) {
|
||||
const AstVar* const portp = itr.first;
|
||||
const AstArg* const argp = itr.second;
|
||||
if (const AstNodeExpr* const pinp = argp->exprp()) {
|
||||
if ((portp->isRef() || portp->isConstRef()) && !VN_IS(pinp, VarRef)) {
|
||||
UINFO(9, "No function inline due to ref " << pinp << endl);
|
||||
taskVtxp->noInline(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void visit(AstNodeFTask* nodep) override {
|
||||
UINFO(9, " TASK " << nodep << endl);
|
||||
|
|
@ -494,12 +509,7 @@ class TaskVisitor final : public VNVisitor {
|
|||
UASSERT_OBJ(localVscp, varrefp, "Null var scope");
|
||||
portp->user2p(localVscp);
|
||||
} else {
|
||||
pinp->v3warn(E_TASKNSVAR, "Unsupported: ref argument of inlined "
|
||||
"function/task is not a simple variable");
|
||||
// Providing a var to avoid an internal error.
|
||||
AstVarScope* const newvscp
|
||||
= createVarScope(portp, namePrefix + "__" + portp->shortName());
|
||||
portp->user2p(newvscp);
|
||||
pinp->v3fatalSrc("ref argument should have caused non-inline of function");
|
||||
}
|
||||
}
|
||||
} else if (portp->isInoutish()) {
|
||||
|
|
|
|||
|
|
@ -1,18 +1,20 @@
|
|||
#!/usr/bin/perl
|
||||
#!/usr/bin/env perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Copyright 2024 by Wilson Snyder. This program is free software; you
|
||||
# can redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
scenarios(vlt => 1);
|
||||
scenarios(simulator => 1);
|
||||
|
||||
lint(
|
||||
fails => 1,
|
||||
expect_filename => $Self->{golden_filename},
|
||||
compile(
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
%Error-TASKNSVAR: t/t_func_ref_unsup.v:29:28: Unsupported: ref argument of inlined function/task is not a simple variable
|
||||
29 | b = get_val_set_5(mi.x);
|
||||
| ^
|
||||
... For error description see https://verilator.org/warn/TASKNSVAR?v=latest
|
||||
%Error-TASKNSVAR: t/t_func_ref_unsup.v:34:28: Unsupported: ref argument of inlined function/task is not a simple variable
|
||||
34 | b = get_val_set_5(arr[0]);
|
||||
| ^
|
||||
%Error: Exiting due to
|
||||
|
|
@ -9,7 +9,8 @@
|
|||
|
||||
module t(/*AUTOARG*/);
|
||||
|
||||
int q[$];
|
||||
int qdel[$];
|
||||
int qkept[$];
|
||||
|
||||
task automatic func(ref int vrefed);
|
||||
`ifdef TEST_NOINLINE
|
||||
|
|
@ -18,23 +19,35 @@ module t(/*AUTOARG*/);
|
|||
`checkd(vrefed, 2);
|
||||
#100;
|
||||
vrefed = 10;
|
||||
#10;
|
||||
`checkd(vrefed, 10);
|
||||
endtask
|
||||
|
||||
initial begin
|
||||
q.push_back(1);
|
||||
q.push_back(2);
|
||||
q.push_back(3);
|
||||
`checkd(q[0], 1);
|
||||
`checkd(q[1], 2);
|
||||
`checkd(q[2], 3);
|
||||
func(q[1]);
|
||||
qkept.push_back(1);
|
||||
qkept.push_back(2);
|
||||
qkept.push_back(3);
|
||||
qdel = qkept;
|
||||
$display("qkept=%p qdel=%p", qkept, qdel);
|
||||
`checkd(qkept[0], 1);
|
||||
`checkd(qkept[1], 2);
|
||||
`checkd(qkept[2], 3);
|
||||
|
||||
func(qdel[1]);
|
||||
func(qkept[1]);
|
||||
|
||||
$display("qkept=%p qdel=%p", qkept, qdel);
|
||||
`checkd(qdel.size, 0);
|
||||
`checkd(qkept[0], 1);
|
||||
`checkd(qkept[1], 10);
|
||||
`checkd(qkept[2], 3);
|
||||
end
|
||||
|
||||
initial begin
|
||||
#50;
|
||||
`checkd(q[1], 2);
|
||||
q.delete();
|
||||
`checkd(qdel[1], 2);
|
||||
`checkd(qkept[1], 2);
|
||||
qdel.delete();
|
||||
#100;
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
|
|
|
|||
|
|
@ -18,9 +18,11 @@ if (!$Self->have_coroutines) {
|
|||
else {
|
||||
compile(
|
||||
timing_loop => 1,
|
||||
verilator_flags2 => ["--binary --timing"],
|
||||
fails => 1, # bug3385 need to fix "ref"
|
||||
expect_filename => $Self->{golden_filename},
|
||||
verilator_flags2 => ["--timing"],
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
%Error-TASKNSVAR: t/t_queue_persistence.v:31:13: Unsupported: ref argument of inlined function/task is not a simple variable
|
||||
31 | func(q[1]);
|
||||
| ^
|
||||
... For error description see https://verilator.org/warn/TASKNSVAR?v=latest
|
||||
%Error: Exiting due to
|
||||
Loading…
Reference in New Issue