CIRCT 22.0.0git
Loading...
Searching...
No Matches
AnnotateInputOnlyModules.cpp
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
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 file defines the AnnotateInputOnlyModules pass.
10//
11//===----------------------------------------------------------------------===//
12
18#include "mlir/Pass/Pass.h"
19
20#define DEBUG_TYPE "firrtl-annotate-input-only-modules"
21
22namespace circt {
23namespace firrtl {
24#define GEN_PASS_DEF_ANNOTATEINPUTONLYMODULES
25#include "circt/Dialect/FIRRTL/Passes.h.inc"
26} // namespace firrtl
27} // namespace circt
28
29using namespace circt;
30using namespace firrtl;
31
32namespace {
33struct AnnotateInputOnlyModulesPass
34 : public circt::firrtl::impl::AnnotateInputOnlyModulesBase<
35 AnnotateInputOnlyModulesPass> {
36 void runOnOperation() override;
37
38 LogicalResult initialize(MLIRContext *context) override {
39 // Cache the inline annotation.
40 inlineAnno = DictionaryAttr::getWithSorted(
41 context, {{StringAttr::get(context, "class"),
42 StringAttr::get(context, inlineAnnoClass)}});
43 return success();
44 }
45
46 mlir::DictionaryAttr inlineAnno;
47};
48
49} // end anonymous namespace
50
51void AnnotateInputOnlyModulesPass::runOnOperation() {
52 auto circuit = getOperation();
53 bool changed = false;
54 auto &instanceInfo = getAnalysis<InstanceInfo>();
55 for (auto module : circuit.getOps<FModuleOp>()) {
56 // Inline input only modules in design.
57 // Don't inline if the module is public or has a layer enabled.
58 if (!instanceInfo.anyInstanceInEffectiveDesign(module) ||
59 module.isPublic() || !module.getLayers().empty())
60 continue;
61
62 // Check if the module has only input ports (no output ports)
63 bool hasHardwareOutputPort =
64 llvm::any_of(module.getPorts(), [&](auto port) {
65 return port.direction == Direction::Out &&
66 type_isa<FIRRTLBaseType>(port.type);
67 });
68
69 // If the module has only input ports, add InlineAnnotation
70 if (hasHardwareOutputPort)
71 continue;
72
73 AnnotationSet annos(module);
74
75 // Check if InlineAnnotation or DontTouchAnnotation exists
76 if (annos.hasAnnotation(inlineAnnoClass) || annos.hasDontTouch())
77 continue;
78
79 LLVM_DEBUG(llvm::dbgs() << "Annotating inline annotation "
80 << module.getModuleName() << "\n");
81
82 // Create InlineAnnotation
83 annos.addAnnotations(ArrayRef<Attribute>{inlineAnno});
84 annos.applyToOperation(module);
85
86 ++numAnnotated;
87 changed = true;
88 }
89
90 if (!changed)
91 return markAllAnalysesPreserved();
92
93 markAnalysesPreserved<igraph::InstanceGraph, InstanceInfo>();
94}
static std::unique_ptr< Context > context
This class provides a read-only projection over the MLIR attributes that represent a set of annotatio...
constexpr const char * inlineAnnoClass
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.