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}.")
22 def __init__(self, module: str, port_names: List[str]):
…
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"):
27def get_value(obj) -> ir.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")
57def var_to_attribute(obj, none_on_fail: bool =
False) -> ir.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 ir.TupleType(t)
105 return hw.ArrayType(t)
109 return hw.StructType(t)
113 return hw.TypeAliasType(t)
117 return hw.InOutType(t)
121 return seq.ClockType(t)
137 return rtg.LabelType(t)
141 return rtg.SetType(t)
145 return rtg.BagType(t)
149 return rtg.SequenceType(t)
153 return rtg.RandomizedSequenceType(t)
157 return rtg.DictType(t)
161 return rtg.ImmediateType(t)
165 return rtg.ArrayType(t)
169 return rtg.MemoryType(t)
173 return rtg.MemoryBlockType(t)
177 return rtgtest.IntegerRegisterType(t)
181 return rtgtest.CPUType(t)
185 raise TypeError(f
"Cannot convert {repr(t)} to python type")
191def attribute_to_var(attr):
195 if not isinstance(attr, ir.Attribute):
196 raise TypeError(
"attribute_to_var only accepts MLIR Attributes")
200 if attr.__class__ != ir.Attribute
and hasattr(attr,
"value"):
203 from .dialects
import hw, om
205 return ir.BoolAttr(attr).value
209 return ir.IntegerAttr(attr).value
213 return ir.StringAttr(hw.InnerSymAttr(attr).symName).value
217 return ir.StringAttr(attr).value
221 return ir.FlatSymbolRefAttr(attr).value
225 return ir.TypeAttr(attr).value
229 arr = ir.ArrayAttr(attr)
230 return [attribute_to_var(x)
for x
in arr]
234 dict = ir.DictAttr(attr)
235 return {i.name: attribute_to_var(i.attr)
for i
in dict}
239 return attribute_to_var(om.ReferenceAttr(attr).inner_ref)
243 ref = hw.InnerRefAttr(attr)
244 return (ir.StringAttr(ref.module).value, ir.StringAttr(ref.name).value)
248 return list(map(attribute_to_var, om.ListAttr(attr)))
252 return {name: attribute_to_var(value)
for name, value
in om.MapAttr(attr)}
256 return int(str(om.OMIntegerAttr(attr)))
260 return om.PathAttr(attr).value
264 raise TypeError(f
"Cannot convert {repr(attr)} to python value")
191def attribute_to_var(attr):
…
268 from .dialects
import hw
269 if type(mlir_type)
is ir.Type:
271 if isinstance(mlir_type, hw.TypeAliasType):
285 instance_of: ir.Operation,
286 loc: ir.Location =
None):
287 self.creator: BackedgeBuilder = creator
288 self.
dummy_op = ir.Operation.create(
"builtin.unrealized_conversion_cast",
304 if self
in self.creator.edges:
305 self.creator.edges.remove(self)
314 bb = _current_backedge_builder.get(
None)
316 raise RuntimeError(
"No backedge builder found in context!")
321 return BackedgeBuilder.current().
_create(*args, **kwargs)
327 instance_of: ir.Operation =
None,
328 loc: ir.Location =
None):
337 def __exit__(self, exc_type, exc_value, traceback):
338 if exc_value
is not None:
342 for edge
in list(self.
edges):
344 msg =
"Backedge: " + edge.port_name +
"\n"
345 if edge.instance_of
is not None:
346 msg +=
"InstanceOf: " + str(edge.instance_of).split(
" {")[0] +
"\n"
347 if edge.op_view
is not None:
348 op = edge.op_view.operation
349 msg +=
"Instance: " + str(op)
350 if edge.loc
is not None:
351 msg +=
"Location: " + str(edge.loc)
356 0, f
"Uninitialized backedges remain in module '{self.circuit_name}'")
361 __slots__ = [
"index",
"operation",
"value",
"backedge_owner"]
364 operation: ir.Operation,
367 backedge_owner=
None):
368 if not isinstance(index, int):
369 raise TypeError(
"Index must be int")
372 if not hasattr(operation,
"operands"):
373 raise TypeError(
"Operation must be have 'operands' attribute")
381 return self.
value.type
385 """Helper class to incrementally construct an instance of an operation that
386 names its operands and results"""
391 input_port_mapping=None,
394 needs_result_type=False,
397 if input_port_mapping
is None:
398 input_port_mapping = {}
401 if post_args
is None:
405 result_names = self.result_names()
407 for i
in range(len(result_names)):
408 result_indices[result_names[i]] = i
415 operand_names = self.operand_names()
416 for i
in range(len(operand_names)):
417 arg_name = operand_names[i]
418 operand_indices[arg_name] = i
419 if arg_name
in input_port_mapping:
420 value = get_value(input_port_mapping[arg_name])
424 backedges[i] = backedge
425 operand = backedge.result
426 operand_values.append(operand)
429 if isinstance(data_type, list):
430 operand_values = [operand_values]
438 if data_type
is not None and (needs_result_type
or len(backedges) == 0):
439 pre_args.insert(0, data_type)
441 self.
opview = cls(*pre_args, *operand_values, *post_args, **kwargs)
450 value = self.
opview.operands[index]
456 value = self.
opview.results[index]
460 if name ==
"attributes":
461 return self.
opview.operation.attributes
464 raise AttributeError(f
"unknown port name {name}")
467 return BackedgeBuilder.create(data_type, arg_name, self)
471 """Get the operation associated with this builder."""
472 return self.
opview.operation
480 op_names_identifiers = [name.OPERATION_NAME
for name
in op_views]
481 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)