Skip to content

Commit 4af132e

Browse files
committed
Make the block iterator an AbstractVector too.
1 parent 17e8e1f commit 4af132e

File tree

1 file changed

+23
-8
lines changed

1 file changed

+23
-8
lines changed

src/core/function.jl

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -115,24 +115,39 @@ end
115115

116116
export blocks
117117

118-
struct FunctionBlockSet
118+
struct FunctionBlockSet <: AbstractVector{BasicBlock}
119119
f::Function
120+
cache::Vector{API.LLVMValueRef}
121+
122+
FunctionBlockSet(f::Function) = new(f, BasicBlock[])
120123
end
121124

122125
blocks(f::Function) = FunctionBlockSet(f)
123126

124-
Base.eltype(::FunctionBlockSet) = BasicBlock
125-
126-
function Base.iterate(iter::FunctionBlockSet, state=API.LLVMGetFirstBasicBlock(iter.f))
127-
state == C_NULL ? nothing : (BasicBlock(state), API.LLVMGetNextBasicBlock(state))
128-
end
127+
Base.size(iter::FunctionBlockSet) = (Int(API.LLVMCountBasicBlocks(iter.f)),)
129128

130129
Base.first(iter::FunctionBlockSet) = BasicBlock(API.LLVMGetFirstBasicBlock(iter.f))
131130
Base.last(iter::FunctionBlockSet) = BasicBlock(API.LLVMGetLastBasicBlock(iter.f))
132131

133-
Base.isempty(iter::FunctionBlockSet) = length(iter) == 0
132+
function Base.iterate(iter::FunctionBlockSet, state=API.LLVMGetFirstBasicBlock(iter.f))
133+
state == C_NULL ? nothing : (BasicBlock(state), API.LLVMGetNextBasicBlock(state))
134+
end
134135

135-
Base.length(iter::FunctionBlockSet) = API.LLVMCountBasicBlocks(iter.f)
136+
# provide a random access interface by maintaining a cache of blocks
137+
function Base.getindex(iter::FunctionBlockSet, i::Int)
138+
i <= 0 && throw(BoundsError(iter, i))
139+
i == 1 && return first(iter)
140+
while i > length(iter.cache)
141+
next = if isempty(iter.cache)
142+
iterate(iter)
143+
else
144+
iterate(iter, iter.cache[end])
145+
end
146+
next === nothing && throw(BoundsError(iter, i))
147+
push!(iter.cache, next[2])
148+
end
149+
return BasicBlock(iter.cache[i-1])
150+
end
136151

137152
# NOTE: optimized `collect`
138153
function Base.collect(iter::FunctionBlockSet)

0 commit comments

Comments
 (0)