12#include "mlir/IR/Matchers.h"
21 return isa_and_nonnull<SigArrayGetOp, SigExtractOp, SigStructExtractOp>(op);
33 TypeSwitch<Operation *>(op)
34 .Case<SigArrayGetOp>([&](
auto op) {
35 if (!matchPattern(op.getIndex(), m_ConstantInt(&index))) {
36 dynIndex = op.getIndex();
39 offset = index.getZExtValue() * width;
42 .Case<SigExtractOp>([&](
auto op) {
43 if (!matchPattern(op.getLowBit(), m_ConstantInt(&index))) {
44 dynIndex = op.getLowBit();
46 width = op.getResultWidth();
47 offset = index.getZExtValue();
50 .Case<SigStructExtractOp>([&](
auto op) {
51 auto inputType = cast<RefType>(op.getInput().getType()).getNestedType();
52 if (
auto unionType = dyn_cast<hw::UnionType>(inputType)) {
55 auto structType = cast<hw::StructType>(inputType);
56 auto elements = structType.getElements();
57 auto fieldIdx = *structType.getFieldIndex(op.getFieldAttr());
58 bool fieldWidthsKnown =
true;
59 for (
auto field : elements.drop_front(fieldIdx + 1)) {
62 fieldWidthsKnown =
false;
71 .Default([](
auto) { llvm_unreachable(
"Unsupported projection type."); });
85 auto *ca = std::get_if<ConstProjectionRange>(&a);
86 auto *cb = std::get_if<ConstProjectionRange>(&b);
91 if (ca->offset + ca->width <= cb->offset ||
92 cb->offset + cb->width <= ca->offset)
100 Operation *op = sig.getDefiningOp();
103 op = op->getOperand(0).getDefiningOp();
107 if (isa_and_nonnull<SignalOp>(op))
112std::pair<Operation *, std::optional<ProjectionRange>>
125 Operation *op = sig.getDefiningOp();
129 if (isConst && projRange && !
isDynamic(*projRange)) {
130 auto constRange = std::get<ConstProjectionRange>(*projRange);
131 offset += constRange.offset;
135 op = op->getOperand(0).getDefiningOp();
140 if (!isa_and_nonnull<SignalOp>(op))
144 return {op, std::nullopt};
int64_t getBitWidth(mlir::Type type)
Return the hardware bit width of a type.
std::pair< Operation *, std::optional< ProjectionRange > > getRootSignalAndRange(Value sig)
Given a signal or a projection, find the root signal declaration by traversing the projection chain.
std::optional< ProjectionRange > getProjectionRange(Operation *op)
Calculate a projection's range.
std::variant< ConstProjectionRange, DynProjectionRange > ProjectionRange
Portion of the signal operand that is selected by a projection.
Type getStoredType(Value slot)
Return the type stored in a signal or projection.
Operation * getRootSignal(Value sig)
Given a signal or a projection, walk back the projection chain until you find the root signal declara...
bool isProjection(const Operation *op)
Check if an op is one of the supported projection types.
bool isDynamic(const ProjectionRange &range)
Helper to check if a projection range is dynamic or not.
bool isProvablyDisjoint(const ProjectionRange &a, const ProjectionRange &b)
Check whether two projections provably describe disjoint storage.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Portion of a signal selected by a projection, with a statically known offset and width in bits.
Portion of a signal selected by a projection with a dynamic index.