llvm-project
227 строк · 6.2 Кб
1"""GDB pretty printers for MLIR types."""
2
3import gdb.printing4
5
6class StoragePrinter:7"""Prints bases of a struct and its fields."""8
9def __init__(self, val):10self.val = val11
12def children(self):13for field in self.val.type.fields():14if field.is_base_class:15yield "<%s>" % field.name, self.val.cast(field.type)16else:17yield field.name, self.val[field.name]18
19def to_string(self):20return "mlir::Storage"21
22
23class TupleTypeStoragePrinter(StoragePrinter):24def children(self):25for child in StoragePrinter.children(self):26yield child27pointer_type = gdb.lookup_type("mlir::Type").pointer()28elements = (self.val.address + 1).cast(pointer_type)29for i in range(self.val["numElements"]):30yield "elements[%u]" % i, elements[i]31
32def to_string(self):33return "mlir::TupleTypeStorage of %u elements" % self.val["numElements"]34
35
36class FusedLocationStoragePrinter(StoragePrinter):37def children(self):38for child in StoragePrinter.children(self):39yield child40pointer_type = gdb.lookup_type("mlir::Location").pointer()41elements = (self.val.address + 1).cast(pointer_type)42for i in range(self.val["numLocs"]):43yield "locs[%u]" % i, elements[i]44
45def to_string(self):46return "mlir::FusedLocationStorage of %u locs" % self.val["numLocs"]47
48
49class StorageTypeMap:50"""Maps a TypeID to the corresponding concrete type.51
52Types need to be registered by name before the first lookup.
53"""
54
55def __init__(self):56self.map = None57self.type_names = []58
59def register_type(self, type_name):60assert not self.map, "register_type called after __getitem__"61self.type_names += [type_name]62
63def _init_map(self):64"""Lazy initialization of self.map."""65if self.map:66return67self.map = {}68for type_name in self.type_names:69concrete_type = gdb.lookup_type(type_name)70try:71storage = gdb.parse_and_eval(72"&'mlir::detail::TypeIDExported::get<%s>()::instance'" % type_name73)74except gdb.error:75# Skip when TypeID instance cannot be found in current context.76continue77if concrete_type and storage:78self.map[int(storage)] = concrete_type79
80def __getitem__(self, type_id):81self._init_map()82return self.map.get(int(type_id["storage"]))83
84
85storage_type_map = StorageTypeMap()86
87
88def get_type_id_printer(val):89"""Returns a printer of the name of a mlir::TypeID."""90
91class TypeIdPrinter:92def __init__(self, string):93self.string = string94
95def to_string(self):96return self.string97
98concrete_type = storage_type_map[val]99if not concrete_type:100return None101return TypeIdPrinter("mlir::TypeID::get<%s>()" % concrete_type)102
103
104def get_attr_or_type_printer(val, get_type_id):105"""Returns a printer for mlir::Attribute or mlir::Type."""106
107class AttrOrTypePrinter:108def __init__(self, type_id, impl):109self.type_id = type_id110self.impl = impl111
112def children(self):113yield "typeID", self.type_id114yield "impl", self.impl115
116def to_string(self):117return "cast<%s>" % self.impl.type118
119if not val["impl"]:120return None121impl = val["impl"].dereference()122type_id = get_type_id(impl)123concrete_type = storage_type_map[type_id]124if not concrete_type:125return None126# 3rd template argument of StorageUserBase is the storage type.127storage_type = concrete_type.fields()[0].type.template_argument(2)128if not storage_type:129return None130return AttrOrTypePrinter(type_id, impl.cast(storage_type))131
132
133class ImplPrinter:134"""Printer for an instance with a single 'impl' member pointer."""135
136def __init__(self, val):137self.val = val138self.impl = val["impl"]139
140def children(self):141if self.impl:142yield "impl", self.impl.dereference()143
144def to_string(self):145return self.val.type.name146
147
148# Printers of types deriving from Attribute::AttrBase or Type::TypeBase.
149for name in [150# mlir/IR/Attributes.h151"ArrayAttr",152"DictionaryAttr",153"FloatAttr",154"IntegerAttr",155"IntegerSetAttr",156"OpaqueAttr",157"StringAttr",158"SymbolRefAttr",159"TypeAttr",160"UnitAttr",161"DenseStringElementsAttr",162"DenseIntOrFPElementsAttr",163"SparseElementsAttr",164# mlir/IR/BuiltinTypes.h165"ComplexType",166"IndexType",167"IntegerType",168"Float16Type",169"FloatTF32Type",170"Float32Type",171"Float64Type",172"Float80Type",173"Float128Type",174"NoneType",175"VectorType",176"RankedTensorType",177"UnrankedTensorType",178"MemRefType",179"UnrankedMemRefType",180"TupleType",181# mlir/IR/Location.h182"CallSiteLoc",183"FileLineColLoc",184"FusedLoc",185"NameLoc",186"OpaqueLoc",187"UnknownLoc",188]:189storage_type_map.register_type("mlir::%s" % name) # Register for upcasting.190storage_type_map.register_type("void") # Register default.191
192
193pp = gdb.printing.RegexpCollectionPrettyPrinter("MLIRSupport")194
195pp.add_printer("mlir::OperationName", "^mlir::OperationName$", ImplPrinter)196pp.add_printer("mlir::Value", "^mlir::Value$", ImplPrinter)197
198# Printers for types deriving from AttributeStorage or TypeStorage.
199pp.add_printer(200"mlir::detail::FusedLocationStorage",201"^mlir::detail::FusedLocationStorage",202FusedLocationStoragePrinter,203)
204pp.add_printer(205"mlir::detail::TupleTypeStorage",206"^mlir::detail::TupleTypeStorage$",207TupleTypeStoragePrinter,208)
209
210pp.add_printer("mlir::TypeID", "^mlir::TypeID$", get_type_id_printer)211
212
213def add_attr_or_type_printers(name):214"""Adds printers for mlir::Attribute or mlir::Type and their Storage type."""215get_type_id = lambda val: val["abstract%s" % name]["typeID"]216pp.add_printer(217"mlir::%s" % name,218"^mlir::%s$" % name,219lambda val: get_attr_or_type_printer(val, get_type_id),220)221
222
223# Upcasting printers of mlir::Attribute and mlir::Type.
224for name in ["Attribute", "Type"]:225add_attr_or_type_printers(name)226
227gdb.printing.register_pretty_printer(gdb.current_objfile(), pp)228