CIRCT  19.0.0git
LowerFirMem.cpp
Go to the documentation of this file.
1 //===- LowerFirMem.cpp - Seq FIRRTL memory lowering -----------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This transform translate Seq FirMem ops to instances of HW generated modules.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "FirMemLowering.h"
15 #include "circt/Dialect/HW/HWOps.h"
18 #include "mlir/IR/Builders.h"
19 #include "mlir/IR/Threading.h"
20 #include "mlir/Pass/Pass.h"
21 #include "llvm/Support/Debug.h"
22 
23 #define DEBUG_TYPE "lower-seq-firmem"
24 
25 using namespace circt;
26 using namespace hw;
27 using llvm::MapVector;
28 
29 //===----------------------------------------------------------------------===//
30 // Pass Implementation
31 //===----------------------------------------------------------------------===//
32 
33 namespace {
34 #define GEN_PASS_DEF_LOWERFIRMEM
35 #include "circt/Conversion/Passes.h.inc"
36 
37 struct LowerFirMemPass : public impl::LowerFirMemBase<LowerFirMemPass> {
38  void runOnOperation() override;
39 };
40 } // namespace
41 
42 void LowerFirMemPass::runOnOperation() {
43  auto circuit = getOperation();
44 
45  auto modules = llvm::to_vector(circuit.getOps<HWModuleOp>());
46  LLVM_DEBUG(llvm::dbgs() << "Lowering memories in " << modules.size()
47  << " modules\n");
48 
49  FirMemLowering lowering(circuit);
50 
51  // Gather all `FirMemOp`s in the HW modules and group them by configuration.
52  auto uniqueMems = lowering.collectMemories(modules);
53  LLVM_DEBUG(llvm::dbgs() << "Found " << uniqueMems.size()
54  << " unique memory congiurations\n");
55  if (uniqueMems.empty()) {
56  markAllAnalysesPreserved();
57  return;
58  }
59 
60  // Group the list of memories that we need to update per HW module. This will
61  // allow us to parallelize across HW modules.
62  MapVector<HWModuleOp, SmallVector<FirMemLowering::MemoryConfig>> memsByModule;
63  for (auto &[config, memOps] : uniqueMems) {
64  // Create the `HWModuleGeneratedOp`s for each unique configuration.
65  auto genOp = lowering.createMemoryModule(config, memOps);
66 
67  // Group memories by their parent module for parallelism.
68  for (auto memOp : memOps) {
69  auto parent = memOp->getParentOfType<HWModuleOp>();
70  memsByModule[parent].emplace_back(&config, genOp, memOp);
71  }
72  }
73 
74  // Replace all `FirMemOp`s with instances of the generated module.
75  mlir::parallelForEach(&getContext(), memsByModule, [&](auto pair) {
76  lowering.lowerMemoriesInModule(pair.first, pair.second);
77  });
78 }
79 
80 //===----------------------------------------------------------------------===//
81 // Pass Infrastructure
82 //===----------------------------------------------------------------------===//
83 
84 std::unique_ptr<Pass> circt::createLowerFirMemPass() {
85  return std::make_unique<LowerFirMemPass>();
86 }
FIR memory lowering helper.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Definition: DebugAnalysis.h:21
std::unique_ptr< mlir::Pass > createLowerFirMemPass()
Definition: LowerFirMem.cpp:84
Definition: hw.py:1