16 #include "mlir/IR/Attributes.h"
17 #include "mlir/IR/BuiltinTypes.h"
18 #include "mlir/IR/Matchers.h"
19 #include "mlir/IR/PatternMatch.h"
20 #include "mlir/IR/Region.h"
21 #include "mlir/IR/Types.h"
22 #include "mlir/IR/Value.h"
23 #include "llvm/ADT/ArrayRef.h"
24 #include "llvm/ADT/SmallVector.h"
26 using namespace circt;
31 if (
auto sig = dyn_cast<hw::InOutType>(type))
32 type = sig.getElementType();
33 else if (
auto ptr = dyn_cast<llhd::PtrType>(type))
34 type = ptr.getElementType();
35 if (
auto array = dyn_cast<hw::ArrayType>(type))
36 return array.getNumElements();
37 if (
auto tup = dyn_cast<hw::StructType>(type))
38 return tup.getElements().size();
39 return type.getIntOrFloatBitWidth();
43 if (
auto sig = dyn_cast<hw::InOutType>(type))
44 type = sig.getElementType();
45 else if (
auto ptr = dyn_cast<llhd::PtrType>(type))
46 type = ptr.getElementType();
47 if (
auto array = dyn_cast<hw::ArrayType>(type))
48 return array.getElementType();
56 OpFoldResult llhd::ConstantTimeOp::fold(FoldAdaptor adaptor) {
57 assert(adaptor.getOperands().empty() &&
"const has no operands");
58 return getValueAttr();
61 void llhd::ConstantTimeOp::build(OpBuilder &builder, OperationState &result,
62 unsigned time,
const StringRef &timeUnit,
63 unsigned delta,
unsigned epsilon) {
64 auto *ctx = builder.getContext();
65 auto attr =
TimeAttr::get(ctx, time, timeUnit, delta, epsilon);
75 setNameFn(getResult(), *
getName());
89 if (op.getResultWidth() == op.getInputWidth() &&
90 cast<IntegerAttr>(operands[1]).getValue().isZero())
96 OpFoldResult llhd::SigExtractOp::fold(FoldAdaptor adaptor) {
100 OpFoldResult llhd::PtrExtractOp::fold(FoldAdaptor adaptor) {
110 ArrayRef<Attribute> operands) {
115 if (op.getResultWidth() == op.getInputWidth() &&
116 cast<IntegerAttr>(operands[1]).getValue().isZero())
117 return op.getInput();
122 OpFoldResult llhd::SigArraySliceOp::fold(FoldAdaptor adaptor) {
126 OpFoldResult llhd::PtrArraySliceOp::fold(FoldAdaptor adaptor) {
132 PatternRewriter &rewriter) {
133 IntegerAttr indexAttr;
134 if (!matchPattern(op.getLowIndex(), m_Constant(&indexAttr)))
140 if (matchPattern(op.getInput(),
141 m_Op<Op>(matchers::m_Any(), m_Constant(&a)))) {
142 auto sliceOp = op.getInput().template getDefiningOp<Op>();
143 rewriter.modifyOpInPlace(op, [&]() {
144 op.getInputMutable().assign(sliceOp.getInput());
146 op->getLoc(), a.getValue() + indexAttr.getValue());
147 op.getLowIndexMutable().assign(newIndex);
157 PatternRewriter &rewriter) {
162 PatternRewriter &rewriter) {
170 template <
class SigPtrType>
172 MLIRContext *context, std::optional<Location> loc, ValueRange operands,
173 DictionaryAttr attrs, mlir::OpaqueProperties properties,
174 mlir::RegionRange regions, SmallVectorImpl<Type> &results) {
176 cast<hw::StructType>(
177 cast<SigPtrType>(operands[0].getType()).getElementType())
179 cast<StringAttr>(attrs.getNamed(
"field")->getValue()).getValue());
181 context->getDiagEngine().emit(loc.value_or(UnknownLoc()),
182 DiagnosticSeverity::Error)
183 <<
"invalid field name specified";
191 MLIRContext *context, std::optional<Location> loc, ValueRange operands,
192 DictionaryAttr attrs, mlir::OpaqueProperties properties,
193 mlir::RegionRange regions, SmallVectorImpl<Type> &results) {
194 return inferReturnTypesOfStructExtractOp<hw::InOutType>(
195 context, loc, operands, attrs, properties, regions, results);
199 MLIRContext *context, std::optional<Location> loc, ValueRange operands,
200 DictionaryAttr attrs, mlir::OpaqueProperties properties,
201 mlir::RegionRange regions, SmallVectorImpl<Type> &results) {
202 return inferReturnTypesOfStructExtractOp<llhd::PtrType>(
203 context, loc, operands, attrs, properties, regions, results);
210 LogicalResult llhd::DrvOp::fold(FoldAdaptor adaptor,
211 SmallVectorImpl<OpFoldResult> &result) {
215 if (matchPattern(getEnable(), m_One())) {
216 getEnableMutable().clear();
224 PatternRewriter &rewriter) {
228 if (matchPattern(op.getEnable(), m_Zero())) {
229 rewriter.eraseOp(op);
241 SuccessorOperands llhd::WaitOp::getSuccessorOperands(
unsigned index) {
242 assert(index == 0 &&
"invalid successor index");
243 return SuccessorOperands(getDestOpsMutable());
251 PatternRewriter &rewriter) {
252 if (op.getLhs() == op.getRhs())
253 rewriter.eraseOp(op);
257 #include "circt/Dialect/LLHD/IR/LLHDEnums.cpp.inc"
259 #define GET_OP_CLASSES
260 #include "circt/Dialect/LLHD/IR/LLHD.cpp.inc"
assert(baseType &&"element must be base type")
static InstancePath empty
static LogicalResult inferReturnTypesOfStructExtractOp(MLIRContext *context, std::optional< Location > loc, ValueRange operands, DictionaryAttr attrs, mlir::OpaqueProperties properties, mlir::RegionRange regions, SmallVectorImpl< Type > &results)
static OpFoldResult foldSigPtrArraySliceOp(Op op, ArrayRef< Attribute > operands)
static LogicalResult canonicalizeSigPtrArraySliceOp(Op op, PatternRewriter &rewriter)
static OpFoldResult foldSigPtrExtractOp(Op op, ArrayRef< Attribute > operands)
static LogicalResult canonicalize(Op op, PatternRewriter &rewriter)
Direction get(bool isOutput)
Returns an output direction if isOutput is true, otherwise returns an input direction.
LogicalResult inferReturnTypes(MLIRContext *context, std::optional< Location > loc, ValueRange operands, DictionaryAttr attrs, mlir::OpaqueProperties properties, mlir::RegionRange regions, SmallVectorImpl< Type > &results, llvm::function_ref< FIRRTLType(ValueRange, ArrayRef< NamedAttribute >, std::optional< Location >)> callback)
StringAttr getName(ArrayAttr names, size_t idx)
Return the name at the specified index of the ArrayAttr or null if it cannot be determined.
void getAsmResultNames(OpAsmSetValueNameFn setNameFn, StringRef instanceName, ArrayAttr resultNames, ValueRange results)
Suggest a name for each result value based on the saved result names attribute.
unsigned getLLHDTypeWidth(Type type)
Type getLLHDElementType(Type type)
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
function_ref< void(Value, StringRef)> OpAsmSetValueNameFn