2 * yosys -- Yosys Open SYnthesis Suite
4 * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 #include "kernel/register.h"
21 #include "kernel/bitpattern.h"
22 #include "kernel/log.h"
29 PRIVATE_NAMESPACE_BEGIN
31 void proc_rmdead(RTLIL::SwitchRule
*sw
, int &counter
, int &full_case_counter
)
33 BitPatternPool
pool(sw
->signal
);
35 for (size_t i
= 0; i
< sw
->cases
.size(); i
++)
37 bool is_default
= GetSize(sw
->cases
[i
]->compare
) == 0 && (!pool
.empty() || GetSize(sw
->signal
) == 0);
39 for (size_t j
= 0; j
< sw
->cases
[i
]->compare
.size(); j
++) {
40 RTLIL::SigSpec sig
= sw
->cases
[i
]->compare
[j
];
41 if (!sig
.is_fully_const())
44 sw
->cases
[i
]->compare
.erase(sw
->cases
[i
]->compare
.begin() + (j
--));
48 if (sw
->cases
[i
]->compare
.size() == 0) {
50 sw
->cases
.erase(sw
->cases
.begin() + (i
--));
55 // sw->cases[i]->compare.clear();
58 for (auto switch_it
: sw
->cases
[i
]->switches
)
59 proc_rmdead(switch_it
, counter
, full_case_counter
);
65 if (pool
.empty() && !sw
->get_bool_attribute("\\full_case")) {
66 sw
->set_bool_attribute("\\full_case");
71 struct ProcRmdeadPass
: public Pass
{
72 ProcRmdeadPass() : Pass("proc_rmdead", "eliminate dead trees in decision trees") { }
73 void help() YS_OVERRIDE
75 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
77 log(" proc_rmdead [selection]\n");
79 log("This pass identifies unreachable branches in decision trees and removes them.\n");
82 void execute(std::vector
<std::string
> args
, RTLIL::Design
*design
) YS_OVERRIDE
84 log_header(design
, "Executing PROC_RMDEAD pass (remove dead branches from decision trees).\n");
86 extra_args(args
, 1, design
);
88 int total_counter
= 0;
89 for (auto mod
: design
->modules()) {
90 if (!design
->selected(mod
))
92 for (auto &proc_it
: mod
->processes
) {
93 if (!design
->selected(mod
, proc_it
.second
))
95 int counter
= 0, full_case_counter
= 0;
96 for (auto switch_it
: proc_it
.second
->root_case
.switches
)
97 proc_rmdead(switch_it
, counter
, full_case_counter
);
99 log("Removed %d dead cases from process %s in module %s.\n", counter
,
100 log_id(proc_it
.first
), log_id(mod
));
101 if (full_case_counter
> 0)
102 log("Marked %d switch rules as full_case in process %s in module %s.\n",
103 full_case_counter
, log_id(proc_it
.first
), log_id(mod
));
104 total_counter
+= counter
;
108 log("Removed a total of %d dead cases.\n", total_counter
);
112 PRIVATE_NAMESPACE_END