diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8393ec3f8..713fc60f2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -82,7 +82,6 @@ set(HEADERS V3DfgDataType.h V3DfgOptimizer.h V3DfgPasses.h - V3DfgPatternStats.h V3DfgPeepholePatterns.h V3DfgVertices.h V3DiagSarif.h @@ -250,6 +249,7 @@ set(COMMON_SOURCES V3DfgDataType.cpp V3DfgDecomposition.cpp V3DfgDfgToAst.cpp + V3DfgDumpPatterns.cpp V3DfgOptimizer.cpp V3DfgPasses.cpp V3DfgPeephole.cpp diff --git a/src/Makefile_obj.in b/src/Makefile_obj.in index 00ae0273c..dd3895c0d 100644 --- a/src/Makefile_obj.in +++ b/src/Makefile_obj.in @@ -263,6 +263,7 @@ RAW_OBJS_PCH_ASTNOMT = \ V3DfgDataType.o \ V3DfgDecomposition.o \ V3DfgDfgToAst.o \ + V3DfgDumpPatterns.o \ V3DfgOptimizer.o \ V3DfgPasses.o \ V3DfgPeephole.o \ diff --git a/src/V3DfgContext.h b/src/V3DfgContext.h index 46de10ccc..dc1b54666 100644 --- a/src/V3DfgContext.h +++ b/src/V3DfgContext.h @@ -25,11 +25,12 @@ #include "config_build.h" #include "verilatedos.h" -#include "V3DfgPatternStats.h" +#include "V3Ast.h" #include "V3DfgPeepholePatterns.h" +#include "V3Error.h" #include "V3File.h" +#include "V3Global.h" #include "V3Stats.h" -#include "V3String.h" class V3DfgContext; diff --git a/src/V3DfgPatternStats.h b/src/V3DfgDumpPatterns.cpp similarity index 89% rename from src/V3DfgPatternStats.h rename to src/V3DfgDumpPatterns.cpp index 8af8a4571..be7e765c3 100644 --- a/src/V3DfgPatternStats.h +++ b/src/V3DfgDumpPatterns.cpp @@ -18,6 +18,7 @@ #define VERILATOR_V3DFGPATTERNSTATS_H_ #include "V3Dfg.h" +#include "V3DfgPasses.h" #include "V3File.h" #include @@ -29,7 +30,6 @@ class V3DfgPatternStats final { static constexpr uint32_t MAX_PATTERN_DEPTH = 4; std::map m_internedConsts; // Interned constants - std::map m_internedVars; // Interned variables std::map m_internedSelLsbs; // Interned lsb value for selects std::map m_internedWordWidths; // Interned widths std::map m_internedWideWidths; // Interned widths @@ -51,12 +51,6 @@ class V3DfgPatternStats final { return pair.first->second; } - const std::string& internVar(const DfgVertexVar& vtx) { - const auto pair = m_internedVars.emplace(vtx.vscp(), "v"); - if (pair.second) pair.first->second += toLetters(m_internedVars.size() - 1); - return pair.first->second; - } - const std::string& internSelLsb(uint32_t value) { const auto pair = m_internedSelLsbs.emplace(value, ""); if (pair.second) pair.first->second += toLetters(m_internedSelLsbs.size() - 1); @@ -76,7 +70,7 @@ class V3DfgPatternStats final { } const std::string& internVertex(const DfgVertex& vtx) { - const auto pair = m_internedVertices.emplace(&vtx, "_"); + const auto pair = m_internedVertices.emplace(&vtx, ""); if (pair.second) pair.first->second += toLetters(m_internedVertices.size() - 1); return pair.first->second; } @@ -95,12 +89,9 @@ class V3DfgPatternStats final { } else { ss << internConst(*constp); } - } else if (const DfgVertexVar* const varp = vtx.cast()) { - // Base case 2: variable - ss << internVar(*varp); } else if (depth == 0) { - // Base case 3: deep vertex - ss << internVertex(vtx); + // Base case 2: deep vertex + ss << "_"; } else { // Recursively print an S-expression for the vertex @@ -117,7 +108,6 @@ class V3DfgPatternStats final { ss << internSelLsb(selp->lsb()); } } - // Operands vtx.foreachSource([&](const DfgVertex& src) { ss << ' '; @@ -126,13 +116,14 @@ class V3DfgPatternStats final { }); // S-expression end ss << ')'; - - // Mark it if it has multiple sinks - if (vtx.hasMultipleSinks()) ss << '*'; } + // Annotate identity + ss << ":" << internVertex(vtx); + // Mark it if it has multiple sinks + if (vtx.hasMultipleSinks()) ss << '*'; // Annotate type - ss << ':'; + ss << '/'; if (!vtx.dtype().isPacked()) { vtx.dtype().astDtypep()->dumpSmall(ss); } else { @@ -196,7 +187,6 @@ public: std::ostringstream ss; if (render(ss, vtx, i)) m_patterCounts[i][ss.str()] += 1; m_internedConsts.clear(); - m_internedVars.clear(); m_internedSelLsbs.clear(); m_internedWordWidths.clear(); m_internedWideWidths.clear(); @@ -206,4 +196,9 @@ public: } }; +void V3DfgPasses::dumpPatterns(const std::vector>& graphs) { + V3DfgPatternStats patternStats; + for (auto& cp : graphs) patternStats.accumulate(*cp); +} + #endif diff --git a/src/V3DfgOptimizer.cpp b/src/V3DfgOptimizer.cpp index e32a64be9..7c4daaedd 100644 --- a/src/V3DfgOptimizer.cpp +++ b/src/V3DfgOptimizer.cpp @@ -363,19 +363,16 @@ class DataflowOptimize final { endOfStage("binToOneHot", dfg, acyclicComps); for (auto& cp : acyclicComps) V3DfgPasses::peephole(*cp, m_ctx.m_peepholeContext); endOfStage("peephole", dfg, acyclicComps); + // Accumulate patterns for reporting + if (v3Global.opt.stats()) { + V3DfgPasses::dumpPatterns(acyclicComps); + endOfStage("patterns"); + } for (auto& cp : acyclicComps) V3DfgPasses::pushDownSels(*cp, m_ctx.m_pushDownSelsContext); endOfStage("pushDownSels", dfg, acyclicComps); for (auto& cp : acyclicComps) V3DfgPasses::cse(*cp, m_ctx.m_cseContext1); endOfStage("cse1", dfg, acyclicComps); - // Accumulate patterns for reporting - if (v3Global.opt.stats()) { - { - V3DfgPatternStats patternStats; - for (auto& cp : acyclicComps) patternStats.accumulate(*cp); - } - endOfStage("patterns"); - } // Merge everything back under the main DFG dfg.mergeGraphs(std::move(acyclicComps)); diff --git a/src/V3DfgPasses.h b/src/V3DfgPasses.h index cd0378248..a7d2b04fb 100644 --- a/src/V3DfgPasses.h +++ b/src/V3DfgPasses.h @@ -20,6 +20,8 @@ #include "config_build.h" #include "verilatedos.h" +#include "V3Ast.h" +#include "V3Dfg.h" #include "V3DfgContext.h" class AstModule; @@ -62,6 +64,8 @@ void peephole(DfgGraph&, V3DfgPeepholeContext&) VL_MT_DISABLED; void regularize(DfgGraph&, V3DfgRegularizeContext&) VL_MT_DISABLED; // Convert DfgGraph back into Ast, and insert converted graph back into the Ast. void dfgToAst(DfgGraph&, V3DfgContext&) VL_MT_DISABLED; +// Dump the patterns in the given graphs +void dumpPatterns(const std::vector>&) VL_MT_DISABLED; //=========================================================================== // Intermediate/internal operations diff --git a/test_regress/t/t_dfg_stats_patterns.out b/test_regress/t/t_dfg_stats_patterns.out index dc228e88a..c18754212 100644 --- a/test_regress/t/t_dfg_stats_patterns.out +++ b/test_regress/t/t_dfg_stats_patterns.out @@ -1,98 +1,121 @@ DFG patterns with depth 1 - 9 (CONCAT _A:1 _B:a):b - 8 (REDXOR _A:a):1 - 3 (NOT vA:a)*:a - 2 (AND _A:a _B:a):a - 1 (AND _A:a _B:a)*:a - 1 (CONCAT _A:1 _B:1):a - 1 (NOT _A:a):a - 1 (REDXOR _A:a)*:1 - 1 (REPLICATE _A:1 cA:a)*:b - 1 (REPLICATE _A:a cA:a)*:b - 1 (REPLICATE _A:a cA:a):b - 1 (REPLICATE _A:a cA:b)*:b - 1 (REPLICATE _A:a cA:b)*:c - 1 (SEL@0 _A:a):1 - 1 (SEL@0 _A:a):b - 1 (SEL@A _A:a):1 + 8 (CONCAT _:A/1 _:B/a):C/b + 5 (REDXOR _:A*/a):B/1 + 5 (VARPACKED _:A*/a):B/a + 3 (NOT _:A/a):B*/a + 3 (REDXOR _:A/a):B/1 + 2 (AND _:A*/a _:B*/a):C/a + 1 (AND _:A*/a _:B*/a):C*/a + 1 (CONCAT _:A*/1 _:B/a):C/b + 1 (CONCAT _:A/1 _:B*/1):C/a + 1 (NOT _:A*/a):B/a + 1 (REDXOR _:A/a):B*/1 + 1 (REPLICATE _:A*/a cA:B/a):C/b + 1 (REPLICATE _:A*/a cA:B/b):C*/b + 1 (REPLICATE _:A*/a cA:B/b):C*/c + 1 (REPLICATE _:A/1 cA:B/a):C*/b + 1 (REPLICATE _:A/a cA:B/a):C*/b + 1 (SEL@0 _:A*/a):B/1 + 1 (SEL@0 _:A*/a):B/b + 1 (SEL@A _:A*/a):B/1 + 1 (VARPACKED _:A/a):B/a DFG patterns with depth 2 - 6 (CONCAT (REDXOR _A:a):1 (CONCAT _B:1 _C:b):c):d - 2 (AND (NOT vA:a)*:a (NOT vB:a)*:a):a - 2 (REDXOR (AND _A:a _B:a):a):1 - 1 (AND (NOT vA:a)*:a (NOT vB:a)*:a)*:a - 1 (CONCAT (REDXOR _A:a)*:1 (CONCAT _B:1 _C:b):c):d - 1 (CONCAT (REDXOR _A:a):1 (CONCAT _B:1 _C:1):b):c - 1 (CONCAT (REDXOR _A:a):1 (REDXOR _B:b)*:1):c - 1 (CONCAT (SEL@0 _A:a):1 (CONCAT _B:1 _C:b):c):d - 1 (NOT (REPLICATE _A:a cA:b)*:b):b - 1 (REDXOR (AND _A:a _B:a)*:a):1 - 1 (REDXOR (REPLICATE _A:1 cA:a)*:b):1 - 1 (REDXOR (REPLICATE _A:a cA:a)*:b):1 - 1 (REDXOR (REPLICATE _A:a cA:a):b)*:1 - 1 (REDXOR (REPLICATE _A:a cA:b)*:b):1 - 1 (REDXOR (REPLICATE _A:a cA:b)*:c):1 - 1 (REDXOR (SEL@0 _A:a):b):1 - 1 (REPLICATE (NOT _A:a):a cA:a)*:b - 1 (REPLICATE (REPLICATE _A:1 cA:a)*:b cB:a)*:c - 1 (REPLICATE (REPLICATE _A:a cA:b)*:b cA:b):c - 1 (REPLICATE (REPLICATE _A:a cA:b)*:c cA:b)*:b - 1 (REPLICATE (SEL@A _A:a):1 cA:b)*:c - 1 (SEL@0 (AND _A:a _B:a)*:a):1 - 1 (SEL@0 (REPLICATE _A:a cA:a)*:b):c - 1 (SEL@A (AND _A:a _B:a)*:a):1 + 3 (CONCAT (REDXOR _:A*/a):B/1 (CONCAT _:C/1 _:D/b):E/c):F/d + 2 (AND (NOT _:A/a):B*/a (NOT _:C/a):D*/a):E/a + 2 (CONCAT (REDXOR _:A/a):B/1 (CONCAT _:C/1 _:D/b):E/c):F/d + 2 (REDXOR (AND _:A*/a _:B*/a):C/a):D/1 + 1 (AND (NOT _:A/a):B*/a (NOT _:C/a):D*/a):E*/a + 1 (CONCAT (REDXOR _:A*/a):B/1 (CONCAT _:C*/1 _:D/b):E/c):F/d + 1 (CONCAT (REDXOR _:A*/a):B/1 (CONCAT _:C/1 _:D*/1):E/b):F/c + 1 (CONCAT (REDXOR _:A/a):B*/1 (CONCAT _:C/1 _:D/b):E/c):F/d + 1 (CONCAT (REDXOR _:A/a):B/1 (REDXOR _:C/b):D*/1):E/c + 1 (CONCAT (SEL@0 _:A*/a):B/1 (CONCAT _:C/1 _:D/b):E/c):F/d + 1 (NOT (REPLICATE _:A*/a cA:B/b):C*/b):D/b + 1 (REDXOR (AND _:A*/a _:B*/a):C*/a):D/1 + 1 (REDXOR (REPLICATE _:A*/a cA:B/a):C/b):D*/1 + 1 (REDXOR (REPLICATE _:A*/a cA:B/b):C*/b):D/1 + 1 (REDXOR (REPLICATE _:A*/a cA:B/b):C*/c):D/1 + 1 (REDXOR (REPLICATE _:A/1 cA:B/a):C*/b):D/1 + 1 (REDXOR (REPLICATE _:A/a cA:B/a):C*/b):D/1 + 1 (REDXOR (SEL@0 _:A*/a):B/b):C/1 + 1 (REPLICATE (NOT _:A*/a):B/a cA:C/a):D*/b + 1 (REPLICATE (REPLICATE _:A*/a cA:B/b):C*/b cA:D/b):E/c + 1 (REPLICATE (REPLICATE _:A*/a cA:B/b):C*/c cA:D/b):E*/b + 1 (REPLICATE (REPLICATE _:A/1 cA:B/a):C*/b cB:D/a):E*/c + 1 (REPLICATE (SEL@A _:A*/a):B/1 cA:C/b):D*/c + 1 (SEL@0 (AND _:A*/a _:B*/a):C*/a):D/1 + 1 (SEL@0 (REPLICATE _:A/a cA:B/a):C*/b):D/c + 1 (SEL@A (AND _:A*/a _:B*/a):C*/a):D/1 + 1 (VARPACKED (AND _:A*/a _:B*/a):C*/a):D/a + 1 (VARPACKED (CONCAT _:A/1 _:B/a):C/b):D/b + 1 (VARPACKED (REPLICATE _:A*/a cA:B/b):C*/b):D/b + 1 (VARPACKED (REPLICATE _:A*/a cA:B/b):C*/c):D/c + 1 (VARPACKED (REPLICATE _:A/1 cA:B/a):C*/b):D/b + 1 (VARPACKED (REPLICATE _:A/a cA:B/a):C*/b):D/b DFG patterns with depth 3 - 2 (REDXOR (AND (NOT vA:a)*:a (NOT vB:a)*:a):a):1 - 1 (CONCAT (REDXOR (AND _A:a _B:a)*:a):1 (CONCAT (REDXOR _C:a):1 (CONCAT _D:1 _E:b):c):d):e - 1 (CONCAT (REDXOR (AND _A:a _B:a):a):1 (CONCAT (REDXOR _C:a):1 (CONCAT _D:1 _E:b):c):d):e - 1 (CONCAT (REDXOR (AND _A:a _B:a):a):1 (CONCAT (SEL@0 _C:a):1 (CONCAT _D:1 _E:b):c):d):e - 1 (CONCAT (REDXOR (REPLICATE _A:1 cA:a)*:b):1 (CONCAT (REDXOR _B:c):1 (CONCAT _C:1 _D:d):e):f):g - 1 (CONCAT (REDXOR (REPLICATE _A:a cA:a)*:b):1 (CONCAT (REDXOR _B:c):1 (REDXOR _C:b)*:1):d):e - 1 (CONCAT (REDXOR (REPLICATE _A:a cA:a):b)*:1 (CONCAT (REDXOR _B:b):1 (CONCAT _C:1 _D:1):c):d):e - 1 (CONCAT (REDXOR (REPLICATE _A:a cA:b)*:b):1 (CONCAT (REDXOR _B:c)*:1 (CONCAT _C:1 _D:d):e):f):g - 1 (CONCAT (REDXOR (REPLICATE _A:a cA:b)*:c):1 (CONCAT (REDXOR _B:b):1 (CONCAT _C:1 _D:d):e):f):g - 1 (CONCAT (REDXOR (SEL@0 _A:a):b):1 (REDXOR (REPLICATE _B:c cA:c):a)*:1):d - 1 (CONCAT (SEL@0 (AND _A:a _B:a)*:a):1 (CONCAT (REDXOR _C:b):1 (CONCAT _D:1 _E:c):d):e):b - 1 (NOT (REPLICATE (REPLICATE _A:a cA:b)*:c cA:b)*:b):b - 1 (REDXOR (AND (NOT vA:a)*:a (NOT vB:a)*:a)*:a):1 - 1 (REDXOR (REPLICATE (NOT _A:a):a cA:a)*:b):1 - 1 (REDXOR (REPLICATE (REPLICATE _A:1 cA:a)*:b cB:a)*:c):1 - 1 (REDXOR (REPLICATE (REPLICATE _A:a cA:b)*:b cA:b):c)*:1 - 1 (REDXOR (REPLICATE (REPLICATE _A:a cA:b)*:c cA:b)*:b):1 - 1 (REDXOR (REPLICATE (SEL@A _A:a):1 cA:b)*:c):1 - 1 (REDXOR (SEL@0 (REPLICATE _A:a cA:a)*:b):c):1 - 1 (REPLICATE (NOT (REPLICATE _A:a cA:b)*:b):b cA:b)*:c - 1 (REPLICATE (REPLICATE (REPLICATE _A:1 cA:a)*:b cB:a)*:c cB:a)*:a - 1 (REPLICATE (REPLICATE (REPLICATE _A:a cA:b)*:c cA:b)*:b cA:b):d - 1 (REPLICATE (REPLICATE (SEL@A _A:a):1 cA:b)*:c cB:b)*:d - 1 (REPLICATE (SEL@A (AND _A:a _B:a)*:a):1 cA:b)*:c - 1 (SEL@0 (AND (NOT vA:a)*:a (NOT vB:a)*:a)*:a):1 - 1 (SEL@0 (REPLICATE (NOT _A:a):a cA:a)*:b):c - 1 (SEL@A (AND (NOT vA:a)*:a (NOT vB:a)*:a)*:a):1 + 2 (REDXOR (AND (NOT _:A/a):B*/a (NOT _:C/a):D*/a):E/a):F/1 + 1 (CONCAT (REDXOR (AND _:A*/a _:B*/a):C*/a):D/1 (CONCAT (REDXOR _:E/a):F/1 (CONCAT _:G/1 _:H/b):I/c):J/d):K/e + 1 (CONCAT (REDXOR (AND _:A*/a _:B*/a):C/a):D/1 (CONCAT (REDXOR _:E/a):F/1 (CONCAT _:G/1 _:H/b):I/c):J/d):K/e + 1 (CONCAT (REDXOR (AND _:A*/a _:B*/a):C/a):D/1 (CONCAT (SEL@0 _:E*/a):F/1 (CONCAT _:G/1 _:H/b):I/c):J/d):K/e + 1 (CONCAT (REDXOR (REPLICATE _:A*/a cA:B/a):C/b):D*/1 (CONCAT (REDXOR _:E*/b):F/1 (CONCAT _:G/1 _:D*/1):H/c):I/d):J/e + 1 (CONCAT (REDXOR (REPLICATE _:A*/a cA:B/b):C*/b):D/1 (CONCAT (REDXOR _:E/c):F*/1 (CONCAT _:G/1 _:H/d):I/e):J/f):K/g + 1 (CONCAT (REDXOR (REPLICATE _:A*/a cA:B/b):C*/c):D/1 (CONCAT (REDXOR _:E*/b):F/1 (CONCAT _:G*/1 _:H/d):I/e):J/f):K/g + 1 (CONCAT (REDXOR (REPLICATE _:A/1 cA:B/a):C*/b):D/1 (CONCAT (REDXOR _:E*/c):F/1 (CONCAT _:G/1 _:H/d):I/e):J/f):K/g + 1 (CONCAT (REDXOR (REPLICATE _:A/a cA:B/a):C*/b):D/1 (CONCAT (REDXOR _:E/c):F/1 (REDXOR _:G/b):H*/1):I/d):J/e + 1 (CONCAT (REDXOR (SEL@0 _:A*/a):B/b):C/1 (REDXOR (REPLICATE _:D*/c cA:E/c):F/a):G*/1):H/d + 1 (CONCAT (SEL@0 (AND _:A*/a _:B*/a):C*/a):D/1 (CONCAT (REDXOR _:E*/b):F/1 (CONCAT _:G/1 _:H/c):I/d):J/e):K/b + 1 (NOT (REPLICATE (REPLICATE _:A*/a cA:B/b):C*/c cA:D/b):E*/b):F/b + 1 (REDXOR (AND (NOT _:A/a):B*/a (NOT _:C/a):D*/a):E*/a):F/1 + 1 (REDXOR (REPLICATE (NOT _:A*/a):B/a cA:C/a):D*/b):E/1 + 1 (REDXOR (REPLICATE (REPLICATE _:A*/a cA:B/b):C*/b cA:D/b):E/c):F*/1 + 1 (REDXOR (REPLICATE (REPLICATE _:A*/a cA:B/b):C*/c cA:D/b):E*/b):F/1 + 1 (REDXOR (REPLICATE (REPLICATE _:A/1 cA:B/a):C*/b cB:D/a):E*/c):F/1 + 1 (REDXOR (REPLICATE (SEL@A _:A*/a):B/1 cA:C/b):D*/c):E/1 + 1 (REDXOR (SEL@0 (REPLICATE _:A/a cA:B/a):C*/b):D/c):E/1 + 1 (REPLICATE (NOT (REPLICATE _:A*/a cA:B/b):C*/b):D/b cA:E/b):F*/c + 1 (REPLICATE (REPLICATE (REPLICATE _:A*/a cA:B/b):C*/c cA:D/b):E*/b cA:F/b):G/d + 1 (REPLICATE (REPLICATE (REPLICATE _:A/1 cA:B/a):C*/b cB:D/a):E*/c cB:F/a):G*/a + 1 (REPLICATE (REPLICATE (SEL@A _:A*/a):B/1 cA:C/b):D*/c cB:E/b):F*/d + 1 (REPLICATE (SEL@A (AND _:A*/a _:B*/a):C*/a):D/1 cA:E/b):F*/c + 1 (SEL@0 (AND (NOT _:A/a):B*/a (NOT _:C/a):D*/a):E*/a):F/1 + 1 (SEL@0 (REPLICATE (NOT _:A*/a):B/a cA:C/a):D*/b):E/c + 1 (SEL@A (AND (NOT _:A/a):B*/a (NOT _:C/a):D*/a):E*/a):F/1 + 1 (VARPACKED (AND (NOT _:A/a):B*/a (NOT _:C/a):D*/a):E*/a):F/a + 1 (VARPACKED (CONCAT (REDXOR _:A*/a):B/1 (CONCAT _:C/1 _:D/b):E/c):F/d):G/d + 1 (VARPACKED (REPLICATE (NOT _:A*/a):B/a cA:C/a):D*/b):E/b + 1 (VARPACKED (REPLICATE (REPLICATE _:A*/a cA:B/b):C*/c cA:D/b):E*/b):F/b + 1 (VARPACKED (REPLICATE (REPLICATE _:A/1 cA:B/a):C*/b cB:D/a):E*/c):F/c + 1 (VARPACKED (REPLICATE (SEL@A _:A*/a):B/1 cA:C/b):D*/c):E/c DFG patterns with depth 4 - 1 (CONCAT (REDXOR (AND (NOT vA:a)*:a (NOT vB:a)*:a)*:a):1 (CONCAT (REDXOR (AND _A:a _B:a):a):1 (CONCAT (REDXOR _C:a):1 (CONCAT _D:1 _E:b):c):d):e):f - 1 (CONCAT (REDXOR (AND (NOT vA:a)*:a (NOT vB:a)*:a):a):1 (CONCAT (REDXOR (AND _A:a _B:a):a):1 (CONCAT (SEL@0 _C:a):1 (CONCAT _D:1 _E:b):c):d):e):f - 1 (CONCAT (REDXOR (AND (NOT vA:a)*:a (NOT vB:a)*:a):a):1 (CONCAT (SEL@0 (AND _A:a _B:a)*:a):1 (CONCAT (REDXOR _C:b):1 (CONCAT _D:1 _E:c):d):e):b):f - 1 (CONCAT (REDXOR (REPLICATE (NOT _A:a):a cA:a)*:b):1 (CONCAT (REDXOR (SEL@0 _B:b):c):1 (REDXOR (REPLICATE _A:a cA:a):b)*:1):d):e - 1 (CONCAT (REDXOR (REPLICATE (REPLICATE _A:1 cA:a)*:b cB:a)*:c):1 (CONCAT (REDXOR (REPLICATE _B:c cB:a)*:a):1 (CONCAT (REDXOR _C:d)*:1 (CONCAT _D:1 _E:e):f):g):h):i - 1 (CONCAT (REDXOR (REPLICATE (REPLICATE _A:a cA:b)*:b cA:b):c)*:1 (CONCAT (REDXOR (REPLICATE _B:b cA:b)*:c):1 (CONCAT (REDXOR _C:d):1 (REDXOR _D:c)*:1):e):f):g - 1 (CONCAT (REDXOR (REPLICATE (REPLICATE _A:a cA:b)*:c cA:b)*:b):1 (CONCAT (REDXOR (REPLICATE _B:b cA:b):d)*:1 (CONCAT (REDXOR _C:d):1 (CONCAT _D:1 _E:1):e):f):g):h - 1 (CONCAT (REDXOR (REPLICATE (SEL@A _A:a):1 cA:b)*:c):1 (CONCAT (REDXOR (REPLICATE _B:c cB:b)*:d):1 (CONCAT (REDXOR _C:b):1 (CONCAT _D:1 _E:e):a):f):g):h - 1 (CONCAT (REDXOR (SEL@0 (REPLICATE _A:a cA:a)*:b):c):1 (REDXOR (REPLICATE (REPLICATE _B:d cA:a)*:a cA:a):b)*:1):e - 1 (CONCAT (SEL@0 (AND (NOT vA:a)*:a (NOT vB:a)*:a)*:a):1 (CONCAT (REDXOR (REPLICATE _A:1 cA:b)*:c):1 (CONCAT (REDXOR _B:d):1 (CONCAT _C:1 _D:a):e):f):g):c - 1 (NOT (REPLICATE (REPLICATE (REPLICATE _A:1 cA:a)*:b cB:a)*:c cB:a)*:a):a - 1 (REDXOR (REPLICATE (NOT (REPLICATE _A:a cA:b)*:b):b cA:b)*:c):1 - 1 (REDXOR (REPLICATE (REPLICATE (REPLICATE _A:1 cA:a)*:b cB:a)*:c cB:a)*:a):1 - 1 (REDXOR (REPLICATE (REPLICATE (REPLICATE _A:a cA:b)*:c cA:b)*:b cA:b):d)*:1 - 1 (REDXOR (REPLICATE (REPLICATE (SEL@A _A:a):1 cA:b)*:c cB:b)*:d):1 - 1 (REDXOR (REPLICATE (SEL@A (AND _A:a _B:a)*:a):1 cA:b)*:c):1 - 1 (REDXOR (SEL@0 (REPLICATE (NOT _A:a):a cA:a)*:b):c):1 - 1 (REPLICATE (NOT (REPLICATE (REPLICATE _A:a cA:b)*:c cA:b)*:b):b cA:b)*:d - 1 (REPLICATE (REPLICATE (REPLICATE (REPLICATE _A:1 cA:a)*:b cB:a)*:c cB:a)*:a cB:a):d - 1 (REPLICATE (REPLICATE (REPLICATE (SEL@A _A:a):1 cA:b)*:c cB:b)*:d cB:b)*:b - 1 (REPLICATE (REPLICATE (SEL@A (AND _A:a _B:a)*:a):1 cA:b)*:c cB:b)*:d - 1 (REPLICATE (SEL@A (AND (NOT vA:a)*:a (NOT vB:a)*:a)*:a):1 cA:b)*:c - 1 (SEL@0 (REPLICATE (NOT (REPLICATE _A:a cA:b)*:b):b cA:b)*:c):d + 1 (CONCAT (REDXOR (AND (NOT _:A/a):B*/a (NOT _:C/a):D*/a):E*/a):F/1 (CONCAT (REDXOR (AND _:D*/a _:G*/a):H/a):I/1 (CONCAT (REDXOR _:J/a):K/1 (CONCAT _:L/1 _:M/b):N/c):O/d):P/e):Q/f + 1 (CONCAT (REDXOR (AND (NOT _:A/a):B*/a (NOT _:C/a):D*/a):E/a):F/1 (CONCAT (REDXOR (AND _:G*/a _:D*/a):H/a):I/1 (CONCAT (SEL@0 _:J*/a):K/1 (CONCAT _:L/1 _:M/b):N/c):O/d):P/e):Q/f + 1 (CONCAT (REDXOR (AND (NOT _:A/a):B*/a (NOT _:C/a):D*/a):E/a):F/1 (CONCAT (SEL@0 (AND _:B*/a _:G*/a):H*/a):I/1 (CONCAT (REDXOR _:J*/b):K/1 (CONCAT _:L/1 _:M/c):N/d):O/e):P/b):Q/f + 1 (CONCAT (REDXOR (REPLICATE (NOT _:A*/a):B/a cA:C/a):D*/b):E/1 (CONCAT (REDXOR (SEL@0 _:D*/b):F/c):G/1 (REDXOR (REPLICATE _:A*/a cA:H/a):I/b):J*/1):K/d):L/e + 1 (CONCAT (REDXOR (REPLICATE (REPLICATE _:A*/a cA:B/b):C*/b cA:D/b):E/c):F*/1 (CONCAT (REDXOR (REPLICATE _:G/b cA:H/b):I*/c):J/1 (CONCAT (REDXOR _:K/d):L/1 (REDXOR _:E/c):F*/1):M/e):N/f):O/g + 1 (CONCAT (REDXOR (REPLICATE (REPLICATE _:A*/a cA:B/b):C*/c cA:D/b):E*/b):F/1 (CONCAT (REDXOR (REPLICATE _:E*/b cA:G/b):H/d):I*/1 (CONCAT (REDXOR _:J*/d):K/1 (CONCAT _:L/1 _:I*/1):M/e):N/f):O/g):P/h + 1 (CONCAT (REDXOR (REPLICATE (REPLICATE _:A/1 cA:B/a):C*/b cB:D/a):E*/c):F/1 (CONCAT (REDXOR (REPLICATE _:E*/c cB:G/a):H*/a):I/1 (CONCAT (REDXOR _:J/d):K*/1 (CONCAT _:L/1 _:M/e):N/f):O/g):P/h):Q/i + 1 (CONCAT (REDXOR (REPLICATE (SEL@A _:A*/a):B/1 cA:C/b):D*/c):E/1 (CONCAT (REDXOR (REPLICATE _:D*/c cB:F/b):G*/d):H/1 (CONCAT (REDXOR _:I*/b):J/1 (CONCAT _:K*/1 _:L/e):M/a):N/f):O/g):P/h + 1 (CONCAT (REDXOR (SEL@0 (REPLICATE _:A/a cA:B/a):C*/b):D/c):E/1 (REDXOR (REPLICATE (REPLICATE _:F*/d cA:G/a):H*/a cA:I/a):J/b):K*/1):L/e + 1 (CONCAT (SEL@0 (AND (NOT _:A/a):B*/a (NOT _:C/a):D*/a):E*/a):F/1 (CONCAT (REDXOR (REPLICATE _:G/1 cA:H/b):I*/c):J/1 (CONCAT (REDXOR _:K*/d):L/1 (CONCAT _:M/1 _:N/a):O/e):P/f):Q/g):R/c + 1 (NOT (REPLICATE (REPLICATE (REPLICATE _:A/1 cA:B/a):C*/b cB:D/a):E*/c cB:F/a):G*/a):H/a + 1 (REDXOR (REPLICATE (NOT (REPLICATE _:A*/a cA:B/b):C*/b):D/b cA:E/b):F*/c):G/1 + 1 (REDXOR (REPLICATE (REPLICATE (REPLICATE _:A*/a cA:B/b):C*/c cA:D/b):E*/b cA:F/b):G/d):H*/1 + 1 (REDXOR (REPLICATE (REPLICATE (REPLICATE _:A/1 cA:B/a):C*/b cB:D/a):E*/c cB:F/a):G*/a):H/1 + 1 (REDXOR (REPLICATE (REPLICATE (SEL@A _:A*/a):B/1 cA:C/b):D*/c cB:E/b):F*/d):G/1 + 1 (REDXOR (REPLICATE (SEL@A (AND _:A*/a _:B*/a):C*/a):D/1 cA:E/b):F*/c):G/1 + 1 (REDXOR (SEL@0 (REPLICATE (NOT _:A*/a):B/a cA:C/a):D*/b):E/c):F/1 + 1 (REPLICATE (NOT (REPLICATE (REPLICATE _:A*/a cA:B/b):C*/c cA:D/b):E*/b):F/b cA:G/b):H*/d + 1 (REPLICATE (REPLICATE (REPLICATE (REPLICATE _:A/1 cA:B/a):C*/b cB:D/a):E*/c cB:F/a):G*/a cB:H/a):I/d + 1 (REPLICATE (REPLICATE (REPLICATE (SEL@A _:A*/a):B/1 cA:C/b):D*/c cB:E/b):F*/d cB:G/b):H*/b + 1 (REPLICATE (REPLICATE (SEL@A (AND _:A*/a _:B*/a):C*/a):D/1 cA:E/b):F*/c cB:G/b):H*/d + 1 (REPLICATE (SEL@A (AND (NOT _:A/a):B*/a (NOT _:C/a):D*/a):E*/a):F/1 cA:G/b):H*/c + 1 (SEL@0 (REPLICATE (NOT (REPLICATE _:A*/a cA:B/b):C*/b):D/b cA:E/b):F*/c):G/d + 1 (VARPACKED (CONCAT (REDXOR (AND _:A*/a _:B*/a):C*/a):D/1 (CONCAT (REDXOR _:E/a):F/1 (CONCAT _:G/1 _:H/b):I/c):J/d):K/e):L/e + 1 (VARPACKED (REPLICATE (NOT (REPLICATE _:A*/a cA:B/b):C*/b):D/b cA:E/b):F*/c):G/c + 1 (VARPACKED (REPLICATE (REPLICATE (REPLICATE _:A/1 cA:B/a):C*/b cB:D/a):E*/c cB:F/a):G*/a):H/a + 1 (VARPACKED (REPLICATE (REPLICATE (SEL@A _:A*/a):B/1 cA:C/b):D*/c cB:E/b):F*/d):G/d + 1 (VARPACKED (REPLICATE (SEL@A (AND _:A*/a _:B*/a):C*/a):D/1 cA:E/b):F*/c):G/c