Fix O(n*2) analysis in const-bit-op-tree (#6791)
Note this might miss some cases where a sub-tree within an And/Or/Xor tree is optimizeable, but not the whole tree, but in practice this seems to work better than the alternative of keeping a set of failed nodes and bail early.
This commit is contained in:
parent
afc4bed0f8
commit
af1be26b96
|
|
@ -1297,23 +1297,32 @@ class ConstVisitor final : public VNVisitor {
|
|||
if (nodep->widthMin() != 1) return false;
|
||||
if (!v3Global.opt.fConstBitOpTree()) return false;
|
||||
|
||||
string debugPrefix;
|
||||
const int width = nodep->width();
|
||||
AstNodeExpr* rootp = nodep;
|
||||
unsigned externalOps = 0;
|
||||
// Reach past a plain making AND
|
||||
if (const AstAnd* const andp = VN_CAST(nodep, And)) {
|
||||
if (isConst(andp->lhsp(), 1)) {
|
||||
rootp = andp->rhsp();
|
||||
externalOps = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Only optimize if rootp is in fact the root of a tree of identical
|
||||
// operations, otherwise analysis on an eventually unoptimizable unablanced
|
||||
// tree can go O(N^2) as we would re-analyze every time as we move up the
|
||||
// tree, repeatedly re-discover the sub-tree is not optimizable.
|
||||
if (rootp->type() == nodep->backp()->type()) return false;
|
||||
|
||||
std::string debugPrefix;
|
||||
if (debug() >= 9) { // LCOV_EXCL_START
|
||||
static int s_c = 0;
|
||||
debugPrefix = "- matchBitOpTree[";
|
||||
debugPrefix += cvtToStr(++s_c);
|
||||
debugPrefix += "] ";
|
||||
debugPrefix = "- matchBitOpTree[" + std::to_string(++s_c) + "] ";
|
||||
nodep->dumpTree(debugPrefix + "INPUT: ");
|
||||
} // LCOV_EXCL_STOP
|
||||
|
||||
AstNode* newp = nullptr;
|
||||
const AstAnd* const andp = VN_CAST(nodep, And);
|
||||
const int width = nodep->width();
|
||||
if (andp && isConst(andp->lhsp(), 1)) { // 1 & BitOpTree
|
||||
newp = ConstBitOpTreeVisitor::simplify(andp->rhsp(), width, 1, m_statBitOpReduction);
|
||||
} else { // BitOpTree
|
||||
newp = ConstBitOpTreeVisitor::simplify(nodep, width, 0, m_statBitOpReduction);
|
||||
}
|
||||
AstNodeExpr* const newp
|
||||
= ConstBitOpTreeVisitor::simplify(rootp, width, externalOps, m_statBitOpReduction);
|
||||
|
||||
if (newp) {
|
||||
nodep->replaceWithKeepDType(newp);
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ test.compile(verilator_flags2=["-Wno-UNOPTTHREADS", "-fno-dfg", "--stats", test.
|
|||
test.execute()
|
||||
|
||||
if test.vlt:
|
||||
test.file_grep(test.stats, r'Optimizations, Const bit op reduction\s+(\d+)', 44)
|
||||
test.file_grep(test.stats, r'Optimizations, Const bit op reduction\s+(\d+)', 49)
|
||||
test.file_grep(test.stats, r'SplitVar, packed variables split automatically\s+(\d+)', 1)
|
||||
|
||||
test.passes()
|
||||
|
|
|
|||
|
|
@ -16,6 +16,6 @@ test.compile(verilator_flags2=["-Wno-UNOPTTHREADS", "--stats", "--coverage", "--
|
|||
test.execute()
|
||||
|
||||
if test.vlt:
|
||||
test.file_grep(test.stats, r'Optimizations, Const bit op reduction\s+(\d+)', 478)
|
||||
test.file_grep(test.stats, r'Optimizations, Const bit op reduction\s+(\d+)', 550)
|
||||
|
||||
test.passes()
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ test.compile(verilator_flags2=["-Wno-UNOPTTHREADS", "--stats", test.pli_filename
|
|||
test.execute()
|
||||
|
||||
if test.vlt:
|
||||
test.file_grep(test.stats, r'Optimizations, Const bit op reduction\s+(\d+)', 37)
|
||||
test.file_grep(test.stats, r'Optimizations, Const bit op reduction\s+(\d+)', 43)
|
||||
test.file_grep(test.stats, r'SplitVar, packed variables split automatically\s+(\d+)', 1)
|
||||
|
||||
test.passes()
|
||||
|
|
|
|||
|
|
@ -19,6 +19,6 @@ test.compile(verilator_flags2=[
|
|||
test.execute()
|
||||
|
||||
if test.vlt:
|
||||
test.file_grep(test.stats, r'Optimizations, Const bit op reduction\s+(\d+)', 1)
|
||||
test.file_grep(test.stats, r'Optimizations, Const bit op reduction\s+(\d+)', 4)
|
||||
|
||||
test.passes()
|
||||
|
|
|
|||
|
|
@ -16,6 +16,6 @@ test.compile(verilator_flags2=["-Wno-UNOPTTHREADS", "--stats"])
|
|||
test.execute()
|
||||
|
||||
if test.vlt:
|
||||
test.file_grep(test.stats, r'Optimizations, Const bit op reduction\s+(\d+)', 158)
|
||||
test.file_grep(test.stats, r'Optimizations, Const bit op reduction\s+(\d+)', 160)
|
||||
|
||||
test.passes()
|
||||
|
|
|
|||
Loading…
Reference in New Issue