CIRCT 20.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;
27using llvm::MapVector;
28
29//===----------------------------------------------------------------------===//
30// Pass Implementation
31//===----------------------------------------------------------------------===//
32
33namespace {
34#define GEN_PASS_DEF_LOWERFIRMEM
35#include "circt/Conversion/Passes.h.inc"
36
37struct LowerFirMemPass : public impl::LowerFirMemBase<LowerFirMemPass> {
38 void runOnOperation() override;
39};
40} // namespace
41
42void 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
84std::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.
std::unique_ptr< mlir::Pass > createLowerFirMemPass()
Definition hw.py:1