Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "LLVM"
uuid = "929cbde3-209d-540e-8aea-75f648917ca0"
version = "9.4.0"
version = "9.4.1"

[deps]
CEnum = "fa961155-64e5-5f13-b03f-caf6b980ea82"
Expand Down
3 changes: 3 additions & 0 deletions deps/LLVMExtra/include/LLVMExtra.h
Original file line number Diff line number Diff line change
Expand Up @@ -255,5 +255,8 @@ LLVMErrorRef LLVMRunJuliaPassesOnFunction(LLVMValueRef F, const char *Passes,
LLVMPassBuilderOptionsRef Options,
LLVMPassBuilderExtensionsRef Extensions);

// More DataLayout queries
unsigned LLVMGlobalsAddressSpace(LLVMTargetDataRef TD);

LLVM_C_EXTERN_C_END
#endif
9 changes: 9 additions & 0 deletions deps/LLVMExtra/lib/Core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -795,6 +795,15 @@ LLVMContextRef LLVMGetBuilderContext(LLVMBuilderRef Builder) {
return wrap(&unwrap(Builder)->getContext());
}


//
// More DataLayout queries
//

unsigned LLVMGlobalsAddressSpace(LLVMTargetDataRef TD) {
return unwrap(TD)->getDefaultGlobalsAddressSpace();
}

#endif

#endif
1 change: 1 addition & 0 deletions docs/src/lib/codegen.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ dispose(::DataLayout)
byteorder
pointersize
intptr
globals_addrspace
sizeof(::DataLayout, ::LLVMType)
storage_size
abi_size
Expand Down
1 change: 1 addition & 0 deletions docs/src/man/codegen.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ generating IR:
- `byteorder`
- `pointersize`
- `intptr`
- `globals_addrspace`
- `sizeof`
- `storage_size`
- `abi_alignment`
Expand Down
4 changes: 4 additions & 0 deletions lib/15/libLLVM_extra.jl
Original file line number Diff line number Diff line change
Expand Up @@ -401,3 +401,7 @@ function LLVMRunJuliaPassesOnFunction(F, Passes, TM, Options, Extensions)
ccall((:LLVMRunJuliaPassesOnFunction, libLLVMExtra), LLVMErrorRef, (LLVMValueRef, Cstring, LLVMTargetMachineRef, LLVMPassBuilderOptionsRef, LLVMPassBuilderExtensionsRef), F, Passes, TM, Options, Extensions)
end

function LLVMGlobalsAddressSpace(TD)
ccall((:LLVMGlobalsAddressSpace, libLLVMExtra), Cuint, (LLVMTargetDataRef,), TD)
end

4 changes: 4 additions & 0 deletions lib/16/libLLVM_extra.jl
Original file line number Diff line number Diff line change
Expand Up @@ -401,3 +401,7 @@ function LLVMRunJuliaPassesOnFunction(F, Passes, TM, Options, Extensions)
ccall((:LLVMRunJuliaPassesOnFunction, libLLVMExtra), LLVMErrorRef, (LLVMValueRef, Cstring, LLVMTargetMachineRef, LLVMPassBuilderOptionsRef, LLVMPassBuilderExtensionsRef), F, Passes, TM, Options, Extensions)
end

function LLVMGlobalsAddressSpace(TD)
ccall((:LLVMGlobalsAddressSpace, libLLVMExtra), Cuint, (LLVMTargetDataRef,), TD)
end

4 changes: 4 additions & 0 deletions lib/17/libLLVM_extra.jl
Original file line number Diff line number Diff line change
Expand Up @@ -361,3 +361,7 @@ function LLVMRunJuliaPassesOnFunction(F, Passes, TM, Options, Extensions)
ccall((:LLVMRunJuliaPassesOnFunction, libLLVMExtra), LLVMErrorRef, (LLVMValueRef, Cstring, LLVMTargetMachineRef, LLVMPassBuilderOptionsRef, LLVMPassBuilderExtensionsRef), F, Passes, TM, Options, Extensions)
end

function LLVMGlobalsAddressSpace(TD)
ccall((:LLVMGlobalsAddressSpace, libLLVMExtra), Cuint, (LLVMTargetDataRef,), TD)
end

4 changes: 4 additions & 0 deletions lib/18/libLLVM_extra.jl
Original file line number Diff line number Diff line change
Expand Up @@ -295,3 +295,7 @@ function LLVMRunJuliaPassesOnFunction(F, Passes, TM, Options, Extensions)
ccall((:LLVMRunJuliaPassesOnFunction, libLLVMExtra), LLVMErrorRef, (LLVMValueRef, Cstring, LLVMTargetMachineRef, LLVMPassBuilderOptionsRef, LLVMPassBuilderExtensionsRef), F, Passes, TM, Options, Extensions)
end

function LLVMGlobalsAddressSpace(TD)
ccall((:LLVMGlobalsAddressSpace, libLLVMExtra), Cuint, (LLVMTargetDataRef,), TD)
end

4 changes: 4 additions & 0 deletions lib/19/libLLVM_extra.jl
Original file line number Diff line number Diff line change
Expand Up @@ -295,3 +295,7 @@ function LLVMRunJuliaPassesOnFunction(F, Passes, TM, Options, Extensions)
ccall((:LLVMRunJuliaPassesOnFunction, libLLVMExtra), LLVMErrorRef, (LLVMValueRef, Cstring, LLVMTargetMachineRef, LLVMPassBuilderOptionsRef, LLVMPassBuilderExtensionsRef), F, Passes, TM, Options, Extensions)
end

function LLVMGlobalsAddressSpace(TD)
ccall((:LLVMGlobalsAddressSpace, libLLVMExtra), Cuint, (LLVMTargetDataRef,), TD)
end

4 changes: 4 additions & 0 deletions lib/20/libLLVM_extra.jl
Original file line number Diff line number Diff line change
Expand Up @@ -247,3 +247,7 @@ function LLVMRunJuliaPassesOnFunction(F, Passes, TM, Options, Extensions)
ccall((:LLVMRunJuliaPassesOnFunction, libLLVMExtra), LLVMErrorRef, (LLVMValueRef, Cstring, LLVMTargetMachineRef, LLVMPassBuilderOptionsRef, LLVMPassBuilderExtensionsRef), F, Passes, TM, Options, Extensions)
end

function LLVMGlobalsAddressSpace(TD)
ccall((:LLVMGlobalsAddressSpace, libLLVMExtra), Cuint, (LLVMTargetDataRef,), TD)
end

91 changes: 49 additions & 42 deletions src/datalayout.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
## data layout

export DataLayout, dispose,
byteorder, pointersize, intptr,
byteorder, pointersize, intptr, globals_addrspace,
sizeof, storage_size, abi_size,
abi_alignment, frame_alignment, preferred_alignment,
element_at, offsetof
Expand Down Expand Up @@ -38,119 +38,126 @@ This object needs to be disposed of using [`dispose`](@ref).
DataLayout(tm::TargetMachine) = mark_alloc(DataLayout(API.LLVMCreateTargetDataLayout(tm)))

"""
dispose(data::DataLayout)
dispose(dl::DataLayout)

Dispose of the given target data layout.
"""
dispose(data::DataLayout) = mark_dispose(API.LLVMDisposeTargetData, data)
dispose(dl::DataLayout) = mark_dispose(API.LLVMDisposeTargetData, dl)

function DataLayout(f::Core.Function, args...; kwargs...)
data = DataLayout(args...; kwargs...)
dl = DataLayout(args...; kwargs...)
try
f(data)
f(dl)
finally
dispose(data)
dispose(dl)
end
end

Base.string(data::DataLayout) =
unsafe_message(API.LLVMCopyStringRepOfTargetData(data))
Base.string(dl::DataLayout) =
unsafe_message(API.LLVMCopyStringRepOfTargetData(dl))

function Base.show(io::IO, data::DataLayout)
@printf(io, "DataLayout(%s)", string(data))
function Base.show(io::IO, dl::DataLayout)
@printf(io, "DataLayout(%s)", string(dl))
end

"""
byteorder(data::DataLayout)
byteorder(dl::DataLayout)

Get the byte order of the target data layout.
"""
byteorder(data::DataLayout) = API.LLVMByteOrder(data)
byteorder(dl::DataLayout) = API.LLVMByteOrder(dl)

"""
pointersize(data::DataLayout, [addrspace::Integer])
pointersize(dl::DataLayout, [addrspace::Integer])

Get the pointer size of the target data layout.
"""
pointersize(data::DataLayout, addrspace::Integer=0) =
API.LLVMPointerSizeForAS(data, addrspace)
pointersize(dl::DataLayout, addrspace::Integer=0) =
API.LLVMPointerSizeForAS(dl, addrspace)

"""
intptr(data::DataLayout, [addrspace::Integer])
intptr(dl::DataLayout, [addrspace::Integer])

Get the integer type that is the same size as a pointer for the target data layout.
"""
intptr(data::DataLayout, addrspace::Integer=0) =
IntegerType(API.LLVMIntPtrTypeForASInContext(context(), data, addrspace))
intptr(dl::DataLayout, addrspace::Integer=0) =
IntegerType(API.LLVMIntPtrTypeForASInContext(context(), dl, addrspace))

"""
sizeof(data::DataLayout, typ::LLVMType)
globals_addrspace(dl::DataLayout)

Get the address space used for global variables in the target data layout.
"""
globals_addrspace(dl::DataLayout) = API.LLVMGlobalsAddressSpace(dl) |> Int

"""
sizeof(dl::DataLayout, typ::LLVMType)

Get the size of the given type in bytes for the target data layout.
"""
Base.sizeof(data::DataLayout, typ::LLVMType) = Int(API.LLVMSizeOfTypeInBits(data, typ) / 8)
Base.sizeof(dl::DataLayout, typ::LLVMType) = Int(API.LLVMSizeOfTypeInBits(dl, typ) / 8)

"""
storage_size(data::DataLayout, typ::LLVMType)
storage_size(dl::DataLayout, typ::LLVMType)

Get the storage size of the given type in bytes for the target data layout.
"""
storage_size(data::DataLayout, typ::LLVMType) = API.LLVMStoreSizeOfType(data, typ)
storage_size(dl::DataLayout, typ::LLVMType) = API.LLVMStoreSizeOfType(dl, typ)

"""
abi_size(data::DataLayout, typ::LLVMType)
abi_size(dl::DataLayout, typ::LLVMType)

Get the ABI size of the given type in bytes for the target data layout.
"""
abi_size(data::DataLayout, typ::LLVMType) = API.LLVMABISizeOfType(data, typ)
abi_size(dl::DataLayout, typ::LLVMType) = API.LLVMABISizeOfType(dl, typ)

"""
abi_alignment(data::DataLayout, typ::LLVMType)
abi_alignment(dl::DataLayout, typ::LLVMType)

Get the ABI alignment of the given type in bytes for the target data layout.
"""
abi_alignment(data::DataLayout, typ::LLVMType) =
API.LLVMABIAlignmentOfType(data, typ)
abi_alignment(dl::DataLayout, typ::LLVMType) =
API.LLVMABIAlignmentOfType(dl, typ)

"""
frame_alignment(data::DataLayout, typ::LLVMType)
frame_alignment(dl::DataLayout, typ::LLVMType)

Get the call frame alignment of the given type in bytes for the target data layout.
"""
frame_alignment(data::DataLayout, typ::LLVMType) =
API.LLVMCallFrameAlignmentOfType(data, typ)
frame_alignment(dl::DataLayout, typ::LLVMType) =
API.LLVMCallFrameAlignmentOfType(dl, typ)


"""
preferred_alignment(data::DataLayout, typ::LLVMType)
preferred_alignment(data::DataLayout, var::GlobalVariable)
preferred_alignment(dl::DataLayout, typ::LLVMType)
preferred_alignment(dl::DataLayout, var::GlobalVariable)

Get the preferred alignment of the given type or global variable in bytes for the target
data layout.
"""
preferred_alignment(::DataLayout, ::Union{LLVMType, GlobalVariable})

preferred_alignment(data::DataLayout, typ::LLVMType) =
API.LLVMPreferredAlignmentOfType(data, typ)
preferred_alignment(data::DataLayout, var::GlobalVariable) =
API.LLVMPreferredAlignmentOfGlobal(data, var)
preferred_alignment(dl::DataLayout, typ::LLVMType) =
API.LLVMPreferredAlignmentOfType(dl, typ)
preferred_alignment(dl::DataLayout, var::GlobalVariable) =
API.LLVMPreferredAlignmentOfGlobal(dl, var)

"""
element_at(data::DataLayout, typ::StructType, offset::Integer)
element_at(dl::DataLayout, typ::StructType, offset::Integer)

Get the element at the given offset in a struct type for the target data layout.

See also: [`offsetof`](@ref).
"""
element_at(data::DataLayout, typ::StructType, offset::Integer) =
API.LLVMElementAtOffset(data, typ, Culonglong(offset))
element_at(dl::DataLayout, typ::StructType, offset::Integer) =
API.LLVMElementAtOffset(dl, typ, Culonglong(offset))

"""
offsetof(data::DataLayout, typ::StructType, element::Integer)
offsetof(dl::DataLayout, typ::StructType, element::Integer)

Get the offset of the given element in a struct type for the target data layout.

See also: [`element_at`](@ref).
"""
offsetof(data::DataLayout, typ::StructType, element::Integer) =
API.LLVMOffsetOfElement(data, typ, element)
offsetof(dl::DataLayout, typ::StructType, element::Integer) =
API.LLVMOffsetOfElement(dl, typ, element)
5 changes: 3 additions & 2 deletions src/irbuilder.jl
Original file line number Diff line number Diff line change
Expand Up @@ -523,14 +523,15 @@ not!(builder::IRBuilder, V::Value, Name::String="") =

# re-implementation for flexibility (exposing addrspace, add_null)
function globalstring!(mod::LLVM.Module, str::String, name::String="";
addrspace::Integer=0, add_null::Bool=true)
addrspace::Union{Integer,Nothing}=nothing, add_null::Bool=true)
bytes = Vector{UInt8}(str)
if add_null
push!(bytes, 0x00)
end
constant = ConstantDataArray(bytes)

gv = GlobalVariable(mod, value_type(constant), name, addrspace)
gv = GlobalVariable(mod, value_type(constant), name,
something(addrspace, globals_addrspace(datalayout(mod))))
alignment!(gv, 1)
unnamed_addr!(gv, true)
initializer!(gv, constant)
Expand Down
37 changes: 21 additions & 16 deletions test/datalayout_tests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,39 +3,44 @@
dlstr = "E-p:32:32-f128:128:128"

let
data = DataLayout(dlstr)
dispose(data)
dl = DataLayout(dlstr)
dispose(dl)
end

DataLayout(dlstr) do data
DataLayout(dlstr) do dl
end

@dispose ctx=Context() data=DataLayout(dlstr) begin
@test string(data) == dlstr
@dispose ctx=Context() dl=DataLayout(dlstr) begin
@test string(dl) == dlstr

@test occursin(dlstr, sprint(io->show(io,data)))
@test occursin(dlstr, sprint(io->show(io,dl)))

@test byteorder(data) == LLVM.API.LLVMBigEndian
@test pointersize(data) == pointersize(data, 0) == 4
@test byteorder(dl) == LLVM.API.LLVMBigEndian
@test pointersize(dl) == pointersize(dl, 0) == 4

@test intptr(data) == intptr(data, 0) == LLVM.Int32Type()
@test intptr(dl) == intptr(dl, 0) == LLVM.Int32Type()

@test sizeof(data, LLVM.Int32Type()) == storage_size(data, LLVM.Int32Type()) == abi_size(data, LLVM.Int32Type()) == 4
@test sizeof(dl, LLVM.Int32Type()) == storage_size(dl, LLVM.Int32Type()) == abi_size(dl, LLVM.Int32Type()) == 4

@test abi_alignment(data, LLVM.Int32Type()) == frame_alignment(data, LLVM.Int32Type()) == preferred_alignment(data, LLVM.Int32Type()) == 4
@test abi_alignment(dl, LLVM.Int32Type()) == frame_alignment(dl, LLVM.Int32Type()) == preferred_alignment(dl, LLVM.Int32Type()) == 4

@dispose mod=LLVM.Module("SomeModule") begin
gv = GlobalVariable(mod, LLVM.Int32Type(), "SomeGlobal")
@test preferred_alignment(data, gv) == 4
@test preferred_alignment(dl, gv) == 4

datalayout!(mod, data)
@test string(datalayout(mod)) == string(data)
datalayout!(mod, dl)
@test string(datalayout(mod)) == string(dl)
end

elem = [LLVM.Int32Type(), LLVM.FloatType()]
let st = LLVM.StructType(elem)
@test element_at(data, st, 4) == 1
@test offsetof(data, st, 1) == 4
@test element_at(dl, st, 4) == 1
@test offsetof(dl, st, 1) == 4
end

@test globals_addrspace(dl) == 0
@dispose dl2=DataLayout(dlstr*"-G1") begin
@test globals_addrspace(dl2) == 1
end
end

Expand Down
Loading