Skip to content

Commit 0200715

Browse files
committed
Make some iterators a subtype of AbstractVector.
Simplifies the implementation by reusing the AbstractArray implementation.
1 parent 8a3f215 commit 0200715

File tree

3 files changed

+26
-40
lines changed

3 files changed

+26
-40
lines changed

src/core/function.jl

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -83,15 +83,17 @@ export Argument, parameters
8383
end
8484
identify(::Type{Value}, ::Val{API.LLVMArgumentValueKind}) = Argument
8585

86-
struct FunctionParameterSet
86+
struct FunctionParameterSet <: AbstractVector{Argument}
8787
f::Function
8888
end
8989

9090
parameters(f::Function) = FunctionParameterSet(f)
9191

92-
Base.eltype(::FunctionParameterSet) = Argument
92+
Base.size(iter::FunctionParameterSet) = (API.LLVMCountParams(iter.f),)
9393

94-
function Base.getindex(iter::FunctionParameterSet, i)
94+
Base.IndexStyle(::FunctionParameterSet) = IndexLinear()
95+
96+
function Base.getindex(iter::FunctionParameterSet, i::Int)
9597
@boundscheck 1 <= i <= length(iter) || throw(BoundsError(iter, i))
9698
return Argument(API.LLVMGetParam(iter.f, i-1))
9799
end
@@ -100,13 +102,7 @@ function Base.iterate(iter::FunctionParameterSet, state=API.LLVMGetFirstParam(it
100102
state == C_NULL ? nothing : (Argument(state), API.LLVMGetNextParam(state))
101103
end
102104

103-
Base.last(iter::FunctionParameterSet) =
104-
Argument(API.LLVMGetLastParam(iter.f))
105-
106-
Base.isempty(iter::FunctionParameterSet) =
107-
API.LLVMGetLastParam(iter.f) == C_NULL
108-
109-
Base.length(iter::FunctionParameterSet) = API.LLVMCountParams(iter.f)
105+
Base.last(iter::FunctionParameterSet) = Argument(API.LLVMGetLastParam(iter.f))
110106

111107
# NOTE: optimized `collect`
112108
function Base.collect(iter::FunctionParameterSet)
@@ -131,11 +127,10 @@ function Base.iterate(iter::FunctionBlockSet, state=API.LLVMGetFirstBasicBlock(i
131127
state == C_NULL ? nothing : (BasicBlock(state), API.LLVMGetNextBasicBlock(state))
132128
end
133129

134-
Base.last(iter::FunctionBlockSet) =
135-
BasicBlock(API.LLVMGetLastBasicBlock(iter.f))
130+
Base.first(iter::FunctionBlockSet) = BasicBlock(API.LLVMGetFirstBasicBlock(iter.f))
131+
Base.last(iter::FunctionBlockSet) = BasicBlock(API.LLVMGetLastBasicBlock(iter.f))
136132

137-
Base.isempty(iter::FunctionBlockSet) =
138-
API.LLVMGetLastBasicBlock(iter.f) == C_NULL
133+
Base.isempty(iter::FunctionBlockSet) = length(iter) == 0
139134

140135
Base.length(iter::FunctionBlockSet) = API.LLVMCountBasicBlocks(iter.f)
141136

src/core/instructions.jl

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -156,57 +156,50 @@ default_dest(switch::Instruction) =
156156

157157
export successors
158158

159-
struct TerminatorSuccessorSet
159+
struct TerminatorSuccessorSet <: AbstractVector{BasicBlock}
160160
term::Instruction
161161
end
162162

163163
successors(term::Instruction) = TerminatorSuccessorSet(term)
164164

165-
Base.eltype(::TerminatorSuccessorSet) = BasicBlock
165+
Base.size(iter::TerminatorSuccessorSet) = (API.LLVMGetNumSuccessors(iter.term),)
166166

167-
function Base.getindex(iter::TerminatorSuccessorSet, i)
167+
Base.IndexStyle(::TerminatorSuccessorSet) = IndexLinear()
168+
169+
function Base.getindex(iter::TerminatorSuccessorSet, i::Int)
168170
@boundscheck 1 <= i <= length(iter) || throw(BoundsError(iter, i))
169171
return BasicBlock(API.LLVMGetSuccessor(iter.term, i-1))
170172
end
171173

172-
Base.setindex!(iter::TerminatorSuccessorSet, bb::BasicBlock, i) =
174+
Base.setindex!(iter::TerminatorSuccessorSet, bb::BasicBlock, i::Int) =
173175
API.LLVMSetSuccessor(iter.term, i-1, bb)
174176

175-
function Base.iterate(iter::TerminatorSuccessorSet, i=1)
176-
i >= length(iter) + 1 ? nothing : (iter[i], i+1)
177-
end
178-
179-
Base.length(iter::TerminatorSuccessorSet) = API.LLVMGetNumSuccessors(iter.term)
180-
181-
Base.lastindex(iter::TerminatorSuccessorSet) = length(iter)
182-
183177

184178
## phi nodes
185179

186180
# incoming iteration
187181

188182
export PhiIncomingSet
189183

190-
struct PhiIncomingSet
184+
struct PhiIncomingSet <: AbstractVector{Tuple{Value,BasicBlock}}
191185
phi::Instruction
192186
end
193187

194188
incoming(phi::Instruction) = PhiIncomingSet(phi)
195189

196-
Base.eltype(::PhiIncomingSet) = Tuple{Value,BasicBlock}
190+
Base.size(iter::PhiIncomingSet) = (API.LLVMCountIncoming(iter.phi),)
191+
192+
Base.IndexStyle(::PhiIncomingSet) = IndexLinear()
197193

198-
function Base.getindex(iter::PhiIncomingSet, i)
194+
function Base.getindex(iter::PhiIncomingSet, i::Int)
199195
@boundscheck 1 <= i <= length(iter) || throw(BoundsError(iter, i))
200196
return tuple(Value(API.LLVMGetIncomingValue(iter.phi, i-1)),
201197
BasicBlock(API.LLVMGetIncomingBlock(iter.phi, i-1)))
202198
end
203199

204200
function Base.append!(iter::PhiIncomingSet, args::Vector{Tuple{V, BasicBlock}} where V <: Value)
205201
vals, blocks = zip(args...)
206-
API.LLVMAddIncoming(iter.phi, collect(vals),
207-
collect(blocks), length(args))
202+
API.LLVMAddIncoming(iter.phi, collect(vals), collect(blocks), length(args))
208203
end
209204

210205
Base.push!(iter::PhiIncomingSet, args::Tuple{<:Value, BasicBlock}) = append!(iter, [args])
211-
212-
Base.length(iter::PhiIncomingSet) = API.LLVMCountIncoming(iter.phi)

src/core/value/user.jl

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,17 @@ abstract type User <: Value end
66

77
export operands
88

9-
struct UserOperandSet
9+
struct UserOperandSet <: AbstractVector{Value}
1010
user::User
1111
end
1212

1313
operands(user::User) = UserOperandSet(user)
1414

15-
Base.eltype(::UserOperandSet) = Value
15+
Base.size(iter::UserOperandSet) = (API.LLVMGetNumOperands(iter.user),)
1616

17-
function Base.getindex(iter::UserOperandSet, i::Integer) # TODO: otherwise unitrange indexing errors
17+
Base.IndexStyle(::UserOperandSet) = IndexLinear()
18+
19+
function Base.getindex(iter::UserOperandSet, i::Int)
1820
@boundscheck 1 <= i <= length(iter) || throw(BoundsError(iter, i))
1921
return Value(API.LLVMGetOperand(iter.user, i-1))
2022
end
@@ -25,7 +27,3 @@ Base.setindex!(iter::UserOperandSet, val::Value, i) =
2527
function Base.iterate(iter::UserOperandSet, i=1)
2628
i >= length(iter) + 1 ? nothing : (iter[i], i+1)
2729
end
28-
29-
Base.length(iter::UserOperandSet) = API.LLVMGetNumOperands(iter.user)
30-
31-
Base.lastindex(iter::UserOperandSet) = length(iter)

0 commit comments

Comments
 (0)