diff --git a/src/compiler/crystal/codegen/crystal_llvm_builder.cr b/src/compiler/crystal/codegen/crystal_llvm_builder.cr index 9bf84dc25d7f..54116a9d265e 100644 --- a/src/compiler/crystal/codegen/crystal_llvm_builder.cr +++ b/src/compiler/crystal/codegen/crystal_llvm_builder.cr @@ -74,12 +74,12 @@ module Crystal end {% for name in %w(add add_handler alloca and ashr atomicrmw bit_cast build_catch_ret call - catch_pad catch_switch cmpxchg cond current_debug_location exact_sdiv - extract_value fadd fcmp fdiv fence fmul fp2si fp2ui fpext fptrunc fsub - global_string_pointer icmp inbounds_gep int2ptr invoke landing_pad load - lshr mul not or phi ptr2int sdiv select set_current_debug_location sext - shl si2fp srem store store_volatile sub switch trunc udiv ui2fp urem va_arg - xor zext) %} + catch_pad catch_switch clear_current_debug_location cmpxchg cond + current_debug_location exact_sdiv extract_value fadd fcmp fdiv fence fmul + fp2si fp2ui fpext fptrunc fsub global_string_pointer icmp inbounds_gep int2ptr + invoke landing_pad load lshr mul not or phi ptr2int sdiv select + set_current_debug_location sext shl si2fp srem store store_volatile sub switch + trunc udiv ui2fp urem va_arg xor zext) %} def {{name.id}}(*args, **kwargs) return llvm_nil if @end diff --git a/src/compiler/crystal/codegen/debug.cr b/src/compiler/crystal/codegen/debug.cr index f866e14e12f8..9fe5ce5c6ca9 100644 --- a/src/compiler/crystal/codegen/debug.cr +++ b/src/compiler/crystal/codegen/debug.cr @@ -463,7 +463,9 @@ module Crystal scope = get_current_debug_scope(location) if scope - builder.set_current_debug_location(location.line_number || 1, location.column_number, scope) + debug_loc = di_builder.create_debug_location(location.line_number || 1, location.column_number, scope) + # NOTE: `di_builder.context` is only necessary for LLVM 8 + builder.set_current_debug_location(debug_loc, di_builder.context) else clear_current_debug_location end @@ -472,7 +474,7 @@ module Crystal def clear_current_debug_location @current_debug_location = nil - builder.set_current_debug_location(0, 0, nil) + builder.clear_current_debug_location end def emit_fun_debug_metadata(func, fun_name, location, *, debug_types = [] of LibLLVM::MetadataRef, is_optimized = false) diff --git a/src/llvm/builder.cr b/src/llvm/builder.cr index 818316186532..3018eae6e642 100644 --- a/src/llvm/builder.cr +++ b/src/llvm/builder.cr @@ -333,10 +333,27 @@ class LLVM::Builder Value.new LibLLVM.build_va_arg(self, list, type, name) end + @[Deprecated("Call `#set_current_debug_location(metadata, context)` or `#clear_current_debug_location` instead")] def set_current_debug_location(line, column, scope, inlined_at = nil) LibLLVMExt.set_current_debug_location(self, line, column, scope, inlined_at) end + def set_current_debug_location(metadata, context : LLVM::Context) + {% if LibLLVM::IS_LT_90 %} + LibLLVM.set_current_debug_location(self, LibLLVM.metadata_as_value(context, metadata)) + {% else %} + LibLLVM.set_current_debug_location2(self, metadata) + {% end %} + end + + def clear_current_debug_location + {% if LibLLVM::IS_LT_90 %} + LibLLVMExt.clear_current_debug_location(self) + {% else %} + LibLLVM.set_current_debug_location2(self, nil) + {% end %} + end + def set_metadata(value, kind, node) LibLLVM.set_metadata(value, kind, node) end diff --git a/src/llvm/di_builder.cr b/src/llvm/di_builder.cr index 1fca2301f1dd..41bb18244c3c 100644 --- a/src/llvm/di_builder.cr +++ b/src/llvm/di_builder.cr @@ -14,6 +14,10 @@ struct LLVM::DIBuilder LibLLVM.dispose_di_builder(self) end + def context + @llvm_module.context + end + def create_compile_unit(lang : DwarfSourceLanguage, file, dir, producer, optimized, flags, runtime_version) file = create_file(file, dir) {% if LibLLVM::IS_LT_110 %} @@ -151,6 +155,10 @@ struct LLVM::DIBuilder LibLLVM.di_builder_get_or_create_subrange(self, lo, count) end + def create_debug_location(line, column, scope, inlined_at = nil) + LibLLVM.di_builder_create_debug_location(context, line, column, scope, inlined_at) + end + def end LibLLVM.di_builder_finalize(self) end @@ -191,7 +199,7 @@ struct LLVM::DIBuilder end private def extract_metadata_array(metadata : LibLLVM::MetadataRef) - metadata_as_value = LibLLVM.metadata_as_value(@llvm_module.context, metadata) + metadata_as_value = LibLLVM.metadata_as_value(context, metadata) operand_count = LibLLVM.get_md_node_num_operands(metadata_as_value).to_i operands = Pointer(LibLLVM::ValueRef).malloc(operand_count) LibLLVM.get_md_node_operands(metadata_as_value, operands) diff --git a/src/llvm/ext/llvm_ext.cc b/src/llvm/ext/llvm_ext.cc index f821abf30703..acc95d63bcae 100644 --- a/src/llvm/ext/llvm_ext.cc +++ b/src/llvm/ext/llvm_ext.cc @@ -1,6 +1,5 @@ -#include +#include #include -#include #include #include @@ -9,50 +8,27 @@ using namespace llvm; #define LLVM_VERSION_GE(major, minor) \ (LLVM_VERSION_MAJOR > (major) || LLVM_VERSION_MAJOR == (major) && LLVM_VERSION_MINOR >= (minor)) -#define LLVM_VERSION_EQ(major, minor) \ - (LLVM_VERSION_MAJOR == (major) && LLVM_VERSION_MINOR == (minor)) - -#define LLVM_VERSION_LE(major, minor) \ - (LLVM_VERSION_MAJOR < (major) || LLVM_VERSION_MAJOR == (major) && LLVM_VERSION_MINOR <= (minor)) +#if !LLVM_VERSION_GE(9, 0) +#include +#endif #if LLVM_VERSION_GE(16, 0) #define makeArrayRef ArrayRef #endif -typedef DIBuilder *DIBuilderRef; -#define DIArray DINodeArray -template T *unwrapDIptr(LLVMMetadataRef v) { - return (T *)(v ? unwrap(v) : NULL); -} - extern "C" { -#if LLVM_VERSION_GE(9, 0) -#else +#if !LLVM_VERSION_GE(9, 0) LLVMMetadataRef LLVMExtDIBuilderCreateEnumerator( LLVMDIBuilderRef Dref, const char *Name, int64_t Value) { DIEnumerator *e = unwrap(Dref)->createEnumerator(Name, Value); return wrap(e); } -#endif -void LLVMExtSetCurrentDebugLocation( - LLVMBuilderRef Bref, unsigned Line, unsigned Col, LLVMMetadataRef Scope, - LLVMMetadataRef InlinedAt) { -#if LLVM_VERSION_GE(12, 0) - if (!Scope) - unwrap(Bref)->SetCurrentDebugLocation(DebugLoc()); - else - unwrap(Bref)->SetCurrentDebugLocation( - DILocation::get(unwrap(Scope)->getContext(), Line, Col, - unwrapDIptr(Scope), - unwrapDIptr(InlinedAt))); -#else - unwrap(Bref)->SetCurrentDebugLocation( - DebugLoc::get(Line, Col, Scope ? unwrap(Scope) : nullptr, - InlinedAt ? unwrap(InlinedAt) : nullptr)); -#endif +void LLVMExtClearCurrentDebugLocation(LLVMBuilderRef B) { + unwrap(B)->SetCurrentDebugLocation(DebugLoc::get(0, 0, nullptr)); } +#endif OperandBundleDef *LLVMExtBuildOperandBundleDef( const char *Name, LLVMValueRef *Inputs, unsigned NumInputs) { diff --git a/src/llvm/lib_llvm/core.cr b/src/llvm/lib_llvm/core.cr index 1d44cb005d98..a0cfb708d515 100644 --- a/src/llvm/lib_llvm/core.cr +++ b/src/llvm/lib_llvm/core.cr @@ -183,8 +183,11 @@ lib LibLLVM fun get_insert_block = LLVMGetInsertBlock(builder : BuilderRef) : BasicBlockRef fun dispose_builder = LLVMDisposeBuilder(builder : BuilderRef) - {% unless LibLLVM::IS_LT_90 %} + {% if LibLLVM::IS_LT_90 %} + fun set_current_debug_location = LLVMSetCurrentDebugLocation(builder : BuilderRef, l : ValueRef) + {% else %} fun get_current_debug_location2 = LLVMGetCurrentDebugLocation2(builder : BuilderRef) : MetadataRef + fun set_current_debug_location2 = LLVMSetCurrentDebugLocation2(builder : BuilderRef, loc : MetadataRef) {% end %} fun get_current_debug_location = LLVMGetCurrentDebugLocation(builder : BuilderRef) : ValueRef diff --git a/src/llvm/lib_llvm/debug_info.cr b/src/llvm/lib_llvm/debug_info.cr index 8aeba0d6a99a..8482a0644ae3 100644 --- a/src/llvm/lib_llvm/debug_info.cr +++ b/src/llvm/lib_llvm/debug_info.cr @@ -45,6 +45,10 @@ lib LibLLVM builder : DIBuilderRef, scope : MetadataRef, file_scope : MetadataRef, discriminator : UInt ) : MetadataRef + fun di_builder_create_debug_location = LLVMDIBuilderCreateDebugLocation( + ctx : ContextRef, line : UInt, column : UInt, scope : MetadataRef, inlined_at : MetadataRef + ) : MetadataRef + fun di_builder_get_or_create_type_array = LLVMDIBuilderGetOrCreateTypeArray(builder : DIBuilderRef, types : MetadataRef*, length : SizeT) : MetadataRef fun di_builder_create_subroutine_type = LLVMDIBuilderCreateSubroutineType( diff --git a/src/llvm/lib_llvm_ext.cr b/src/llvm/lib_llvm_ext.cr index 6520cae55dfc..4efb572b6eed 100644 --- a/src/llvm/lib_llvm_ext.cr +++ b/src/llvm/lib_llvm_ext.cr @@ -13,10 +13,9 @@ lib LibLLVMExt {% if LibLLVM::IS_LT_90 %} fun di_builder_create_enumerator = LLVMExtDIBuilderCreateEnumerator(builder : LibLLVM::DIBuilderRef, name : Char*, value : Int64) : LibLLVM::MetadataRef + fun clear_current_debug_location = LLVMExtClearCurrentDebugLocation(b : LibLLVM::BuilderRef) {% end %} - fun set_current_debug_location = LLVMExtSetCurrentDebugLocation(LibLLVM::BuilderRef, Int, Int, LibLLVM::MetadataRef, LibLLVM::MetadataRef) - fun build_operand_bundle_def = LLVMExtBuildOperandBundleDef(name : LibC::Char*, input : LibLLVM::ValueRef*, num_input : LibC::UInt) : LibLLVMExt::OperandBundleDefRef