xref: /llvm-project/mlir/utils/gdb-scripts/prettyprinters.py (revision 6685fd82391d3e654d3b05f2d54cdcdec6e6d887)
1e9b38841SChristian Sigg"""GDB pretty printers for MLIR types."""
2e9b38841SChristian Sigg
3e9b38841SChristian Siggimport gdb.printing
4e9b38841SChristian Sigg
5e9b38841SChristian Sigg
6e9b38841SChristian Siggclass StoragePrinter:
7e9b38841SChristian Sigg    """Prints bases of a struct and its fields."""
8e9b38841SChristian Sigg
9e9b38841SChristian Sigg    def __init__(self, val):
10e9b38841SChristian Sigg        self.val = val
11e9b38841SChristian Sigg
12e9b38841SChristian Sigg    def children(self):
13e9b38841SChristian Sigg        for field in self.val.type.fields():
14e9b38841SChristian Sigg            if field.is_base_class:
15f9008e63STobias Hieta                yield "<%s>" % field.name, self.val.cast(field.type)
16e9b38841SChristian Sigg            else:
17635f8f3cSChristian Sigg                yield field.name, self.val[field.name]
18e9b38841SChristian Sigg
197c5c4e78SKrzysztof Drewniak    def to_string(self):
20f9008e63STobias Hieta        return "mlir::Storage"
21f9008e63STobias Hieta
22e9b38841SChristian Sigg
23e9b38841SChristian Siggclass TupleTypeStoragePrinter(StoragePrinter):
24e9b38841SChristian Sigg    def children(self):
25e9b38841SChristian Sigg        for child in StoragePrinter.children(self):
26e9b38841SChristian Sigg            yield child
27f9008e63STobias Hieta        pointer_type = gdb.lookup_type("mlir::Type").pointer()
28e9b38841SChristian Sigg        elements = (self.val.address + 1).cast(pointer_type)
29f9008e63STobias Hieta        for i in range(self.val["numElements"]):
30f9008e63STobias Hieta            yield "elements[%u]" % i, elements[i]
31e9b38841SChristian Sigg
327c5c4e78SKrzysztof Drewniak    def to_string(self):
33f9008e63STobias Hieta        return "mlir::TupleTypeStorage of %u elements" % self.val["numElements"]
34f9008e63STobias Hieta
35e9b38841SChristian Sigg
36e9b38841SChristian Siggclass FusedLocationStoragePrinter(StoragePrinter):
37e9b38841SChristian Sigg    def children(self):
38e9b38841SChristian Sigg        for child in StoragePrinter.children(self):
39e9b38841SChristian Sigg            yield child
40f9008e63STobias Hieta        pointer_type = gdb.lookup_type("mlir::Location").pointer()
41e9b38841SChristian Sigg        elements = (self.val.address + 1).cast(pointer_type)
42f9008e63STobias Hieta        for i in range(self.val["numLocs"]):
43f9008e63STobias Hieta            yield "locs[%u]" % i, elements[i]
44e9b38841SChristian Sigg
457c5c4e78SKrzysztof Drewniak    def to_string(self):
46f9008e63STobias Hieta        return "mlir::FusedLocationStorage of %u locs" % self.val["numLocs"]
477c5c4e78SKrzysztof Drewniak
48e9b38841SChristian Sigg
49e9b38841SChristian Siggclass StorageTypeMap:
50635f8f3cSChristian Sigg    """Maps a TypeID to the corresponding concrete type.
51e9b38841SChristian Sigg
52e9b38841SChristian Sigg    Types need to be registered by name before the first lookup.
53e9b38841SChristian Sigg    """
54e9b38841SChristian Sigg
55e9b38841SChristian Sigg    def __init__(self):
56e9b38841SChristian Sigg        self.map = None
57e9b38841SChristian Sigg        self.type_names = []
58e9b38841SChristian Sigg
59e9b38841SChristian Sigg    def register_type(self, type_name):
60f9008e63STobias Hieta        assert not self.map, "register_type called after __getitem__"
61e9b38841SChristian Sigg        self.type_names += [type_name]
62e9b38841SChristian Sigg
63e9b38841SChristian Sigg    def _init_map(self):
64e9b38841SChristian Sigg        """Lazy initialization  of self.map."""
65e9b38841SChristian Sigg        if self.map:
66e9b38841SChristian Sigg            return
67e9b38841SChristian Sigg        self.map = {}
68e9b38841SChristian Sigg        for type_name in self.type_names:
69e9b38841SChristian Sigg            concrete_type = gdb.lookup_type(type_name)
70e851e566SChristian Sigg            try:
71e9b38841SChristian Sigg                storage = gdb.parse_and_eval(
72f9008e63STobias Hieta                    "&'mlir::detail::TypeIDExported::get<%s>()::instance'" % type_name
73f9008e63STobias Hieta                )
74e851e566SChristian Sigg            except gdb.error:
75e851e566SChristian Sigg                # Skip when TypeID instance cannot be found in current context.
76e851e566SChristian Sigg                continue
77e9b38841SChristian Sigg            if concrete_type and storage:
78e9b38841SChristian Sigg                self.map[int(storage)] = concrete_type
79e9b38841SChristian Sigg
80e9b38841SChristian Sigg    def __getitem__(self, type_id):
81e9b38841SChristian Sigg        self._init_map()
82f9008e63STobias Hieta        return self.map.get(int(type_id["storage"]))
83e9b38841SChristian Sigg
84e9b38841SChristian Sigg
85e9b38841SChristian Siggstorage_type_map = StorageTypeMap()
86e9b38841SChristian Sigg
87e9b38841SChristian Sigg
88e9b38841SChristian Siggdef get_type_id_printer(val):
89e9b38841SChristian Sigg    """Returns a printer of the name of a mlir::TypeID."""
90e9b38841SChristian Sigg
91635f8f3cSChristian Sigg    class TypeIdPrinter:
92e9b38841SChristian Sigg        def __init__(self, string):
93e9b38841SChristian Sigg            self.string = string
94e9b38841SChristian Sigg
95e9b38841SChristian Sigg        def to_string(self):
96e9b38841SChristian Sigg            return self.string
97e9b38841SChristian Sigg
98e9b38841SChristian Sigg    concrete_type = storage_type_map[val]
99e9b38841SChristian Sigg    if not concrete_type:
100e9b38841SChristian Sigg        return None
101f9008e63STobias Hieta    return TypeIdPrinter("mlir::TypeID::get<%s>()" % concrete_type)
102e9b38841SChristian Sigg
103e9b38841SChristian Sigg
104e9b38841SChristian Siggdef get_attr_or_type_printer(val, get_type_id):
105e9b38841SChristian Sigg    """Returns a printer for mlir::Attribute or mlir::Type."""
106e9b38841SChristian Sigg
107635f8f3cSChristian Sigg    class AttrOrTypePrinter:
108635f8f3cSChristian Sigg        def __init__(self, type_id, impl):
109635f8f3cSChristian Sigg            self.type_id = type_id
110635f8f3cSChristian Sigg            self.impl = impl
111e9b38841SChristian Sigg
112e9b38841SChristian Sigg        def children(self):
113f9008e63STobias Hieta            yield "typeID", self.type_id
114f9008e63STobias Hieta            yield "impl", self.impl
1157c5c4e78SKrzysztof Drewniak
1167c5c4e78SKrzysztof Drewniak        def to_string(self):
117f9008e63STobias Hieta            return "cast<%s>" % self.impl.type
118e9b38841SChristian Sigg
119f9008e63STobias Hieta    if not val["impl"]:
120e9b38841SChristian Sigg        return None
121f9008e63STobias Hieta    impl = val["impl"].dereference()
122635f8f3cSChristian Sigg    type_id = get_type_id(impl)
123e9b38841SChristian Sigg    concrete_type = storage_type_map[type_id]
124e9b38841SChristian Sigg    if not concrete_type:
125e9b38841SChristian Sigg        return None
126635f8f3cSChristian Sigg    # 3rd template argument of StorageUserBase is the storage type.
127635f8f3cSChristian Sigg    storage_type = concrete_type.fields()[0].type.template_argument(2)
128635f8f3cSChristian Sigg    if not storage_type:
129635f8f3cSChristian Sigg        return None
130635f8f3cSChristian Sigg    return AttrOrTypePrinter(type_id, impl.cast(storage_type))
131e9b38841SChristian Sigg
132e9b38841SChristian Sigg
133635f8f3cSChristian Siggclass ImplPrinter:
134635f8f3cSChristian Sigg    """Printer for an instance with a single 'impl' member pointer."""
135e9b38841SChristian Sigg
136635f8f3cSChristian Sigg    def __init__(self, val):
1377c5c4e78SKrzysztof Drewniak        self.val = val
138f9008e63STobias Hieta        self.impl = val["impl"]
139e9b38841SChristian Sigg
140635f8f3cSChristian Sigg    def children(self):
1417c5c4e78SKrzysztof Drewniak        if self.impl:
142f9008e63STobias Hieta            yield "impl", self.impl.dereference()
1437c5c4e78SKrzysztof Drewniak
1447c5c4e78SKrzysztof Drewniak    def to_string(self):
1457c5c4e78SKrzysztof Drewniak        return self.val.type.name
146635f8f3cSChristian Sigg
147e9b38841SChristian Sigg
148e9b38841SChristian Sigg# Printers of types deriving from Attribute::AttrBase or Type::TypeBase.
149e9b38841SChristian Siggfor name in [
150e9b38841SChristian Sigg    # mlir/IR/Attributes.h
151f9008e63STobias Hieta    "ArrayAttr",
152f9008e63STobias Hieta    "DictionaryAttr",
153f9008e63STobias Hieta    "FloatAttr",
154f9008e63STobias Hieta    "IntegerAttr",
155f9008e63STobias Hieta    "IntegerSetAttr",
156f9008e63STobias Hieta    "OpaqueAttr",
157f9008e63STobias Hieta    "StringAttr",
158f9008e63STobias Hieta    "SymbolRefAttr",
159f9008e63STobias Hieta    "TypeAttr",
160f9008e63STobias Hieta    "UnitAttr",
161f9008e63STobias Hieta    "DenseStringElementsAttr",
162f9008e63STobias Hieta    "DenseIntOrFPElementsAttr",
163f9008e63STobias Hieta    "SparseElementsAttr",
16409f7a55fSRiver Riddle    # mlir/IR/BuiltinTypes.h
165f9008e63STobias Hieta    "ComplexType",
166f9008e63STobias Hieta    "IndexType",
167f9008e63STobias Hieta    "IntegerType",
168f9008e63STobias Hieta    "Float16Type",
169*6685fd82SJeremy Furtek    "FloatTF32Type",
170f9008e63STobias Hieta    "Float32Type",
171f9008e63STobias Hieta    "Float64Type",
172f9008e63STobias Hieta    "Float80Type",
173f9008e63STobias Hieta    "Float128Type",
174f9008e63STobias Hieta    "NoneType",
175f9008e63STobias Hieta    "VectorType",
176f9008e63STobias Hieta    "RankedTensorType",
177f9008e63STobias Hieta    "UnrankedTensorType",
178f9008e63STobias Hieta    "MemRefType",
179f9008e63STobias Hieta    "UnrankedMemRefType",
180f9008e63STobias Hieta    "TupleType",
181e9b38841SChristian Sigg    # mlir/IR/Location.h
182f9008e63STobias Hieta    "CallSiteLoc",
183f9008e63STobias Hieta    "FileLineColLoc",
184f9008e63STobias Hieta    "FusedLoc",
185f9008e63STobias Hieta    "NameLoc",
186f9008e63STobias Hieta    "OpaqueLoc",
187f9008e63STobias Hieta    "UnknownLoc",
188e9b38841SChristian Sigg]:
189f9008e63STobias Hieta    storage_type_map.register_type("mlir::%s" % name)  # Register for upcasting.
190f9008e63STobias Hietastorage_type_map.register_type("void")  # Register default.
191635f8f3cSChristian Sigg
192635f8f3cSChristian Sigg
193f9008e63STobias Hietapp = gdb.printing.RegexpCollectionPrettyPrinter("MLIRSupport")
194635f8f3cSChristian Sigg
195f9008e63STobias Hietapp.add_printer("mlir::OperationName", "^mlir::OperationName$", ImplPrinter)
196f9008e63STobias Hietapp.add_printer("mlir::Value", "^mlir::Value$", ImplPrinter)
197635f8f3cSChristian Sigg
198635f8f3cSChristian Sigg# Printers for types deriving from AttributeStorage or TypeStorage.
199f9008e63STobias Hietapp.add_printer(
200f9008e63STobias Hieta    "mlir::detail::FusedLocationStorage",
201f9008e63STobias Hieta    "^mlir::detail::FusedLocationStorage",
202f9008e63STobias Hieta    FusedLocationStoragePrinter,
203f9008e63STobias Hieta)
204f9008e63STobias Hietapp.add_printer(
205f9008e63STobias Hieta    "mlir::detail::TupleTypeStorage",
206f9008e63STobias Hieta    "^mlir::detail::TupleTypeStorage$",
207f9008e63STobias Hieta    TupleTypeStoragePrinter,
208f9008e63STobias Hieta)
209e9b38841SChristian Sigg
210f9008e63STobias Hietapp.add_printer("mlir::TypeID", "^mlir::TypeID$", get_type_id_printer)
211e9b38841SChristian Sigg
212e9b38841SChristian Sigg
213e9b38841SChristian Siggdef add_attr_or_type_printers(name):
214e9b38841SChristian Sigg    """Adds printers for mlir::Attribute or mlir::Type and their Storage type."""
215f9008e63STobias Hieta    get_type_id = lambda val: val["abstract%s" % name]["typeID"]
216f9008e63STobias Hieta    pp.add_printer(
217f9008e63STobias Hieta        "mlir::%s" % name,
218f9008e63STobias Hieta        "^mlir::%s$" % name,
219f9008e63STobias Hieta        lambda val: get_attr_or_type_printer(val, get_type_id),
220f9008e63STobias Hieta    )
221e9b38841SChristian Sigg
222e9b38841SChristian Sigg
223e9b38841SChristian Sigg# Upcasting printers of mlir::Attribute and mlir::Type.
224f9008e63STobias Hietafor name in ["Attribute", "Type"]:
225e9b38841SChristian Sigg    add_attr_or_type_printers(name)
226e9b38841SChristian Sigg
227e9b38841SChristian Sigggdb.printing.register_pretty_printer(gdb.current_objfile(), pp)
228