Optimize dead functions in more cases (#6430)
Signed-off-by: Artur Bieniek <abieniek@internships.antmicro.com>
This commit is contained in:
parent
e24f84f713
commit
08be65a7dd
|
|
@ -39,6 +39,7 @@
|
|||
|
||||
#include "V3Stats.h"
|
||||
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
|
||||
VL_DEFINE_DEBUG_FUNCTIONS;
|
||||
|
|
@ -53,7 +54,7 @@ class DeadVisitor final : public VNVisitor {
|
|||
// AstVar::user1() -> int. Count of number of references
|
||||
// AstVarScope::user1() -> int. Count of number of references
|
||||
// AstNodeDType::user1() -> int. Count of number of references
|
||||
// AstNodeFTask::user1() -> int. Non-zero if ever referenced (called)
|
||||
// AstNodeFTask::user1() -> int. Count of number of references (via AstNodeFTaskRefs)
|
||||
const VNUser1InUse m_inuser1;
|
||||
|
||||
// TYPES
|
||||
|
|
@ -72,7 +73,7 @@ class DeadVisitor final : public VNVisitor {
|
|||
std::vector<AstCell*> m_cellsp;
|
||||
std::vector<AstClass*> m_classesp;
|
||||
std::vector<AstTypedef*> m_typedefsp;
|
||||
std::vector<AstNodeFTask*> m_tasksp; // All the tasks that could be removed if not called
|
||||
std::queue<AstNodeFTask*> m_tasksp; // All the tasks that could be removed if not called
|
||||
AssignMap m_assignMap; // List of all simple assignments for each variable
|
||||
bool m_sideEffect = false; // Side effects discovered in assign RHS
|
||||
|
||||
|
|
@ -173,7 +174,7 @@ class DeadVisitor final : public VNVisitor {
|
|||
void visit(AstNodeFTaskRef* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
checkAll(nodep);
|
||||
if (nodep->taskp()) nodep->taskp()->user1(1);
|
||||
if (nodep->taskp()) nodep->taskp()->user1Inc();
|
||||
if (nodep->classOrPackagep()) {
|
||||
if (m_elimCells) {
|
||||
nodep->classOrPackagep(nullptr);
|
||||
|
|
@ -325,7 +326,7 @@ class DeadVisitor final : public VNVisitor {
|
|||
iterateChildren(nodep);
|
||||
checkAll(nodep);
|
||||
if (!nodep->taskPublic() && !nodep->dpiExport() && !nodep->dpiImport())
|
||||
m_tasksp.push_back(nodep);
|
||||
m_tasksp.push(nodep);
|
||||
if (nodep->classOrPackagep()) {
|
||||
if (m_elimCells) {
|
||||
nodep->classOrPackagep(nullptr);
|
||||
|
|
@ -365,8 +366,17 @@ class DeadVisitor final : public VNVisitor {
|
|||
}
|
||||
|
||||
void deadCheckTasks() {
|
||||
for (AstNodeFTask* taskp : m_tasksp) {
|
||||
if (!taskp->user1() && !taskp->classMethod()) {
|
||||
while (!m_tasksp.empty()) {
|
||||
AstNodeFTask* taskp = m_tasksp.front();
|
||||
m_tasksp.pop();
|
||||
if (taskp->user1() == 0 && !taskp->classMethod()) {
|
||||
taskp->foreach([this](AstNodeFTaskRef* ftaskrefp) {
|
||||
AstNodeFTask* task2p = ftaskrefp->taskp();
|
||||
if (!task2p) return;
|
||||
task2p->user1Inc(-1);
|
||||
if (task2p->user1() == 0) m_tasksp.push(task2p);
|
||||
});
|
||||
taskp->user1(-1); // we don't want to try deleting twice
|
||||
deleting(taskp);
|
||||
m_statFTasksDeadified++;
|
||||
}
|
||||
|
|
@ -611,12 +621,12 @@ void V3Dead::deadifyDTypesScoped(AstNetlist* nodep) {
|
|||
|
||||
void V3Dead::deadifyAll(AstNetlist* nodep) {
|
||||
UINFO(2, __FUNCTION__ << ":");
|
||||
{ DeadVisitor{nodep, true, true, false, true, false, false}; } // Destruct before checking
|
||||
{ DeadVisitor{nodep, true, true, false, true, false, true}; } // Destruct before checking
|
||||
V3Global::dumpCheckGlobalTree("deadAll", 0, dumpTreeEitherLevel() >= 3);
|
||||
}
|
||||
|
||||
void V3Dead::deadifyAllScoped(AstNetlist* nodep) {
|
||||
UINFO(2, __FUNCTION__ << ":");
|
||||
{ DeadVisitor{nodep, true, true, true, true, false, false}; } // Destruct before checking
|
||||
{ DeadVisitor{nodep, true, true, true, true, false, true}; } // Destruct before checking
|
||||
V3Global::dumpCheckGlobalTree("deadAllScoped", 0, dumpTreeEitherLevel() >= 3);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ test.scenarios('simulator')
|
|||
test.compile(verilator_flags2=["--stats"])
|
||||
|
||||
if test.vlt_all:
|
||||
test.file_grep(test.stats, r'Optimizations, deadified FTasks\s+(\d+)', 2)
|
||||
test.file_grep(test.stats, r'Optimizations, deadified FTasks\s+(\d+)', 6)
|
||||
|
||||
test.execute()
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,21 @@ module t (input clk);
|
|||
|
||||
// These should be deadified
|
||||
function deadfunc();
|
||||
deeptask2();
|
||||
endfunction
|
||||
task deadtask;
|
||||
deeptask1();
|
||||
endtask
|
||||
// A chain of dead tasks calling each other to ensure V3Dead can remove chained dead tasks
|
||||
task deeptask1;
|
||||
deeptask2();
|
||||
endtask
|
||||
task deeptask2;
|
||||
deeptask3();
|
||||
endtask
|
||||
task deeptask3;
|
||||
deeptask4();
|
||||
endtask
|
||||
task deeptask4;
|
||||
endtask
|
||||
endmodule
|
||||
|
|
|
|||
Loading…
Reference in New Issue