Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch LLVM codegen of Ptr{T} to an actual pointer type. #53687

Merged
merged 13 commits into from
Mar 21, 2024
5 changes: 5 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ Language changes
Compiler/Runtime improvements
-----------------------------

- Generated LLVM IR now uses actual pointer types instead of passing pointers as integers.
This affects `llvmcall`: Inline LLVM IR should be updated to use `i8*` or `ptr` instead of
`i32` or `i64`, and remove unneeded `ptrtoint`/`inttoptr` conversions. For compatibility,
IR with integer pointers is still supported, but generates a deprecation warning. ([#53687])

Command-line option changes
---------------------------

Expand Down
12 changes: 6 additions & 6 deletions base/atomics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -364,13 +364,13 @@ for typ in atomictypes
irt = "$ilt, $ilt*"
@eval getindex(x::Atomic{$typ}) =
GC.@preserve x llvmcall($"""
%ptr = inttoptr i$WORD_SIZE %0 to $lt*
%ptr = bitcast i8* %0 to $lt*
%rv = load atomic $rt %ptr acquire, align $(gc_alignment(typ))
ret $lt %rv
""", $typ, Tuple{Ptr{$typ}}, unsafe_convert(Ptr{$typ}, x))
@eval setindex!(x::Atomic{$typ}, v::$typ) =
GC.@preserve x llvmcall($"""
%ptr = inttoptr i$WORD_SIZE %0 to $lt*
%ptr = bitcast i8* %0 to $lt*
store atomic $lt %1, $lt* %ptr release, align $(gc_alignment(typ))
ret void
""", Cvoid, Tuple{Ptr{$typ}, $typ}, unsafe_convert(Ptr{$typ}, x), v)
Expand All @@ -379,7 +379,7 @@ for typ in atomictypes
if typ <: Integer
@eval atomic_cas!(x::Atomic{$typ}, cmp::$typ, new::$typ) =
GC.@preserve x llvmcall($"""
%ptr = inttoptr i$WORD_SIZE %0 to $lt*
%ptr = bitcast i8* %0 to $lt*
%rs = cmpxchg $lt* %ptr, $lt %1, $lt %2 acq_rel acquire
%rv = extractvalue { $lt, i1 } %rs, 0
ret $lt %rv
Expand All @@ -388,7 +388,7 @@ for typ in atomictypes
else
@eval atomic_cas!(x::Atomic{$typ}, cmp::$typ, new::$typ) =
GC.@preserve x llvmcall($"""
%iptr = inttoptr i$WORD_SIZE %0 to $ilt*
%iptr = bitcast i8* %0 to $ilt*
%icmp = bitcast $lt %1 to $ilt
%inew = bitcast $lt %2 to $ilt
%irs = cmpxchg $ilt* %iptr, $ilt %icmp, $ilt %inew acq_rel acquire
Expand All @@ -411,15 +411,15 @@ for typ in atomictypes
if typ <: Integer
@eval $fn(x::Atomic{$typ}, v::$typ) =
GC.@preserve x llvmcall($"""
%ptr = inttoptr i$WORD_SIZE %0 to $lt*
%ptr = bitcast i8* %0 to $lt*
%rv = atomicrmw $rmw $lt* %ptr, $lt %1 acq_rel
ret $lt %rv
""", $typ, Tuple{Ptr{$typ}, $typ}, unsafe_convert(Ptr{$typ}, x), v)
else
rmwop === :xchg || continue
@eval $fn(x::Atomic{$typ}, v::$typ) =
GC.@preserve x llvmcall($"""
%iptr = inttoptr i$WORD_SIZE %0 to $ilt*
%iptr = bitcast i8* %0 to $ilt*
%ival = bitcast $lt %1 to $ilt
%irv = atomicrmw $rmw $ilt* %iptr, $ilt %ival acq_rel
%rv = bitcast $ilt %irv to $lt
Expand Down
7 changes: 5 additions & 2 deletions base/compiler/tfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,6 @@ add_tfunc(sdiv_int, 2, 2, math_tfunc, 20)
add_tfunc(udiv_int, 2, 2, math_tfunc, 20)
add_tfunc(srem_int, 2, 2, math_tfunc, 20)
add_tfunc(urem_int, 2, 2, math_tfunc, 20)
add_tfunc(add_ptr, 2, 2, math_tfunc, 1)
add_tfunc(sub_ptr, 2, 2, math_tfunc, 1)
add_tfunc(neg_float, 1, 1, math_tfunc, 1)
add_tfunc(add_float, 2, 2, math_tfunc, 2)
add_tfunc(sub_float, 2, 2, math_tfunc, 2)
Expand Down Expand Up @@ -662,6 +660,9 @@ function pointer_eltype(@nospecialize(ptr))
return Any
end

@nospecs function pointerarith_tfunc(𝕃::AbstractLattice, ptr, offset)
return ptr
end
@nospecs function pointerref_tfunc(𝕃::AbstractLattice, a, i, align)
return pointer_eltype(a)
end
Expand Down Expand Up @@ -705,6 +706,8 @@ end
end
return ccall(:jl_apply_cmpswap_type, Any, (Any,), T) where T
end
add_tfunc(add_ptr, 2, 2, pointerarith_tfunc, 1)
add_tfunc(sub_ptr, 2, 2, pointerarith_tfunc, 1)
add_tfunc(pointerref, 3, 3, pointerref_tfunc, 4)
add_tfunc(pointerset, 4, 4, pointerset_tfunc, 5)
add_tfunc(atomic_fence, 1, 1, atomic_fence_tfunc, 4)
Expand Down
4 changes: 2 additions & 2 deletions base/pointer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -313,8 +313,8 @@ isless(x::Ptr{T}, y::Ptr{T}) where {T} = x < y
<(x::Ptr, y::Ptr) = UInt(x) < UInt(y)
-(x::Ptr, y::Ptr) = UInt(x) - UInt(y)

+(x::Ptr, y::Integer) = oftype(x, add_ptr(UInt(x), (y % UInt) % UInt))
-(x::Ptr, y::Integer) = oftype(x, sub_ptr(UInt(x), (y % UInt) % UInt))
+(x::Ptr, y::Integer) = add_ptr(x, (y % UInt) % UInt)
-(x::Ptr, y::Integer) = sub_ptr(x, (y % UInt) % UInt)
+(x::Integer, y::Ptr) = y + x

unsigned(x::Ptr) = UInt(x)
Expand Down
3 changes: 1 addition & 2 deletions base/task.jl
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,7 @@ const _state_index = findfirst(==(:_state), fieldnames(Task))
@eval function load_state_acquire(t)
# TODO: Replace this by proper atomic operations when available
@GC.preserve t llvmcall($("""
%ptr = inttoptr i$(Sys.WORD_SIZE) %0 to i8*
%rv = load atomic i8, i8* %ptr acquire, align 8
%rv = load atomic i8, i8* %0 acquire, align 8
ret i8 %rv
"""), UInt8, Tuple{Ptr{UInt8}},
Ptr{UInt8}(pointer_from_objref(t) + fieldoffset(Task, _state_index)))
Expand Down
Loading