mirror of
https://github.com/intel/llvm.git
synced 2026-01-28 19:43:38 +08:00
[mlir][llvm] Use before def debug intrinsic import
This commit adds special handling for the debug intrinsic value handling. LLVM allows to relax the def before use property for debug intrinsics, so this property cannot be assumed for metadata values. Reviewed By: gysit Differential Revision: https://reviews.llvm.org/D144177
This commit is contained in:
@@ -291,9 +291,13 @@ class LLVM_DbgIntrOp<string name, string argName> : LLVM_IntrOp<name, [], [], []
|
||||
// argument variable would not work here, since the builder variables are
|
||||
// converted before entering the builder, which would result in an error
|
||||
// when attempting to convert an argument list.
|
||||
FailureOr<Value> argOperand = moduleImport.convertValue(llvmOperands[0]);
|
||||
|
||||
FailureOr<Value> argOperand = moduleImport.convertMetadataValue(llvmOperands[0]);
|
||||
// Drop the intrinsic when its operand could not be converted. This can
|
||||
// happen for use before definition cases that are allowed for debug
|
||||
// intrinsics.
|
||||
if (failed(argOperand))
|
||||
return failure();
|
||||
return success();
|
||||
$_op = $_builder.create<$_qualCppClassName>($_location,
|
||||
*argOperand, $_var_attr($varInfo));
|
||||
}];
|
||||
|
||||
@@ -119,6 +119,11 @@ public:
|
||||
/// LLVM values.
|
||||
FailureOr<Value> convertValue(llvm::Value *value);
|
||||
|
||||
/// Converts an LLVM metadata value to an MLIR value, or returns failure if
|
||||
/// the conversion fails. Uses the `convertConstant` method to translate
|
||||
/// constant LLVM values.
|
||||
FailureOr<Value> convertMetadataValue(llvm::Value *value);
|
||||
|
||||
/// Converts a range of LLVM values to a range of MLIR values using the
|
||||
/// `convertValue` method, or returns failure if the conversion fails.
|
||||
FailureOr<SmallVector<Value>> convertValues(ArrayRef<llvm::Value *> values);
|
||||
|
||||
@@ -1132,11 +1132,8 @@ FailureOr<Value> ModuleImport::convertConstantExpr(llvm::Constant *constant) {
|
||||
}
|
||||
|
||||
FailureOr<Value> ModuleImport::convertValue(llvm::Value *value) {
|
||||
// A value may be wrapped as metadata, for example, when passed to a debug
|
||||
// intrinsic. Unwrap these values before the conversion.
|
||||
if (auto *nodeAsVal = dyn_cast<llvm::MetadataAsValue>(value))
|
||||
if (auto *node = dyn_cast<llvm::ValueAsMetadata>(nodeAsVal->getMetadata()))
|
||||
value = node->getValue();
|
||||
assert(!isa<llvm::MetadataAsValue>(value) &&
|
||||
"expected value to not be metadata");
|
||||
|
||||
// Return the mapped value if it has been converted before.
|
||||
if (valueMapping.count(value))
|
||||
@@ -1152,6 +1149,27 @@ FailureOr<Value> ModuleImport::convertValue(llvm::Value *value) {
|
||||
return emitError(loc) << "unhandled value: " << diag(*value);
|
||||
}
|
||||
|
||||
FailureOr<Value> ModuleImport::convertMetadataValue(llvm::Value *value) {
|
||||
// A value may be wrapped as metadata, for example, when passed to a debug
|
||||
// intrinsic. Unwrap these values before the conversion.
|
||||
auto *nodeAsVal = dyn_cast<llvm::MetadataAsValue>(value);
|
||||
if (!nodeAsVal)
|
||||
return failure();
|
||||
auto *node = dyn_cast<llvm::ValueAsMetadata>(nodeAsVal->getMetadata());
|
||||
if (!node)
|
||||
return failure();
|
||||
value = node->getValue();
|
||||
|
||||
// Return the mapped value if it has been converted before.
|
||||
if (valueMapping.count(value))
|
||||
return lookupValue(value);
|
||||
|
||||
// Convert constants such as immediate values that have no mapping yet.
|
||||
if (auto *constant = dyn_cast<llvm::Constant>(value))
|
||||
return convertConstantExpr(constant);
|
||||
return failure();
|
||||
}
|
||||
|
||||
FailureOr<SmallVector<Value>>
|
||||
ModuleImport::convertValues(ArrayRef<llvm::Value *> values) {
|
||||
SmallVector<Value> remapped;
|
||||
|
||||
@@ -344,3 +344,26 @@ declare !dbg !3 void @variadic_func()
|
||||
!3 = !DISubprogram(name: "variadic_func", scope: !2, file: !2, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, type: !4)
|
||||
!4 = !DISubroutineType(types: !5)
|
||||
!5 = !{null, null}
|
||||
|
||||
; // -----
|
||||
|
||||
define void @dbg_use_before_def(ptr %arg) {
|
||||
call void @llvm.dbg.value(metadata ptr %dbg_arg, metadata !7, metadata !DIExpression()), !dbg !9
|
||||
%dbg_arg = getelementptr double, ptr %arg, i64 16
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @llvm.dbg.value(metadata, metadata, metadata)
|
||||
|
||||
!llvm.dbg.cu = !{!1}
|
||||
!llvm.module.flags = !{!0}
|
||||
!0 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
!1 = distinct !DICompileUnit(language: DW_LANG_C, file: !2)
|
||||
!2 = !DIFile(filename: "debug-info.ll", directory: "/")
|
||||
!3 = !DICompositeType(tag: DW_TAG_class_type, name: "class_field", file: !2, line: 42, flags: DIFlagTypePassByReference | DIFlagNonTrivial, elements: !4)
|
||||
!4 = !{!6}
|
||||
!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !3, flags: DIFlagArtificial | DIFlagObjectPointer)
|
||||
!6 = !DIDerivedType(tag: DW_TAG_member, name: "call_field", file: !2, baseType: !5)
|
||||
!7 = !DILocalVariable(scope: !8, name: "var", file: !2, type: !5);
|
||||
!8 = distinct !DISubprogram(name: "dbg_use_before_def", scope: !2, file: !2, spFlags: DISPFlagDefinition, unit: !1)
|
||||
!9 = !DILocation(line: 1, column: 2, scope: !8)
|
||||
|
||||
Reference in New Issue
Block a user