hdl._ir: remember origins of a fragment during elaboration.

This isn't expected to result in a significant increase in memory use,
so for now it's enabled by default. Elaboration chains where it is not
desired to preserve origins can delete the `origins` attribute from
the fragment and nothing will be stored.

The interface `Fragment.origins` remains private, as is the rest of
the `Fragment` interface (including itself), but it enables certain
codebases that currently use a much more invasive technique to rely on
reading a single private field.
This commit is contained in:
Catherine 2024-02-13 14:54:54 +00:00
parent c40cfc9fb5
commit 09029cdd91
2 changed files with 32 additions and 0 deletions

View file

@ -31,8 +31,11 @@ class Fragment:
@staticmethod
def get(obj, platform):
code = None
origins = []
while True:
if isinstance(obj, Fragment):
if hasattr(obj, "origins"):
obj.origins = tuple(origins)
return obj
elif isinstance(obj, Elaboratable):
code = obj.elaborate.__code__
@ -58,6 +61,7 @@ class Fragment:
category=UserWarning,
filename=code.co_filename,
lineno=code.co_firstlineno)
origins.append(obj)
obj = new_obj
def __init__(self, *, src_loc=None):
@ -70,6 +74,7 @@ class Fragment:
self.generated = OrderedDict()
self.flatten = False
self.src_loc = src_loc
self.origins = None
def add_ports(self, *ports, dir):
assert dir in ("i", "o", "io")