CIRCT 24.0.0git
Loading...
Searching...
No Matches
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"
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
25using namespace circt;
26using namespace hw;
27
28//===----------------------------------------------------------------------===//
29// Pass Implementation
30//===----------------------------------------------------------------------===//
31
32namespace {
33#define GEN_PASS_DEF_LOWERFIRMEM
34#include "circt/Conversion/Passes.h.inc"
35
36struct LowerFirMemPass : public impl::LowerFirMemBase<LowerFirMemPass> {
37 void runOnOperation() override;
38};
39} // namespace
40
41void LowerFirMemPass::runOnOperation() {
42 auto circuit = getOperation();
43
44 auto modules = llvm::to_vector(circuit.getOps<HWModuleOp>());
45 LLVM_DEBUG(llvm::dbgs() << "Lowering memories in " << modules.size()
46 << " modules\n");
47
48 FirMemLowering lowering(circuit);
49
50 // Gather all `FirMemOp`s in the HW modules and group them by configuration.
51 auto uniqueMems = lowering.collectMemories(modules);
52 LLVM_DEBUG(llvm::dbgs() << "Found " << uniqueMems.size()
53 << " unique memory congiurations\n");
54 if (uniqueMems.empty()) {
55 markAllAnalysesPreserved();
56 return;
57 }
58
59 // Group the list of memories that we need to update per HW module. This will
60 // allow us to parallelize across HW modules.
61 MapVector<HWModuleOp, SmallVector<FirMemLowering::MemoryConfig>> memsByModule;
62 for (auto &[config, memOps] : uniqueMems) {
63 // Create the `HWModuleGeneratedOp`s for each unique configuration.
64 auto genOp = lowering.createMemoryModule(config, memOps);
65
66 // Group memories by their parent module for parallelism.
67 for (auto memOp : memOps) {
68 auto parent = memOp->getParentOfType<HWModuleOp>();
69 memsByModule[parent].emplace_back(&config, genOp, memOp);
70 }
71 }
72
73 // Replace all `FirMemOp`s with instances of the generated module.
74 mlir::parallelForEach(&getContext(), memsByModule, [&](auto pair) {
75 lowering.lowerMemoriesInModule(pair.first, pair.second);
76 });
77}
78
79//===----------------------------------------------------------------------===//
80// Pass Infrastructure
81//===----------------------------------------------------------------------===//
82
83std::unique_ptr<Pass> circt::createLowerFirMemPass() {
84 return std::make_unique<LowerFirMemPass>();
85}
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
std::unique_ptr< mlir::Pass > createLowerFirMemPass()
Definition hw.py:1