[PyCDE] Improve location information (#8635)

- Move from single location to stack
- Add location to a bunch of places it was missing
This commit is contained in:
John Demme 2025-07-07 08:58:16 -07:00 committed by GitHub
parent 587474b1aa
commit 74736548c8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 65 additions and 45 deletions

View File

@ -7,6 +7,7 @@ from typing import Dict, Tuple, Type
from ..signals import BundleSignal
from ..common import AppID, Clock, Input, Output
from ..module import Module, generator
from ..support import get_user_loc
from ..system import System
from ..types import (Bits, Bundle, BundledChannel, Channel, ChannelDirection,
StructType, UInt)
@ -107,7 +108,8 @@ def CosimBSP(user_module: Type[Module], emulate_dma: bool = False) -> Module:
appID=AppID("cosim")._appid,
service_symbol=None,
impl_type=ir.StringAttr.get("cosim"),
inputs=[ports.clk.value, ports.rst.value])
inputs=[ports.clk.value, ports.rst.value],
loc=get_user_loc())
return ESI_Cosim_Top

View File

@ -81,7 +81,8 @@ class ServiceDecl(_PyProxy):
for (_, attr) in self.__dict__.items():
if isinstance(attr, _RequestConnection):
raw_esi.ServiceDeclPortOp(attr._name,
ir.TypeAttr.get(attr.type._type))
ir.TypeAttr.get(attr.type._type),
loc=get_user_loc())
return sym_name
def instantiate_builtin(self,
@ -99,7 +100,8 @@ class ServiceDecl(_PyProxy):
service_symbol=ir.FlatSymbolRefAttr.get(
self._materialize_service_decl()),
impl_type=ir.StringAttr.get(builtin),
inputs=[x.value for x in inputs]).operation.results
inputs=[x.value for x in inputs],
loc=get_user_loc()).operation.results
return [_FromCirctValue(x) for x in impl_results]
def implement_as(self,
@ -131,8 +133,10 @@ class _RequestConnection:
type = self.type
self.decl._materialize_service_decl()
return _FromCirctValue(
raw_esi.RequestConnectionOp(type._type, self.service_port,
appid._appid).toClient)
raw_esi.RequestConnectionOp(type._type,
self.service_port,
appid._appid,
loc=get_user_loc()).toClient)
def Cosim(decl: ServiceDecl, clk, rst):
@ -190,13 +194,12 @@ class _OutputBundleSetter(AssignableSignal):
with get_user_loc(), ir.InsertionPoint.at_block_begin(
self.rec.reqDetails.blocks[0]):
raw_esi.ServiceImplClientRecordOp(
self.req.relativeAppIDPath,
self.req.servicePort,
ir.TypeAttr.get(self.req.toClient.type),
channelAssignments=channel_assignments,
implDetails=details,
)
raw_esi.ServiceImplClientRecordOp(self.req.relativeAppIDPath,
self.req.servicePort,
ir.TypeAttr.get(self.req.toClient.type),
channelAssignments=channel_assignments,
implDetails=details,
loc=get_user_loc())
@property
def client_name(self) -> List[AppID]:
@ -231,10 +234,13 @@ class EngineServiceRecord:
details: Optional[Dict[str, object]] = None):
rec_appid = AppID(f"{engine.appid.name}_record", engine.appid.index)
details = optional_dict_to_dict_attr(details)
self._rec = raw_esi.ServiceImplRecordOp(appID=rec_appid._appid,
serviceImplName=engine.TypeName,
implDetails=details,
isEngine=True)
self._rec = raw_esi.ServiceImplRecordOp(
appID=rec_appid._appid,
serviceImplName=engine.TypeName,
implDetails=details,
isEngine=True,
loc=get_user_loc(),
)
self._rec.regions[0].blocks.append()
def add_record(self,
@ -256,6 +262,7 @@ class EngineServiceRecord:
ir.TypeAttr.get(client.req.toClient.type),
channelAssignments=channel_assignments,
implDetails=details,
loc=get_user_loc(),
)
@ -498,8 +505,10 @@ def DeclareRandomAccessMemory(inner_type: Type,
@staticmethod
def _op(sym_name: ir.StringAttr):
return raw_esi.RandomAccessMemoryDeclOp(
sym_name, ir.TypeAttr.get(inner_type._type),
ir.IntegerAttr.get(ir.IntegerType.get_signless(64), depth))
sym_name,
ir.TypeAttr.get(inner_type._type),
ir.IntegerAttr.get(ir.IntegerType.get_signless(64), depth),
loc=get_user_loc())
if name is not None:
DeclareRandomAccessMemory.name = name
@ -628,7 +637,7 @@ class MMIO:
@staticmethod
def _op(sym_name: ir.StringAttr):
return raw_esi.MMIOServiceDeclOp(sym_name)
return raw_esi.MMIOServiceDeclOp(sym_name, loc=get_user_loc())
class _HostMem(ServiceDecl):
@ -692,10 +701,12 @@ class _HostMem(ServiceDecl):
return cast(
BundleSignal,
_FromCirctValue(
raw_esi.RequestConnectionOp(
write_bundle_type._type,
hw.InnerRefAttr.get(self.symbol, ir.StringAttr.get("write")),
appid._appid).toClient))
raw_esi.RequestConnectionOp(write_bundle_type._type,
hw.InnerRefAttr.get(
self.symbol,
ir.StringAttr.get("write")),
appid._appid,
loc=get_user_loc()).toClient))
def read_bundle_type(self, resp_type: Type) -> Bundle:
"""Build a read bundle type for the given data type."""
@ -715,10 +726,12 @@ class _HostMem(ServiceDecl):
return cast(
BundleSignal,
_FromCirctValue(
raw_esi.RequestConnectionOp(
read_bundle_type._type,
hw.InnerRefAttr.get(self.symbol, ir.StringAttr.get("read")),
appid._appid).toClient))
raw_esi.RequestConnectionOp(read_bundle_type._type,
hw.InnerRefAttr.get(
self.symbol,
ir.StringAttr.get("read")),
appid._appid,
loc=get_user_loc()).toClient))
def read(self, appid: AppID, req: ChannelSignal,
data_type: Type) -> ChannelSignal:
@ -734,7 +747,7 @@ class _HostMem(ServiceDecl):
@staticmethod
def _op(sym_name: ir.StringAttr):
return raw_esi.HostMemServiceDeclOp(sym_name)
return raw_esi.HostMemServiceDeclOp(sym_name, loc=get_user_loc())
HostMem = _HostMem()
@ -823,16 +836,18 @@ class _FuncService(ServiceDecl):
BundledChannel("result", ChannelDirection.FROM, result.type)
])
self._materialize_service_decl()
func_call = raw_esi.RequestConnectionOp(
bundle._type, hw.InnerRefAttr.get(self.symbol,
ir.StringAttr.get("call")),
name._appid)
func_call = raw_esi.RequestConnectionOp(bundle._type,
hw.InnerRefAttr.get(
self.symbol,
ir.StringAttr.get("call")),
name._appid,
loc=get_user_loc())
to_funcs = _FromCirctValue(func_call.toClient).unpack(result=result)
return to_funcs['arg']
@staticmethod
def _op(sym_name: ir.StringAttr):
return raw_esi.FuncServiceDeclOp(sym_name)
return raw_esi.FuncServiceDeclOp(sym_name, loc=get_user_loc())
FuncService = _FuncService()
@ -862,16 +877,17 @@ class _CallService(ServiceDecl):
self._materialize_service_decl()
func_call = _FromCirctValue(
raw_esi.RequestConnectionOp(
func_type._type,
hw.InnerRefAttr.get(self.symbol, ir.StringAttr.get("call")),
name._appid).toClient)
raw_esi.RequestConnectionOp(func_type._type,
hw.InnerRefAttr.get(
self.symbol, ir.StringAttr.get("call")),
name._appid,
loc=get_user_loc()).toClient)
assert isinstance(func_call, BundleSignal)
return func_call
@staticmethod
def _op(sym_name: ir.StringAttr):
return raw_esi.CallServiceDeclOp(sym_name)
return raw_esi.CallServiceDeclOp(sym_name, loc=get_user_loc())
CallService = _CallService()
@ -907,7 +923,7 @@ class _Telemetry(ServiceDecl):
@staticmethod
def _op(sym_name: ir.StringAttr):
return raw_esi.TelemetryServiceDeclOp(sym_name)
return raw_esi.TelemetryServiceDeclOp(sym_name, loc=get_user_loc())
Telemetry = _Telemetry()

View File

@ -52,7 +52,7 @@ class Signal:
def bitcast(self, new_type: Type) -> Signal:
from .circt.dialects import hw
casted_value = hw.BitcastOp(new_type._type, self.value)
casted_value = hw.BitcastOp(new_type._type, self.value, loc=get_user_loc())
return _FromCirctValue(casted_value.result, new_type)
def reg(self,

View File

@ -70,19 +70,21 @@ def optional_dict_to_dict_attr(d: Optional[Dict]) -> ir.DictAttr:
__dir__ = os.path.dirname(__file__)
_local_files = set([os.path.join(__dir__, x) for x in os.listdir(__dir__)])
_hidden_filenames = set(["functools.py"])
_hidden_filenames = set(["functools.py", "support.py"])
def get_user_loc() -> ir.Location:
import traceback
stack_locs = []
stack = reversed(traceback.extract_stack())
for frame in stack:
fn = os.path.split(frame.filename)[1]
if frame.filename in _local_files or fn in _hidden_filenames:
if fn in _hidden_filenames:
continue
return ir.Location.file(frame.filename, frame.lineno, 0)
return ir.Location.unknown()
stack_locs.append(ir.Location.file(frame.filename, frame.lineno, 0))
if len(stack_locs) == 0:
return ir.Location.unknown()
return ir.Location.callsite(stack_locs[0], stack_locs[1:])
def create_const_zero(type):