7from ._mlir_libs._circt._support
import _walk_with_filter
8from .ir
import Operation
9from contextlib
import AbstractContextManager
10from contextvars
import ContextVar
11from typing
import List
13_current_backedge_builder = ContextVar(
"current_bb")
22 def __init__(self, module: str, port_names: List[str]):
24 f
"Ports {port_names} unconnected in design module {module}.")
27def get_value(obj) -> ir.Value:
28 """Resolve a Value from a few supported types."""
30 if isinstance(obj, ir.Value):
32 if hasattr(obj,
"result"):
34 if hasattr(obj,
"value"):
40 """A convenient way to use BackedgeBuilder."""
41 if not isinstance(destination, OpOperand):
43 f
"cannot connect to destination of type {type(destination)}. "
45 value = get_value(source)
47 raise TypeError(f
"cannot connect from source of type {type(source)}")
49 index = destination.index
50 destination.operation.operands[index] = value
51 if destination.backedge_owner
and \
52 index
in destination.backedge_owner.backedges:
53 destination.backedge_owner.backedges[index].erase()
54 del destination.backedge_owner.backedges[index]
57def var_to_attribute(obj, none_on_fail: bool =
False) -> ir.Attribute:
58 """Create an MLIR attribute from a Python object for a few common cases."""
59 if isinstance(obj, ir.Attribute):
61 if isinstance(obj, bool):
62 return ir.BoolAttr.get(obj)
63 if isinstance(obj, int):
64 attrTy = ir.IntegerType.get_signless(64)
65 return ir.IntegerAttr.get(attrTy, obj)
66 if isinstance(obj, str):
67 return ir.StringAttr.get(obj)
68 if isinstance(obj, list):
69 arr = [var_to_attribute(x, none_on_fail)
for x
in obj]
71 return ir.ArrayAttr.get(arr)
75 raise TypeError(f
"Cannot convert type '{type(obj)}' to MLIR attribute")
83 if not isinstance(t, ir.Type):
84 raise TypeError(
"type_to_pytype only accepts MLIR Type objects")
88 if t.__class__ != ir.Type:
91 from .dialects
import esi, hw, seq, rtg, rtgtest
93 return ir.IntegerType(t)
101 return hw.ArrayType(t)
105 return hw.StructType(t)
109 return hw.TypeAliasType(t)
113 return hw.InOutType(t)
117 return seq.ClockType(t)
133 return rtg.LabelType(t)
137 return rtg.SetType(t)
141 return rtg.BagType(t)
145 return rtg.SequenceType(t)
149 return rtg.RandomizedSequenceType(t)
153 return rtg.DictType(t)
157 return rtgtest.IntegerRegisterType(t)
161 return rtgtest.Imm5Type(t)
165 return rtgtest.Imm12Type(t)
169 return rtgtest.Imm13Type(t)
173 return rtgtest.Imm21Type(t)
177 return rtgtest.Imm32Type(t)
181 raise TypeError(f
"Cannot convert {repr(t)} to python type")
187def attribute_to_var(attr):
191 if not isinstance(attr, ir.Attribute):
192 raise TypeError(
"attribute_to_var only accepts MLIR Attributes")
196 if attr.__class__ != ir.Attribute
and hasattr(attr,
"value"):
199 from .dialects
import hw, om
201 return ir.BoolAttr(attr).value
205 return ir.IntegerAttr(attr).value
209 return ir.StringAttr(hw.InnerSymAttr(attr).symName).value
213 return ir.StringAttr(attr).value
217 return ir.FlatSymbolRefAttr(attr).value
221 return ir.TypeAttr(attr).value
225 arr = ir.ArrayAttr(attr)
226 return [attribute_to_var(x)
for x
in arr]
230 dict = ir.DictAttr(attr)
231 return {i.name: attribute_to_var(i.attr)
for i
in dict}
235 return attribute_to_var(om.ReferenceAttr(attr).inner_ref)
239 ref = hw.InnerRefAttr(attr)
240 return (ir.StringAttr(ref.module).value, ir.StringAttr(ref.name).value)
244 return list(map(attribute_to_var, om.ListAttr(attr)))
248 return {name: attribute_to_var(value)
for name, value
in om.MapAttr(attr)}
252 return int(str(om.OMIntegerAttr(attr)))
256 return om.PathAttr(attr).value
260 raise TypeError(f
"Cannot convert {repr(attr)} to python value")
264 from .dialects
import hw
265 if type(mlir_type)
is ir.Type:
267 if isinstance(mlir_type, hw.TypeAliasType):
281 instance_of: ir.Operation,
282 loc: ir.Location =
None):
283 self.creator: BackedgeBuilder = creator
284 self.
dummy_op = ir.Operation.create(
"builtin.unrealized_conversion_cast",
300 if self
in self.creator.edges:
301 self.creator.edges.remove(self)
310 bb = _current_backedge_builder.get(
None)
312 raise RuntimeError(
"No backedge builder found in context!")
317 return BackedgeBuilder.current().
_create(*args, **kwargs)
323 instance_of: ir.Operation =
None,
324 loc: ir.Location =
None):
333 def __exit__(self, exc_type, exc_value, traceback):
334 if exc_value
is not None:
338 for edge
in list(self.
edges):
340 msg =
"Backedge: " + edge.port_name +
"\n"
341 if edge.instance_of
is not None:
342 msg +=
"InstanceOf: " + str(edge.instance_of).split(
" {")[0] +
"\n"
343 if edge.op_view
is not None:
344 op = edge.op_view.operation
345 msg +=
"Instance: " + str(op)
346 if edge.loc
is not None:
347 msg +=
"Location: " + str(edge.loc)
352 0, f
"Uninitialized backedges remain in module '{self.circuit_name}'")
357 __slots__ = [
"index",
"operation",
"value",
"backedge_owner"]
360 operation: ir.Operation,
363 backedge_owner=
None):
364 if not isinstance(index, int):
365 raise TypeError(
"Index must be int")
368 if not hasattr(operation,
"operands"):
369 raise TypeError(
"Operation must be have 'operands' attribute")
377 return self.
value.type
381 """Helper class to incrementally construct an instance of an operation that
382 names its operands and results"""
387 input_port_mapping=None,
390 needs_result_type=False,
393 if input_port_mapping
is None:
394 input_port_mapping = {}
397 if post_args
is None:
401 result_names = self.result_names()
403 for i
in range(len(result_names)):
404 result_indices[result_names[i]] = i
411 operand_names = self.operand_names()
412 for i
in range(len(operand_names)):
413 arg_name = operand_names[i]
414 operand_indices[arg_name] = i
415 if arg_name
in input_port_mapping:
416 value = get_value(input_port_mapping[arg_name])
420 backedges[i] = backedge
421 operand = backedge.result
422 operand_values.append(operand)
425 if isinstance(data_type, list):
426 operand_values = [operand_values]
434 if data_type
is not None and (needs_result_type
or len(backedges) == 0):
435 pre_args.insert(0, data_type)
437 self.
opview = cls(*pre_args, *operand_values, *post_args, **kwargs)
446 value = self.
opview.operands[index]
452 value = self.
opview.results[index]
456 if name ==
"attributes":
457 return self.
opview.operation.attributes
460 raise AttributeError(f
"unknown port name {name}")
463 return BackedgeBuilder.create(data_type, arg_name, self)
467 """Get the operation associated with this builder."""
468 return self.
opview.operation
476 op_names_identifiers = [name.OPERATION_NAME
for name
in op_views]
477 return _walk_with_filter(operation, op_names_identifiers, callback,
__init__(self, creator, ir.Type type, str backedge_name, op_view, ir.Operation instance_of, ir.Location loc=None)
__init__(self, str circuit_name="")
_create(self, ir.Type type, str port_name, op_view, ir.Operation instance_of=None, ir.Location loc=None)
__exit__(self, exc_type, exc_value, traceback)
__init__(self, cls, data_type=None, input_port_mapping=None, pre_args=None, post_args=None, needs_result_type=False, **kwargs)
create_default_value(self, index, data_type, arg_name)
__init__(self, ir.Operation operation, int index, value, backedge_owner=None)
__init__(self, str module, List[str] port_names)
The "any" type is a special type which can be used to represent any type, as identified by the type i...
Bundles represent a collection of channels.
Channels are the basic communication primitives.
get_self_or_inner(mlir_type)
walk_with_filter(Operation operation, List[ir.OpView] op_views, callback, walk_order)
ir.Type type_to_pytype(t)
connect(destination, source)