CIRCT  18.0.0git
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 
13 #include "PassDetails.h"
19 #include "mlir/IR/Threading.h"
20 
21 using namespace circt;
22 using namespace firrtl;
23 
24 /// Returns null type if no conversion is needed.
26  auto nonConstType = type.getAllConstDroppedType();
27  return nonConstType != type ? nonConstType : FIRRTLBaseType{};
28 }
29 
30 /// Returns null type if no conversion is needed.
31 static Type convertType(Type type) {
32  if (auto base = type_dyn_cast<FIRRTLBaseType>(type)) {
33  return convertType(base);
34  }
35 
36  if (auto refType = type_dyn_cast<RefType>(type)) {
37  if (auto converted = convertType(refType.getType()))
38  return RefType::get(converted, refType.getForceable());
39  }
40 
41  return {};
42 }
43 
44 namespace {
45 class DropConstPass : public DropConstBase<DropConstPass> {
46  void runOnOperation() override {
47  mlir::parallelForEach(
48  &getContext(), getOperation().getOps<firrtl::FModuleLike>(),
49  [](auto module) {
50  // Convert the module body if present
51  module->walk([](Operation *op) {
52  if (auto constCastOp = dyn_cast<ConstCastOp>(op)) {
53  // Remove any `ConstCastOp`, replacing results with inputs
54  constCastOp.getResult().replaceAllUsesWith(
55  constCastOp.getInput());
56  constCastOp->erase();
57  return;
58  }
59 
60  // Convert any block arguments
61  for (auto &region : op->getRegions())
62  for (auto &block : region.getBlocks())
63  for (auto argument : block.getArguments())
64  if (auto convertedType = convertType(argument.getType()))
65  argument.setType(convertedType);
66 
67  for (auto result : op->getResults())
68  if (auto convertedType = convertType(result.getType()))
69  result.setType(convertedType);
70  });
71 
72  // Update the module signature with non-'const' ports
73  SmallVector<Attribute> portTypes;
74  portTypes.reserve(module.getNumPorts());
75  bool convertedAny = false;
76  llvm::transform(module.getPortTypes(), std::back_inserter(portTypes),
77  [&](Attribute type) -> Attribute {
78  if (auto convertedType = convertType(
79  cast<TypeAttr>(type).getValue())) {
80  convertedAny = true;
81  return TypeAttr::get(convertedType);
82  }
83  return type;
84  });
85  if (convertedAny)
86  module->setAttr(FModuleLike::getPortTypesAttrName(),
87  ArrayAttr::get(module.getContext(), portTypes));
88  });
89 
90  markAnalysesPreserved<InstanceGraph>();
91  }
92 };
93 } // namespace
94 
95 std::unique_ptr<mlir::Pass> circt::firrtl::createDropConstPass() {
96  return std::make_unique<DropConstPass>();
97 }
static FIRRTLBaseType convertType(FIRRTLBaseType type)
Returns null type if no conversion is needed.
Definition: DropConst.cpp:25
FIRRTLBaseType getAllConstDroppedType()
Return this type with a 'const' modifiers dropped.
Direction get(bool isOutput)
Returns an output direction if isOutput is true, otherwise returns an input direction.
Definition: CalyxOps.cpp:53
std::unique_ptr< mlir::Pass > createDropConstPass()
Definition: DropConst.cpp:95
This file defines an intermediate representation for circuits acting as an abstraction for constraint...
Definition: DebugAnalysis.h:21