Add GDB prettyprinters for a few more MLIR types.

Reviewed By: dblaikie, jpienaar

Differential Revision: https://reviews.llvm.org/D87159
This commit is contained in:
Christian Sigg 2020-09-29 15:19:54 +02:00
parent 1b60f63e4f
commit e9b3884161
8 changed files with 417 additions and 8 deletions

View File

@ -22,6 +22,16 @@ set(DEBUGINFO_TEST_DEPS
not
)
if ("mlir" IN_LIST LLVM_ENABLE_PROJECTS)
add_llvm_executable(check-gdb-mlir-support
llvm-prettyprinters/gdb/mlir-support.cpp
)
target_include_directories(check-gdb-mlir-support PRIVATE ${LLVM_EXTERNAL_MLIR_SOURCE_DIR}/include)
target_link_libraries(check-gdb-mlir-support PRIVATE MLIRIR)
list(APPEND DEBUGINFO_TEST_DEPS check-gdb-mlir-support)
set(MLIR_SOURCE_DIR ${LLVM_EXTERNAL_MLIR_SOURCE_DIR})
endif()
if("compiler-rt" IN_LIST LLVM_ENABLE_PROJECTS)
# llgdb-tests/asan.c and other asan* files.
if(TARGET asan)

View File

@ -157,6 +157,6 @@ if platform.system() == 'Darwin':
if apple_lldb_vers < 1000:
config.available_features.add('apple-lldb-pre-1000')
llvm_config.feature_config([('--build-mode', {
'Debug|RelWithDebInfo': 'debug-info'
})])
llvm_config.feature_config(
[('--build-mode', {'Debug|RelWithDebInfo': 'debug-info'})]
)

View File

@ -20,6 +20,8 @@ config.target_triple = "@TARGET_TRIPLE@"
config.host_arch = "@HOST_ARCH@"
config.is_msvc = lit.util.pythonize_bool("@MSVC@")
config.mlir_src_root = "@MLIR_SOURCE_DIR@"
config.llvm_use_sanitizer = "@LLVM_USE_SANITIZER@"
config.python3_executable = "@Python3_EXECUTABLE@"

View File

@ -4,6 +4,10 @@ import lit.util
if 'native' not in config.available_features or lit.util.which('gdb') is None:
config.unsupported = True
if config.mlir_src_root:
config.substitutions.append(("%mlir_src_root", config.mlir_src_root))
config.available_features.add('mlir')
config.suffixes = ['.gdb']

View File

@ -53,8 +53,13 @@ auto SimpleIlist = []() {
return Result;
}();
// Check expected instances to avoid compile errors.
auto CheckExpectedValue = static_cast<bool>(ExpectedValue);
auto CheckExpectedError = static_cast<bool>(ExpectedError);
int main() { return 0; }
int main() {
// Reference symbols that might otherwise be stripped.
ArrayRef[0];
MutableArrayRef[0];
!ExpectedValue;
!ExpectedError;
*OptionalValue;
*OptionalNone;
return 0;
}

View File

@ -0,0 +1,41 @@
#include "mlir/IR/Identifier.h"
#include "mlir/IR/Location.h"
#include "mlir/IR/MLIRContext.h"
#include "mlir/IR/OperationSupport.h"
#include "mlir/IR/StandardTypes.h"
mlir::MLIRContext Context;
auto Identifier = mlir::Identifier::get("foo", &Context);
mlir::OperationName OperationName("FooOp", &Context);
mlir::Value Value({reinterpret_cast<void *>(0x8),
mlir::Value::Kind::TrailingOpResult});
mlir::Type Type(nullptr);
mlir::Type IndexType = mlir::IndexType::get(&Context);
mlir::Type IntegerType =
mlir::IntegerType::get(3, mlir::IntegerType::Unsigned, &Context);
mlir::Type FloatType = mlir::Float32Type::get(&Context);
mlir::Type MemRefType = mlir::MemRefType::get({4, 5}, FloatType);
mlir::Type UnrankedMemRefType = mlir::UnrankedMemRefType::get(IntegerType, 6);
mlir::Type VectorType = mlir::VectorType::get({1, 2}, FloatType);
mlir::Type TupleType =
mlir::TupleType::get(mlir::TypeRange({IndexType, FloatType}), &Context);
auto UnknownLoc = mlir::UnknownLoc::get(&Context);
auto FileLineColLoc = mlir::FileLineColLoc::get("file", 7, 8, &Context);
auto OpaqueLoc = mlir::OpaqueLoc::get<uintptr_t>(9, &Context);
auto NameLoc = mlir::NameLoc::get(Identifier, &Context);
auto CallSiteLoc = mlir::CallSiteLoc::get(FileLineColLoc, OpaqueLoc);
auto FusedLoc = mlir::FusedLoc::get({FileLineColLoc, NameLoc}, &Context);
mlir::Attribute UnitAttr = mlir::UnitAttr::get(&Context);
mlir::Attribute FloatAttr = mlir::FloatAttr::get(FloatType, 1.0);
mlir::Attribute IntegerAttr = mlir::IntegerAttr::get(IntegerType, 10);
mlir::Attribute TypeAttr = mlir::TypeAttr::get(IndexType);
mlir::Attribute ArrayAttr = mlir::ArrayAttr::get({UnitAttr}, &Context);
mlir::Attribute StringAttr = mlir::StringAttr::get("foo", &Context);
mlir::Attribute ElementsAttr = mlir::DenseElementsAttr::get(
VectorType.cast<mlir::ShapedType>(), llvm::ArrayRef<float>{2.0f, 3.0f});
int main() { return 0; }

View File

@ -0,0 +1,112 @@
# RUN: gdb -q -batch -n -iex 'source %mlir_src_root/utils/gdb-scripts/prettyprinters.py' -iex 'source %llvm_src_root/utils/gdb-scripts/prettyprinters.py' -x %s %llvm_tools_dir/check-gdb-mlir-support | FileCheck %s
# REQUIRES: debug-info
# REQUIRES: mlir
break main
run
# CHECK: "foo"
p Identifier
# CHECK: "FooOp"
p OperationName
# CHECK: 0x8
# CHECK: TrailingOpResult
p Value
# CHECK: impl = 0x0
p Type
# CHECK: cast<mlir::IndexType>
p IndexType
# CHECK: cast<mlir::IntegerType>
# CHECK: width = 3
# CHECK: Unsigned
p IntegerType
# CHECK: cast<mlir::Float32Type>
p FloatType
# CHECK: cast<mlir::MemRefType>
# CHECK: shapeSize = 2
# CHECK: shapeElements[0] = 4
# CHECK: shapeElements[1] = 5
p MemRefType
# CHECK: cast<mlir::UnrankedMemRefType>
# CHECK: memorySpace = 6
p UnrankedMemRefType
# CHECK: cast<mlir::VectorType>
# CHECK: shapeSize = 2
# CHECK: shapeElements[0] = 1
# CHECK: shapeElements[1] = 2
p VectorType
# CHECK: cast<mlir::TupleType>
# CHECK: numElements = 2
# CHECK: elements[0]
# CHECK: mlir::IndexType
# CHECK: elements[1]
# CHECK: mlir::Float32Type
p TupleType
# CHECK: cast<mlir::UnknownLoc>
p UnknownLoc
# CHECK: cast<mlir::FileLineColLoc>
# CHECK: filename = "file"
# CHECK: line = 7
# CHECK: column = 8
p FileLineColLoc
# CHECK: cast<mlir::OpaqueLoc>
# CHECK: underlyingLocation = 9
p OpaqueLoc
# CHECK: cast<mlir::NameLoc>
# CHECK: name = "foo"
# CHECK: mlir::UnknownLoc
p NameLoc
# CHECK: cast<mlir::CallSiteLoc>
# CHECK: callee
# CHECK: mlir::FileLineColLoc
# CHECK: caller
# CHECK: mlir::OpaqueLoc
p CallSiteLoc
# CHECK: cast<mlir::FusedLoc>
# CHECK: numLocs = 2
# CHECK: locs[0]
# CHECK: mlir::FileLineColLoc
# CHECK: locs[1]
# CHECK: mlir::NameLoc
p FusedLoc
# CHECK: cast<mlir::UnitAttr>
p UnitAttr
# CHECK: cast<mlir::FloatAttr>
p FloatAttr
# CHECK: cast<mlir::IntegerAttr>
p IntegerAttr
# CHECK: cast<mlir::TypeAttr>
# CHECK: mlir::IndexType
p TypeAttr
# CHECK: cast<mlir::ArrayAttr>
# CHECK: llvm::ArrayRef of length 1
# CHECK: mlir::UnitAttr
p ArrayAttr
# CHECK: cast<mlir::StringAttr>
# CHECK: value = "foo"
p StringAttr
# CHECK: cast<mlir::DenseIntOrFPElementsAttr>
p ElementsAttr

View File

@ -0,0 +1,235 @@
"""GDB pretty printers for MLIR types."""
import gdb.printing
class IdentifierPrinter:
"""Prints an mlir::Identifier instance."""
def __init__(self, val):
self.entry = val['entry']
def to_string(self):
ptr = (self.entry + 1).cast(gdb.lookup_type('char').pointer())
return ptr.string(length=self.entry['keyLength'])
def display_hint(self):
return 'string'
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)
storage = gdb.parse_and_eval(
"&'mlir::TypeID::get<%s>()::instance'" % type_name)
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')
pp.add_printer('mlir::Identifier', '^mlir::Identifier$', IdentifierPrinter)
# 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/StandardTypes.h
'ComplexType',
'IndexType',
'IntegerType',
'Float16Type',
'Float32Type',
'Float64Type',
'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)