Skip to content

Commit 3870fdf

Browse files
committed
Merge remote-tracking branch 'origin/master' into teh-jn/lazydotfuse
* origin/master: (22 commits) separate `isbitstype(::Type)` from `isbits` (#26850) bugfix for regex matches ending with non-ASCII (#26831) [NewOptimizer] track inbounds state as a per-statement flag change default LOAD_PATH and DEPOT_PATH (#26804, fix #25709) Change url scheme to https (#26835) [NewOptimizer] inlining: Refactor todo object inference: enable CodeInfo method_for_inference_limit_heuristics support (#26822) [NewOptimizer] Fix _apply elision (#26821) add test case from issue #26607, cfunction with no args (#26838) add `do` in front-end deparser. fixes #17781 (#26840) Preserve CallInst metadata in LateLowerGCFrame pass. Improve differences from R documentation (#26810) reserve syntax that could be used for computed field types (#18466) (#26816) Add support for Atomic{Bool} (Fix #26542). (#26597) Remove argument restriction on dims2string and inds2string (#26799) (#26817) remove some unnecessary `eltype` methods (#26791) optimize: ensure merge_value_ssa doesn't drop PiNodes inference: improve tmerge for Conditional and Const ensure more iterators stay type-stable code loading docs (#26787) ...
2 parents 2e9c0f2 + 5179455 commit 3870fdf

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

81 files changed

+967
-328
lines changed

Makefile

+4-11
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,13 @@
11
JULIAHOME := $(abspath $(dir $(lastword $(MAKEFILE_LIST))))
22
include $(JULIAHOME)/Make.inc
33

4-
# TODO: Code bundled with Julia should be installed into a versioned directory,
5-
# prefix/share/julia/VERSDIR, so that in the future one can have multiple
6-
# major versions of Julia installed concurrently. Third-party code that
7-
# is not controlled by Pkg should be installed into
8-
# prefix/share/julia/site/VERSDIR (not prefix/share/julia/VERSDIR/site ...
9-
# so that prefix/share/julia/VERSDIR can be overwritten without touching
10-
# third-party code).
114
VERSDIR := v`cut -d. -f1-2 < $(JULIAHOME)/VERSION`
125

136
default: $(JULIA_BUILD_MODE) # contains either "debug" or "release"
147
all: debug release
158

169
# sort is used to remove potential duplicates
17-
DIRS := $(sort $(build_bindir) $(build_depsbindir) $(build_libdir) $(build_private_libdir) $(build_libexecdir) $(build_includedir) $(build_includedir)/julia $(build_sysconfdir)/julia $(build_datarootdir)/julia $(build_datarootdir)/julia/site $(build_man1dir))
10+
DIRS := $(sort $(build_bindir) $(build_depsbindir) $(build_libdir) $(build_private_libdir) $(build_libexecdir) $(build_includedir) $(build_includedir)/julia $(build_sysconfdir)/julia $(build_datarootdir)/julia $(build_datarootdir)/julia/stdlib $(build_man1dir))
1811
ifneq ($(BUILDROOT),$(JULIAHOME))
1912
BUILDDIRS := $(BUILDROOT) $(addprefix $(BUILDROOT)/,base src ui doc deps test test/embedding)
2013
BUILDDIRMAKE := $(addsuffix /Makefile,$(BUILDDIRS))
@@ -46,8 +39,8 @@ endif
4639
$(foreach dir,$(DIRS),$(eval $(call dir_target,$(dir))))
4740
$(foreach link,base $(JULIAHOME)/test,$(eval $(call symlink_target,$(link),$(build_datarootdir)/julia,$(notdir $(link)))))
4841

49-
build_defaultpkgdir = $(build_datarootdir)/julia/site/$(shell echo $(VERSDIR))
50-
$(eval $(call symlink_target,$(JULIAHOME)/stdlib,$(build_datarootdir)/julia/site,$(shell echo $(VERSDIR))))
42+
build_defaultpkgdir = $(build_datarootdir)/julia/stdlib/$(shell echo $(VERSDIR))
43+
$(eval $(call symlink_target,$(JULIAHOME)/stdlib,$(build_datarootdir)/julia/stdlib,$(shell echo $(VERSDIR))))
5144

5245
julia_flisp.boot.inc.phony: julia-deps
5346
@$(MAKE) $(QUIET_MAKE) -C $(BUILDROOT)/src julia_flisp.boot.inc.phony
@@ -284,7 +277,7 @@ endef
284277

285278
install: $(build_depsbindir)/stringreplace $(BUILDROOT)/doc/_build/html/en/index.html
286279
@$(MAKE) $(QUIET_MAKE) all
287-
@for subdir in $(bindir) $(datarootdir)/julia/site/$(VERSDIR) $(docdir) $(man1dir) $(includedir)/julia $(libdir) $(private_libdir) $(sysconfdir); do \
280+
@for subdir in $(bindir) $(datarootdir)/julia/stdlib/$(VERSDIR) $(docdir) $(man1dir) $(includedir)/julia $(libdir) $(private_libdir) $(sysconfdir); do \
288281
mkdir -p $(DESTDIR)$$subdir; \
289282
done
290283

base/Enums.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ macro enum(T, syms...)
7575
if isa(T, Expr) && T.head == :(::) && length(T.args) == 2 && isa(T.args[1], Symbol)
7676
typename = T.args[1]
7777
basetype = eval(__module__, T.args[2])
78-
if !isa(basetype, DataType) || !(basetype <: Integer) || !isbits(basetype)
78+
if !isa(basetype, DataType) || !(basetype <: Integer) || !isbitstype(basetype)
7979
throw(ArgumentError("invalid base type for Enum $typename, $T=::$basetype; base type must be an integer primitive type"))
8080
end
8181
elseif !isa(T, Symbol)

base/abstractdict.jl

+5-5
Original file line numberDiff line numberDiff line change
@@ -672,11 +672,11 @@ _oidd_nextind(a, i) = reinterpret(Int, ccall(:jl_eqtable_nextind, Csize_t, (Any,
672672

673673
start(d::IdDict) = _oidd_nextind(d.ht, 0)
674674
done(d::IdDict, i) = (i == -1)
675-
next(d::IdDict{K,V}, i) where {K, V} = (Pair{K,V}(d.ht[i+1], d.ht[i+2]), _oidd_nextind(d.ht, i+2))
675+
next(d::IdDict{K, V}, i) where {K, V} = (Pair{K, V}(d.ht[i + 1]::K, d.ht[i + 2]::V), _oidd_nextind(d.ht, i + 2))
676676

677677
length(d::IdDict) = d.count
678678

679-
copy(d::IdDict) = IdDict(d)
679+
copy(d::IdDict) = typeof(d)(d)
680680

681681
get!(d::IdDict{K,V}, @nospecialize(key), @nospecialize(default)) where {K, V} = (d[key] = get(d, key, default))::V
682682

@@ -689,14 +689,14 @@ mutable struct IdSet{T} <: AbstractSet{T}
689689
dict::IdDict{T,Nothing}
690690

691691
IdSet{T}() where {T} = new(IdDict{T,Nothing}())
692-
IdSet{T}(s::IdSet{T}) where {T} = new(IdDict{T,Nothing}(s.dict))
692+
IdSet{T}(s::IdSet{T}) where {T} = new(copy(s.dict))
693693
end
694694

695695
IdSet{T}(itr) where {T} = union!(IdSet{T}(), itr)
696696
IdSet() = IdSet{Any}()
697697

698-
copy(s::IdSet{T}) where {T} = IdSet{T}(s)
699-
copymutable(s::IdSet{T}) where {T} = IdSet{T}(s)
698+
copymutable(s::IdSet) = typeof(s)(s)
699+
copy(s::IdSet) = typeof(s)(s)
700700

701701
isempty(s::IdSet) = isempty(s.dict)
702702
length(s::IdSet) = length(s.dict)

base/array.jl

+6-7
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ UInt8
8585
```
8686
"""
8787
eltype(::Type) = Any
88-
eltype(::Type{Any}) = Any
8988
eltype(::Type{Bottom}) = throw(ArgumentError("Union{} does not have elements"))
9089
eltype(x) = eltype(typeof(x))
9190

@@ -117,15 +116,15 @@ asize_from(a::Array, n) = n > ndims(a) ? () : (arraysize(a,n), asize_from(a, n+1
117116
"""
118117
Base.isbitsunion(::Type{T})
119118
120-
Return whether a type is an "is-bits" Union type, meaning each type included in a Union is `isbits`.
119+
Return whether a type is an "is-bits" Union type, meaning each type included in a Union is `isbitstype`.
121120
"""
122121
isbitsunion(u::Union) = ccall(:jl_array_store_unboxed, Cint, (Any,), u) == Cint(1)
123122
isbitsunion(x) = false
124123

125124
"""
126125
Base.bitsunionsize(U::Union)
127126
128-
For a Union of `isbits` types, return the size of the largest type; assumes `Base.isbitsunion(U) == true`
127+
For a Union of `isbitstype` types, return the size of the largest type; assumes `Base.isbitsunion(U) == true`
129128
"""
130129
function bitsunionsize(u::Union)
131130
sz = Ref{Csize_t}(0)
@@ -135,7 +134,7 @@ function bitsunionsize(u::Union)
135134
end
136135

137136
length(a::Array) = arraylen(a)
138-
elsize(::Type{<:Array{T}}) where {T} = isbits(T) ? sizeof(T) : (isbitsunion(T) ? bitsunionsize(T) : sizeof(Ptr))
137+
elsize(::Type{<:Array{T}}) where {T} = isbitstype(T) ? sizeof(T) : (isbitsunion(T) ? bitsunionsize(T) : sizeof(Ptr))
139138
sizeof(a::Array) = Core.sizeof(a)
140139

141140
function isassigned(a::Array, i::Int...)
@@ -178,7 +177,7 @@ the same manner as C.
178177
function unsafe_copyto!(dest::Array{T}, doffs, src::Array{T}, soffs, n) where T
179178
t1 = @_gc_preserve_begin dest
180179
t2 = @_gc_preserve_begin src
181-
if isbits(T)
180+
if isbitstype(T)
182181
unsafe_copyto!(pointer(dest, doffs), pointer(src, soffs), n)
183182
elseif isbitsunion(T)
184183
ccall(:memmove, Ptr{Cvoid}, (Ptr{Cvoid}, Ptr{Cvoid}, UInt),
@@ -1478,7 +1477,7 @@ function vcat(arrays::Vector{T}...) where T
14781477
end
14791478
arr = Vector{T}(undef, n)
14801479
ptr = pointer(arr)
1481-
if isbits(T)
1480+
if isbitstype(T)
14821481
elsz = Core.sizeof(T)
14831482
elseif isbitsunion(T)
14841483
elsz = bitsunionsize(T)
@@ -1490,7 +1489,7 @@ function vcat(arrays::Vector{T}...) where T
14901489
for a in arrays
14911490
na = length(a)
14921491
nba = na * elsz
1493-
if isbits(T)
1492+
if isbitstype(T)
14941493
ccall(:memcpy, Ptr{Cvoid}, (Ptr{Cvoid}, Ptr{Cvoid}, UInt),
14951494
ptr, a, nba)
14961495
elseif isbitsunion(T)

base/arraymath.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ function reverse(A::Array{T}; dims::Integer) where T
9494
end
9595
end
9696
else
97-
if isbits(T) && M>200
97+
if isbitstype(T) && M>200
9898
for i = 1:sd
9999
ri = sd+1-i
100100
for j=0:stride:(N-stride)

base/atomics.jl

+16-10
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,12 @@ else
2626
UInt8, UInt16, UInt32, UInt64, UInt128)
2727
end
2828
const floattypes = (Float16, Float32, Float64)
29-
# TODO: Support Bool, Ptr
30-
const atomictypes = (inttypes..., floattypes...)
29+
const arithmetictypes = (inttypes..., floattypes...)
30+
# TODO: Support Ptr
31+
const atomictypes = (arithmetictypes..., Bool)
3132
const IntTypes = Union{inttypes...}
3233
const FloatTypes = Union{floattypes...}
34+
const ArithmeticTypes = Union{arithmetictypes...}
3335
const AtomicTypes = Union{atomictypes...}
3436

3537
"""
@@ -39,8 +41,8 @@ Holds a reference to an object of type `T`, ensuring that it is only
3941
accessed atomically, i.e. in a thread-safe manner.
4042
4143
Only certain "simple" types can be used atomically, namely the
42-
primitive integer and float-point types. These are `Int8`...`Int128`,
43-
`UInt8`...`UInt128`, and `Float16`...`Float64`.
44+
primitive boolean, integer, and float-point types. These are `Bool`,
45+
`Int8`...`Int128`, `UInt8`...`UInt128`, and `Float16`...`Float64`.
4446
4547
New atomic objects can be created from a non-atomic values; if none is
4648
specified, the atomic object is initialized with zero.
@@ -130,11 +132,12 @@ julia> x[]
130132
function atomic_xchg! end
131133

132134
"""
133-
Threads.atomic_add!(x::Atomic{T}, val::T) where T
135+
Threads.atomic_add!(x::Atomic{T}, val::T) where T <: ArithmeticTypes
134136
135137
Atomically add `val` to `x`
136138
137-
Performs `x[] += val` atomically. Returns the **old** value.
139+
Performs `x[] += val` atomically. Returns the **old** value. Not defined for
140+
`Atomic{Bool}`.
138141
139142
For further details, see LLVM's `atomicrmw add` instruction.
140143
@@ -153,11 +156,12 @@ julia> x[]
153156
function atomic_add! end
154157

155158
"""
156-
Threads.atomic_sub!(x::Atomic{T}, val::T) where T
159+
Threads.atomic_sub!(x::Atomic{T}, val::T) where T <: ArithmeticTypes
157160
158161
Atomically subtract `val` from `x`
159162
160-
Performs `x[] -= val` atomically. Returns the **old** value.
163+
Performs `x[] -= val` atomically. Returns the **old** value. Not defined for
164+
`Atomic{Bool}`.
161165
162166
For further details, see LLVM's `atomicrmw sub` instruction.
163167
@@ -317,7 +321,7 @@ unsafe_convert(::Type{Ptr{T}}, x::Atomic{T}) where {T} = convert(Ptr{T}, pointer
317321
setindex!(x::Atomic{T}, v) where {T} = setindex!(x, convert(T, v))
318322

319323
const llvmtypes = IdDict{Any,String}(
320-
Bool => "i1",
324+
Bool => "i8", # julia represents bools with 8-bits for now. # TODO: is this okay?
321325
Int8 => "i8", UInt8 => "i8",
322326
Int16 => "i16", UInt16 => "i16",
323327
Int32 => "i32", UInt32 => "i32",
@@ -380,13 +384,15 @@ for typ in atomictypes
380384
unsafe_convert(Ptr{$typ}, x), cmp, new)
381385
end
382386

383-
for rmwop in [:xchg, :add, :sub, :and, :nand, :or, :xor, :max, :min]
387+
arithmetic_ops = [:add, :sub]
388+
for rmwop in [arithmetic_ops..., :xchg, :and, :nand, :or, :xor, :max, :min]
384389
rmw = string(rmwop)
385390
fn = Symbol("atomic_", rmw, "!")
386391
if (rmw == "max" || rmw == "min") && typ <: Unsigned
387392
# LLVM distinguishes signedness in the operation, not the integer type.
388393
rmw = "u" * rmw
389394
end
395+
if rmwop in arithmetic_ops && !(typ <: ArithmeticTypes) continue end
390396
if typ <: Integer
391397
@eval $fn(x::Atomic{$typ}, v::$typ) =
392398
llvmcall($"""

base/compiler/abstractinterpretation.jl

+4-1
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ function abstract_call_method(method::Method, @nospecialize(sig), sparams::Simpl
187187
cyclei = 0
188188
infstate = sv
189189
edgecycle = false
190+
method2 = method_for_inference_heuristics(method, sig, sparams, sv.params.world) # Union{Method, Nothing}
190191
while !(infstate === nothing)
191192
infstate = infstate::InferenceState
192193
if method === infstate.linfo.def
@@ -197,7 +198,9 @@ function abstract_call_method(method::Method, @nospecialize(sig), sparams::Simpl
197198
edgecycle = true
198199
break
199200
end
200-
if topmost === nothing
201+
inf_method2 = infstate.src.method_for_inference_limit_heuristics # limit only if user token match
202+
inf_method2 isa Method || (inf_method2 = nothing) # Union{Method, Nothing}
203+
if topmost === nothing && method2 === inf_method2
201204
# inspect the parent of this edge,
202205
# to see if they are the same Method as sv
203206
# in which case we'll need to ensure it is convergent

base/compiler/compiler.jl

+6
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,12 @@ using .Sort
103103

104104
inlining_enabled() = (JLOptions().can_inline == 1)
105105
coverage_enabled() = (JLOptions().code_coverage != 0)
106+
function inbounds_option()
107+
opt_check_bounds = JLOptions().check_bounds
108+
opt_check_bounds == 0 && return :default
109+
opt_check_bounds == 1 && return :on
110+
return :off
111+
end
106112

107113
include("compiler/utilities.jl")
108114
include("compiler/validation.jl")

base/compiler/optimize.jl

+26-6
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,9 @@ const SLOT_USEDUNDEF = 32 # slot has uses that might raise UndefVarError
218218

219219
# const SLOT_CALLED = 64
220220

221+
const IR_FLAG_INBOUNDS = 0x01
222+
223+
221224
# known affect-free calls (also effect-free)
222225
const _PURE_BUILTINS = Any[tuple, svec, fieldtype, apply_type, ===, isa, typeof, UnionAll, nfields]
223226

@@ -263,7 +266,7 @@ function isinlineable(m::Method, src::CodeInfo, mod::Module, params::Params, bon
263266
return inlineable
264267
end
265268

266-
const enable_new_optimizer = RefValue(true)
269+
const enable_new_optimizer = RefValue(false)
267270

268271
# converge the optimization work
269272
function optimize(me::InferenceState)
@@ -396,7 +399,7 @@ function optimize(me::InferenceState)
396399
me.src.inlineable = false
397400
elseif !me.src.inlineable && isa(def, Method)
398401
bonus = 0
399-
if me.bestguess Tuple && !isbits(widenconst(me.bestguess))
402+
if me.bestguess Tuple && !isbitstype(widenconst(me.bestguess))
400403
bonus = me.params.inline_tupleret_bonus
401404
end
402405
me.src.inlineable = isinlineable(def, me.src, me.mod, me.params, bonus)
@@ -706,7 +709,7 @@ end
706709
# since codegen optimizations of functions like `is` will depend on knowing it
707710
function widen_slot_type(@nospecialize(ty), untypedload::Bool)
708711
if isa(ty, DataType)
709-
if untypedload || isbits(ty) || isdefined(ty, :instance)
712+
if untypedload || isbitstype(ty) || isdefined(ty, :instance)
710713
return ty
711714
end
712715
elseif isa(ty, Union)
@@ -1154,6 +1157,7 @@ function inlineable(@nospecialize(f), @nospecialize(ft), e::Expr, atypes::Vector
11541157
f === Core.sizeof || f === isdefined ||
11551158
istopfunction(topmod, f, :typejoin) ||
11561159
istopfunction(topmod, f, :isbits) ||
1160+
istopfunction(topmod, f, :isbitstype) ||
11571161
istopfunction(topmod, f, :promote_type) ||
11581162
(f === Core.kwfunc && length(argexprs) == 2) ||
11591163
(is_inlineable_constant(val) &&
@@ -2712,7 +2716,7 @@ function merge_value_ssa!(ctx::AllocOptContext, info, key)
27122716
# There are other cases that we can merge
27132717
# but those require control flow analysis.
27142718
var_has_static_undef(ctx.sv.src, key.first, key.second) && return false
2715-
local defkey
2719+
local defkey, deftyp
27162720
for def in info.defs
27172721
# No NewvarNode def for variables that aren't used undefined
27182722
defex = (def.assign::Expr).args[2]
@@ -2735,6 +2739,12 @@ function merge_value_ssa!(ctx::AllocOptContext, info, key)
27352739
else
27362740
return @isdefined(defkey)
27372741
end
2742+
new_deftyp = exprtype(defex, ctx.sv.src, ctx.sv.mod)
2743+
if @isdefined(deftyp) && deftyp != new_deftyp
2744+
return true
2745+
else
2746+
deftyp = new_deftyp
2747+
end
27382748
end
27392749

27402750
if defkey.second || defkey.first > ctx.sv.nargs
@@ -2759,8 +2769,18 @@ function merge_value_ssa!(ctx::AllocOptContext, info, key)
27592769
if defkey.second
27602770
# SSAValue def
27612771
replace_v = SSAValue(defkey.first - 1)
2772+
# don't replace TypedSlots with SSAValues
2773+
replace_typ = exprtype(replace_v, ctx.sv.src, ctx.sv.mod)
2774+
if !(replace_typ deftyp)
2775+
return false
2776+
end
27622777
else
27632778
replace_v = SlotNumber(defkey.first)
2779+
# don't lose type information from TypedSlots
2780+
replace_typ = exprtype(replace_v, ctx.sv.src, ctx.sv.mod)
2781+
if !(replace_typ deftyp)
2782+
replace_v = TypedSlot(defkey.first, deftyp)
2783+
end
27642784
end
27652785
for use in info.uses
27662786
if isdefined(use, :expr)
@@ -3077,7 +3097,7 @@ function structinfo_new(ctx::AllocOptContext, ex::Expr, vt::DataType)
30773097
si.defs[i] = ex.args[i + 1]
30783098
else
30793099
ft = fieldtype(vt, i)
3080-
if isbits(ft)
3100+
if isbitstype(ft)
30813101
ex = Expr(:new, ft)
30823102
ex.typ = ft
30833103
si.defs[i] = ex
@@ -3614,7 +3634,7 @@ function split_struct_alloc_single!(ctx::AllocOptContext, info, key, nf, has_pre
36143634
if !@isdefined(fld_name)
36153635
fld_name = :struct_field
36163636
end
3617-
need_preserved_root = has_preserve && !isbits(field_typ)
3637+
need_preserved_root = has_preserve && !isbitstype(field_typ)
36183638
local var_slot
36193639
if !has_def
36203640
# If there's no direct use of the field

0 commit comments

Comments
 (0)