CIRCT 21.0.0git
Loading...
Searching...
No Matches
DropConst.cpp
Go to the documentation of this file.
1//===- DropConst.cpp - Check and remove const types -------------*- C++ -*-===//
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 DropConst pass.
10//
11//===----------------------------------------------------------------------===//
12
18#include "mlir/IR/Threading.h"
19#include "mlir/Pass/Pass.h"
20
21namespace circt {
22namespace firrtl {
23#define GEN_PASS_DEF_DROPCONST
24#include "circt/Dialect/FIRRTL/Passes.h.inc"
25} // namespace firrtl
26} // namespace circt
27
28using namespace circt;
29using namespace firrtl;
30
31/// Returns null type if no conversion is needed.
33 auto nonConstType = type.getAllConstDroppedType();
34 return nonConstType != type ? nonConstType : FIRRTLBaseType{};
35}
36
37/// Returns null type if no conversion is needed.
38static Type convertType(Type type) {
39 if (auto base = type_dyn_cast<FIRRTLBaseType>(type)) {
40 return convertType(base);
41 }
42
43 if (auto refType = type_dyn_cast<RefType>(type)) {
44 if (auto converted = convertType(refType.getType()))
45 return RefType::get(converted, refType.getForceable(),
46 refType.getLayer());
47 }
48
49 return {};
50}
51
52namespace {
53class DropConstPass : public circt::firrtl::impl::DropConstBase<DropConstPass> {
54 void runOnOperation() override {
55
56 // Update signatures of all module-likes.
57 auto moduleLikes = getOperation().getOps<FModuleLike>();
58 for (auto mod : moduleLikes) {
59 //// Update the module signature with non-'const' ports
60 SmallVector<Attribute> portTypes;
61 portTypes.reserve(mod.getNumPorts());
62 bool convertedAny = false;
63 llvm::transform(mod.getPortTypes(), std::back_inserter(portTypes),
64 [&](Attribute type) -> Attribute {
65 if (auto convertedType =
66 convertType(cast<TypeAttr>(type).getValue())) {
67 convertedAny = true;
68 return TypeAttr::get(convertedType);
69 }
70 return type;
71 });
72 if (convertedAny)
73 mod.setPortTypesAttr(ArrayAttr::get(mod.getContext(), portTypes));
74 };
75
76 // Rewrite module bodies in parallel.
77 // Filter on FModuleOp specifically as there's no "hasBody()".
78 mlir::parallelForEach(
79 &getContext(),
80 llvm::make_filter_range(moduleLikes, llvm::IsaPred<FModuleOp>),
81 [](auto module) {
82 // Convert the module body if present
83 module->walk([](Operation *op) {
84 if (auto constCastOp = dyn_cast<ConstCastOp>(op)) {
85 // Remove any `ConstCastOp`, replacing results with inputs
86 constCastOp.getResult().replaceAllUsesWith(
87 constCastOp.getInput());
88 constCastOp->erase();
89 return;
90 }
91
92 // Convert any block arguments
93 for (auto &region : op->getRegions())
94 for (auto &block : region.getBlocks())
95 for (auto argument : block.getArguments())
96 if (auto convertedType = convertType(argument.getType()))
97 argument.setType(convertedType);
98
99 for (auto result : op->getResults())
100 if (auto convertedType = convertType(result.getType()))
101 result.setType(convertedType);
102 });
103 });
104
105 markAnalysesPreserved<InstanceGraph>();
106 }
107};
108} // namespace
109
110std::unique_ptr<mlir::Pass> circt::firrtl::createDropConstPass() {
111 return std::make_unique<DropConstPass>();
112}
static FIRRTLBaseType convertType(FIRRTLBaseType type)
Returns null type if no conversion is needed.
Definition DropConst.cpp:32
FIRRTLBaseType getAllConstDroppedType()
Return this type with a 'const' modifiers dropped.
std::unique_ptr< mlir::Pass > createDropConstPass()
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.