mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-30 07:16:08 +00:00

This diff adds support for TF32 as a Builtin floating point type. This supplements the recent addition of the TF32 semantic to the LLVM APFloat class by extending usage to MLIR. https://reviews.llvm.org/D151923 More information on the TF32 type can be found here: https://blogs.nvidia.com/blog/2020/05/14/tensorfloat-32-precision-format/ Reviewed By: jpienaar Differential Revision: https://reviews.llvm.org/D153705
228 lines
6.2 KiB
Python
228 lines
6.2 KiB
Python
"""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]
|
|
|
|
def to_string(self):
|
|
return "mlir::Storage"
|
|
|
|
|
|
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]
|
|
|
|
def to_string(self):
|
|
return "mlir::TupleTypeStorage of %u elements" % self.val["numElements"]
|
|
|
|
|
|
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]
|
|
|
|
def to_string(self):
|
|
return "mlir::FusedLocationStorage of %u locs" % self.val["numLocs"]
|
|
|
|
|
|
class StorageTypeMap:
|
|
"""Maps a TypeID to the corresponding concrete type.
|
|
|
|
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 TypeIdPrinter:
|
|
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 TypeIdPrinter("mlir::TypeID::get<%s>()" % concrete_type)
|
|
|
|
|
|
def get_attr_or_type_printer(val, get_type_id):
|
|
"""Returns a printer for mlir::Attribute or mlir::Type."""
|
|
|
|
class AttrOrTypePrinter:
|
|
def __init__(self, type_id, impl):
|
|
self.type_id = type_id
|
|
self.impl = impl
|
|
|
|
def children(self):
|
|
yield "typeID", self.type_id
|
|
yield "impl", self.impl
|
|
|
|
def to_string(self):
|
|
return "cast<%s>" % self.impl.type
|
|
|
|
if not val["impl"]:
|
|
return None
|
|
impl = val["impl"].dereference()
|
|
type_id = get_type_id(impl)
|
|
concrete_type = storage_type_map[type_id]
|
|
if not concrete_type:
|
|
return None
|
|
# 3rd template argument of StorageUserBase is the storage type.
|
|
storage_type = concrete_type.fields()[0].type.template_argument(2)
|
|
if not storage_type:
|
|
return None
|
|
return AttrOrTypePrinter(type_id, impl.cast(storage_type))
|
|
|
|
|
|
class ImplPrinter:
|
|
"""Printer for an instance with a single 'impl' member pointer."""
|
|
|
|
def __init__(self, val):
|
|
self.val = val
|
|
self.impl = val["impl"]
|
|
|
|
def children(self):
|
|
if self.impl:
|
|
yield "impl", self.impl.dereference()
|
|
|
|
def to_string(self):
|
|
return self.val.type.name
|
|
|
|
|
|
# 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",
|
|
"SparseElementsAttr",
|
|
# mlir/IR/BuiltinTypes.h
|
|
"ComplexType",
|
|
"IndexType",
|
|
"IntegerType",
|
|
"Float16Type",
|
|
"FloatTF32Type",
|
|
"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.
|
|
storage_type_map.register_type("void") # Register default.
|
|
|
|
|
|
pp = gdb.printing.RegexpCollectionPrettyPrinter("MLIRSupport")
|
|
|
|
pp.add_printer("mlir::OperationName", "^mlir::OperationName$", ImplPrinter)
|
|
pp.add_printer("mlir::Value", "^mlir::Value$", ImplPrinter)
|
|
|
|
# Printers for types deriving from AttributeStorage or TypeStorage.
|
|
pp.add_printer(
|
|
"mlir::detail::FusedLocationStorage",
|
|
"^mlir::detail::FusedLocationStorage",
|
|
FusedLocationStoragePrinter,
|
|
)
|
|
pp.add_printer(
|
|
"mlir::detail::TupleTypeStorage",
|
|
"^mlir::detail::TupleTypeStorage$",
|
|
TupleTypeStoragePrinter,
|
|
)
|
|
|
|
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),
|
|
)
|
|
|
|
|
|
# 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)
|