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 rtg.ImmediateType(t)
161 return rtg.ArrayType(t)
165 return rtgtest.IntegerRegisterType(t)
169 raise TypeError(f
"Cannot convert {repr(t)} to python type")
175def attribute_to_var(attr):
179 if not isinstance(attr, ir.Attribute):
180 raise TypeError(
"attribute_to_var only accepts MLIR Attributes")
184 if attr.__class__ != ir.Attribute
and hasattr(attr,
"value"):
187 from .dialects
import hw, om
189 return ir.BoolAttr(attr).value
193 return ir.IntegerAttr(attr).value
197 return ir.StringAttr(hw.InnerSymAttr(attr).symName).value
201 return ir.StringAttr(attr).value
205 return ir.FlatSymbolRefAttr(attr).value
209 return ir.TypeAttr(attr).value
213 arr = ir.ArrayAttr(attr)
214 return [attribute_to_var(x)
for x
in arr]
218 dict = ir.DictAttr(attr)
219 return {i.name: attribute_to_var(i.attr)
for i
in dict}
223 return attribute_to_var(om.ReferenceAttr(attr).inner_ref)
227 ref = hw.InnerRefAttr(attr)
228 return (ir.StringAttr(ref.module).value, ir.StringAttr(ref.name).value)
232 return list(map(attribute_to_var, om.ListAttr(attr)))
236 return {name: attribute_to_var(value)
for name, value
in om.MapAttr(attr)}
240 return int(str(om.OMIntegerAttr(attr)))
244 return om.PathAttr(attr).value
248 raise TypeError(f
"Cannot convert {repr(attr)} to python value")
252 from .dialects
import hw
253 if type(mlir_type)
is ir.Type:
255 if isinstance(mlir_type, hw.TypeAliasType):
269 instance_of: ir.Operation,
270 loc: ir.Location =
None):
271 self.creator: BackedgeBuilder = creator
272 self.
dummy_op = ir.Operation.create(
"builtin.unrealized_conversion_cast",
288 if self
in self.creator.edges:
289 self.creator.edges.remove(self)
298 bb = _current_backedge_builder.get(
None)
300 raise RuntimeError(
"No backedge builder found in context!")
305 return BackedgeBuilder.current().
_create(*args, **kwargs)
311 instance_of: ir.Operation =
None,
312 loc: ir.Location =
None):
321 def __exit__(self, exc_type, exc_value, traceback):
322 if exc_value
is not None:
326 for edge
in list(self.
edges):
328 msg =
"Backedge: " + edge.port_name +
"\n"
329 if edge.instance_of
is not None:
330 msg +=
"InstanceOf: " + str(edge.instance_of).split(
" {")[0] +
"\n"
331 if edge.op_view
is not None:
332 op = edge.op_view.operation
333 msg +=
"Instance: " + str(op)
334 if edge.loc
is not None:
335 msg +=
"Location: " + str(edge.loc)
340 0, f
"Uninitialized backedges remain in module '{self.circuit_name}'")
345 __slots__ = [
"index",
"operation",
"value",
"backedge_owner"]
348 operation: ir.Operation,
351 backedge_owner=
None):
352 if not isinstance(index, int):
353 raise TypeError(
"Index must be int")
356 if not hasattr(operation,
"operands"):
357 raise TypeError(
"Operation must be have 'operands' attribute")
365 return self.
value.type
369 """Helper class to incrementally construct an instance of an operation that
370 names its operands and results"""
375 input_port_mapping=None,
378 needs_result_type=False,
381 if input_port_mapping
is None:
382 input_port_mapping = {}
385 if post_args
is None:
389 result_names = self.result_names()
391 for i
in range(len(result_names)):
392 result_indices[result_names[i]] = i
399 operand_names = self.operand_names()
400 for i
in range(len(operand_names)):
401 arg_name = operand_names[i]
402 operand_indices[arg_name] = i
403 if arg_name
in input_port_mapping:
404 value = get_value(input_port_mapping[arg_name])
408 backedges[i] = backedge
409 operand = backedge.result
410 operand_values.append(operand)
413 if isinstance(data_type, list):
414 operand_values = [operand_values]
422 if data_type
is not None and (needs_result_type
or len(backedges) == 0):
423 pre_args.insert(0, data_type)
425 self.
opview = cls(*pre_args, *operand_values, *post_args, **kwargs)
434 value = self.
opview.operands[index]
440 value = self.
opview.results[index]
444 if name ==
"attributes":
445 return self.
opview.operation.attributes
448 raise AttributeError(f
"unknown port name {name}")
451 return BackedgeBuilder.create(data_type, arg_name, self)
455 """Get the operation associated with this builder."""
456 return self.
opview.operation
464 op_names_identifiers = [name.OPERATION_NAME
for name
in op_views]
465 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)