Skip to content

Commit 18d06dc

Browse files
authored
Cloning: Fix parameter mismatch when dropping arguments. (#475)
1 parent b625c13 commit 18d06dc

File tree

5 files changed

+62
-37
lines changed

5 files changed

+62
-37
lines changed

src/bitcode.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ function Base.parse(::Type{Module}, membuf::MemoryBuffer)
66
status = API.LLVMParseBitcodeInContext2(context(), membuf, out_ref) |> Bool
77
@assert !status # caught by diagnostics handler
88

9-
Module(out_ref[])
9+
mark_alloc(Module(out_ref[]))
1010
end
1111

1212
function Base.parse(::Type{Module}, data::Vector)

src/ir.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ function Base.parse(::Type{Module}, ir::String)
1414
throw(LLVMException(error))
1515
end
1616

17-
Module(out_ref[])
17+
mark_alloc(Module(out_ref[]))
1818
end
1919

2020

src/utils.jl

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ function materializer_callback(val, materializer)
1616
end
1717

1818
function clone_into!(new::Function, old::Function;
19-
value_map::Dict{Value,Value}=Dict{Value,Value}(),
19+
value_map::Dict{<:Value,<:Value}=Dict{Value,Value}(),
2020
changes=API.LLVMCloneFunctionChangeTypeLocalChangesOnly,
2121
suffix::String="", type_mapper=nothing, materializer=nothing)
2222
value_map_array = Value[]
@@ -43,14 +43,16 @@ function clone_into!(new::Function, old::Function;
4343
materializer_ptr, materializer_data)
4444
end
4545

46-
function clone(f::Function; value_map::Dict{Value,Value}=Dict{Value,Value}())
46+
function clone(f::Function; value_map::Dict{<:Value,<:Value}=Dict{Value,Value}())
4747
argtypes = LLVMType[]
4848

4949
# The user might be deleting arguments to the function by specifying them in
5050
# the VMap. If so, we need to not add the arguments to the arg ty vector
51+
remaining_parameters = Value[]
5152
for arg in parameters(f)
5253
if !in(arg, keys(value_map)) # Haven't mapped the argument to anything yet?
5354
push!(argtypes, value_type(arg))
55+
push!(remaining_parameters, arg)
5456
end
5557
end
5658

@@ -65,7 +67,8 @@ function clone(f::Function; value_map::Dict{Value,Value}=Dict{Value,Value}())
6567
# TODO: address space
6668

6769
# Loop over the arguments, copying the names of the mapped arguments over...
68-
for (arg, new_arg) in zip(parameters(f), parameters(new_f))
70+
value_map = Dict{Value,Value}(value_map)
71+
for (arg, new_arg) in zip(remaining_parameters, parameters(new_f))
6972
if !in(arg, keys(value_map)) # Is this argument preserved?
7073
name!(new_arg, name(arg)) # Copy the name over...
7174
value_map[arg] = new_arg # Add mapping to VMap
@@ -95,7 +98,7 @@ basic block.
9598
This can be done passing a `value_map` dictionary.
9699
"""
97100
function clone(bb::BasicBlock; dest::Union{Nothing,Function}=parent(bb), suffix::String="",
98-
value_map::Dict{Value,Value}=Dict{Value,Value}())
101+
value_map::Dict{<:Value,<:Value}=Dict{Value,Value}())
99102
value_map_array = Value[]
100103
for (src, dest) in value_map
101104
push!(value_map_array, src)

test/core_tests.jl

Lines changed: 35 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -949,42 +949,44 @@ end
949949

950950
bar_md = MDNode([ConstantInt(Int32(42)), nothing, MDString("string")])
951951
@test foo_md == bar_md
952+
953+
dispose(mod)
952954
end
953955

954956
@testset "debuginfo" begin
955957

956958
@dispose ctx=Context() begin
957-
mod = parse(LLVM.Module, raw"""
958-
define double @test(i64 signext %0, double %1) !dbg !5 {
959-
top:
960-
%2 = sitofp i64 %0 to double, !dbg !7
961-
%3 = fadd double %2, %1, !dbg !18
962-
ret double %3, !dbg !17
963-
}
964-
965-
!llvm.module.flags = !{!0, !1}
966-
!llvm.dbg.cu = !{!2}
967-
968-
!0 = !{i32 2, !"Dwarf Version", i32 4}
969-
!1 = !{i32 1, !"Debug Info Version", i32 3}
970-
!2 = distinct !DICompileUnit(language: DW_LANG_Julia, file: !3, producer: "julia", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, nameTableKind: GNU)
971-
!3 = !DIFile(filename: "promotion.jl", directory: ".")
972-
!4 = !{}
973-
!5 = distinct !DISubprogram(name: "+", linkageName: "julia_+_2055", scope: null, file: !3, line: 321, type: !6, scopeLine: 321, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !4)
974-
!6 = !DISubroutineType(types: !4)
975-
!7 = !DILocation(line: 94, scope: !8, inlinedAt: !10)
976-
!8 = distinct !DISubprogram(name: "Float64;", linkageName: "Float64", scope: !9, file: !9, type: !6, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !4)
977-
!9 = !DIFile(filename: "float.jl", directory: ".")
978-
!10 = !DILocation(line: 7, scope: !11, inlinedAt: !13)
979-
!11 = distinct !DISubprogram(name: "convert;", linkageName: "convert", scope: !12, file: !12, type: !6, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !4)
980-
!12 = !DIFile(filename: "number.jl", directory: ".")
981-
!13 = !DILocation(line: 269, scope: !14, inlinedAt: !15)
982-
!14 = distinct !DISubprogram(name: "_promote;", linkageName: "_promote", scope: !3, file: !3, type: !6, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !4)
983-
!15 = !DILocation(line: 292, scope: !16, inlinedAt: !17)
984-
!16 = distinct !DISubprogram(name: "promote;", linkageName: "promote", scope: !3, file: !3, type: !6, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !4)
985-
!17 = !DILocation(line: 321, scope: !5)
986-
!18 = !DILocation(line: 326, scope: !19, inlinedAt: !17)
987-
!19 = distinct !DISubprogram(name: "+;", linkageName: "+", scope: !9, file: !9, type: !6, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !4)""")
959+
mod = parse(LLVM.Module, raw"""
960+
define double @test(i64 signext %0, double %1) !dbg !5 {
961+
top:
962+
%2 = sitofp i64 %0 to double, !dbg !7
963+
%3 = fadd double %2, %1, !dbg !18
964+
ret double %3, !dbg !17
965+
}
966+
967+
!llvm.module.flags = !{!0, !1}
968+
!llvm.dbg.cu = !{!2}
969+
970+
!0 = !{i32 2, !"Dwarf Version", i32 4}
971+
!1 = !{i32 1, !"Debug Info Version", i32 3}
972+
!2 = distinct !DICompileUnit(language: DW_LANG_Julia, file: !3, producer: "julia", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, nameTableKind: GNU)
973+
!3 = !DIFile(filename: "promotion.jl", directory: ".")
974+
!4 = !{}
975+
!5 = distinct !DISubprogram(name: "+", linkageName: "julia_+_2055", scope: null, file: !3, line: 321, type: !6, scopeLine: 321, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !4)
976+
!6 = !DISubroutineType(types: !4)
977+
!7 = !DILocation(line: 94, scope: !8, inlinedAt: !10)
978+
!8 = distinct !DISubprogram(name: "Float64;", linkageName: "Float64", scope: !9, file: !9, type: !6, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !4)
979+
!9 = !DIFile(filename: "float.jl", directory: ".")
980+
!10 = !DILocation(line: 7, scope: !11, inlinedAt: !13)
981+
!11 = distinct !DISubprogram(name: "convert;", linkageName: "convert", scope: !12, file: !12, type: !6, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !4)
982+
!12 = !DIFile(filename: "number.jl", directory: ".")
983+
!13 = !DILocation(line: 269, scope: !14, inlinedAt: !15)
984+
!14 = distinct !DISubprogram(name: "_promote;", linkageName: "_promote", scope: !3, file: !3, type: !6, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !4)
985+
!15 = !DILocation(line: 292, scope: !16, inlinedAt: !17)
986+
!16 = distinct !DISubprogram(name: "promote;", linkageName: "promote", scope: !3, file: !3, type: !6, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !4)
987+
!17 = !DILocation(line: 321, scope: !5)
988+
!18 = !DILocation(line: 326, scope: !19, inlinedAt: !17)
989+
!19 = distinct !DISubprogram(name: "+;", linkageName: "+", scope: !9, file: !9, type: !6, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !4)""")
988990

989991
fun = functions(mod)["test"]
990992
bb = first(collect(blocks(fun)))
@@ -1023,6 +1025,8 @@ mod = parse(LLVM.Module, raw"""
10231025

10241026
loc = LLVM.inlined_at(loc)
10251027
@test loc === nothing
1028+
1029+
dispose(mod)
10261030
end
10271031

10281032
end

test/util_tests.jl

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,24 @@
8888
@test value_type(add) == LLVM.Int64Type()
8989
end
9090
end
91+
92+
# bug in basic clone: mapped parameters were incorrect
93+
let
94+
ir = """
95+
define i64 @"add"(i64 %0, i64 %1) {
96+
top:
97+
%2 = add i64 %1, %0
98+
ret i64 %2
99+
}""";
100+
@dispose ctx=Context() mod=parse(LLVM.Module, ir) begin
101+
src = functions(mod)["add"]
102+
value_map = Dict(
103+
parameters(src)[1] => ConstantInt(42)
104+
);
105+
dst = clone(src; value_map)
106+
@test length(parameters(dst)) == 1
107+
end
108+
end
91109
end
92110

93111
@testset "basic block cloning" begin

0 commit comments

Comments
 (0)