@asterite I do understand. No issues at all. I need your help with understanding how block variables are defined. I have some interesting effect when my block arguments are shown not in the block but in the parent scope of def each (in the scope of yield). I localized that arguments code in codegen.cr around line 1480 ( I added declare_variable call after line 1480:
unless block_var.debug_var
declare_variable arg.name, block_var.type, block_var.pointer, block_var.location
end
block_var.debug_var is my flag that tracks if variable has debug variable value already created or not.
If I use exp_type, exp_value instead of block_var.type, block_var.pointer then it shows in correct place but no values
Also what closured variable means in crystal codegen context? Is it variable that captured from outside scope? Does alloca_non_closured_vars should allocate block variables?
I factored llvm module a little by exposing enumerables for basic blocks and instructions as well as accessing for instruction metadata so now it can be much easier to work directly on per alloca variable info data as per this example:
def body_to_ll_string
String.build do |str|
str << "def " << self.name << "(#{self.params.join(", ")}):\n"
self.basic_blocks.each do |block|
str << "Block " << block.name << ":\n"
block.instructions.each do |inst|
str << "\t" << inst << " -> metadata: " << (inst.instruction_metadata || "N/A") << "\n"
end
str << "\n"
end
end
end
which in turn provides this debug snippet:
</Users/sergey/Projects/crystal/crystal/src/compiler/crystal/codegen/codegen.cr:368> def *UInt64::new<UInt64>:UInt64(i64 %value):
Block alloca:
call void @llvm.dbg.declare(metadata i64 %value, metadata !19768, metadata !DIExpression()), !dbg !19769 -> metadata: !DILocation(line: 1019, column: 3, scope: <0x7f9912cbfbb0>) = !DILocation(line: 1019, column: 3, scope: <0x7f9912cbfbb0>)
br label %entry -> metadata: N/A
Block entry:
%0 = icmp ult i64 %value, 0, !dbg !375 -> metadata: !DILocation(line: 1019, column: 3, scope: <0x7f9912cbfbb0>) = !DILocation(line: 1019, column: 3, scope: <0x7f9912cbfbb0>)
%1 = icmp ugt i64 %value, -1, !dbg !375 -> metadata: !DILocation(line: 1019, column: 3, scope: <0x7f9912cbfbb0>) = !DILocation(line: 1019, column: 3, scope: <0x7f9912cbfbb0>)
%2 = or i1 %0, %1, !dbg !375 -> metadata: !DILocation(line: 1019, column: 3, scope: <0x7f9912cbfbb0>) = !DILocation(line: 1019, column: 3, scope: <0x7f9912cbfbb0>)
%3 = call i1 @llvm.expect.i1(i1 %2, i1 false), !dbg !375 -> metadata: !DILocation(line: 1019, column: 3, scope: <0x7f9912cbfbb0>) = !DILocation(line: 1019, column: 3, scope: <0x7f9912cbfbb0>)
br i1 %3, label %overflow, label %normal, !dbg !375 -> metadata: !DILocation(line: 1019, column: 3, scope: <0x7f9912cbfbb0>) = !DILocation(line: 1019, column: 3, scope: <0x7f9912cbfbb0>)
Block overflow:
call void @__crystal_raise_overflow(), !dbg !376 -> metadata: !DILocation(line: 1020, column: 11, scope: <0x7f9912cbfbb0>) = !DILocation(line: 1020, column: 11, scope: <0x7f9912cbfbb0>)
unreachable, !dbg !376 -> metadata: !DILocation(line: 1020, column: 11, scope: <0x7f9912cbfbb0>) = !DILocation(line: 1020, column: 11, scope: <0x7f9912cbfbb0>)
Block normal:
ret i64 %value, !dbg !376 -> metadata: !DILocation(line: 1020, column: 11, scope: <0x7f9912cbfbb0>) = !DILocation(line: 1020, column: 11, scope: <0x7f9912cbfbb0>)
</Users/sergey/Projects/crystal/crystal/src/compiler/crystal/codegen/codegen.cr:368> def *GC::realloc<Pointer(Void), UInt64>:Pointer(Void)(i8* %ptr, i64 %size):
Block alloca:
call void @llvm.dbg.declare(metadata i8* %ptr, metadata !19773, metadata !DIExpression()), !dbg !19775 -> metadata: !DILocation(line: 119, column: 3, scope: <0x7f9912cc1480>) = !DILocation(line: 119, column: 3, scope: <0x7f9912cc1480>)
call void @llvm.dbg.declare(metadata i64 %size, metadata !19774, metadata !DIExpression()), !dbg !19775 -> metadata: !DILocation(line: 119, column: 3, scope: <0x7f9912cc1480>) = !DILocation(line: 119, column: 3, scope: <0x7f9912cc1480>)
br label %entry -> metadata: N/A
Block entry:
%0 = call i8* @GC_realloc(i8* %ptr, i64 %size), !dbg !379 -> metadata: !DILocation(line: 120, column: 5, scope: <0x7f9912cc1480>) = !DILocation(line: 120, column: 5, scope: <0x7f9912cc1480>)
ret i8* %0, !dbg !379 -> metadata: !DILocation(line: 120, column: 5, scope: <0x7f9912cc1480>) = !DILocation(line: 120, column: 5, scope: <0x7f9912cc1480>)
It helps me to debug debug lines mismatch.
Are you okay if my changes can go into LLVM standard lib package?