Skip to content

Commit f7e5f62

Browse files
committed
Perform kind lookups using a global dict, not dispatch.
1 parent b4dfdfc commit f7e5f62

File tree

8 files changed

+62
-50
lines changed

8 files changed

+62
-50
lines changed

src/core/basicblock.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export BasicBlock, unsafe_delete!,
55
@checked struct BasicBlock <: Value
66
ref::API.LLVMValueRef
77
end
8-
identify(::Type{Value}, ::Val{API.LLVMBasicBlockValueKind}) = BasicBlock
8+
value_kinds[API.LLVMBasicBlockValueKind] = BasicBlock
99

1010
BasicBlock(ref::API.LLVMBasicBlockRef) = BasicBlock(API.LLVMBasicBlockAsValue(ref))
1111
Base.unsafe_convert(::Type{API.LLVMBasicBlockRef}, bb::BasicBlock) = API.LLVMValueAsBasicBlock(bb)

src/core/function.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export unsafe_delete!,
55
entry
66

77
# forward declaration of Function in src/core/basicblock.jl
8-
identify(::Type{Value}, ::Val{API.LLVMFunctionValueKind}) = Function
8+
value_kinds[API.LLVMFunctionValueKind] = Function
99

1010
Function(mod::Module, name::String, ft::FunctionType) =
1111
Function(API.LLVMAddFunction(mod, name, ft))
@@ -81,7 +81,7 @@ export Argument, parameters
8181
@checked struct Argument <: Value
8282
ref::API.LLVMValueRef
8383
end
84-
identify(::Type{Value}, ::Val{API.LLVMArgumentValueKind}) = Argument
84+
value_kinds[API.LLVMArgumentValueKind] = Argument
8585

8686
struct FunctionParameterSet <: AbstractVector{Argument}
8787
f::Function

src/core/instructions.jl

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,14 @@ export Instruction, unsafe_delete!,
44
predicate_int, predicate_real
55

66
# forward definition of Instruction in src/core/value/constant.jl
7-
identify(::Type{Value}, ::Val{API.LLVMInstructionValueKind}) = Instruction
7+
value_kinds[API.LLVMInstructionValueKind] = Instruction
88

9-
identify(::Type{Instruction}, ref::API.LLVMValueRef) =
10-
identify(Instruction, Val{API.LLVMGetInstructionOpcode(ref)}())
11-
identify(::Type{Instruction}, ::Val{K}) where {K} = error("Unknown instruction kind $K")
9+
const instruction_opcodes = Dict{API.LLVMOpcode, Type{<:Instruction}}()
10+
function identify(::Type{Instruction}, ref::API.LLVMValueRef)
11+
opcode = API.LLVMGetInstructionOpcode(ref)
12+
haskey(instruction_opcodes, opcode) || error("Unknown instruction opcode $opcode")
13+
return instruction_opcodes[opcode]
14+
end
1215

1316
@inline function refcheck(::Type{T}, ref::API.LLVMValueRef) where T<:Instruction
1417
ref==C_NULL && throw(UndefRefError())
@@ -115,7 +118,7 @@ for op in opcodes
115118
@checked struct $typename <: Instruction
116119
ref::API.LLVMValueRef
117120
end
118-
identify(::Type{Instruction}, ::Val{API.$enum}) = $typename
121+
instruction_opcodes[API.$enum] = $typename
119122
end
120123
end
121124

src/core/metadata.jl

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@ abstract type Metadata end
55

66
Base.unsafe_convert(::Type{API.LLVMMetadataRef}, md::Metadata) = md.ref
77

8-
identify(::Type{Metadata}, ref::API.LLVMMetadataRef) =
9-
identify(Metadata, Val{API.LLVMGetMetadataKind(ref)}())
10-
identify(::Type{Metadata}, ::Val{K}) where {K} = error("Unknown metadata kind $K")
8+
const metadata_kinds = Dict{API.LLVMMetadataKind, Type{<:Metadata}}()
9+
function identify(::Type{Metadata}, ref::API.LLVMMetadataRef)
10+
kind = API.LLVMGetMetadataKind(ref)
11+
haskey(metadata_kinds, kind) || error("Unknown metadata kind $kind")
12+
return metadata_kinds[kind]
13+
end
1114

1215
@inline function refcheck(::Type{T}, ref::API.LLVMMetadataRef) where T<:Metadata
1316
ref==C_NULL && throw(UndefRefError())
@@ -37,7 +40,7 @@ end
3740
@checked struct MetadataAsValue <: Value
3841
ref::API.LLVMValueRef
3942
end
40-
identify(::Type{Value}, ::Val{API.LLVMMetadataAsValueValueKind}) = MetadataAsValue
43+
value_kinds[API.LLVMMetadataAsValueValueKind] = MetadataAsValue
4144

4245
Value(md::Metadata; ctx::Context) = MetadataAsValue(API.LLVMMetadataAsValue(ctx, md))
4346

@@ -52,12 +55,12 @@ abstract type ValueAsMetadata <: Metadata end
5255
@checked struct ConstantAsMetadata <: ValueAsMetadata
5356
ref::API.LLVMMetadataRef
5457
end
55-
identify(::Type{Metadata}, ::Val{API.LLVMConstantAsMetadataMetadataKind}) = ConstantAsMetadata
58+
metadata_kinds[API.LLVMConstantAsMetadataMetadataKind] = ConstantAsMetadata
5659

5760
@checked struct LocalAsMetadata <: ValueAsMetadata
5861
ref::API.LLVMMetadataRef
5962
end
60-
identify(::Type{Metadata}, ::Val{API.LLVMLocalAsMetadataMetadataKind}) = LocalAsMetadata
63+
metadata_kinds[API.LLVMLocalAsMetadataMetadataKind] = LocalAsMetadata
6164

6265
# NOTE: this can be used to both pack e.g. constants as metadata, and to extract the
6366
# metadata from an MetadataAsValue, so we don't type-assert narrowly here
@@ -73,7 +76,7 @@ export MDString
7376
@checked struct MDString <: Metadata
7477
ref::API.LLVMMetadataRef
7578
end
76-
identify(::Type{Metadata}, ::Val{API.LLVMMDStringMetadataKind}) = MDString
79+
metadata_kinds[API.LLVMMDStringMetadataKind] = MDString
7780

7881
MDString(val::String; ctx::Context) =
7982
MDString(API.LLVMMDStringInContext2(ctx, val, length(val)))
@@ -106,7 +109,7 @@ export MDTuple
106109
@checked struct MDTuple <: MDNode
107110
ref::API.LLVMMetadataRef
108111
end
109-
identify(::Type{Metadata}, ::Val{API.LLVMMDTupleMetadataKind}) = MDTuple
112+
metadata_kinds[API.LLVMMDTupleMetadataKind] = MDTuple
110113

111114
# MDTuples are commonly referred to as MDNodes, so keep that name
112115
MDNode(mds::Vector{<:Metadata}; ctx::Context) =

src/core/type.jl

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,12 @@ Base.eltype(typ::LLVMType) = Any
77

88
Base.unsafe_convert(::Type{API.LLVMTypeRef}, typ::LLVMType) = typ.ref
99

10-
identify(::Type{LLVMType}, ref::API.LLVMTypeRef) =
11-
identify(LLVMType, Val{API.LLVMGetTypeKind(ref)}())
12-
identify(::Type{LLVMType}, ::Val{K}) where {K} = error("Unknown type kind $K")
10+
const type_kinds = Dict{API.LLVMTypeKind, Type{<:LLVMType}}()
11+
function identify(::Type{LLVMType}, ref::API.LLVMTypeRef)
12+
kind = API.LLVMGetTypeKind(ref)
13+
haskey(type_kinds, kind) || error("Unknown type kind $kind")
14+
return type_kinds[kind]
15+
end
1316

1417
@inline function refcheck(::Type{T}, ref::API.LLVMTypeRef) where T<:LLVMType
1518
ref==C_NULL && throw(UndefRefError())
@@ -45,7 +48,7 @@ export width
4548
@checked struct IntegerType <: LLVMType
4649
ref::API.LLVMTypeRef
4750
end
48-
identify(::Type{LLVMType}, ::Val{API.LLVMIntegerTypeKind}) = IntegerType
51+
type_kinds[API.LLVMIntegerTypeKind] = IntegerType
4952

5053
for T in [:Int1, :Int8, :Int16, :Int32, :Int64, :Int128]
5154
jl_fname = Symbol(T, :Type)
@@ -79,7 +82,7 @@ for T in [:Half, :Float, :Double]
7982
@checked struct $api_typename <: FloatingPointType
8083
ref::API.LLVMTypeRef
8184
end
82-
identify(::Type{LLVMType}, ::Val{API.$enumkind}) = $api_typename
85+
type_kinds[API.$enumkind] = $api_typename
8386

8487
$jl_fname(ctx::Context) =
8588
$api_typename(API.$(Symbol(api_fname, :InContext))(ctx))
@@ -94,7 +97,7 @@ export isvararg, return_type, parameters
9497
@checked struct FunctionType <: LLVMType
9598
ref::API.LLVMTypeRef
9699
end
97-
identify(::Type{LLVMType}, ::Val{API.LLVMFunctionTypeKind}) = FunctionType
100+
type_kinds[API.LLVMFunctionTypeKind] = FunctionType
98101

99102
FunctionType(rettyp::LLVMType, params::Vector{<:LLVMType}=LLVMType[];
100103
vararg::Core.Bool=false) =
@@ -133,7 +136,7 @@ Base.eltype(typ::SequentialType) = LLVMType(API.LLVMGetElementType(typ))
133136
@checked struct PointerType <: SequentialType
134137
ref::API.LLVMTypeRef
135138
end
136-
identify(::Type{LLVMType}, ::Val{API.LLVMPointerTypeKind}) = PointerType
139+
type_kinds[API.LLVMPointerTypeKind] = PointerType
137140

138141
function PointerType(eltyp::LLVMType, addrspace=0)
139142
return PointerType(API.LLVMPointerType(eltyp, addrspace))
@@ -146,7 +149,7 @@ addrspace(ptrtyp::PointerType) =
146149
@checked struct ArrayType <: SequentialType
147150
ref::API.LLVMTypeRef
148151
end
149-
identify(::Type{LLVMType}, ::Val{API.LLVMArrayTypeKind}) = ArrayType
152+
type_kinds[API.LLVMArrayTypeKind] = ArrayType
150153

151154
function ArrayType(eltyp::LLVMType, count)
152155
return ArrayType(API.LLVMArrayType(eltyp, count))
@@ -160,7 +163,7 @@ Base.isempty(@nospecialize(T::ArrayType)) = length(T) == 0 || isempty(eltype(T))
160163
@checked struct VectorType <: SequentialType
161164
ref::API.LLVMTypeRef
162165
end
163-
identify(::Type{LLVMType}, ::Val{API.LLVMVectorTypeKind}) = VectorType
166+
type_kinds[API.LLVMVectorTypeKind] = VectorType
164167

165168
function VectorType(eltyp::LLVMType, count)
166169
return VectorType(API.LLVMVectorType(eltyp, count))
@@ -176,7 +179,7 @@ export name, ispacked, isopaque, elements!
176179
@checked struct StructType <: SequentialType
177180
ref::API.LLVMTypeRef
178181
end
179-
identify(::Type{LLVMType}, ::Val{API.LLVMStructTypeKind}) = StructType
182+
type_kinds[API.LLVMStructTypeKind] = StructType
180183

181184
function StructType(name::String; ctx::Context)
182185
return StructType(API.LLVMStructCreateNamed(ctx, name))
@@ -237,28 +240,28 @@ end
237240
@checked struct VoidType <: LLVMType
238241
ref::API.LLVMTypeRef
239242
end
240-
identify(::Type{LLVMType}, ::Val{API.LLVMVoidTypeKind}) = VoidType
243+
type_kinds[API.LLVMVoidTypeKind] = VoidType
241244

242245
VoidType(ctx::Context) = VoidType(API.LLVMVoidTypeInContext(ctx))
243246

244247
@checked struct LabelType <: LLVMType
245248
ref::API.LLVMTypeRef
246249
end
247-
identify(::Type{LLVMType}, ::Val{API.LLVMLabelTypeKind}) = LabelType
250+
type_kinds[API.LLVMLabelTypeKind] = LabelType
248251

249252
LabelType(ctx::Context) = LabelType(API.LLVMLabelTypeInContext(ctx))
250253

251254
@checked struct MetadataType <: LLVMType
252255
ref::API.LLVMTypeRef
253256
end
254-
identify(::Type{LLVMType}, ::Val{API.LLVMMetadataTypeKind}) = MetadataType
257+
type_kinds[API.LLVMMetadataTypeKind] = MetadataType
255258

256259
MetadataType(ctx::Context) = MetadataType(API.LLVMMetadataTypeInContext(ctx))
257260

258261
@checked struct TokenType <: LLVMType
259262
ref::API.LLVMTypeRef
260263
end
261-
identify(::Type{LLVMType}, ::Val{API.LLVMTokenTypeKind}) = TokenType
264+
type_kinds[API.LLVMTokenTypeKind] = TokenType
262265

263266
TokenType(ctx::Context) = TokenType(API.LLVMTokenTypeInContext(ctx))
264267

src/core/value.jl

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,12 @@ abstract type Value end
88

99
Base.unsafe_convert(::Type{API.LLVMValueRef}, val::Value) = val.ref
1010

11-
identify(::Type{Value}, ref::API.LLVMValueRef) =
12-
identify(Value, Val{API.LLVMGetValueKind(ref)}())
13-
identify(::Type{Value}, ::Val{K}) where {K} = error("Unknown value kind $K")
11+
const value_kinds = Dict{API.LLVMValueKind, Type{<:Value}}()
12+
function identify(::Type{Value}, ref::API.LLVMValueRef)
13+
kind = API.LLVMGetValueKind(ref)
14+
haskey(value_kinds, kind) || error("Unknown value kind $kind")
15+
return value_kinds[kind]
16+
end
1417

1518
@inline function refcheck(::Type{T}, ref::API.LLVMValueRef) where T<:Value
1619
ref==C_NULL && throw(UndefRefError())

src/core/value/constant.jl

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,15 @@ abstract type Instruction <: User end
1919
@checked struct PointerNull <: Constant
2020
ref::API.LLVMValueRef
2121
end
22-
identify(::Type{Value}, ::Val{API.LLVMConstantPointerNullValueKind}) = PointerNull
22+
value_kinds[API.LLVMConstantPointerNullValueKind] = PointerNull
2323

2424
PointerNull(typ::PointerType) = PointerNull(API.LLVMConstPointerNull(typ))
2525

2626

2727
@checked struct UndefValue <: Constant
2828
ref::API.LLVMValueRef
2929
end
30-
identify(::Type{Value}, ::Val{API.LLVMUndefValueValueKind}) = UndefValue
30+
value_kinds[API.LLVMUndefValueValueKind] = UndefValue
3131

3232
UndefValue(typ::LLVMType) = UndefValue(API.LLVMGetUndef(typ))
3333

@@ -39,7 +39,7 @@ export ConstantInt, ConstantFP
3939
@checked struct ConstantInt <: Constant
4040
ref::API.LLVMValueRef
4141
end
42-
identify(::Type{Value}, ::Val{API.LLVMConstantIntValueKind}) = ConstantInt
42+
value_kinds[API.LLVMConstantIntValueKind] = ConstantInt
4343

4444
# NOTE: fixed set for dispatch, also because we can't rely on sizeof(T)==width(T)
4545
const WideInteger = Union{Int64, UInt64}
@@ -83,7 +83,7 @@ Base.convert(::Type{Core.Bool}, val::ConstantInt) = convert(Int, val) != 0
8383
@checked struct ConstantFP <: Constant
8484
ref::API.LLVMValueRef
8585
end
86-
identify(::Type{Value}, ::Val{API.LLVMConstantFPValueKind}) = ConstantFP
86+
value_kinds[API.LLVMConstantFPValueKind] = ConstantFP
8787

8888
ConstantFP(typ::FloatingPointType, val::Real) =
8989
ConstantFP(API.LLVMConstReal(typ, Cdouble(val)))
@@ -106,7 +106,7 @@ export ConstantAggregateZero
106106
@checked struct ConstantAggregateZero <: Constant
107107
ref::API.LLVMValueRef
108108
end
109-
identify(::Type{Value}, ::Val{API.LLVMConstantAggregateZeroValueKind}) = ConstantAggregateZero
109+
value_kinds[API.LLVMConstantAggregateZeroValueKind] = ConstantAggregateZero
110110

111111
# array interface
112112
# FIXME: can we reuse the ::ConstantArray functionality with ConstantAggregateZero values?
@@ -127,8 +127,8 @@ abstract type ConstantAggregate <: Constant end
127127
@checked struct ConstantArray <: ConstantAggregate
128128
ref::API.LLVMValueRef
129129
end
130-
identify(::Type{Value}, ::Val{API.LLVMConstantArrayValueKind}) = ConstantArray
131-
identify(::Type{Value}, ::Val{API.LLVMConstantDataArrayValueKind}) = ConstantArray
130+
value_kinds[API.LLVMConstantArrayValueKind] = ConstantArray
131+
value_kinds[API.LLVMConstantDataArrayValueKind] = ConstantArray
132132

133133
ConstantArrayOrAggregateZero(value) = Value(value)::Union{ConstantArray,ConstantAggregateZero}
134134

@@ -205,7 +205,7 @@ end
205205
@checked struct ConstantStruct <: ConstantAggregate
206206
ref::API.LLVMValueRef
207207
end
208-
identify(::Type{Value}, ::Val{API.LLVMConstantStructValueKind}) = ConstantStruct
208+
value_kinds[API.LLVMConstantStructValueKind] = ConstantStruct
209209

210210
ConstantStructOrAggregateZero(value) = Value(value)::Union{ConstantStruct,ConstantAggregateZero}
211211

@@ -256,7 +256,7 @@ end
256256
@checked struct ConstantVector <: ConstantAggregate
257257
ref::API.LLVMValueRef
258258
end
259-
identify(::Type{Value}, ::Val{API.LLVMConstantVectorValueKind}) = ConstantVector
259+
value_kinds[API.LLVMConstantVectorValueKind] = ConstantVector
260260

261261

262262
## constant expressions
@@ -266,15 +266,15 @@ export ConstantExpr, ConstantAggregate, ConstantArray, ConstantStruct, ConstantV
266266
@checked struct ConstantExpr <: Constant
267267
ref::API.LLVMValueRef
268268
end
269-
identify(::Type{Value}, ::Val{API.LLVMConstantExprValueKind}) = ConstantExpr
269+
value_kinds[API.LLVMConstantExprValueKind] = ConstantExpr
270270

271271

272272
## inline assembly
273273

274274
@checked struct InlineAsm <: Constant
275275
ref::API.LLVMValueRef
276276
end
277-
identify(::Type{Value}, ::Val{API.LLVMInlineAsmValueKind}) = InlineAsm
277+
value_kinds[API.LLVMInlineAsmValueKind] = InlineAsm
278278

279279
InlineAsm(typ::FunctionType, asm::String, constraints::String,
280280
side_effects::Core.Bool, align_stack::Core.Bool=false) =
@@ -352,7 +352,7 @@ export GlobalVariable, unsafe_delete!,
352352
@checked struct GlobalVariable <: GlobalObject
353353
ref::API.LLVMValueRef
354354
end
355-
identify(::Type{Value}, ::Val{API.LLVMGlobalVariableValueKind}) = GlobalVariable
355+
value_kinds[API.LLVMGlobalVariableValueKind] = GlobalVariable
356356

357357
GlobalVariable(mod::Module, typ::LLVMType, name::String) =
358358
GlobalVariable(API.LLVMAddGlobal(mod, typ, name))

src/debuginfo.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export DILocation
55
@checked struct DILocation <: MDNode
66
ref::API.LLVMMetadataRef
77
end
8-
identify(::Type{Metadata}, ::Val{API.LLVMDILocationMetadataKind}) = DILocation
8+
metadata_kinds[API.LLVMDILocationMetadataKind] = DILocation
99

1010
line(location::DILocation) = Int(API.LLVMDILocationGetLine(location))
1111
column(location::DILocation) = Int(API.LLVMDILocationGetColumn(location))
@@ -41,7 +41,7 @@ for var in (:Local, :Global)
4141
@checked struct $var_name <: DIVariable
4242
ref::API.LLVMMetadataRef
4343
end
44-
identify(::Type{Metadata}, ::Val{API.$var_kind}) = $var_name
44+
metadata_kinds[API.$var_kind] = $var_name
4545
end
4646
end
4747

@@ -77,7 +77,7 @@ export DIFile
7777
@checked struct DIFile <: DIScope
7878
ref::API.LLVMMetadataRef
7979
end
80-
identify(::Type{Metadata}, ::Val{API.LLVMDIFileMetadataKind}) = DIFile
80+
metadata_kinds[API.LLVMDIFileMetadataKind] = DIFile
8181

8282
function directory(file::DIFile)
8383
len = Ref{Cuint}()
@@ -111,7 +111,7 @@ for typ in (:Basic, :Derived, :Composite, :Subroutine)
111111
@checked struct $typ_name <: DIType
112112
ref::API.LLVMMetadataRef
113113
end
114-
identify(::Type{Metadata}, ::Val{API.$typ_kind}) = $typ_name
114+
metadata_kinds[API.$typ_kind] = $typ_name
115115
end
116116
end
117117

@@ -134,7 +134,7 @@ export DISubProgram
134134
@checked struct DISubProgram <: DIScope
135135
ref::API.LLVMMetadataRef
136136
end
137-
identify(::Type{Metadata}, ::Val{API.LLVMDISubprogramMetadataKind}) = DISubProgram
137+
metadata_kinds[API.LLVMDISubprogramMetadataKind] = DISubProgram
138138

139139
line(subprogram::DISubProgram) = Int(API.LLVMDISubprogramGetLine(subprogram))
140140

0 commit comments

Comments
 (0)