2020#include " circt/Dialect/FIRRTL/Passes.h"
2121#include " circt/Dialect/HW/HWAttributes.h"
2222#include " circt/Dialect/HW/InnerSymbolNamespace.h"
23+ #include " circt/Support/Debug.h"
2324#include " circt/Support/LLVM.h"
2425#include " mlir/IR/IRMapping.h"
2526#include " mlir/IR/Threading.h"
2930#include " llvm/ADT/Hashing.h"
3031#include " llvm/ADT/PostOrderIterator.h"
3132#include " llvm/ADT/SmallPtrSet.h"
33+ #include " llvm/Support/Debug.h"
3234#include " llvm/Support/Format.h"
3335#include " llvm/Support/SHA256.h"
3436
37+ #define DEBUG_TYPE " firrtl-dedup"
38+
3539namespace circt {
3640namespace firrtl {
3741#define GEN_PASS_DEF_DEDUP
@@ -70,22 +74,6 @@ static bool canRemoveModule(mlir::SymbolOpInterface symbol) {
7074// Hashing
7175// ===----------------------------------------------------------------------===//
7276
73- llvm::raw_ostream &printHex (llvm::raw_ostream &stream,
74- ArrayRef<uint8_t > bytes) {
75- // Print the hash on a single line.
76- return stream << format_bytes (bytes, std::nullopt , 32 ) << " \n " ;
77- }
78-
79- llvm::raw_ostream &printHash (llvm::raw_ostream &stream, llvm::SHA256 &data) {
80- return printHex (stream, data.result ());
81- }
82-
83- llvm::raw_ostream &printHash (llvm::raw_ostream &stream, std::string data) {
84- ArrayRef<uint8_t > bytes (reinterpret_cast <const uint8_t *>(data.c_str ()),
85- data.length ());
86- return printHex (stream, bytes);
87- }
88-
8977// This struct contains information to determine module module uniqueness. A
9078// first element is a structural hash of the module, and the second element is
9179// an array which tracks module names encountered in the walk. Since module
@@ -1673,6 +1661,11 @@ class DedupPass : public circt::firrtl::impl::DedupBase<DedupPass> {
16731661 Deduper deduper (instanceGraph, symbolTable, nlaTable, circuit);
16741662 Equivalence equiv (context, instanceGraph);
16751663 auto anythingChanged = false ;
1664+ LLVM_DEBUG ({
1665+ llvm::dbgs () << " \n " ;
1666+ debugHeader (Twine (" Dedup circuit \" " ) + circuit.getName () + " \" " )
1667+ << " \n\n " ;
1668+ });
16761669
16771670 // Modules annotated with this should not be considered for deduplication.
16781671 auto noDedupClass = StringAttr::get (context, noDedupAnnoClass);
@@ -1695,6 +1688,7 @@ class DedupPass : public circt::firrtl::impl::DedupBase<DedupPass> {
16951688 llvm::map_range (llvm::post_order (&instanceGraph), [](auto *node) {
16961689 return cast<FModuleLike>(*node->getModule ());
16971690 }));
1691+ LLVM_DEBUG (llvm::dbgs () << " Found " << modules.size () << " modules\n " );
16981692
16991693 SmallVector<std::optional<ModuleInfo>> moduleInfos (modules.size ());
17001694 StructuralHasherSharedConstants hasherConstants (&getContext ());
@@ -1726,6 +1720,7 @@ class DedupPass : public circt::firrtl::impl::DedupBase<DedupPass> {
17261720 }
17271721
17281722 // Calculate module information parallelly.
1723+ LLVM_DEBUG (llvm::dbgs () << " Computing module information\n " );
17291724 auto result = mlir::failableParallelForEach (
17301725 context, llvm::seq (modules.size ()), [&](unsigned idx) {
17311726 auto module = modules[idx];
@@ -1744,9 +1739,25 @@ class DedupPass : public circt::firrtl::impl::DedupBase<DedupPass> {
17441739 return success ();
17451740 });
17461741
1742+ // Dump out the module hashes for debugging.
1743+ LLVM_DEBUG ({
1744+ auto &os = llvm::dbgs ();
1745+ for (auto [module , info] : llvm::zip (modules, moduleInfos)) {
1746+ os << " - Hash " ;
1747+ if (info) {
1748+ os << llvm::format_bytes (info->structuralHash , std::nullopt , 32 , 32 );
1749+ } else {
1750+ os << " --------------------------------" ;
1751+ os << " --------------------------------" ;
1752+ }
1753+ os << " for " << module .getModuleNameAttr () << " \n " ;
1754+ }
1755+ });
1756+
17471757 if (result.failed ())
17481758 return signalPassFailure ();
17491759
1760+ LLVM_DEBUG (llvm::dbgs () << " Update modules\n " );
17501761 for (auto [i, module ] : llvm::enumerate (modules)) {
17511762 auto moduleName = module .getModuleNameAttr ();
17521763 auto &maybeModuleInfo = moduleInfos[i];
@@ -1766,7 +1777,7 @@ class DedupPass : public circt::firrtl::impl::DedupBase<DedupPass> {
17661777 for (auto &referredModule : moduleInfo.referredModuleNames )
17671778 referredModule = dedupMap[referredModule];
17681779
1769- // Check if there a module with the same hash.
1780+ // Check if there is a module with the same hash.
17701781 auto it = moduleInfoToModule.find (moduleInfo);
17711782 if (it != moduleInfoToModule.end ()) {
17721783 auto original = cast<FModuleLike>(it->second );
@@ -1791,6 +1802,8 @@ class DedupPass : public circt::firrtl::impl::DedupBase<DedupPass> {
17911802 }
17921803
17931804 // Record the group ID of the other module.
1805+ LLVM_DEBUG (llvm::dbgs () << " - Replace " << moduleName << " with "
1806+ << originalName << " \n " );
17941807 dedupMap[moduleName] = originalName;
17951808 deduper.dedup (original, module );
17961809 ++erasedModules;
@@ -1833,6 +1846,7 @@ class DedupPass : public circt::firrtl::impl::DedupBase<DedupPass> {
18331846 return it->second ;
18341847 };
18351848
1849+ LLVM_DEBUG (llvm::dbgs () << " Update annotations\n " );
18361850 AnnotationSet::removeAnnotations (circuit, [&](Annotation annotation) {
18371851 if (!annotation.isClass (mustDedupAnnoClass))
18381852 return false ;
0 commit comments