| """GDB pretty printers for MLIR types.""" |
| |
| import gdb.printing |
| |
| |
| class StoragePrinter: |
| """Prints bases of a struct and its fields.""" |
| |
| def __init__(self, val): |
| self.val = val |
| |
| def children(self): |
| for field in self.val.type.fields(): |
| if field.is_base_class: |
| yield ('<%s>' % field.name, self.val.cast(field.type)) |
| else: |
| yield (field.name, self.val[field.name]) |
| |
| |
| class TupleTypeStoragePrinter(StoragePrinter): |
| |
| def children(self): |
| for child in StoragePrinter.children(self): |
| yield child |
| pointer_type = gdb.lookup_type('mlir::Type').pointer() |
| elements = (self.val.address + 1).cast(pointer_type) |
| for i in range(self.val['numElements']): |
| yield 'elements[%u]' % i, elements[i] |
| |
| |
| class RankedTypeStoragePrinter(StoragePrinter): |
| |
| def children(self): |
| for child in StoragePrinter.children(self): |
| yield child |
| for i in range(self.val['shapeSize']): |
| yield 'shapeElements[%u]' % i, self.val['shapeElements'][i] |
| |
| |
| class MemRefTypeStoragePrinter(RankedTypeStoragePrinter): |
| |
| def children(self): |
| for child in RankedTypeStoragePrinter.children(self): |
| yield child |
| for i in range(self.val['numAffineMaps']): |
| yield 'affineMapsList[%u]' % i, self.val['affineMapsList'][i] |
| |
| |
| class FusedLocationStoragePrinter(StoragePrinter): |
| |
| def children(self): |
| for child in StoragePrinter.children(self): |
| yield child |
| pointer_type = gdb.lookup_type('mlir::Location').pointer() |
| elements = (self.val.address + 1).cast(pointer_type) |
| for i in range(self.val['numLocs']): |
| yield 'locs[%u]' % i, elements[i] |
| |
| |
| class StorageUserBasePrinter: |
| """Printer for an mlir::detail::StorageUserBase instance.""" |
| |
| def __init__(self, val): |
| self.val = val |
| |
| def children(self): |
| storage_type = self.val.type.template_argument(2) |
| yield 'impl', self.val['impl'].dereference().cast(storage_type) |
| |
| |
| class StorageTypeMap: |
| """Maps a TypeID to the corresponding type derived from StorageUserBase. |
| |
| Types need to be registered by name before the first lookup. |
| """ |
| |
| def __init__(self): |
| self.map = None |
| self.type_names = [] |
| |
| def register_type(self, type_name): |
| assert not self.map, 'register_type called after __getitem__' |
| self.type_names += [type_name] |
| |
| def _init_map(self): |
| """Lazy initialization of self.map.""" |
| if self.map: |
| return |
| self.map = {} |
| for type_name in self.type_names: |
| concrete_type = gdb.lookup_type(type_name) |
| try: |
| storage = gdb.parse_and_eval( |
| "&'mlir::detail::TypeIDExported::get<%s>()::instance'" % type_name) |
| except gdb.error: |
| # Skip when TypeID instance cannot be found in current context. |
| continue |
| if concrete_type and storage: |
| self.map[int(storage)] = concrete_type |
| |
| def __getitem__(self, type_id): |
| self._init_map() |
| return self.map.get(int(type_id['storage'])) |
| |
| |
| storage_type_map = StorageTypeMap() |
| |
| |
| def get_type_id_printer(val): |
| """Returns a printer of the name of a mlir::TypeID.""" |
| |
| class StringPrinter: |
| |
| def __init__(self, string): |
| self.string = string |
| |
| def to_string(self): |
| return self.string |
| |
| concrete_type = storage_type_map[val] |
| if not concrete_type: |
| return None |
| return StringPrinter('"%s"' % concrete_type.name) |
| |
| |
| def get_attr_or_type_printer(val, get_type_id): |
| """Returns a printer for mlir::Attribute or mlir::Type.""" |
| |
| class UpcastPrinter: |
| |
| def __init__(self, val, type): |
| self.val = val.cast(type) |
| |
| def children(self): |
| yield 'cast<%s>' % self.val.type.name, self.val |
| |
| if not val['impl']: |
| return None |
| type_id = get_type_id(val['impl'].dereference()) |
| concrete_type = storage_type_map[type_id] |
| if not concrete_type: |
| return None |
| return UpcastPrinter(val, concrete_type) |
| |
| |
| pp = gdb.printing.RegexpCollectionPrettyPrinter('MLIRSupport') |
| |
| # Printers for types deriving from AttributeStorage or TypeStorage. |
| pp.add_printer('mlir::detail::FusedLocationStorage', |
| '^mlir::detail::FusedLocationStorage', |
| FusedLocationStoragePrinter) |
| pp.add_printer('mlir::detail::VectorTypeStorage', |
| '^mlir::detail::VectorTypeStorage', RankedTypeStoragePrinter) |
| pp.add_printer('mlir::detail::RankedTensorTypeStorage', |
| '^mlir::detail::RankedTensorTypeStorage', |
| RankedTypeStoragePrinter) |
| pp.add_printer('mlir::detail::MemRefTypeStorage', |
| '^mlir::detail::MemRefTypeStorage$', MemRefTypeStoragePrinter) |
| pp.add_printer('mlir::detail::TupleTypeStorage', |
| '^mlir::detail::TupleTypeStorage$', TupleTypeStoragePrinter) |
| |
| # Printers for Attribute::AttrBase or Type::TypeBase typedefs. |
| pp.add_printer('mlir::detail::StorageUserBase', |
| '^mlir::detail::StorageUserBase<.*>$', StorageUserBasePrinter) |
| |
| # Printers of types deriving from Attribute::AttrBase or Type::TypeBase. |
| for name in [ |
| # mlir/IR/Attributes.h |
| 'ArrayAttr', |
| 'DictionaryAttr', |
| 'FloatAttr', |
| 'IntegerAttr', |
| 'IntegerSetAttr', |
| 'OpaqueAttr', |
| 'StringAttr', |
| 'SymbolRefAttr', |
| 'TypeAttr', |
| 'UnitAttr', |
| 'DenseStringElementsAttr', |
| 'DenseIntOrFPElementsAttr', |
| 'OpaqueElementsAttr', |
| 'SparseElementsAttr', |
| # mlir/IR/BuiltinTypes.h |
| 'ComplexType', |
| 'IndexType', |
| 'IntegerType', |
| 'Float16Type', |
| 'Float32Type', |
| 'Float64Type', |
| 'Float80Type', |
| 'Float128Type', |
| 'NoneType', |
| 'VectorType', |
| 'RankedTensorType', |
| 'UnrankedTensorType', |
| 'MemRefType', |
| 'UnrankedMemRefType', |
| 'TupleType', |
| # mlir/IR/Location.h |
| 'CallSiteLoc', |
| 'FileLineColLoc', |
| 'FusedLoc', |
| 'NameLoc', |
| 'OpaqueLoc', |
| 'UnknownLoc' |
| ]: |
| storage_type_map.register_type('mlir::%s' % name) # Register for upcasting. |
| |
| pp.add_printer('mlir::TypeID', '^mlir::TypeID$', get_type_id_printer) |
| |
| |
| def add_attr_or_type_printers(name): |
| """Adds printers for mlir::Attribute or mlir::Type and their Storage type.""" |
| get_type_id = lambda val: val['abstract%s' % name]['typeID'] |
| pp.add_printer('mlir::%s' % name, '^mlir::%s$' % name, |
| lambda val: get_attr_or_type_printer(val, get_type_id)) |
| pp.add_printer('mlir::%sStorage' % name, '^mlir::%sStorage$' % name, |
| lambda val: get_type_id_printer(get_type_id(val))) |
| |
| |
| # Upcasting printers of mlir::Attribute and mlir::Type. |
| for name in ['Attribute', 'Type']: |
| add_attr_or_type_printers(name) |
| |
| gdb.printing.register_pretty_printer(gdb.current_objfile(), pp) |