Loading [MathJax]/extensions/tex2jax.js
CIRCT 22.0.0git
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
EmbedValidationValuesPass.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
12#include "llvm/Support/Debug.h"
13#include "llvm/Support/LineIterator.h"
14#include "llvm/Support/MemoryBuffer.h"
15
16namespace circt {
17namespace rtg {
18#define GEN_PASS_DEF_EMBEDVALIDATIONVALUESPASS
19#include "circt/Dialect/RTG/Transforms/RTGPasses.h.inc"
20} // namespace rtg
21} // namespace circt
22
23using namespace mlir;
24using namespace circt;
25
26#define DEBUG_TYPE "rtg-embed-validation-values"
27
28//===----------------------------------------------------------------------===//
29// Embed Validation Values Pass
30//===----------------------------------------------------------------------===//
31
32namespace {
33struct EmbedValidationValuesPass
34 : public rtg::impl::EmbedValidationValuesPassBase<
35 EmbedValidationValuesPass> {
36 using Base::Base;
37
38 void runOnOperation() override;
39 LogicalResult parseFile(DenseMap<StringAttr, rtg::ValidateOp> &opById,
40 DenseMap<StringAttr, TypedAttr> &valueMap);
41};
42} // namespace
43
44LogicalResult EmbedValidationValuesPass::parseFile(
45 DenseMap<StringAttr, rtg::ValidateOp> &opById,
46 DenseMap<StringAttr, TypedAttr> &valueMap) {
47 auto buff = llvm::MemoryBuffer::getFile(filename, /*IsText=*/true);
48 if (auto ec = buff.getError())
49 return emitError(UnknownLoc::get(&getContext()))
50 << "cannot open file '" << filename << "': " << ec.message();
51
52 for (llvm::line_iterator i(**buff); !i.is_at_eof(); ++i) {
53 auto *ctxt = &getContext();
54 auto [id, value] = i->split('=');
55 Location idLoc = FileLineColLoc::get(ctxt, filename, i.line_number(), 1);
56 Location valueLoc =
57 FileLineColLoc::get(ctxt, filename, i.line_number(), id.size() + 1);
58 if (value.empty())
59 return emitError(valueLoc) << "no value for ID '" << id << "'";
60
61 auto idAttr = StringAttr::get(ctxt, id);
62
63 auto op = opById[idAttr];
64 if (!op)
65 continue;
66
67 auto valueAttr =
68 op.getRef().getType().parseContentValue(value, op.getValue().getType());
69 if (!valueAttr)
70 return emitError(valueLoc)
71 << "cannot parse value of type " << op.getValue().getType()
72 << " from string '" << value << "'";
73
74 if (!valueMap.insert({idAttr, valueAttr}).second)
75 return emitError(idLoc) << "duplicate ID in input file: " << idAttr;
76
77 LLVM_DEBUG(llvm::dbgs() << "- Parsed value for " << idAttr << "\n");
78 }
79
80 return success();
81}
82
83void EmbedValidationValuesPass::runOnOperation() {
84 DenseMap<StringAttr, TypedAttr> valueMap;
85 DenseMap<StringAttr, rtg::ValidateOp> opById;
86 SmallVector<rtg::ValidateOp> validateOps;
87
88 auto result = getOperation().walk([&](rtg::ValidateOp op) -> WalkResult {
89 if (op.getIdAttr()) {
90 validateOps.push_back(op);
91 if (!opById.insert({op.getIdAttr(), op}).second)
92 return op->emitError("at least two validate ops have the same ID: ")
93 << op.getIdAttr();
94 }
95 return WalkResult::advance();
96 });
97
98 if (result.wasInterrupted() || failed(parseFile(opById, valueMap)))
99 return signalPassFailure();
100
101 UnusedOpPruner pruner;
102 for (auto op : validateOps) {
103 auto value = valueMap[op.getIdAttr()];
104 // If the input file did not contain a value for this ID, keep the validate
105 // operation as-is.
106 if (!value)
107 continue;
108
109 OpBuilder builder(op);
110 auto *constOp = value.getDialect().materializeConstant(
111 builder, value, value.getType(), op.getLoc());
112 if (!constOp) {
113 op.emitOpError("materializer of dialect '")
114 << value.getDialect().getNamespace()
115 << "' unable to materialize value for attribute '" << value << "'";
116 return signalPassFailure();
117 }
118
119 op.getValue().replaceAllUsesWith(constOp->getResult(0));
120 op.getValues().replaceAllUsesWith(op.getElseValues());
121 pruner.eraseNow(op);
122 }
123
124 pruner.eraseNow();
125}
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Definition rtg.py:1
Utility that tracks operations that have potentially become unused and allows them to be cleaned up a...
void eraseNow(Operation *op)
Erase an operation immediately, and remove it from the set of ops to be removed later.