Skip to content

Commit 0f48aa7

Browse files
authored
Introduce at-dispose to replace do-block constructors. (#309)
1 parent f7cd9eb commit 0f48aa7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+543
-500
lines changed

examples/Kaleidoscope/codegen.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ Base.show(io::IO, cg::CodeGen) = print(io, "CodeGen")
2323

2424
function create_entry_block_allocation(cg::CodeGen, fn::LLVM.Function, varname::String)
2525
local alloc
26-
LLVM.Builder(cg.ctx) do builder
26+
LLVM.@dispose builder=LLVM.Builder(cg.ctx) begin
2727
# Set the builder at the start of the function
2828
entry_block = LLVM.entry(fn)
2929
if isempty(LLVM.instructions(entry_block))

examples/Kaleidoscope/run.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ function generate_IR(str; ctx::LLVM.Context)
1616
end
1717

1818
function optimize!(mod::LLVM.Module)
19-
LLVM.ModulePassManager() do pass_manager
19+
LLVM.@dispose pass_manager=LLVM.ModulePassManager() begin
2020
LLVM.instruction_combining!(pass_manager)
2121
LLVM.reassociate!(pass_manager)
2222
LLVM.gvn!(pass_manager)
@@ -29,7 +29,7 @@ end
2929

3030
function run(mod::LLVM.Module, entry::String)
3131
res_jl = 0.0
32-
LLVM.JIT(mod) do engine
32+
LLVM.@dispose engine=LLVM.JIT(mod) begin
3333
if !haskey(LLVM.functions(engine), entry)
3434
error("did not find entry function '$entry' in module")
3535
end
@@ -44,7 +44,7 @@ end
4444
function write_objectfile(mod::LLVM.Module, path::String)
4545
host_triple = Sys.MACHINE # LLVM.triple() might be wrong (see LLVM.jl#108)
4646
host_t = LLVM.Target(triple=host_triple)
47-
LLVM.TargetMachine(host_t, host_triple) do tm
47+
LLVM.@dispose tm=LLVM.TargetMachine(host_t, host_triple) begin
4848
LLVM.emit(tm, mod, LLVM.API.LLVMObjectFile, path)
4949
end
5050
end

examples/constrained.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ meta(::Type{FPExceptStrict}) = "fpexcept.strict"
3333
{F, round, fpexcept, T<:AbstractFloat, N}
3434
@assert N >= 0
3535

36-
Context() do ctx
36+
@dispose ctx=Context() begin
3737
typ = convert(LLVMType, T; ctx)
3838

3939
# create a function
@@ -50,7 +50,7 @@ meta(::Type{FPExceptStrict}) = "fpexcept.strict"
5050
intrinsic_typ)
5151

5252
# generate IR
53-
Builder(ctx) do builder
53+
@dispose builder=Builder(ctx) begin
5454
entry = BasicBlock(llvm_f, "entry"; ctx)
5555
position!(builder, entry)
5656
val = call!(builder, intrinsic,

examples/generated.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ struct CustomPtr{T}
99
end
1010

1111
@generated function Base.unsafe_load(p::CustomPtr{T}, i::Integer=1) where T
12-
Context() do ctx
12+
@dispose ctx=Context() begin
1313
# get the element type
1414
eltyp = convert(LLVMType, T; ctx)
1515

@@ -21,7 +21,7 @@ end
2121
llvmf, _ = create_function(eltyp, paramtyps)
2222

2323
# generate IR
24-
Builder(ctx) do builder
24+
@dispose builder=Builder(ctx) begin
2525
entry = BasicBlock(llvmf, "entry"; ctx)
2626
position!(builder, entry)
2727

examples/sum.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ else
1111
y = Int32(2)
1212
end
1313

14-
Context() do ctx
14+
@dispose ctx=Context() begin
1515
# set-up
1616
mod = LLVM.Module("my_module"; ctx)
1717

@@ -21,7 +21,7 @@ Context() do ctx
2121
sum = LLVM.Function(mod, "sum", fun_type)
2222

2323
# generate IR
24-
Builder(ctx) do builder
24+
@dispose builder=Builder(ctx) begin
2525
entry = BasicBlock(sum, "entry"; ctx)
2626
position!(builder, entry)
2727

@@ -33,7 +33,7 @@ Context() do ctx
3333
end
3434

3535
# analysis and execution
36-
Interpreter(mod) do engine
36+
@dispose engine=Interpreter(mod) begin
3737
args = [GenericValue(LLVM.Int32Type(ctx), x),
3838
GenericValue(LLVM.Int32Type(ctx), y)]
3939

examples/sum_integrated.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@ else
1212
y = Int32(2)
1313
end
1414

15-
Context() do ctx
15+
@dispose ctx=Context() begin
1616
param_types = [LLVM.Int32Type(ctx), LLVM.Int32Type(ctx)]
1717
ret_type = LLVM.Int32Type(ctx)
1818
sum, _ = create_function(ret_type, param_types)
1919

2020
# generate IR
21-
Builder(ctx) do builder
21+
@dispose builder=Builder(ctx) begin
2222
entry = BasicBlock(sum, "entry"; ctx)
2323
position!(builder, entry)
2424

examples/sum_orc.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ function codegen!(mod::LLVM.Module, name, tm)
2222
sum = LLVM.Function(mod, name, ft)
2323

2424
# generate IR
25-
Builder(ctx) do builder
25+
@dispose builder=Builder(ctx) begin
2626
entry = BasicBlock(sum, "entry"; ctx)
2727
position!(builder, entry)
2828

@@ -32,7 +32,7 @@ function codegen!(mod::LLVM.Module, name, tm)
3232

3333
verify(mod)
3434

35-
ModulePassManager() do pm
35+
@dispose pm=ModulePassManager() begin
3636
add_library_info!(pm, triple(mod))
3737
add_transform_info!(pm, tm)
3838
run!(pm, mod)
@@ -61,7 +61,7 @@ if LLVM.has_orc_v2()
6161
finalizer(LLVM.dispose, lljit)
6262
JIT = lljit
6363
else
64-
Context() do ctx
64+
@dispose ctx=Context() begin
6565
# Setup jit
6666
tm = JITTargetMachine()
6767

src/base.jl

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,45 @@ end
6565
@inline function refcheck(::Type, ref::Ptr)
6666
ref==C_NULL && throw(UndefRefError())
6767
end
68+
69+
70+
## helper macro for disposing resources without do-block syntax
71+
72+
export @dispose
73+
74+
"""
75+
LLVM.@dispose foo=Foo() bar=Bar() begin
76+
...
77+
end
78+
79+
Helper macro for disposing resources (by calling the `LLVM.dispose` function for every
80+
resource in reverse order) after executing a block of code. This is often equivalent to
81+
calling the recourse constructor with do-block syntax, but without using (potentially
82+
costly) closures.
83+
"""
84+
macro dispose(ex...)
85+
resources = ex[1:end-1]
86+
code = ex[end]
87+
88+
Meta.isexpr(code, :block) ||
89+
error("Expected a code block as final argument to LLVM.@dispose")
90+
91+
cleanup = quote
92+
end
93+
for res in reverse(resources)
94+
Meta.isexpr(res, :(=)) ||
95+
error("Resource arguments to LLVM.@dispose should be assignments")
96+
push!(cleanup.args, :(LLVM.dispose($(res.args[1]))))
97+
end
98+
99+
ex = quote
100+
let $(resources...)
101+
try
102+
$code
103+
finally
104+
$(cleanup.args...)
105+
end
106+
end
107+
end
108+
esc(ex)
109+
end

src/core/type.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ end
281281

282282
# FIXME: remove on LLVM 12
283283
function LLVMGetTypeByName2(ctx::Context, name)
284-
Module("dummy"; ctx) do mod
284+
@dispose mod=Module("dummy"; ctx) begin
285285
API.LLVMGetTypeByName(mod, name)
286286
end
287287
end

src/core/value/constant.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -537,8 +537,8 @@ linkage!(val::GlobalValue, linkage::API.LLVMLinkage) =
537537
function section(val::GlobalValue)
538538
#=
539539
The following started to fail on LLVM 4.0:
540-
Context() do ctx
541-
LLVM.Module("SomeModule"; ctx) do mod
540+
@dispose ctx=Context() begin
541+
@dispose mod=LLVM.Module("SomeModule"; ctx) begin
542542
st = LLVM.StructType("SomeType"; ctx)
543543
ft = LLVM.FunctionType(st, [st])
544544
fn = LLVM.Function(mod, "SomeFunction", ft)

0 commit comments

Comments
 (0)