Skip to content

Commit 9b84b1f

Browse files
committed
implement comprehensions as collect of a Generator
this removes `static_typeof` and `type_goto` fixes #7258
1 parent 9d2a40b commit 9b84b1f

14 files changed

+38
-289
lines changed

base/abstractarray.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -911,8 +911,8 @@ typed_hcat{T}(::Type{T}) = Array{T}(0)
911911
## cat: special cases
912912
vcat{T}(X::T...) = T[ X[i] for i=1:length(X) ]
913913
vcat{T<:Number}(X::T...) = T[ X[i] for i=1:length(X) ]
914-
hcat{T}(X::T...) = T[ X[j] for i=1, j=1:length(X) ]
915-
hcat{T<:Number}(X::T...) = T[ X[j] for i=1, j=1:length(X) ]
914+
hcat{T}(X::T...) = T[ X[j] for i=1:1, j=1:length(X) ]
915+
hcat{T<:Number}(X::T...) = T[ X[j] for i=1:1, j=1:length(X) ]
916916

917917
vcat(X::Number...) = hvcat_fill(Array{promote_typeof(X...)}(length(X)), X)
918918
hcat(X::Number...) = hvcat_fill(Array{promote_typeof(X...)}(1,length(X)), X)

base/arraymath.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -324,8 +324,8 @@ function ctranspose(A::AbstractMatrix)
324324
end
325325
ctranspose{T<:Real}(A::AbstractVecOrMat{T}) = transpose(A)
326326

327-
transpose(x::AbstractVector) = [ transpose(v) for i=1, v in x ]
328-
ctranspose{T}(x::AbstractVector{T}) = T[ ctranspose(v) for i=1, v in x ] #Fixme comprehension
327+
transpose(x::AbstractVector) = [ transpose(v) for i=1:1, v in x ]
328+
ctranspose{T}(x::AbstractVector{T}) = T[ ctranspose(v) for i=1:1, v in x ] #Fixme comprehension
329329

330330
_cumsum_type{T<:Number}(v::AbstractArray{T}) = typeof(+zero(T))
331331
_cumsum_type(v) = typeof(v[1]+v[1])

base/inference.jl

+5-106
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,8 @@ end
4040
type InferenceState
4141
sp::SimpleVector # static parameters
4242
label_counter::Int # index of the current highest label for this function
43-
fedbackvars::Dict{SSAValue, Bool}
4443
mod::Module
4544
currpc::LineNum
46-
static_typeof::Bool
4745

4846
# info on the state of inference and the linfo
4947
linfo::LambdaInfo
@@ -68,7 +66,6 @@ type InferenceState
6866
backedges::Vector{Tuple{InferenceState, Vector{LineNum}}}
6967
# iteration fixed-point detection
7068
fixedpoint::Bool
71-
typegotoredo::Bool
7269
inworkq::Bool
7370
optimize::Bool
7471
inferred::Bool
@@ -152,13 +149,13 @@ type InferenceState
152149

153150
inmodule = isdefined(linfo, :def) ? linfo.def.module : current_module() # toplevel thunks are inferred in the current module
154151
frame = new(
155-
sp, nl, Dict{SSAValue, Bool}(), inmodule, 0, false,
152+
sp, nl, inmodule, 0,
156153
linfo, la, s, Union{}, W, n,
157154
cur_hand, handler_at, n_handlers,
158155
ssavalue_uses, ssavalue_init,
159156
ObjectIdDict(), #Dict{InferenceState, Vector{LineNum}}(),
160157
Vector{Tuple{InferenceState, Vector{LineNum}}}(),
161-
false, false, false, optimize, false)
158+
false, false, optimize, false)
162159
push!(active, frame)
163160
nactive[] += 1
164161
return frame
@@ -1062,8 +1059,6 @@ function abstract_eval(e::ANY, vtypes::VarTable, sv::InferenceState)
10621059
return abstract_eval_constant(e)
10631060
end
10641061
e = e::Expr
1065-
# handle:
1066-
# call null new & static_typeof
10671062
if is(e.head,:call)
10681063
t = abstract_eval_call(e, vtypes, sv)
10691064
elseif is(e.head,:null)
@@ -1097,42 +1092,6 @@ function abstract_eval(e::ANY, vtypes::VarTable, sv::InferenceState)
10971092
t = abstract_eval_constant(val)
10981093
end
10991094
end
1100-
elseif is(e.head,:static_typeof)
1101-
var = e.args[1]
1102-
t = widenconst(abstract_eval(var, vtypes, sv))
1103-
if isa(t,DataType) && typeseq(t,t.name.primary)
1104-
# remove unnecessary typevars
1105-
t = t.name.primary
1106-
end
1107-
if is(t,Bottom)
1108-
# if we haven't gotten fed-back type info yet, return Bottom. otherwise
1109-
# Bottom is the actual type of the variable, so return Type{Bottom}.
1110-
if get!(sv.fedbackvars, var, false)
1111-
t = Type{Bottom}
1112-
else
1113-
sv.static_typeof = true
1114-
end
1115-
elseif isleaftype(t)
1116-
t = Type{t}
1117-
elseif isleaftype(sv.linfo.specTypes)
1118-
if isa(t,TypeVar)
1119-
t = Type{t.ub}
1120-
else
1121-
t = Type{t}
1122-
end
1123-
else
1124-
# if there is any type uncertainty in the arguments, we are
1125-
# effectively predicting what static_typeof will say when
1126-
# the function is compiled with actual arguments. in that case
1127-
# abstract types yield Type{<:T} instead of Type{T}.
1128-
# this doesn't really model the situation perfectly, but
1129-
# "isleaftype(inference_stack.types)" should be good enough.
1130-
if isa(t,TypeVar) || isvarargtype(t)
1131-
t = Type{t}
1132-
else
1133-
t = Type{TypeVar(:_,t)}
1134-
end
1135-
end
11361095
elseif is(e.head,:method)
11371096
t = (length(e.args) == 1) ? Any : Void
11381097
elseif is(e.head,:copyast)
@@ -1638,23 +1597,19 @@ function typeinf_frame(frame)
16381597
W = frame.ip
16391598
s = frame.stmt_types
16401599
n = frame.nstmts
1641-
@label restart_typeinf
16421600
while !isempty(W)
16431601
# make progress on the active ip set
16441602
local pc::Int = first(W), pc´::Int
16451603
while true # inner loop optimizes the common case where it can run straight from pc to pc + 1
16461604
#print(pc,": ",s[pc],"\n")
16471605
delete!(W, pc)
16481606
frame.currpc = pc
1649-
frame.static_typeof = false
16501607
frame.cur_hand = frame.handler_at[pc]
16511608
stmt = frame.linfo.code[pc]
16521609
changes = abstract_interpret(stmt, s[pc]::Array{Any,1}, frame)
16531610
if changes === ()
1654-
# if there was a Expr(:static_typeof) on this line,
1655-
# need to continue to the next pc even though the return type was Bottom
1656-
# otherwise, this line threw an error and there is no need to continue
1657-
frame.static_typeof || break
1611+
# this line threw an error and there is no need to continue
1612+
break
16581613
changes = s[pc]
16591614
end
16601615
if frame.cur_hand !== ()
@@ -1704,26 +1659,6 @@ function typeinf_frame(frame)
17041659
s[l] = newstate
17051660
end
17061661
end
1707-
elseif is(hd, :type_goto)
1708-
for i = 2:length(stmt.args)
1709-
var = stmt.args[i]::SSAValue
1710-
# Store types that need to be fed back via type_goto
1711-
# in ssavalue_init. After finishing inference, if any
1712-
# of these types changed, start over with the fed-back
1713-
# types known from the beginning.
1714-
# See issue #3821 (using !typeseq instead of !subtype),
1715-
# and issue #7810.
1716-
id = var.id+1
1717-
vt = frame.linfo.ssavaluetypes[id]
1718-
ot = frame.ssavalue_init[id]
1719-
if ot===NF || !(vtot && otvt)
1720-
frame.ssavalue_init[id] = vt
1721-
if get(frame.fedbackvars, var, false)
1722-
frame.typegotoredo = true
1723-
end
1724-
end
1725-
frame.fedbackvars[var] = true
1726-
end
17271662
elseif is(hd, :return)
17281663
pc´ = n + 1
17291664
rt = abstract_eval(stmt.args[1], s[pc], frame)
@@ -1793,39 +1728,6 @@ function typeinf_frame(frame)
17931728
end
17941729

17951730
if finished || frame.fixedpoint
1796-
if frame.typegotoredo
1797-
# if any type_gotos changed, clear state and restart.
1798-
frame.typegotoredo = false
1799-
for ll = 2:length(s)
1800-
s[ll] = ()
1801-
end
1802-
empty!(W)
1803-
push!(W, 1)
1804-
frame.cur_hand = ()
1805-
frame.handler_at = Any[ () for i=1:n ]
1806-
frame.n_handlers = 0
1807-
frame.linfo.ssavaluetypes[:] = frame.ssavalue_init
1808-
@goto restart_typeinf
1809-
else
1810-
# if a static_typeof was never reached,
1811-
# use Union{} as its real type and continue
1812-
# running type inference from its uses
1813-
# (one of which is the static_typeof)
1814-
# TODO: this restart should happen just before calling finish()
1815-
for (fbvar, seen) in frame.fedbackvars
1816-
if !seen
1817-
frame.fedbackvars[fbvar] = true
1818-
id = (fbvar::SSAValue).id + 1
1819-
for r in frame.ssavalue_uses[id]
1820-
if !is(s[r], ()) # s[r] === () => unreached statement
1821-
push!(W, r)
1822-
end
1823-
end
1824-
@goto restart_typeinf
1825-
end
1826-
end
1827-
end
1828-
18291731
if finished
18301732
finish(frame)
18311733
else # fixedpoint propagation
@@ -1991,7 +1893,7 @@ function eval_annotate(e::ANY, vtypes::ANY, sv::InferenceState, undefs, pass)
19911893

19921894
e = e::Expr
19931895
head = e.head
1994-
if is(head,:static_typeof) || is(head,:line) || is(head,:const)
1896+
if is(head,:line) || is(head,:const)
19951897
return e
19961898
elseif is(head,:(=))
19971899
e.args[2] = eval_annotate(e.args[2], vtypes, sv, undefs, pass)
@@ -2213,9 +2115,6 @@ function effect_free(e::ANY, sv, allow_volatile::Bool)
22132115
end
22142116
if isa(e,Expr)
22152117
e = e::Expr
2216-
if e.head === :static_typeof
2217-
return true
2218-
end
22192118
if e.head === :static_parameter
22202119
return true
22212120
end

base/range.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ maximum(r::UnitRange) = isempty(r) ? throw(ArgumentError("range must be non-empt
384384
minimum(r::Range) = isempty(r) ? throw(ArgumentError("range must be non-empty")) : min(first(r), last(r))
385385
maximum(r::Range) = isempty(r) ? throw(ArgumentError("range must be non-empty")) : max(first(r), last(r))
386386

387-
ctranspose(r::Range) = [x for _=1, x=r]
387+
ctranspose(r::Range) = [x for _=1:1, x=r]
388388
transpose(r::Range) = r'
389389

390390
# Ranges are immutable

base/sparse/sparsematrix.jl

+10-10
Original file line numberDiff line numberDiff line change
@@ -2819,8 +2819,8 @@ end
28192819

28202820
function vcat(X::SparseMatrixCSC...)
28212821
num = length(X)
2822-
mX = [ size(x, 1) for x in X ]
2823-
nX = [ size(x, 2) for x in X ]
2822+
mX = Int[ size(x, 1) for x in X ]
2823+
nX = Int[ size(x, 2) for x in X ]
28242824
m = sum(mX)
28252825
n = nX[1]
28262826

@@ -2837,7 +2837,7 @@ function vcat(X::SparseMatrixCSC...)
28372837
Ti = promote_type(Ti, eltype(X[i].rowval))
28382838
end
28392839

2840-
nnzX = [ nnz(x) for x in X ]
2840+
nnzX = Int[ nnz(x) for x in X ]
28412841
nnz_res = sum(nnzX)
28422842
colptr = Array{Ti}(n + 1)
28432843
rowval = Array{Ti}(nnz_res)
@@ -2879,8 +2879,8 @@ end
28792879

28802880
function hcat(X::SparseMatrixCSC...)
28812881
num = length(X)
2882-
mX = [ size(x, 1) for x in X ]
2883-
nX = [ size(x, 2) for x in X ]
2882+
mX = Int[ size(x, 1) for x in X ]
2883+
nX = Int[ size(x, 2) for x in X ]
28842884
m = mX[1]
28852885
for i = 2 : num
28862886
if mX[i] != m; throw(DimensionMismatch("")); end
@@ -2891,7 +2891,7 @@ function hcat(X::SparseMatrixCSC...)
28912891
Ti = promote_type(map(x->eltype(x.rowval), X)...)
28922892

28932893
colptr = Array{Ti}(n + 1)
2894-
nnzX = [ nnz(x) for x in X ]
2894+
nnzX = Int[ nnz(x) for x in X ]
28952895
nnz_res = sum(nnzX)
28962896
rowval = Array{Ti}(nnz_res)
28972897
nzval = Array{Tv}(nnz_res)
@@ -2947,16 +2947,16 @@ Concatenate matrices block-diagonally. Currently only implemented for sparse mat
29472947
"""
29482948
function blkdiag(X::SparseMatrixCSC...)
29492949
num = length(X)
2950-
mX = [ size(x, 1) for x in X ]
2951-
nX = [ size(x, 2) for x in X ]
2950+
mX = Int[ size(x, 1) for x in X ]
2951+
nX = Int[ size(x, 2) for x in X ]
29522952
m = sum(mX)
29532953
n = sum(nX)
29542954

29552955
Tv = promote_type(map(x->eltype(x.nzval), X)...)
29562956
Ti = promote_type(map(x->eltype(x.rowval), X)...)
29572957

29582958
colptr = Array{Ti}(n + 1)
2959-
nnzX = [ nnz(x) for x in X ]
2959+
nnzX = Int[ nnz(x) for x in X ]
29602960
nnz_res = sum(nnzX)
29612961
rowval = Array{Ti}(nnz_res)
29622962
nzval = Array{Tv}(nnz_res)
@@ -3197,7 +3197,7 @@ function trace{Tv}(A::SparseMatrixCSC{Tv})
31973197
s
31983198
end
31993199

3200-
diag(A::SparseMatrixCSC) = [d for d in SpDiagIterator(A)]
3200+
diag{Tv}(A::SparseMatrixCSC{Tv}) = Tv[d for d in SpDiagIterator(A)]
32013201

32023202
function diagm{Tv,Ti}(v::SparseMatrixCSC{Tv,Ti})
32033203
if (size(v,1) != 1 && size(v,2) != 1)

src/alloc.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -88,13 +88,12 @@ jl_sym_t *null_sym; jl_sym_t *body_sym;
8888
jl_sym_t *method_sym; jl_sym_t *core_sym;
8989
jl_sym_t *enter_sym; jl_sym_t *leave_sym;
9090
jl_sym_t *exc_sym; jl_sym_t *error_sym;
91-
jl_sym_t *static_typeof_sym;
9291
jl_sym_t *globalref_sym;
9392
jl_sym_t *new_sym; jl_sym_t *using_sym;
9493
jl_sym_t *const_sym; jl_sym_t *thunk_sym;
9594
jl_sym_t *anonymous_sym; jl_sym_t *underscore_sym;
9695
jl_sym_t *abstracttype_sym; jl_sym_t *bitstype_sym;
97-
jl_sym_t *compositetype_sym; jl_sym_t *type_goto_sym;
96+
jl_sym_t *compositetype_sym;
9897
jl_sym_t *global_sym; jl_sym_t *list_sym;
9998
jl_sym_t *dot_sym; jl_sym_t *newvar_sym;
10099
jl_sym_t *boundscheck_sym; jl_sym_t *inbounds_sym;

src/codegen.cpp

+1-13
Original file line numberDiff line numberDiff line change
@@ -3076,7 +3076,7 @@ static void emit_stmtpos(jl_value_t *expr, jl_codectx_t *ctx)
30763076
if (jl_is_expr(expr)) {
30773077
jl_sym_t *head = ((jl_expr_t*)expr)->head;
30783078
// some expression types are metadata and can be ignored in statement position
3079-
if (head == line_sym || head == type_goto_sym || head == meta_sym)
3079+
if (head == line_sym || head == meta_sym)
30803080
return;
30813081
// fall-through
30823082
}
@@ -3253,18 +3253,6 @@ static jl_cgval_t emit_expr(jl_value_t *expr, jl_codectx_t *ctx)
32533253
else if (head == null_sym) {
32543254
return ghostValue(jl_void_type);
32553255
}
3256-
else if (head == static_typeof_sym) {
3257-
jl_value_t *extype = expr_type((jl_value_t*)ex, ctx);
3258-
if (jl_is_type_type(extype)) {
3259-
extype = jl_tparam0(extype);
3260-
if (jl_is_typevar(extype))
3261-
extype = ((jl_tvar_t*)extype)->ub;
3262-
}
3263-
else {
3264-
extype = (jl_value_t*)jl_any_type;
3265-
}
3266-
return mark_julia_const(extype);
3267-
}
32683256
else if (head == new_sym) {
32693257
jl_value_t *ty = expr_type(args[0], ctx);
32703258
size_t nargs = jl_array_len(ex->args);

src/interpreter.c

+1-4
Original file line numberDiff line numberDiff line change
@@ -224,9 +224,6 @@ static jl_value_t *eval(jl_value_t *e, interpreter_state *s)
224224
else if (ex->head == copyast_sym) {
225225
return jl_copy_ast(eval(args[0], s));
226226
}
227-
else if (ex->head == static_typeof_sym) {
228-
return (jl_value_t*)jl_any_type;
229-
}
230227
else if (ex->head == exc_sym) {
231228
return jl_exception_in_transit;
232229
}
@@ -430,7 +427,7 @@ static jl_value_t *eval(jl_value_t *e, interpreter_state *s)
430427
jl_throw(args[0]);
431428
}
432429
else if (ex->head == boundscheck_sym || ex->head == inbounds_sym || ex->head == fastmath_sym ||
433-
ex->head == simdloop_sym || ex->head == meta_sym || ex->head == type_goto_sym) {
430+
ex->head == simdloop_sym || ex->head == meta_sym) {
434431
return jl_nothing;
435432
}
436433
jl_errorf("unsupported or misplaced expression %s", jl_symbol_name(ex->head));

src/jltypes.c

-2
Original file line numberDiff line numberDiff line change
@@ -3836,7 +3836,6 @@ void jl_init_types(void)
38363836
exc_sym = jl_symbol("the_exception");
38373837
enter_sym = jl_symbol("enter");
38383838
leave_sym = jl_symbol("leave");
3839-
static_typeof_sym = jl_symbol("static_typeof");
38403839
new_sym = jl_symbol("new");
38413840
const_sym = jl_symbol("const");
38423841
global_sym = jl_symbol("global");
@@ -3847,7 +3846,6 @@ void jl_init_types(void)
38473846
abstracttype_sym = jl_symbol("abstract_type");
38483847
bitstype_sym = jl_symbol("bits_type");
38493848
compositetype_sym = jl_symbol("composite_type");
3850-
type_goto_sym = jl_symbol("type_goto");
38513849
toplevel_sym = jl_symbol("toplevel");
38523850
dot_sym = jl_symbol(".");
38533851
boundscheck_sym = jl_symbol("boundscheck");

0 commit comments

Comments
 (0)