@@ -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
length (argtypes) == 2 || return false
1709
1742
return argtypes[1 ] ⊑ Module && argtypes[2 ] ⊑ Symbol
@@ -1721,7 +1754,7 @@ const _EFFECT_FREE_BUILTINS = [
1721
1754
fieldtype, apply_type, isa, UnionAll,
1722
1755
getfield, arrayref, const_arrayref, isdefined, Core. sizeof,
1723
1756
Core. kwfunc, Core. ifelse, Core. _typevar, (< :),
1724
- typeassert, throw, arraysize
1757
+ typeassert, throw, arraysize, Core . getglobal,
1725
1758
]
1726
1759
1727
1760
const _CONSISTENT_BUILTINS = Any[
@@ -1774,16 +1807,20 @@ function builtin_effects(f::Builtin, argtypes::Vector{Any}, rt)
1774
1807
# InferenceState.
1775
1808
nothrow = getfield_nothrow (argtypes[2 ], argtypes[3 ], true )
1776
1809
ipo_consistent &= nothrow
1777
- end
1810
+ else
1811
+ nothrow = isvarargtype (argtypes[end ]) ? false :
1812
+ builtin_nothrow (f, argtypes[2 : end ], rt)
1813
+ end
1814
+ effect_free = f === isdefined
1815
+ elseif f === Core. getglobal && length (argtypes) >= 3
1816
+ nothrow = effect_free = getglobal_nothrow (argtypes[2 : end ])
1817
+ ipo_consistent = nothrow && isconst ((argtypes[2 ]:: Const ). val, (argtypes[3 ]:: Const ). val)
1818
+ # effect_free = nothrow && isbindingresolved((argtypes[2]::Const).val, (argtypes[3]::Const).val)
1778
1819
else
1779
1820
ipo_consistent = contains_is (_CONSISTENT_BUILTINS, f)
1821
+ effect_free = contains_is (_EFFECT_FREE_BUILTINS, f) || contains_is (_PURE_BUILTINS, f)
1822
+ nothrow = isvarargtype (argtypes[end ]) ? false : builtin_nothrow (f, argtypes[2 : end ], rt)
1780
1823
end
1781
- # If we computed nothrow above for getfield, no need to repeat the procedure here
1782
- if ! nothrow
1783
- nothrow = isvarargtype (argtypes[end ]) ? false :
1784
- builtin_nothrow (f, argtypes[2 : end ], rt)
1785
- end
1786
- effect_free = contains_is (_EFFECT_FREE_BUILTINS, f) || contains_is (_PURE_BUILTINS, f)
1787
1824
1788
1825
return Effects (
1789
1826
ipo_consistent ? ALWAYS_TRUE : ALWAYS_FALSE,
@@ -2030,17 +2067,63 @@ function typename_static(@nospecialize(t))
2030
2067
return isType (t) ? _typename (t. parameters[1 ]) : Core. TypeName
2031
2068
end
2032
2069
2070
+ function global_order_nothrow (@nospecialize (o), loading:: Bool , storing:: Bool )
2071
+ o isa Const || return false
2072
+ sym = o. val
2073
+ if sym isa Symbol
2074
+ order = get_atomic_order (sym, loading, storing)
2075
+ return order != = MEMORY_ORDER_INVALID && order != = MEMORY_ORDER_NOTATOMIC
2076
+ end
2077
+ return false
2078
+ end
2079
+ function getglobal_nothrow (argtypes:: Vector{Any} )
2080
+ 2 ≤ length (argtypes) ≤ 3 || return false
2081
+ if length (argtypes) == 3
2082
+ global_order_nothrow (o, true , false ) || return false
2083
+ end
2084
+ M, s = argtypes
2085
+ if M isa Const && s isa Const
2086
+ M, s = M. val, s. val
2087
+ if M isa Module && s isa Symbol
2088
+ return isdefined (M, s)
2089
+ end
2090
+ end
2091
+ return false
2092
+ end
2093
+ function getglobal_tfunc (@nospecialize (M), @nospecialize (s), @nospecialize (_= Symbol))
2094
+ if M isa Const && s isa Const
2095
+ M, s = M. val, s. val
2096
+ if M isa Module && s isa Symbol
2097
+ return abstract_eval_global (M, s)
2098
+ end
2099
+ return Bottom
2100
+ elseif ! (hasintersect (widenconst (M), Module) && hasintersect (widenconst (s), Symbol))
2101
+ return Bottom
2102
+ end
2103
+ return Any
2104
+ end
2105
+ function setglobal!_tfunc (@nospecialize (M), @nospecialize (s), @nospecialize (v),
2106
+ @nospecialize (_= Symbol))
2107
+ if ! (hasintersect (widenconst (M), Module) && hasintersect (widenconst (s), Symbol))
2108
+ return Bottom
2109
+ end
2110
+ return v
2111
+ end
2112
+ add_tfunc (Core. getglobal, 2 , 3 , getglobal_tfunc, 1 )
2113
+ add_tfunc (Core. setglobal!, 3 , 4 , setglobal!_tfunc, 3 )
2114
+
2033
2115
function get_binding_type_effect_free (@nospecialize (M), @nospecialize (s))
2034
- if M isa Const && widenconst (M) === Module &&
2035
- s isa Const && widenconst (s) === Symbol
2036
- return ccall (:jl_binding_type , Any, (Any, Any), M. val, s. val) != = nothing
2116
+ if M isa Const && s isa Const
2117
+ M, s = M. val, s. val
2118
+ if M isa Module && s isa Symbol
2119
+ return ccall (:jl_binding_type , Any, (Any, Any), M, s) != = nothing
2120
+ end
2037
2121
end
2038
2122
return false
2039
2123
end
2040
2124
function get_binding_type_tfunc (@nospecialize (M), @nospecialize (s))
2041
2125
if get_binding_type_effect_free (M, s)
2042
- @assert M isa Const && s isa Const
2043
- return Const (Core. get_binding_type (M. val, s. val))
2126
+ return Const (Core. get_binding_type ((M:: Const ). val, (s:: Const ). val))
2044
2127
end
2045
2128
return Type
2046
2129
end
0 commit comments