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
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 raise TypeError(f
"Cannot convert {repr(t)} to python type")
139def attribute_to_var(attr):
143 if not isinstance(attr, ir.Attribute):
144 raise TypeError(
"attribute_to_var only accepts MLIR Attributes")
148 if attr.__class__ != ir.Attribute
and hasattr(attr,
"value"):
151 from .dialects
import hw, om
153 return ir.BoolAttr(attr).value
157 return ir.IntegerAttr(attr).value
161 return ir.StringAttr(hw.InnerSymAttr(attr).symName).value
165 return ir.StringAttr(attr).value
169 return ir.FlatSymbolRefAttr(attr).value
173 return ir.TypeAttr(attr).value
177 arr = ir.ArrayAttr(attr)
178 return [attribute_to_var(x)
for x
in arr]
182 dict = ir.DictAttr(attr)
183 return {i.name: attribute_to_var(i.attr)
for i
in dict}
187 return attribute_to_var(om.ReferenceAttr(attr).inner_ref)
191 ref = hw.InnerRefAttr(attr)
192 return (ir.StringAttr(ref.module).value, ir.StringAttr(ref.name).value)
196 return list(map(attribute_to_var, om.ListAttr(attr)))
200 return {name: attribute_to_var(value)
for name, value
in om.MapAttr(attr)}
204 return int(str(om.OMIntegerAttr(attr)))
208 return om.PathAttr(attr).value
212 raise TypeError(f
"Cannot convert {repr(attr)} to python value")
216 from .dialects
import hw
217 if type(mlir_type)
is ir.Type:
219 if isinstance(mlir_type, hw.TypeAliasType):
233 instance_of: ir.Operation,
234 loc: ir.Location =
None):
235 self.creator: BackedgeBuilder = creator
236 self.
dummy_op = ir.Operation.create(
"builtin.unrealized_conversion_cast",
252 if self
in self.creator.edges:
253 self.creator.edges.remove(self)
262 bb = _current_backedge_builder.get(
None)
264 raise RuntimeError(
"No backedge builder found in context!")
269 return BackedgeBuilder.current().
_create(*args, **kwargs)
275 instance_of: ir.Operation =
None,
276 loc: ir.Location =
None):
285 def __exit__(self, exc_type, exc_value, traceback):
286 if exc_value
is not None:
290 for edge
in list(self.
edges):
292 msg =
"Backedge: " + edge.port_name +
"\n"
293 if edge.instance_of
is not None:
294 msg +=
"InstanceOf: " + str(edge.instance_of).split(
" {")[0] +
"\n"
295 if edge.op_view
is not None:
296 op = edge.op_view.operation
297 msg +=
"Instance: " + str(op)
298 if edge.loc
is not None:
299 msg +=
"Location: " + str(edge.loc)
304 0, f
"Uninitialized backedges remain in module '{self.circuit_name}'")
309 __slots__ = [
"index",
"operation",
"value",
"backedge_owner"]
312 operation: ir.Operation,
315 backedge_owner=
None):
316 if not isinstance(index, int):
317 raise TypeError(
"Index must be int")
320 if not hasattr(operation,
"operands"):
321 raise TypeError(
"Operation must be have 'operands' attribute")
329 return self.
value.type
333 """Helper class to incrementally construct an instance of an operation that
334 names its operands and results"""
339 input_port_mapping=None,
342 needs_result_type=False,
345 if input_port_mapping
is None:
346 input_port_mapping = {}
349 if post_args
is None:
353 result_names = self.result_names()
355 for i
in range(len(result_names)):
356 result_indices[result_names[i]] = i
363 operand_names = self.operand_names()
364 for i
in range(len(operand_names)):
365 arg_name = operand_names[i]
366 operand_indices[arg_name] = i
367 if arg_name
in input_port_mapping:
368 value = get_value(input_port_mapping[arg_name])
372 backedges[i] = backedge
373 operand = backedge.result
374 operand_values.append(operand)
377 if isinstance(data_type, list):
378 operand_values = [operand_values]
386 if data_type
is not None and (needs_result_type
or len(backedges) == 0):
387 pre_args.insert(0, data_type)
389 self.
opview = cls(*pre_args, *operand_values, *post_args, **kwargs)
398 value = self.
opview.operands[index]
404 value = self.
opview.results[index]
408 if name ==
"attributes":
409 return self.
opview.operation.attributes
412 raise AttributeError(f
"unknown port name {name}")
415 return BackedgeBuilder.create(data_type, arg_name, self)
419 """Get the operation associated with this builder."""
420 return self.
opview.operation
428 op_names_identifiers = [name.OPERATION_NAME
for name
in op_views]
429 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)