12#include "llvm/Support/Debug.h"
13#include "llvm/Support/LineIterator.h"
14#include "llvm/Support/MemoryBuffer.h"
18#define GEN_PASS_DEF_EMBEDVALIDATIONVALUESPASS
19#include "circt/Dialect/RTG/Transforms/RTGPasses.h.inc"
26#define DEBUG_TYPE "rtg-embed-validation-values"
33struct EmbedValidationValuesPass
34 :
public rtg::impl::EmbedValidationValuesPassBase<
35 EmbedValidationValuesPass> {
38 void runOnOperation()
override;
39 LogicalResult parseFile(DenseMap<StringAttr, rtg::ValidateOp> &opById,
40 DenseMap<StringAttr, TypedAttr> &valueMap);
44LogicalResult EmbedValidationValuesPass::parseFile(
45 DenseMap<StringAttr, rtg::ValidateOp> &opById,
46 DenseMap<StringAttr, TypedAttr> &valueMap) {
47 auto buff = llvm::MemoryBuffer::getFile(filename,
true);
48 if (
auto ec = buff.getError())
49 return emitError(UnknownLoc::get(&getContext()))
50 <<
"cannot open file '" << filename <<
"': " << ec.message();
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);
57 FileLineColLoc::get(ctxt, filename, i.line_number(),
id.size() + 1);
59 return emitError(valueLoc) <<
"no value for ID '" <<
id <<
"'";
61 auto idAttr = StringAttr::get(ctxt,
id);
63 auto op = opById[idAttr];
68 op.getRef().getType().parseContentValue(value, op.getValue().getType());
70 return emitError(valueLoc)
71 <<
"cannot parse value of type " << op.getValue().getType()
72 <<
" from string '" << value <<
"'";
74 if (!valueMap.insert({idAttr, valueAttr}).second)
75 return emitError(idLoc) <<
"duplicate ID in input file: " << idAttr;
77 LLVM_DEBUG(llvm::dbgs() <<
"- Parsed value for " << idAttr <<
"\n");
83void EmbedValidationValuesPass::runOnOperation() {
84 DenseMap<StringAttr, TypedAttr> valueMap;
85 DenseMap<StringAttr, rtg::ValidateOp> opById;
86 SmallVector<rtg::ValidateOp> validateOps;
88 auto result = getOperation().walk([&](rtg::ValidateOp op) -> WalkResult {
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: ")
95 return WalkResult::advance();
98 if (result.wasInterrupted() || failed(parseFile(opById, valueMap)))
99 return signalPassFailure();
102 for (
auto op : validateOps) {
103 auto value = valueMap[op.getIdAttr()];
109 OpBuilder builder(op);
110 auto *constOp = value.getDialect().materializeConstant(
111 builder, value, value.getType(), op.getLoc());
113 op.emitOpError(
"materializer of dialect '")
114 << value.getDialect().getNamespace()
115 <<
"' unable to materialize value for attribute '" << value <<
"'";
116 return signalPassFailure();
119 op.getValue().replaceAllUsesWith(constOp->getResult(0));
120 op.getValues().replaceAllUsesWith(op.getElseValues());
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
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.