CIRCT 24.0.0git
Loading...
Searching...
No Matches
HWDialect.cpp
Go to the documentation of this file.
1//===- HWDialect.cpp - Implement the HW dialect ---------------------------===//
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 implements the HW dialect.
10//
11//===----------------------------------------------------------------------===//
12
17#include "mlir/IR/Builders.h"
18#include "mlir/IR/BuiltinAttributes.h"
19#include "mlir/IR/BuiltinTypes.h"
20#include "mlir/IR/DialectImplementation.h"
21#include "mlir/Transforms/InliningUtils.h"
22
23using namespace circt;
24using namespace hw;
25
26//===----------------------------------------------------------------------===//
27// Dialect specification.
28//===----------------------------------------------------------------------===//
29
30// Pull in the dialect definition.
31#include "circt/Dialect/HW/HWDialect.cpp.inc"
32
33namespace {
34
35// We implement the OpAsmDialectInterface so that HW dialect operations
36// automatically interpret the name attribute on operations as their SSA name.
37struct HWOpAsmDialectInterface : public OpAsmDialectInterface {
38 using OpAsmDialectInterface::OpAsmDialectInterface;
39
40 /// Get a special name to use when printing the given operation. See
41 /// OpAsmInterface.td#getAsmResultNames for usage details and documentation.
42 void getAsmResultNames(Operation *op, OpAsmSetValueNameFn setNameFn) const {}
43};
44} // end anonymous namespace
45
46namespace {
47/// This class defines the interface for handling inlining with HW operations.
48struct HWInlinerInterface : public mlir::DialectInlinerInterface {
49 using mlir::DialectInlinerInterface::DialectInlinerInterface;
50
51 bool isLegalToInline(Operation *op, Region *, bool,
52 mlir::IRMapping &) const final {
53 return isa<ConstantOp>(op) || isa<AggregateConstantOp>(op) ||
54 isa<EnumConstantOp>(op) || isa<BitcastOp>(op) ||
55 isa<ArrayCreateOp>(op) || isa<ArrayConcatOp>(op) ||
56 isa<ArraySliceOp>(op) || isa<ArrayGetOp>(op) ||
57 isa<StructCreateOp>(op) || isa<StructExplodeOp>(op) ||
58 isa<StructExtractOp>(op) || isa<StructInjectOp>(op) ||
59 isa<UnionCreateOp>(op) || isa<UnionExtractOp>(op);
60 }
61
62 bool isLegalToInline(Region *, Region *, bool,
63 mlir::IRMapping &) const final {
64 return false;
65 }
66};
67} // end anonymous namespace
68
69namespace {
70struct HWProbeTypeDialectInterface : public hw::ProbeTypeDialectInterface {
72
73 bool isValidProbeElementType(Type type) const override {
74 if (auto alias = dyn_cast<TypeAliasType>(type))
75 return hw::isValidProbeElementType(alias.getCanonicalType());
76
77 if (auto array = dyn_cast<ArrayType>(type))
78 return hw::isValidProbeElementType(array.getElementType());
79
80 if (auto array = dyn_cast<UnpackedArrayType>(type))
81 return hw::isValidProbeElementType(array.getElementType());
82
83 if (auto structType = dyn_cast<StructType>(type))
84 return llvm::all_of(structType.getElements(), [](auto field) {
85 return hw::isValidProbeElementType(field.type);
86 });
87
88 if (auto unionType = dyn_cast<UnionType>(type))
89 return llvm::all_of(unionType.getElements(), [](auto field) {
90 return hw::isValidProbeElementType(field.type);
91 });
92
93 return isa<IntType, EnumType>(type);
94 }
95};
96} // end anonymous namespace
97
98void HWDialect::initialize() {
99 // Register types and attributes.
100 registerTypes();
101 registerAttributes();
102
103 // Register operations.
104 addOperations<
105#define GET_OP_LIST
106#include "circt/Dialect/HW/HW.cpp.inc"
107 >();
108
109 // Register interface implementations.
110 addInterfaces<HWOpAsmDialectInterface, HWInlinerInterface,
111 HWProbeTypeDialectInterface>();
112}
113
114/// Registered hook to materialize a single constant operation from a given
115/// attribute value with the desired resultant type. This method should use
116/// the provided builder to create the operation without changing the
117/// insertion position. The generated operation is expected to be constant
118/// like, i.e. single result, zero operands, non side-effecting, etc. On
119/// success, this hook should return the value generated to represent the
120/// constant value. Otherwise, it should return null on failure.
121Operation *hw::materializeConstant(OpBuilder &builder, Attribute value,
122 Type type, Location loc) {
123 // Integer constants can materialize into hw.constant
124 if (auto intType = dyn_cast<IntegerType>(type))
125 if (auto attrValue = dyn_cast<IntegerAttr>(value))
126 return ConstantOp::create(builder, loc, type, attrValue);
127
128 // Aggregate constants.
129 if (auto arrayAttr = dyn_cast<ArrayAttr>(value)) {
130 if (type_isa<StructType, ArrayType, UnpackedArrayType>(type))
131 return AggregateConstantOp::create(builder, loc, type, arrayAttr);
132 }
133
134 // Parameter expressions materialize into hw.param.value.
135 Block *block = builder.getBlock();
136 if (!block)
137 return nullptr;
138 auto *parentOp = block->getParentOp();
139 if (!parentOp)
140 return nullptr;
141 auto curModule = dyn_cast<HWModuleOp>(parentOp);
142 if (!curModule)
143 curModule = parentOp->getParentOfType<HWModuleOp>();
144 if (curModule && isValidParameterExpression(value, curModule))
145 return ParamValueOp::create(builder, loc, type, value);
146 return nullptr;
147}
148
149Operation *HWDialect::materializeConstant(OpBuilder &builder, Attribute value,
150 Type type, Location loc) {
151 return hw::materializeConstant(builder, value, type, loc);
152}
create(data_type, value)
Definition hw.py:433
void getAsmResultNames(OpAsmSetValueNameFn setNameFn, StringRef instanceName, ArrayAttr resultNames, ValueRange results)
Suggest a name for each result value based on the saved result names attribute.
bool isValidProbeElementType(mlir::Type type)
Return true if type is a valid probe payload.
bool isValidParameterExpression(Attribute attr, Operation *module)
Return true if the specified attribute tree is made up of nodes that are valid in a parameter express...
Definition HWOps.cpp:221
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Definition hw.py:1
Interface for dialects to classify their types as valid probe payloads.
Definition HWTypes.h:53
ProbeTypeDialectInterface(mlir::Dialect *dialect)
Definition HWTypes.h:54