[LLD][COFF] Emit tail merge pdata for delay load thunks on ARM64EC (#116810)
[llvm-project.git] / mlir / utils / lldb-scripts / mlirDataFormatters.py
blob38e8278eefbbd30cd86129e463a4fa93bf692a0c
1 """
2 LLDB Formatters for MLIR data types.
4 Load into LLDB with 'command script import /path/to/mlirDataFormatters.py'
5 """
7 import re
8 import lldb
11 def get_expression_path(val: lldb.SBValue):
12 """Compute the expression path for the given value."""
14 stream = lldb.SBStream()
15 if not val.GetExpressionPath(stream):
16 return None
17 return stream.GetData()
20 def build_ptr_str_from_addr(addrValue: lldb.SBValue, type: lldb.SBType):
21 """Build a string that computes a pointer using the given address value and type."""
23 if type.is_reference:
24 type = type.GetDereferencedType()
25 if not type.is_pointer:
26 type = type.GetPointerType()
27 return f"(({type}){addrValue.GetData().GetUnsignedInt64(lldb.SBError(), 0)})"
30 # ===----------------------------------------------------------------------=== #
31 # Attributes and Types
32 # ===----------------------------------------------------------------------=== #
34 # This variable defines various mnemonic strings for use by the builtin
35 # dialect attributes and types, which often have special formatting within
36 # the parser/printer.
37 builtin_attr_type_mnemonics = {
38 "mlir::AffineMapAttr": '"affine_map<...>"',
39 "mlir::ArrayAttr": '"[...]"',
40 "mlir::DenseArray": '"array<...>"',
41 "mlir::DenseResourceElementsAttr": '"dense_resource<...>"',
42 "mlir::DictionaryAttr": '"{...}"',
43 "mlir::IntegerAttr": '"float"',
44 "mlir::IntegerAttr": '"integer"',
45 "mlir::IntegerSetAttr": '"affine_set<...>"',
46 "mlir::SparseElementsAttr": '"sparse<...>"',
47 "mlir::StringAttr": '""...""',
48 "mlir::StridedLayout": '"strided_layout"',
49 "mlir::UnitAttr": '"unit"',
50 "mlir::CallSiteLoc": '"loc(callsite(...))"',
51 "mlir::FusedLoc": '"loc(fused<...>[...])"',
52 "mlir::UnknownLoc": '"loc(unknown)"',
53 "mlir::Float4E2M1FNType": '"f4E2M1FN"',
54 "mlir::Float6E2M3FNType": '"f6E2M3FN"',
55 "mlir::Float6E3M2FNType": '"f6E3M2FN"',
56 "mlir::Float8E5M2Type": '"f8E5M2"',
57 "mlir::Float8E4M3Type": '"f8E4M3"',
58 "mlir::Float8E4M3FNType": '"f8E4M3FN"',
59 "mlir::Float8E5M2FNUZType": '"f8E5M2FNUZ"',
60 "mlir::Float8E4M3FNUZType": '"f8E4M3FNUZ"',
61 "mlir::Float8E4M3B11FNUZType": '"f8E4M3B11FNUZ"',
62 "mlir::Float8E3M4Type": '"f8E3M4"',
63 "mlir::Float8E8M0FNUType": '"f8E8M0FNU"',
64 "mlir::BFloat16Type": '"bf16"',
65 "mlir::Float16Type": '"f16"',
66 "mlir::FloatTF32Type": '"tf32"',
67 "mlir::Float32Type": '"f32"',
68 "mlir::Float64Type": '"f64"',
69 "mlir::Float80Type": '"f80"',
70 "mlir::Float128Type": '"f128"',
71 "mlir::FunctionType": '"(...) -> (...)"',
72 "mlir::IndexType": '"index"',
73 "mlir::IntegerType": '"iN"',
74 "mlir::NoneType": '"none"',
75 "mlir::TupleType": '"tuple<...>"',
76 "mlir::MemRefType": '"memref<...>"',
77 "mlir::UnrankedMemRef": '"memref<...>"',
78 "mlir::UnrankedTensorType": '"tensor<...>"',
79 "mlir::RankedTensorType": '"tensor<...>"',
80 "mlir::VectorType": '"vector<...>"',
84 class ComputedTypeIDMap:
85 """Compute a map of type ids to derived attributes, types, and locations.
87 This is necessary for determining the C++ type when holding a base class,
88 where we really only have access to dynamic information.
89 """
91 def __init__(self, target: lldb.SBTarget, internal_dict: dict):
92 self.resolved_typeids = {}
94 # Find all of the `id` variables, which are the name of TypeID variables
95 # defined within the TypeIDResolver.
96 type_ids = target.FindGlobalVariables("id", lldb.UINT32_MAX)
97 for type_id in type_ids:
98 # Strip out any matches that didn't come from a TypeID resolver. This
99 # also lets us extract the derived type name.
100 name = type_id.GetName()
101 match = re.search("^mlir::detail::TypeIDResolver<(.*), void>::id$", name)
102 if not match:
103 continue
104 type_name = match.group(1)
106 # Filter out types that we don't care about.
107 if not type_name.endswith(("Attr", "Loc", "Type")):
108 continue
110 # Find the LLDB type for the derived type.
111 type = None
112 for typeIt in target.FindTypes(type_name):
113 if not typeIt or not typeIt.IsValid():
114 continue
115 type = typeIt
116 break
117 if not type or not type.IsValid():
118 continue
120 # Map the raw address of the type id variable to the LLDB type.
121 self.resolved_typeids[type_id.AddressOf().GetValueAsUnsigned()] = type
123 # Resolve the type for the given TypeID address.
124 def resolve_type(self, typeIdAddr: lldb.SBValue):
125 try:
126 return self.resolved_typeids[typeIdAddr.GetValueAsUnsigned()]
127 except KeyError:
128 return None
131 def is_derived_attribute_or_type(sbtype: lldb.SBType, internal_dict):
132 """Return if the given type is a derived attribute or type."""
134 # We only expect an AttrBase/TypeBase base class.
135 if sbtype.num_bases != 1:
136 return False
137 base_name = sbtype.GetDirectBaseClassAtIndex(0).GetName()
138 return base_name.startswith(("mlir::Attribute::AttrBase", "mlir::Type::TypeBase"))
141 def get_typeid_map(target: lldb.SBTarget, internal_dict: dict):
142 """Get or construct a TypeID map for the given target."""
144 if "typeIdMap" not in internal_dict:
145 internal_dict["typeIdMap"] = ComputedTypeIDMap(target, internal_dict)
146 return internal_dict["typeIdMap"]
149 def is_attribute_or_type(sbtype: lldb.SBType, internal_dict):
150 """Return if the given type is an attribute or type."""
152 num_bases = sbtype.GetNumberOfDirectBaseClasses()
153 typeName = sbtype.GetName()
155 # We bottom out at Attribute/Type/Location.
156 if num_bases == 0:
157 return typeName in ["mlir::Attribute", "mlir::Type", "mlir::Location"]
159 # Check the easy cases of AttrBase/TypeBase.
160 if typeName.startswith(("mlir::Attribute::AttrBase", "mlir::Type::TypeBase")):
161 return True
163 # Otherwise, recurse into the base class.
164 return is_attribute_or_type(
165 sbtype.GetDirectBaseClassAtIndex(0).GetType(), internal_dict
169 def resolve_attr_type_from_value(
170 valobj: lldb.SBValue, abstractVal: lldb.SBValue, internal_dict
172 """Resolve the derived C++ type of an Attribute/Type value."""
174 # Derived attribute/types already have the desired type.
175 if is_derived_attribute_or_type(valobj.GetType(), internal_dict):
176 return valobj.GetType()
178 # Otherwise, we need to resolve the ImplTy from the TypeID. This is
179 # done dynamically, because we don't use C++ RTTI of any kind.
180 typeIdMap = get_typeid_map(valobj.GetTarget(), internal_dict)
181 return typeIdMap.resolve_type(
182 abstractVal.GetChildMemberWithName("typeID").GetChildMemberWithName("storage")
186 class AttrTypeSynthProvider:
187 """Define an LLDB synthetic children provider for Attributes and Types."""
189 def __init__(self, valobj: lldb.SBValue, internal_dict):
190 self.valobj = valobj
192 # Grab the impl variable, which if this is a Location needs to be
193 # resolved through the LocationAttr impl variable.
194 impl: lldb.SBValue = self.valobj.GetChildMemberWithName("impl")
195 if self.valobj.GetTypeName() == "mlir::Location":
196 impl = impl.GetChildMemberWithName("impl")
197 self.abstractVal = impl.GetChildMemberWithName("abstractType")
198 if not self.abstractVal.IsValid():
199 self.abstractVal = impl.GetChildMemberWithName("abstractAttribute")
201 self.type = resolve_attr_type_from_value(
202 valobj, self.abstractVal, internal_dict
204 if not self.type:
205 self.impl_type = None
206 return
208 # Grab the ImplTy from the resolved type. This is the 3rd template
209 # argument of the base class.
210 self.impl_type = (
211 self.type.GetDirectBaseClassAtIndex(0).GetType().GetTemplateArgumentType(2)
213 self.impl_pointer_ty = self.impl_type.GetPointerType()
214 self.num_fields = self.impl_type.GetNumberOfFields()
216 # Optionally add a mnemonic field.
217 type_name = self.type.GetName()
218 if type_name in builtin_attr_type_mnemonics:
219 self.mnemonic = builtin_attr_type_mnemonics[type_name]
220 elif type_name.startswith("mlir::Dense"):
221 self.mnemonic = "dense<...>"
222 else:
223 self.mnemonic = self.valobj.CreateValueFromExpression(
224 "mnemonic", f"(llvm::StringRef){type_name}::getMnemonic()"
226 if not self.mnemonic.summary:
227 self.mnemonic = None
228 if self.mnemonic:
229 self.num_fields += 1
231 def num_children(self):
232 if not self.impl_type:
233 return 0
234 return self.num_fields
236 def get_child_index(self, name):
237 if not self.impl_type:
238 return None
239 if self.mnemonic and name == "[mnemonic]":
240 return self.impl_type.GetNumberOfFields()
241 for i in range(self.impl_type.GetNumberOfFields()):
242 if self.impl_type.GetFieldAtIndex(i).GetName() == name:
243 return i
244 return None
246 def get_child_at_index(self, index):
247 if not self.impl_type or index >= self.num_fields:
248 return None
250 impl: lldb.SBValue = self.valobj.GetChildMemberWithName("impl")
251 impl_ptr: lldb.SBValue = self.valobj.CreateValueFromData(
252 build_ptr_str_from_addr(impl, self.impl_pointer_ty),
253 impl.GetData(),
254 self.impl_pointer_ty,
257 # Check for the mnemonic field.
258 if index == self.impl_type.GetNumberOfFields():
259 return self.valobj.CreateValueFromExpression(
260 "[mnemonic]", self.get_mnemonic_string(impl_ptr)
263 # Otherwise, we expect the index to be a field.
264 field: lldb.SBTypeMember = self.impl_type.GetFieldAtIndex(index)
266 # Build the field access by resolving through the impl variable.
267 return impl_ptr.GetChildMemberWithName(field.GetName())
269 def get_mnemonic_string(self, impl_ptr: lldb.SBValue):
270 if isinstance(self.mnemonic, str):
271 return self.mnemonic
273 # If we don't already have the mnemonic in string form, compute
274 # it from the dialect name and the mnemonic.
275 dialect_name = self.abstractVal.GetChildMemberWithName(
276 "dialect"
277 ).GetChildMemberWithName("name")
278 self.mnemonic = f'{dialect_name.summary}"."{self.mnemonic.summary}'
279 return self.mnemonic
282 def AttrTypeSummaryProvider(valobj: lldb.SBValue, internal_dict):
283 """Define an LLDB summary provider for Attributes and Types."""
285 # Check for a value field.
286 value = valobj.GetChildMemberWithName("value")
287 if value and value.summary:
288 return value.summary
290 # Otherwise, try the mnemoic.
291 mnemonic: lldb.SBValue = valobj.GetChildMemberWithName("[mnemonic]")
292 if not mnemonic.summary:
293 return ""
294 mnemonicStr = mnemonic.summary.strip('"')
296 # Handle a few extremely common builtin attributes/types.
297 ## IntegerType
298 if mnemonicStr == "iN":
299 signedness = valobj.GetChildMemberWithName("signedness").GetValueAsUnsigned()
300 prefix = "i"
301 if signedness == 1:
302 prefix = "si"
303 elif signedness == 2:
304 prefix = "ui"
305 return f"{prefix}{valobj.GetChildMemberWithName('width').GetValueAsUnsigned()}"
306 ## IntegerAttr
307 if mnemonicStr == "integer":
308 value = valobj.GetChildMemberWithName("value")
309 bitwidth = value.GetChildMemberWithName("BitWidth").GetValueAsUnsigned()
310 if bitwidth <= 64:
311 intVal = (
312 value.GetChildMemberWithName("U")
313 .GetChildMemberWithName("VAL")
314 .GetValueAsUnsigned()
317 if bitwidth == 1:
318 return "true" if intVal else "false"
319 return f"{intVal} : i{bitwidth}"
321 return mnemonicStr
324 # ===----------------------------------------------------------------------=== #
325 # mlir::Block
326 # ===----------------------------------------------------------------------=== #
329 class BlockSynthProvider:
330 """Define an LLDB synthetic children provider for Blocks."""
332 def __init__(self, valobj, internal_dict):
333 self.valobj = valobj
335 def num_children(self):
336 return 3
338 def get_child_index(self, name):
339 if name == "parent":
340 return 0
341 if name == "operations":
342 return 1
343 if name == "arguments":
344 return 2
345 return None
347 def get_child_at_index(self, index):
348 if index >= 3:
349 return None
350 if index == 1:
351 return self.valobj.GetChildMemberWithName("operations")
352 if index == 2:
353 return self.valobj.GetChildMemberWithName("arguments")
355 expr_path = build_ptr_str_from_addr(self.valobj, self.valobj.GetType())
356 return self.valobj.CreateValueFromExpression(
357 "parent", f"{expr_path}->getParent()"
361 # ===----------------------------------------------------------------------=== #
362 # mlir::Operation
363 # ===----------------------------------------------------------------------=== #
366 def is_op(sbtype: lldb.SBType, internal_dict):
367 """Return if the given type is an operation."""
369 # Bottom out at OpState/Op.
370 typeName = sbtype.GetName()
371 if sbtype.GetNumberOfDirectBaseClasses() == 0:
372 return typeName == "mlir::OpState"
373 if typeName == "mlir::Operation" or typeName.startswith("mlir::Op<"):
374 return True
376 # Otherwise, recurse into the base class.
377 return is_op(sbtype.GetDirectBaseClassAtIndex(0).GetType(), internal_dict)
380 class OperationSynthProvider:
381 """Define an LLDB synthetic children provider for Operations."""
383 def __init__(self, valobj, internal_dict):
384 self.valobj = valobj
385 self.fields = []
386 self.update()
388 def num_children(self):
389 return len(self.fields)
391 def get_child_index(self, name):
392 try:
393 return self.fields.index(name)
394 except ValueError:
395 return None
397 def get_child_at_index(self, index):
398 if index >= len(self.fields):
399 return None
400 name = self.fields[index]
401 if name == "name":
402 return self.opobj.GetChildMemberWithName("name")
403 if name == "parent":
404 return self.opobj.GetChildMemberWithName("block").Clone("parent")
405 if name == "location":
406 return self.opobj.GetChildMemberWithName("location")
407 if name == "attributes":
408 return self.opobj.GetChildMemberWithName("attrs")
410 expr_path = build_ptr_str_from_addr(self.opobj, self.opobj.GetType())
411 if name == "operands":
412 return self.opobj.CreateValueFromExpression(
413 "operands", f"{expr_path}->debug_getOperands()"
415 if name == "results":
416 return self.opobj.CreateValueFromExpression(
417 "results", f"{expr_path}->debug_getResults()"
419 if name == "successors":
420 return self.opobj.CreateValueFromExpression(
421 "successors", f"{expr_path}->debug_getSuccessors()"
423 if name == "regions":
424 return self.opobj.CreateValueFromExpression(
425 "regions", f"{expr_path}->debug_getRegions()"
427 return None
429 def update(self):
430 # If this is a derived operation, we need to resolve through the
431 # state field.
432 self.opobj = self.valobj
433 if "mlir::Operation" not in self.valobj.GetTypeName():
434 self.opobj = self.valobj.GetChildMemberWithName("state")
436 self.fields = ["parent", "name", "location", "attributes"]
437 if (
438 self.opobj.GetChildMemberWithName("hasOperandStorage").GetValueAsUnsigned(0)
439 != 0
441 self.fields.append("operands")
442 if self.opobj.GetChildMemberWithName("numResults").GetValueAsUnsigned(0) != 0:
443 self.fields.append("results")
444 if self.opobj.GetChildMemberWithName("numSuccs").GetValueAsUnsigned(0) != 0:
445 self.fields.append("successors")
446 if self.opobj.GetChildMemberWithName("numRegions").GetValueAsUnsigned(0) != 0:
447 self.fields.append("regions")
450 def OperationSummaryProvider(valobj: lldb.SBValue, internal_dict):
451 """Define an LLDB summary provider for Operations."""
453 name = valobj.GetChildMemberWithName("name")
454 if name and name.summary:
455 return name.summary
456 return ""
459 # ===----------------------------------------------------------------------=== #
460 # Ranges
461 # ===----------------------------------------------------------------------=== #
464 class DirectRangeSynthProvider:
465 """Define an LLDB synthetic children provider for direct ranges, i.e. those
466 with a base pointer that points to the type of element we want to display.
469 def __init__(self, valobj, internal_dict):
470 self.valobj = valobj
471 self.update()
473 def num_children(self):
474 return self.length
476 def get_child_index(self, name):
477 try:
478 return int(name.lstrip("[").rstrip("]"))
479 except:
480 return None
482 def get_child_at_index(self, index):
483 if index >= self.num_children():
484 return None
485 offset = index * self.type_size
486 return self.data.CreateChildAtOffset(f"[{index}]", offset, self.data_type)
488 def update(self):
489 length_obj = self.valobj.GetChildMemberWithName("count")
490 self.length = length_obj.GetValueAsUnsigned(0)
492 self.data = self.valobj.GetChildMemberWithName("base")
493 self.data_type = self.data.GetType().GetPointeeType()
494 self.type_size = self.data_type.GetByteSize()
495 assert self.type_size != 0
498 class InDirectRangeSynthProvider:
499 """Define an LLDB synthetic children provider for ranges
500 that transform the underlying base pointer, e.g. to convert
501 it to a different type depending on various characteristics
502 (e.g. mlir::ValueRange).
505 def __init__(self, valobj, internal_dict):
506 self.valobj = valobj
507 self.update()
509 def num_children(self):
510 return self.length
512 def get_child_index(self, name):
513 try:
514 return int(name.lstrip("[").rstrip("]"))
515 except:
516 return None
518 def get_child_at_index(self, index):
519 if index >= self.num_children():
520 return None
521 expr_path = get_expression_path(self.valobj)
522 return self.valobj.CreateValueFromExpression(
523 f"[{index}]", f"{expr_path}[{index}]"
526 def update(self):
527 length_obj = self.valobj.GetChildMemberWithName("count")
528 self.length = length_obj.GetValueAsUnsigned(0)
531 class IPListRangeSynthProvider:
532 """Define an LLDB synthetic children provider for an IPList."""
534 def __init__(self, valobj, internal_dict):
535 self.valobj = valobj
536 self.update()
538 def num_children(self):
539 sentinel = self.valobj.GetChildMemberWithName("Sentinel")
540 sentinel_addr = sentinel.AddressOf().GetValueAsUnsigned(0)
542 # Iterate the next pointers looking for the sentinel.
543 count = 0
544 current = sentinel.GetChildMemberWithName("Next")
545 while current.GetValueAsUnsigned(0) != sentinel_addr:
546 current = current.GetChildMemberWithName("Next")
547 count += 1
549 return count
551 def get_child_index(self, name):
552 try:
553 return int(name.lstrip("[").rstrip("]"))
554 except:
555 return None
557 def get_child_at_index(self, index):
558 if index >= self.num_children():
559 return None
561 # Start from the sentinel and grab the next pointer.
562 value: lldb.SBValue = self.valobj.GetChildMemberWithName("Sentinel")
563 it = 0
564 while it <= index:
565 value = value.GetChildMemberWithName("Next")
566 it += 1
568 return value.CreateValueFromExpression(
569 f"[{index}]",
570 f"(({self.value_type})({value.GetTypeName()}){value.GetValueAsUnsigned()})",
573 def update(self):
574 self.value_type = (
575 self.valobj.GetType().GetTemplateArgumentType(0).GetPointerType()
579 # ===----------------------------------------------------------------------=== #
580 # mlir::Value
581 # ===----------------------------------------------------------------------=== #
584 class ValueSynthProvider:
585 """Define an LLDB synthetic children provider for Values."""
587 def __init__(self, valobj, internal_dict):
588 self.valobj = valobj
589 self.update()
591 def num_children(self):
592 # 7: BlockArgument:
593 # index, type, owner, firstUse, location
594 if self.kind == 7:
595 return 5
597 # 0-6: OpResult:
598 # index, type, owner, firstUse
599 return 4
601 def get_child_index(self, name):
602 if name == "index":
603 return 0
604 if name == "type":
605 return 1
606 if name == "owner":
607 return 2
608 if name == "firstUse":
609 return 3
610 if name == "location":
611 return 4
612 return None
614 def get_child_at_index(self, index):
615 if index >= self.num_children():
616 return None
618 # Check if the current value is already an Impl struct.
619 if self.valobj.GetTypeName().endswith("Impl"):
620 impl_ptr_str = build_ptr_str_from_addr(
621 self.valobj.AddressOf(), self.valobj.GetType().GetPointerType()
623 else:
624 impl = self.valobj.GetChildMemberWithName("impl")
625 impl_ptr_str = build_ptr_str_from_addr(impl, impl.GetType())
627 # Cast to the derived Impl type.
628 if self.kind == 7:
629 derived_impl_str = f"((mlir::detail::BlockArgumentImpl *){impl_ptr_str})"
630 elif self.kind == 6:
631 derived_impl_str = f"((mlir::detail::OutOfLineOpResult *){impl_ptr_str})"
632 else:
633 derived_impl_str = f"((mlir::detail::InlineOpResult *){impl_ptr_str})"
635 # Handle the shared fields when possible.
636 if index == 1:
637 return self.valobj.CreateValueFromExpression(
638 "type", f"{derived_impl_str}->debug_getType()"
640 if index == 3:
641 return self.valobj.CreateValueFromExpression(
642 "firstUse", f"{derived_impl_str}->firstUse"
645 # Handle Block argument children.
646 if self.kind == 7:
647 impl = self.valobj.CreateValueFromExpression("impl", derived_impl_str)
648 if index == 0:
649 return impl.GetChildMemberWithName("index")
650 if index == 2:
651 return impl.GetChildMemberWithName("owner")
652 if index == 4:
653 return impl.GetChildMemberWithName("loc")
655 # Handle OpResult children.
656 if index == 0:
657 # Handle the out of line case.
658 if self.kind == 6:
659 return self.valobj.CreateValueFromExpression(
660 "index", f"{derived_impl_str}->outOfLineIndex + 6"
662 return self.valobj.CreateValueFromExpression("index", f"{self.kind}")
663 if index == 2:
664 return self.valobj.CreateValueFromExpression(
665 "owner", f"{derived_impl_str}->getOwner()"
667 return None
669 def update(self):
670 # Check if the current value is already an Impl struct.
671 if self.valobj.GetTypeName().endswith("Impl"):
672 impl_ptr_str = build_ptr_str_from_addr(
673 self.valobj, self.valobj.GetType().GetPointerType()
675 else:
676 impl = self.valobj.GetChildMemberWithName("impl")
677 impl_ptr_str = build_ptr_str_from_addr(impl, impl.GetType())
679 # Compute the kind of value we are dealing with.
680 self.kind = self.valobj.CreateValueFromExpression(
681 "kind", f"{impl_ptr_str}->debug_getKind()"
682 ).GetValueAsUnsigned()
685 def ValueSummaryProvider(valobj: lldb.SBValue, internal_dict):
686 """Define an LLDB summary provider for Values."""
688 index = valobj.GetChildMemberWithName("index").GetValueAsUnsigned()
689 # Check if this is a block argument or not (block arguments have locations).
690 if valobj.GetChildMemberWithName("location").IsValid():
691 summary = f"Block Argument {index}"
692 else:
693 owner_name = (
694 valobj.GetChildMemberWithName("owner")
695 .GetChildMemberWithName("name")
696 .summary
698 summary = f"{owner_name} Result {index}"
700 # Grab the type to help form the summary.
701 type = valobj.GetChildMemberWithName("type")
702 if type.summary:
703 summary += f": {type.summary}"
705 return summary
708 # ===----------------------------------------------------------------------=== #
709 # Initialization
710 # ===----------------------------------------------------------------------=== #
713 def __lldb_init_module(debugger: lldb.SBDebugger, internal_dict):
714 cat: lldb.SBTypeCategory = debugger.CreateCategory("mlir")
715 cat.SetEnabled(True)
717 # Attributes and Types
718 cat.AddTypeSummary(
719 lldb.SBTypeNameSpecifier(
720 "mlirDataFormatters.is_attribute_or_type", lldb.eFormatterMatchCallback
722 lldb.SBTypeSummary.CreateWithFunctionName(
723 "mlirDataFormatters.AttrTypeSummaryProvider"
726 cat.AddTypeSynthetic(
727 lldb.SBTypeNameSpecifier(
728 "mlirDataFormatters.is_attribute_or_type", lldb.eFormatterMatchCallback
730 lldb.SBTypeSynthetic.CreateWithClassName(
731 "mlirDataFormatters.AttrTypeSynthProvider"
735 # Operation
736 cat.AddTypeSynthetic(
737 lldb.SBTypeNameSpecifier("mlir::Block", lldb.eFormatterMatchExact),
738 lldb.SBTypeSynthetic.CreateWithClassName(
739 "mlirDataFormatters.BlockSynthProvider"
743 # NamedAttribute
744 cat.AddTypeSummary(
745 lldb.SBTypeNameSpecifier("mlir::NamedAttribute", lldb.eFormatterMatchExact),
746 lldb.SBTypeSummary.CreateWithSummaryString("${var.name%S} = ${var.value%S}"),
749 # OperationName
750 cat.AddTypeSummary(
751 lldb.SBTypeNameSpecifier("mlir::OperationName", lldb.eFormatterMatchExact),
752 lldb.SBTypeSummary.CreateWithSummaryString("${var.impl->name%S}"),
755 # Operation
756 cat.AddTypeSummary(
757 lldb.SBTypeNameSpecifier(
758 "mlirDataFormatters.is_op", lldb.eFormatterMatchCallback
760 lldb.SBTypeSummary.CreateWithFunctionName(
761 "mlirDataFormatters.OperationSummaryProvider"
764 cat.AddTypeSynthetic(
765 lldb.SBTypeNameSpecifier(
766 "mlirDataFormatters.is_op", lldb.eFormatterMatchCallback
768 lldb.SBTypeSynthetic.CreateWithClassName(
769 "mlirDataFormatters.OperationSynthProvider"
773 # Ranges
774 def add_direct_range_summary_and_synth(name):
775 cat.AddTypeSummary(
776 lldb.SBTypeNameSpecifier(name, lldb.eFormatterMatchExact),
777 lldb.SBTypeSummary.CreateWithSummaryString("size=${svar%#}"),
779 cat.AddTypeSynthetic(
780 lldb.SBTypeNameSpecifier(name, lldb.eFormatterMatchExact),
781 lldb.SBTypeSynthetic.CreateWithClassName(
782 "mlirDataFormatters.DirectRangeSynthProvider"
786 def add_indirect_range_summary_and_synth(name):
787 cat.AddTypeSummary(
788 lldb.SBTypeNameSpecifier(name, lldb.eFormatterMatchExact),
789 lldb.SBTypeSummary.CreateWithSummaryString("size=${svar%#}"),
791 cat.AddTypeSynthetic(
792 lldb.SBTypeNameSpecifier(name, lldb.eFormatterMatchExact),
793 lldb.SBTypeSynthetic.CreateWithClassName(
794 "mlirDataFormatters.InDirectRangeSynthProvider"
798 def add_iplist_range_summary_and_synth(name):
799 cat.AddTypeSummary(
800 lldb.SBTypeNameSpecifier(name, lldb.eFormatterMatchExact),
801 lldb.SBTypeSummary.CreateWithSummaryString("size=${svar%#}"),
803 cat.AddTypeSynthetic(
804 lldb.SBTypeNameSpecifier(name, lldb.eFormatterMatchExact),
805 lldb.SBTypeSynthetic.CreateWithClassName(
806 "mlirDataFormatters.IPListRangeSynthProvider"
810 add_direct_range_summary_and_synth("mlir::Operation::operand_range")
811 add_direct_range_summary_and_synth("mlir::OperandRange")
812 add_direct_range_summary_and_synth("mlir::Operation::result_range")
813 add_direct_range_summary_and_synth("mlir::ResultRange")
814 add_direct_range_summary_and_synth("mlir::SuccessorRange")
815 add_indirect_range_summary_and_synth("mlir::ValueRange")
816 add_indirect_range_summary_and_synth("mlir::TypeRange")
817 add_iplist_range_summary_and_synth("mlir::Block::OpListType")
818 add_iplist_range_summary_and_synth("mlir::Region::BlockListType")
820 # Values
821 def add_value_summary_and_synth(name):
822 cat.AddTypeSummary(
823 lldb.SBTypeNameSpecifier(name, lldb.eFormatterMatchExact),
824 lldb.SBTypeSummary.CreateWithFunctionName(
825 "mlirDataFormatters.ValueSummaryProvider"
828 cat.AddTypeSynthetic(
829 lldb.SBTypeNameSpecifier(name, lldb.eFormatterMatchExact),
830 lldb.SBTypeSynthetic.CreateWithClassName(
831 "mlirDataFormatters.ValueSynthProvider"
835 add_value_summary_and_synth("mlir::BlockArgument")
836 add_value_summary_and_synth("mlir::Value")
837 add_value_summary_and_synth("mlir::OpResult")
838 add_value_summary_and_synth("mlir::detail::OpResultImpl")