Skip to content

Commit bf12473

Browse files
authored
Merge pull request #189 from maleadt/tb/target_iterator
Rework target lookup and iteration.
2 parents 8bd8b96 + e0e5908 commit bf12473

File tree

5 files changed

+48
-42
lines changed

5 files changed

+48
-42
lines changed

examples/Kaleidoscope/run.jl

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

4444
function write_objectfile(mod::LLVM.Module, path::String)
4545
host_triple = Sys.MACHINE # LLVM.triple() might be wrong (see LLVM.jl#108)
46-
host_t = LLVM.Target(host_triple)
46+
host_t = LLVM.Target(triple=host_triple)
4747
LLVM.TargetMachine(host_t, host_triple) do tm
4848
LLVM.emit(tm, mod, LLVM.API.LLVMObjectFile, path)
4949
end

src/deprecated.jl

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
# deprecated methods
22

3-
import Base: get
3+
@deprecate FunctionType(rettyp, params, vararg) FunctionType(rettyp, params; vararg=vararg)
44

5-
@deprecate get(set::TargetSet, name::String) getindex(set, name)
5+
# Target non-kwarg constructor
6+
@deprecate Target(triple::String) Target(; triple=triple)
67

7-
@deprecate FunctionType(rettyp, params, vararg) FunctionType(rettyp, params; vararg=vararg)
8+
# TargetIterator dict-like behavior
9+
import Base: haskey, getindex, get
10+
@deprecate get(set::TargetIterator, name::String) getindex(set, name)
11+
@deprecate haskey(::TargetIterator, name::String) Target(;name=name) !== nothing
12+
@deprecate getindex(iter::TargetIterator, name::String) Target(;name=name)
13+
@deprecate get(::TargetIterator, name::String, default) try Target(;name=name) catch; default end

src/target.jl

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,29 @@ export Target,
99
end
1010
reftype(::Type{Target}) = API.LLVMTargetRef
1111

12-
function Target(triple::String)
13-
out_ref = Ref{API.LLVMTargetRef}()
14-
out_error = Ref{Cstring}()
15-
status = convert(Core.Bool, API.LLVMGetTargetFromTriple(triple, out_ref, out_error))
16-
17-
if status
18-
error = unsafe_message(out_error[])
19-
throw(LLVMException(error))
12+
function Target(; name=nothing, triple=nothing)
13+
(name !== nothing) (triple !== nothing) ||
14+
throw(ArgumentError("Specify either name or triple."))
15+
16+
if triple !== nothing
17+
target_ref = Ref{API.LLVMTargetRef}(0)
18+
error_ref = Ref{Cstring}(C_NULL)
19+
status = convert(Core.Bool, API.LLVMGetTargetFromTriple(triple, target_ref, error_ref))
20+
if status && error_ref[] !== C_NULL
21+
error = unsafe_message(error_ref[])
22+
throw(ArgumentError(error))
23+
elseif status
24+
throw(ArgumentError("Cannot find a target for triple '$triple'"))
25+
end
26+
@assert target_ref[] != C_NULL
27+
return Target(target_ref[])
28+
elseif name !== nothing
29+
target = API.LLVMGetTargetFromName(name)
30+
if target == C_NULL
31+
throw(ArgumentError("Cannot find target '$triple'"))
32+
end
33+
return Target(target)
2034
end
21-
22-
return Target(out_ref[])
2335
end
2436

2537
name(t::Target) = unsafe_string(API.LLVMGetTargetName(ref(t)))
@@ -30,32 +42,23 @@ hasjit(t::Target) = convert(Core.Bool, API.LLVMTargetHasJIT(ref(t)))
3042
hastargetmachine(t::Target) = convert(Core.Bool, API.LLVMTargetHasTargetMachine(ref(t)))
3143
hasasmparser(t::Target) = convert(Core.Bool, API.LLVMTargetHasAsmBackend(ref(t)))
3244

33-
# target iteration
34-
35-
export targets
45+
function Base.show(io::IO, ::MIME"text/plain", target::Target)
46+
print(io, "LLVM.Target($(name(target))): $(description(target))")
47+
end
3648

37-
struct TargetSet end
3849

39-
targets() = TargetSet()
50+
## target iteration
4051

41-
Base.eltype(::TargetSet) = Target
52+
export targets
4253

43-
function Base.haskey(::TargetSet, name::String)
44-
return API.LLVMGetTargetFromName(name) != C_NULL
45-
end
54+
struct TargetIterator end
4655

47-
function Base.get(::TargetSet, name::String, default)
48-
objref = API.LLVMGetTargetFromName(name)
49-
return objref == C_NULL ? default : Target(objref)
50-
end
56+
targets() = TargetIterator()
5157

52-
function Base.getindex(targetset::TargetSet, name::String)
53-
f = get(targetset, name, nothing)
54-
return f == nothing ? throw(KeyError(name)) : f
55-
end
58+
Base.eltype(::TargetIterator) = Target
5659

57-
function Base.iterate(iter::TargetSet, state=API.LLVMGetFirstTarget())
60+
function Base.iterate(iter::TargetIterator, state=API.LLVMGetFirstTarget())
5861
state == C_NULL ? nothing : (Target(state), API.LLVMGetNextTarget(state))
5962
end
6063

61-
Base.IteratorSize(::TargetSet) = Base.SizeUnknown()
64+
Base.IteratorSize(::TargetIterator) = Base.SizeUnknown()

test/target.jl

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
@testset "target" begin
2-
@test_throws LLVMException Target("invalid")
2+
@test_throws ArgumentError Target(triple="invalid")
3+
@test_throws ArgumentError Target(name="invalid")
34

45
host_triple = triple()
5-
host_t = Target(host_triple)
6+
host_t = Target(triple=host_triple)
67

78
host_name = name(host_t)
89
description(host_t)
@@ -13,12 +14,8 @@
1314

1415
# target iteration
1516
let ts = targets()
16-
@test haskey(ts, host_name)
17-
@test ts[host_name] == host_t
18-
19-
@test !haskey(ts, "invalid")
20-
@test get(ts, "invalid", "dummy") == "dummy"
21-
@test_throws KeyError ts["invalid"]
17+
@test !isempty(ts)
18+
@test host_t in ts
2219

2320
@test eltype(ts) == Target
2421

test/targetmachine.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
@testset "targetmachine" begin
22

33
host_triple = triple()
4-
host_t = Target(host_triple)
4+
host_t = Target(triple=host_triple)
55

66
let
77
tm = TargetMachine(host_t, host_triple)

0 commit comments

Comments
 (0)