diff --git a/src/aotcompile.cpp b/src/aotcompile.cpp index d91da9c64cda9..fe340d849d8c0 100644 --- a/src/aotcompile.cpp +++ b/src/aotcompile.cpp @@ -4,6 +4,8 @@ #include "platform.h" // target support +#include "llvm/IR/Constants.h" +#include "llvm/Support/Debug.h" #include #include "llvm/Support/CodeGen.h" #include @@ -199,29 +201,28 @@ static inline SmallVector consume_gv(Module &M, const char *name, bool al return res; } -static Constant *get_ptrdiff32(Type *T_size, Constant *ptr, Constant *base) +static Constant *get_ptrdiff(Type *T_size, Constant *ptr, Constant *base) { if (ptr->getType()->isPointerTy()) ptr = ConstantExpr::getPtrToInt(ptr, T_size); auto ptrdiff = ConstantExpr::getSub(ptr, base); - return T_size->getPrimitiveSizeInBits() > 32 ? ConstantExpr::getTrunc(ptrdiff, Type::getInt32Ty(ptr->getContext())) : ptrdiff; + return ptrdiff; } static Constant *emit_offset_table(Module &M, Type *T_size, ArrayRef vars, StringRef name, StringRef suffix) { - auto T_int32 = Type::getInt32Ty(M.getContext()); uint32_t nvars = vars.size(); - ArrayType *vars_type = ArrayType::get(T_int32, nvars + 1); + ArrayType *vars_type = ArrayType::get(T_size, nvars + 1); auto gv = new GlobalVariable(M, vars_type, true, GlobalVariable::ExternalLinkage, nullptr, name + "_offsets" + suffix); auto vbase = ConstantExpr::getPtrToInt(gv, T_size); SmallVector offsets(nvars + 1); - offsets[0] = ConstantInt::get(T_int32, nvars); + offsets[0] = ConstantInt::get(T_size, nvars); for (uint32_t i = 0; i < nvars; i++) - offsets[i + 1] = get_ptrdiff32(T_size, vars[i], vbase); + offsets[i + 1] = get_ptrdiff(T_size, vars[i], vbase); gv->setInitializer(ConstantArray::get(vars_type, offsets)); gv->setVisibility(GlobalValue::HiddenVisibility); gv->setDSOLocal(true); @@ -1991,7 +1992,7 @@ void jl_dump_native_impl(void *native_code, CodeModel::Model CMModel = CodeModel::Small; if (TheTriple.isPPC() || TheTriple.isRISCV() || - (TheTriple.isX86() && TheTriple.isArch64Bit() && TheTriple.isOSLinux())) { + (TheTriple.isX86() && TheTriple.isArch64Bit() && (TheTriple.isOSLinux() || TheTriple.isOSDarwin()))) { // On PPC the small model is limited to 16bit offsets. For very large images the small code model CMModel = CodeModel::Medium; // isn't good enough on x86 so use Medium, it has no cost because only the image goes in .ldata } diff --git a/src/processor.cpp b/src/processor.cpp index 3edebcc2f3ae6..aebc04fd96d90 100644 --- a/src/processor.cpp +++ b/src/processor.cpp @@ -772,7 +772,7 @@ static inline jl_image_t parse_sysimg(void *hdl, F &&callback) } if (!gvars.empty()) { - auto offsets = (int32_t*)malloc(sizeof(int32_t) * gvars.size()); + auto offsets = (ptrdiff_t*)malloc(sizeof(ptrdiff_t) * gvars.size()); res.gvars_base = (const char*)pointers->header; for (size_t i = 0; i < gvars.size(); i++) { assert(gvars[i] && "Missing global variable pointer!"); diff --git a/src/processor.h b/src/processor.h index 82a1121aaf7c4..e71551b5bada2 100644 --- a/src/processor.h +++ b/src/processor.h @@ -85,7 +85,7 @@ typedef struct _jl_image_fptrs_t { typedef struct { uint64_t base; const char *gvars_base; - const int32_t *gvars_offsets; + const ptrdiff_t *gvars_offsets; uint32_t ngvars; jl_image_fptrs_t fptrs; void **jl_small_typeof; @@ -126,7 +126,7 @@ typedef struct { // Similar to fvar_offsets, but for gvars // This is also the base data pointer // (all data pointers in this shard are stored as offsets to this address) - const int32_t *gvar_offsets; + const ptrdiff_t *gvar_offsets; // This is the mapping of shard global variable index -> global global variable index // Similar to fvar_idxs, but for gvars const uint32_t *gvar_idxs; diff --git a/src/staticdata.c b/src/staticdata.c index 6cb157ad299fc..ca2cfcaf44bfc 100644 --- a/src/staticdata.c +++ b/src/staticdata.c @@ -635,7 +635,7 @@ typedef struct { static void *jl_sysimg_handle = NULL; static jl_image_t sysimage; -static inline uintptr_t *sysimg_gvars(const char *base, const int32_t *offsets, size_t idx) +static inline uintptr_t *sysimg_gvars(const char *base, const ptrdiff_t *offsets, size_t idx) { return (uintptr_t*)(base + offsets[idx]); } diff --git a/test/compileall.jl b/test/compileall.jl index beec0d6df49ab..3e295f9537f51 100644 --- a/test/compileall.jl +++ b/test/compileall.jl @@ -2,10 +2,22 @@ # We make it a separate test target here, so that it can run in parallel # with the rest of the tests. -mktempdir() do dir - @test success(pipeline(`$(Base.julia_cmd()) --compile=all --strip-ir --output-o $(dir)/sys.o.a -e 'exit()'`, stderr=stderr)) skip=(Sys.WORD_SIZE == 32) - if isfile(joinpath(dir, "sys.o.a")) - Base.Linking.link_image(joinpath(dir, "sys.o.a"), joinpath(dir, "sys.so")) - @test success(`$(Base.julia_cmd()) -J $(dir)/sys.so -e 'Base.scrub_repl_backtrace(nothing); exit()'`) + + +if !Sys.iswindows() && !(Sys.WORD_SIZE == 32) #Windows doesn't support large images + mktempdir() do dir + @test success(pipeline(`$(Base.julia_cmd()) --compile=all --strip-ir --output-o $(dir)/sys.o.a -e 'const ballast = Memory{UInt8}(undef, 1 << 31); exit()'`, stderr=stderr)) + if isfile(joinpath(dir, "sys.o.a")) + Base.Linking.link_image(joinpath(dir, "sys.o.a"), joinpath(dir, "sys.so")) + @test success(`$(Base.julia_cmd()) -J $(dir)/sys.so -e 'Base.scrub_repl_backtrace(nothing); exit()'`) + end + end +else + mktempdir() do dir + @test success(pipeline(`$(Base.julia_cmd()) --compile=all --strip-ir --output-o $(dir)/sys.o.a -e 'exit()'`, stderr=stderr)) skip=(Sys.WORD_SIZE == 32) + if isfile(joinpath(dir, "sys.o.a")) + Base.Linking.link_image(joinpath(dir, "sys.o.a"), joinpath(dir, "sys.so")) + @test success(`$(Base.julia_cmd()) -J $(dir)/sys.so -e 'Base.scrub_repl_backtrace(nothing); exit()'`) + end end end diff --git a/test/llvmpasses/multiversioning-clone-only.ll b/test/llvmpasses/multiversioning-clone-only.ll index 00f0db0aa1e91..9b74a2c4aaf78 100644 --- a/test/llvmpasses/multiversioning-clone-only.ll +++ b/test/llvmpasses/multiversioning-clone-only.ll @@ -3,7 +3,7 @@ ; RUN: opt --load-pass-plugin=libjulia-codegen%shlibext -passes='JuliaMultiVersioning' -S %s | FileCheck %s --allow-unused-prefixes=false --check-prefixes=CHECK,OPAQUE ; CHECK: @jl_gvar_base = hidden constant i64 0 -; CHECK: @jl_gvar_offsets = hidden constant [0 x i32] zeroinitializer +; CHECK: @jl_gvar_offsets = hidden constant [0 x i64] zeroinitializer ; CHECK: @jl_fvar_idxs = hidden constant [1 x i32] zeroinitializer ; CHECK: @jl_gvar_idxs = hidden constant [0 x i32] zeroinitializer ; OPAQUE: @subtarget_cloned_gv = hidden global ptr null @@ -18,7 +18,7 @@ @jl_fvars = global [1 x i64*] [i64* bitcast (i32 (i32)* @subtarget_cloned to i64*)], align 8 @jl_gvar_base = hidden constant i64 zeroinitializer, align 8 -@jl_gvar_offsets = hidden constant [0 x i32] zeroinitializer, align 8 +@jl_gvar_offsets = hidden constant [0 x i64] zeroinitializer, align 8 @jl_fvar_idxs = hidden constant [1 x i32] [i32 0], align 8 @jl_gvar_idxs = hidden constant [0 x i32] zeroinitializer, align 8 @subtarget_cloned_gv = hidden global i64* bitcast (i32 (i32)* @subtarget_cloned to i64*), align 8