@@ -480,6 +480,37 @@ function arraysize_nothrow(argtypes::Vector{Any})
480
480
return false
481
481
end
482
482
483
+ struct MemoryOrder x:: Cint end
484
+ const MEMORY_ORDER_UNSPECIFIED = MemoryOrder (- 2 )
485
+ const MEMORY_ORDER_INVALID = MemoryOrder (- 1 )
486
+ const MEMORY_ORDER_NOTATOMIC = MemoryOrder (0 )
487
+ const MEMORY_ORDER_UNORDERED = MemoryOrder (1 )
488
+ const MEMORY_ORDER_MONOTONIC = MemoryOrder (2 )
489
+ const MEMORY_ORDER_CONSUME = MemoryOrder (3 )
490
+ const MEMORY_ORDER_ACQUIRE = MemoryOrder (4 )
491
+ const MEMORY_ORDER_RELEASE = MemoryOrder (5 )
492
+ const MEMORY_ORDER_ACQ_REL = MemoryOrder (6 )
493
+ const MEMORY_ORDER_SEQ_CST = MemoryOrder (7 )
494
+
495
+ function get_atomic_order (order:: Symbol , loading:: Bool , storing:: Bool )
496
+ if order === :not_atomic
497
+ return MEMORY_ORDER_NOTATOMIC
498
+ elseif order === :unordered && (loading ⊻ storing)
499
+ return MEMORY_ORDER_UNORDERED
500
+ elseif order === :monotonic && (loading | storing)
501
+ return MEMORY_ORDER_MONOTONIC
502
+ elseif order === :acquire && loading
503
+ return MEMORY_ORDER_ACQUIRE
504
+ elseif order === :release && storing
505
+ return MEMORY_ORDER_RELEASE
506
+ elseif order === :acquire_release && (loading & storing)
507
+ return MEMORY_ORDER_ACQ_REL
508
+ elseif order === :sequentially_consistent
509
+ return MEMORY_ORDER_SEQ_CST
510
+ end
511
+ return MEMORY_ORDER_INVALID
512
+ end
513
+
483
514
function pointer_eltype (@nospecialize (ptr))
484
515
a = widenconst (ptr)
485
516
if ! has_free_typevars (a)
@@ -1704,6 +1735,8 @@ function _builtin_nothrow(@nospecialize(f), argtypes::Array{Any,1}, @nospecializ
1704
1735
return true
1705
1736
end
1706
1737
return false
1738
+ elseif f === Core. getglobal
1739
+ return getglobal_nothrow (argtypes)
1707
1740
elseif f === Core. get_binding_type
1708
1741
return length (argtypes) == 2
1709
1742
elseif f === donotdelete
@@ -1773,16 +1806,20 @@ function builtin_effects(f::Builtin, argtypes::Vector{Any}, rt)
1773
1806
# InferenceState.
1774
1807
nothrow = getfield_nothrow (argtypes[2 ], argtypes[3 ], true )
1775
1808
ipo_consistent &= nothrow
1776
- end
1809
+ else
1810
+ nothrow = isvarargtype (argtypes[end ]) ? false :
1811
+ builtin_nothrow (f, argtypes[2 : end ], rt)
1812
+ end
1813
+ effect_free = f === isdefined
1814
+ elseif f === Core. getglobal && length (argtypes) >= 3
1815
+ nothrow = effect_free = getglobal_nothrow (argtypes[2 : end ])
1816
+ ipo_consistent = nothrow && isconst ((argtypes[2 ]:: Const ). val, (argtypes[3 ]:: Const ). val)
1817
+ effect_free = nothrow && isbindingresolved ((argtypes[2 ]:: Const ). val, (argtypes[3 ]:: Const ). val)
1777
1818
else
1778
1819
ipo_consistent = contains_is (_CONSISTENT_BUILTINS, f)
1820
+ effect_free = contains_is (_EFFECT_FREE_BUILTINS, f) || contains_is (_PURE_BUILTINS, f)
1821
+ nothrow = isvarargtype (argtypes[end ]) ? false : builtin_nothrow (f, argtypes[2 : end ], rt)
1779
1822
end
1780
- # If we computed nothrow above for getfield, no need to repeat the procedure here
1781
- if ! nothrow
1782
- nothrow = isvarargtype (argtypes[end ]) ? false :
1783
- builtin_nothrow (f, argtypes[2 : end ], rt)
1784
- end
1785
- effect_free = contains_is (_EFFECT_FREE_BUILTINS, f) || contains_is (_PURE_BUILTINS, f)
1786
1823
1787
1824
return Effects (
1788
1825
ipo_consistent ? ALWAYS_TRUE : ALWAYS_FALSE,
@@ -2029,17 +2066,50 @@ function typename_static(@nospecialize(t))
2029
2066
return isType (t) ? _typename (t. parameters[1 ]) : Core. TypeName
2030
2067
end
2031
2068
2069
+ function global_order_nothrow (@nospecialize (o), loading:: Bool , storing:: Bool )
2070
+ o isa Const || return false
2071
+ sym = o. val
2072
+ if sym isa Symbol
2073
+ order = get_atomic_order (sym, loading, storing)
2074
+ return order != = MEMORY_ORDER_INVALID && order != = MEMORY_ORDER_NOTATOMIC
2075
+ end
2076
+ return false
2077
+ end
2078
+ function getglobal_nothrow (argtypes:: Vector{Any} )
2079
+ 2 ≤ length (argtypes) ≤ 3 || return false
2080
+ if length (argtypes) == 3
2081
+ global_order_nothrow (o, true , false ) || return false
2082
+ end
2083
+ M, s = argtypes
2084
+ if M isa Const && s isa Const
2085
+ M, s = M. val, s. val
2086
+ if M isa Module && s isa Symbol
2087
+ return isdefined (M, s)
2088
+ end
2089
+ end
2090
+ return false
2091
+ end
2092
+ function getglobal_tfunc (@nospecialize (M), @nospecialize (s), @nospecialize (_= :monotonic ))
2093
+ if get_binding_type_effect_free (M, s)
2094
+ return abstract_eval_global ((M:: Const ). val, (s:: Const ). val)
2095
+ end
2096
+ return Any
2097
+ end
2098
+ add_tfunc (Core. getglobal, 2 , 3 , getglobal_tfunc, 1 )
2099
+ add_tfunc (Core. setglobal!, 3 , 4 , (M, s, v, _= :monotonic ) -> (@nospecialize ; v), 1 )
2100
+
2032
2101
function get_binding_type_effect_free (@nospecialize (M), @nospecialize (s))
2033
- if M isa Const && widenconst (M) === Module &&
2034
- s isa Const && widenconst (s) === Symbol
2035
- return ccall (:jl_binding_type , Any, (Any, Any), M. val, s. val) != = nothing
2102
+ if M isa Const && s isa Const
2103
+ M, s = M. val, s. val
2104
+ if M isa Module && s isa Symbol
2105
+ return ccall (:jl_binding_type , Any, (Any, Any), M, s) != = nothing
2106
+ end
2036
2107
end
2037
2108
return false
2038
2109
end
2039
2110
function get_binding_type_tfunc (@nospecialize (M), @nospecialize (s))
2040
2111
if get_binding_type_effect_free (M, s)
2041
- @assert M isa Const && s isa Const
2042
- return Const (Core. get_binding_type (M. val, s. val))
2112
+ return Const (Core. get_binding_type ((M:: Const ). val, (s:: Const ). val))
2043
2113
end
2044
2114
return Type
2045
2115
end
0 commit comments