CIRCT 23.0.0git
Loading...
Searching...
No Matches
LowerUniqueLabelsPass.cpp
Go to the documentation of this file.
1//===- LowerUniqueLabelsPass.cpp - RTG LowerUniqueLabelsPass impl. --------===//
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 pass lowers label_unique_decl operations to label_decl operations by
10// creating a unique label string based on all the existing unique and
11// non-unique label declarations in the module.
12//
13//===----------------------------------------------------------------------===//
14
18#include "mlir/IR/PatternMatch.h"
19
20namespace circt {
21namespace rtg {
22#define GEN_PASS_DEF_LOWERUNIQUELABELSPASS
23#include "circt/Dialect/RTG/Transforms/RTGPasses.h.inc"
24} // namespace rtg
25} // namespace circt
26
27using namespace mlir;
28using namespace circt;
29using namespace circt::rtg;
30
31//===----------------------------------------------------------------------===//
32// Lower Unique Labels Pass
33//===----------------------------------------------------------------------===//
34
35namespace {
36struct LowerUniqueLabelsPass
37 : public rtg::impl::LowerUniqueLabelsPassBase<LowerUniqueLabelsPass> {
38 using Base::Base;
39
40 void runOnOperation() override;
41};
42} // namespace
43
44static StringAttr getLabelName(LabelUniqueDeclOp op) {
45 if (auto constOp = op.getNamePrefix().getDefiningOp<ConstantOp>())
46 return dyn_cast<StringAttr>(constOp.getValue());
47
48 op->emitError("label_unique_decl name prefix must be a constant string");
49 return {};
50}
51
52void LowerUniqueLabelsPass::runOnOperation() {
53 Namespace labelNames;
54
55 // Collect all the label names in a first iteration.
56 auto result = getOperation()->walk([&](Operation *op) -> WalkResult {
57 if (isa<StringToLabelOp>(op))
58 return op->emitError(
59 "string_to_label operations must be elaborated before "
60 "lowering unique labels");
61
62 if (auto constOp = dyn_cast<ConstantOp>(op)) {
63 if (auto labelAttr = dyn_cast<LabelAttr>(constOp.getValue()))
64 labelNames.add(labelAttr.getName());
65 } else if (auto labelDecl = dyn_cast<LabelUniqueDeclOp>(op)) {
66 auto res = getLabelName(labelDecl);
67 if (!res)
68 return WalkResult::interrupt();
69 labelNames.add(res);
70 }
71
72 return WalkResult::advance();
73 });
74
75 if (result.wasInterrupted())
76 return signalPassFailure();
77
78 // Lower the unique labels in a second iteration.
79 getOperation()->walk([&](LabelUniqueDeclOp op) {
80 // Convert 'rtg.label_unique_decl' to 'rtg.constant <labelAttr>' by
81 // choosing a unique name based on the set of names we collected during
82 // elaboration.
83 IRRewriter rewriter(op);
84 auto newName = labelNames.newName(getLabelName(op).getValue());
85 rewriter.replaceOpWithNewOp<ConstantOp>(
86 op, LabelAttr::get(rewriter.getContext(), newName));
87 ++numLabelsLowered;
88 });
89}
static StringAttr getLabelName(LabelUniqueDeclOp op)
A namespace that is used to store existing names and generate new names in some scope within the IR.
Definition Namespace.h:30
void add(mlir::ModuleOp module)
Definition Namespace.h:48
StringRef newName(const Twine &name)
Return a unique name, derived from the input name, and add the new name to the internal namespace.
Definition Namespace.h:87
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Definition rtg.py:1