Skip to content

Commit

Permalink
Support LLVM 14 (upstream Git main)
Browse files Browse the repository at this point in the history
Compiles against llvm/llvm-project#2ec3ca747732, with some of
our unmerged local patches from 13.x still required.

Unfortunately, there is quite a bit of fallout from the various
attribute API renames. I chose to introduce some function shims
to separate out all the preprocessor #if clutter.
  • Loading branch information
dnadlinger committed Jan 1, 2022
1 parent c04a3fd commit c36664e
Show file tree
Hide file tree
Showing 16 changed files with 289 additions and 129 deletions.
4 changes: 4 additions & 0 deletions src/aotcompile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@
#include <llvm/Analysis/TargetLibraryInfo.h>
#include <llvm/Analysis/TargetTransformInfo.h>
#include <llvm/IR/DataLayout.h>
#if JL_LLVM_VERSION >= 140000
#include <llvm/MC/TargetRegistry.h>
#else
#include <llvm/Support/TargetRegistry.h>
#endif
#include <llvm/Target/TargetMachine.h>

// analysis passes
Expand Down
40 changes: 18 additions & 22 deletions src/ccall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,7 @@ static GlobalVariable *emit_plt_thunk(
// NoReturn function can trigger LLVM verifier error when declared as
// MustTail since other passes might replace the `ret` with
// `unreachable` (LLVM should probably accept `unreachable`).
if (attrs.hasAttribute(AttributeList::FunctionIndex,
Attribute::NoReturn)) {
if (hasFnAttr(attrs, Attribute::NoReturn)) {
irbuilder.CreateUnreachable();
}
else {
Expand Down Expand Up @@ -272,7 +271,7 @@ static Value *emit_plt(
functype, attrs, cc, f_lib, f_name, libptrgv, llvmgv, runtime_lib);
}
GlobalVariable *got = prepare_global_in(jl_Module, sharedgot);
LoadInst *got_val = ctx.builder.CreateAlignedLoad(got, Align(sizeof(void*)));
LoadInst *got_val = ctx.builder.CreateAlignedLoad(got->getType()->getElementType(), got, Align(sizeof(void*)));
// See comment in `runtime_sym_lookup` above. This in principle needs a
// consume ordering too. This is even less likely to cause issues though
// since the only thing we do to this loaded pointer is to call it
Expand Down Expand Up @@ -404,7 +403,7 @@ static Value *llvm_type_rewrite(
to = emit_bitcast(ctx, from, target_type->getPointerTo());
}
ctx.builder.CreateAlignedStore(v, from, Align(align));
return ctx.builder.CreateAlignedLoad(to, Align(align));
return ctx.builder.CreateAlignedLoad(target_type, to, Align(align));
}

// --- argument passing and scratch space utilities ---
Expand All @@ -422,8 +421,7 @@ static Value *runtime_apply_type_env(jl_codectx_t &ctx, jl_value_t *ty)
ConstantInt::get(T_size, sizeof(jl_svec_t) / sizeof(jl_value_t*)))
};
auto call = ctx.builder.CreateCall(prepare_call(jlapplytype_func), makeArrayRef(args));
call->addAttribute(AttributeList::ReturnIndex,
Attribute::getWithAlignment(jl_LLVMContext, Align(16)));
addRetAttr(call, Attribute::getWithAlignment(jl_LLVMContext, Align(16)));
return call;
}

Expand Down Expand Up @@ -1125,16 +1123,13 @@ std::string generate_func_sig(const char *fname)
const auto &as = paramattrs.at(i);
if (!as.hasAttributes())
continue;
attributes = attributes.addAttributes(jl_LLVMContext, i + 1, as);
attributes = addAttributesAtIndex(attributes, jl_LLVMContext, i + 1, as);
}
// If return value is boxed it must be non-null.
if (retboxed)
attributes = attributes.addAttribute(jl_LLVMContext, AttributeList::ReturnIndex,
Attribute::NonNull);
attributes = addRetAttribute(attributes, jl_LLVMContext, Attribute::NonNull);
if (rt == jl_bottom_type) {
attributes = attributes.addAttribute(jl_LLVMContext,
AttributeList::FunctionIndex,
Attribute::NoReturn);
attributes = addFnAttribute(attributes, jl_LLVMContext, Attribute::NoReturn);
}
return "";
}
Expand Down Expand Up @@ -1487,8 +1482,8 @@ static jl_cgval_t emit_ccall(jl_codectx_t &ctx, jl_value_t **args, size_t nargs)
JL_GC_POP();
Value *ptask_i16 = emit_bitcast(ctx, get_current_task(ctx), T_pint16);
const int tid_offset = offsetof(jl_task_t, tid);
Value *ptid = ctx.builder.CreateInBoundsGEP(ptask_i16, ConstantInt::get(T_size, tid_offset / sizeof(int16_t)));
LoadInst *tid = ctx.builder.CreateAlignedLoad(ptid, Align(sizeof(int16_t)));
Value *ptid = ctx.builder.CreateInBoundsGEP(T_int16, ptask_i16, ConstantInt::get(T_size, tid_offset / sizeof(int16_t)));
LoadInst *tid = ctx.builder.CreateAlignedLoad(T_int16, ptid, Align(sizeof(int16_t)));
tbaa_decorate(tbaa_gcframe, tid);
return mark_or_box_ccall_result(ctx, tid, retboxed, rt, unionall, static_rt);
}
Expand All @@ -1500,8 +1495,8 @@ static jl_cgval_t emit_ccall(jl_codectx_t &ctx, jl_value_t **args, size_t nargs)
JL_GC_POP();
Value *ptls_i32 = emit_bitcast(ctx, get_current_ptls(ctx), T_pint32);
const int finh_offset = offsetof(jl_tls_states_t, finalizers_inhibited);
Value *pfinh = ctx.builder.CreateInBoundsGEP(ptls_i32, ConstantInt::get(T_size, finh_offset / 4));
LoadInst *finh = ctx.builder.CreateAlignedLoad(pfinh, Align(sizeof(int32_t)));
Value *pfinh = ctx.builder.CreateInBoundsGEP(T_int32, ptls_i32, ConstantInt::get(T_size, finh_offset / 4));
LoadInst *finh = ctx.builder.CreateAlignedLoad(T_int32, pfinh, Align(sizeof(int32_t)));
Value *newval;
if (is_libjulia_func(jl_gc_disable_finalizers_internal)) {
newval = ctx.builder.CreateAdd(finh, ConstantInt::get(T_int32, 1));
Expand All @@ -1527,7 +1522,7 @@ static jl_cgval_t emit_ccall(jl_codectx_t &ctx, jl_value_t **args, size_t nargs)
JL_GC_POP();
Value *ptls_pv = emit_bitcast(ctx, get_current_ptls(ctx), T_ppjlvalue);
const int nt_offset = offsetof(jl_tls_states_t, next_task);
Value *pnt = ctx.builder.CreateInBoundsGEP(ptls_pv, ConstantInt::get(T_size, nt_offset / sizeof(void*)));
Value *pnt = ctx.builder.CreateInBoundsGEP(T_pjlvalue, ptls_pv, ConstantInt::get(T_size, nt_offset / sizeof(void*)));
ctx.builder.CreateStore(emit_pointer_from_objref(ctx, boxed(ctx, argv[0])), pnt);
return ghostValue(jl_nothing_type);
}
Expand All @@ -1537,7 +1532,7 @@ static jl_cgval_t emit_ccall(jl_codectx_t &ctx, jl_value_t **args, size_t nargs)
JL_GC_POP();
ctx.builder.CreateCall(prepare_call(gcroot_flush_func));
Value *pdefer_sig = emit_defer_signal(ctx);
Value *defer_sig = ctx.builder.CreateLoad(pdefer_sig);
Value *defer_sig = ctx.builder.CreateLoad(T_sigatomic, pdefer_sig);
defer_sig = ctx.builder.CreateAdd(defer_sig, ConstantInt::get(T_sigatomic, 1));
ctx.builder.CreateStore(defer_sig, pdefer_sig);
emit_signal_fence(ctx);
Expand All @@ -1549,7 +1544,7 @@ static jl_cgval_t emit_ccall(jl_codectx_t &ctx, jl_value_t **args, size_t nargs)
JL_GC_POP();
ctx.builder.CreateCall(prepare_call(gcroot_flush_func));
Value *pdefer_sig = emit_defer_signal(ctx);
Value *defer_sig = ctx.builder.CreateLoad(pdefer_sig);
Value *defer_sig = ctx.builder.CreateLoad(T_sigatomic, pdefer_sig);
emit_signal_fence(ctx);
error_unless(ctx,
ctx.builder.CreateICmpNE(defer_sig, ConstantInt::get(T_sigatomic, 0)),
Expand All @@ -1566,6 +1561,7 @@ static jl_cgval_t emit_ccall(jl_codectx_t &ctx, jl_value_t **args, size_t nargs)
checkBB, contBB);
ctx.builder.SetInsertPoint(checkBB);
ctx.builder.CreateLoad(
T_size,
ctx.builder.CreateConstInBoundsGEP1_32(T_size, get_current_signal_page(ctx), -1),
true);
ctx.builder.CreateBr(contBB);
Expand Down Expand Up @@ -1725,8 +1721,8 @@ static jl_cgval_t emit_ccall(jl_codectx_t &ctx, jl_value_t **args, size_t nargs)
JL_GC_POP();
const int hash_offset = offsetof(jl_sym_t, hash);
Value *ph1 = emit_bitcast(ctx, decay_derived(ctx, boxed(ctx, val)), T_psize);
Value *ph2 = ctx.builder.CreateInBoundsGEP(ph1, ConstantInt::get(T_size, hash_offset / sizeof(size_t)));
LoadInst *hashval = ctx.builder.CreateAlignedLoad(ph2, Align(sizeof(size_t)));
Value *ph2 = ctx.builder.CreateInBoundsGEP(T_size, ph1, ConstantInt::get(T_size, hash_offset / sizeof(size_t)));
LoadInst *hashval = ctx.builder.CreateAlignedLoad(T_size, ph2, Align(sizeof(size_t)));
tbaa_decorate(tbaa_const, hashval);
return mark_or_box_ccall_result(ctx, hashval, retboxed, rt, unionall, static_rt);
}
Expand Down Expand Up @@ -1951,7 +1947,7 @@ jl_cgval_t function_sig_t::emit_a_ccall(
// something alloca'd above is SSA
if (static_rt)
return mark_julia_slot(result, rt, NULL, tbaa_stack);
result = ctx.builder.CreateLoad(result);
result = ctx.builder.CreateLoad(cast<PointerType>(result->getType())->getElementType(), result);
}
}
else {
Expand Down
49 changes: 26 additions & 23 deletions src/cgutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -795,19 +795,21 @@ static Value *emit_nthptr_addr(jl_codectx_t &ctx, Value *v, Value *idx)
idx);
}

static LoadInst *emit_nthptr_recast(jl_codectx_t &ctx, Value *v, Value *idx, MDNode *tbaa, Type *ptype)
static LoadInst *emit_nthptr_recast(jl_codectx_t &ctx, Value *v, Value *idx, MDNode *tbaa, Type *type)
{
// p = (jl_value_t**)v; *(ptype)&p[n]
// p = (jl_value_t**)v; *(type*)&p[n]
Value *vptr = emit_nthptr_addr(ctx, v, idx);
return cast<LoadInst>(tbaa_decorate(tbaa, ctx.builder.CreateLoad(emit_bitcast(ctx, vptr, ptype))));
return cast<LoadInst>(tbaa_decorate(tbaa, ctx.builder.CreateLoad(type,
emit_bitcast(ctx, vptr, PointerType::get(type, 0)))));
}

static LoadInst *emit_nthptr_recast(jl_codectx_t &ctx, Value *v, ssize_t n, MDNode *tbaa, Type *ptype)
static LoadInst *emit_nthptr_recast(jl_codectx_t &ctx, Value *v, ssize_t n, MDNode *tbaa, Type *type)
{
// p = (jl_value_t**)v; *(ptype)&p[n]
// p = (jl_value_t**)v; *(type*)&p[n]
Value *vptr = emit_nthptr_addr(ctx, v, n);
return cast<LoadInst>(tbaa_decorate(tbaa, ctx.builder.CreateLoad(emit_bitcast(ctx, vptr, ptype))));
}
return cast<LoadInst>(tbaa_decorate(tbaa, ctx.builder.CreateLoad(type,
emit_bitcast(ctx, vptr, PointerType::get(type, 0)))));
}

static Value *boxed(jl_codectx_t &ctx, const jl_cgval_t &v);

Expand Down Expand Up @@ -1506,7 +1508,7 @@ static jl_cgval_t typed_load(jl_codectx_t &ctx, Value *ptr, Value *idx_0based, j
alignment = sizeof(void*);
else if (!alignment)
alignment = julia_alignment(jltype);
LoadInst *load = ctx.builder.CreateAlignedLoad(data, Align(alignment), false);
LoadInst *load = ctx.builder.CreateAlignedLoad(elty, data, Align(alignment), false);
load->setOrdering(Order);
if (aliasscope)
load->setMetadata("alias.scope", aliasscope);
Expand All @@ -1519,7 +1521,7 @@ static jl_cgval_t typed_load(jl_codectx_t &ctx, Value *ptr, Value *idx_0based, j
instr = ctx.builder.CreateTrunc(instr, realelty);
if (intcast) {
ctx.builder.CreateStore(instr, ctx.builder.CreateBitCast(intcast, instr->getType()->getPointerTo()));
instr = ctx.builder.CreateLoad(intcast);
instr = ctx.builder.CreateLoad(intcast->getAllocatedType(), intcast);
}
if (maybe_null_if_boxed) {
Value *first_ptr = isboxed ? instr : extract_first_ptr(ctx, instr);
Expand Down Expand Up @@ -1586,7 +1588,7 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx,
return emit_new_struct(ctx, (jl_value_t*)rettyp, 2, argv);
}
}
Value *intcast = nullptr;
AllocaInst *intcast = nullptr;
if (!isboxed && Order != AtomicOrdering::NotAtomic && !elty->isIntOrPtrTy()) {
const DataLayout &DL = jl_data_layout;
unsigned nb = DL.getTypeSizeInBits(elty);
Expand Down Expand Up @@ -1736,7 +1738,7 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx,
if (intcast) {
ctx.builder.CreateStore(realCompare, ctx.builder.CreateBitCast(intcast, realCompare->getType()->getPointerTo()));
if (maybe_null_if_boxed)
realCompare = ctx.builder.CreateLoad(intcast);
realCompare = ctx.builder.CreateLoad(intcast->getAllocatedType(), intcast);
}
if (maybe_null_if_boxed) {
Value *first_ptr = isboxed ? Compare : extract_first_ptr(ctx, Compare);
Expand Down Expand Up @@ -1816,7 +1818,7 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx,
ctx.builder.CreateStore(realinstr, ctx.builder.CreateBitCast(intcast, realinstr->getType()->getPointerTo()));
oldval = mark_julia_slot(intcast, jltype, NULL, tbaa_stack);
if (maybe_null_if_boxed)
realinstr = ctx.builder.CreateLoad(intcast);
realinstr = ctx.builder.CreateLoad(intcast->getAllocatedType(), intcast);
}
else {
oldval = mark_julia_type(ctx, realinstr, isboxed, jltype);
Expand Down Expand Up @@ -1876,7 +1878,7 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx,
instr = ctx.builder.Insert(CastInst::Create(Instruction::Trunc, instr, realelty));
if (intcast) {
ctx.builder.CreateStore(instr, ctx.builder.CreateBitCast(intcast, instr->getType()->getPointerTo()));
instr = ctx.builder.CreateLoad(intcast);
instr = ctx.builder.CreateLoad(intcast->getAllocatedType(), intcast);
}
if (maybe_null_if_boxed) {
Value *first_ptr = isboxed ? instr : extract_first_ptr(ctx, instr);
Expand Down Expand Up @@ -1949,18 +1951,18 @@ static void emit_memcpy_llvm(jl_codectx_t &ctx, Value *dst, MDNode *tbaa_dst, Va
dstty = dstel->getPointerTo();
}

bool direct = false;
llvm::Type *directel = nullptr;
if (srcel->isSized() && srcel->isSingleValueType() && DL.getTypeStoreSize(srcel) == sz) {
direct = true;
directel = srcel;
dst = emit_bitcast(ctx, dst, srcty);
}
else if (dstel->isSized() && dstel->isSingleValueType() &&
DL.getTypeStoreSize(dstel) == sz) {
direct = true;
directel = dstel;
src = emit_bitcast(ctx, src, dstty);
}
if (direct) {
auto val = tbaa_decorate(tbaa_src, ctx.builder.CreateAlignedLoad(src, Align(align), is_volatile));
if (directel) {
auto val = tbaa_decorate(tbaa_src, ctx.builder.CreateAlignedLoad(directel, src, Align(align), is_volatile));
tbaa_decorate(tbaa_dst, ctx.builder.CreateAlignedStore(val, dst, Align(align), is_volatile));
return;
}
Expand Down Expand Up @@ -2430,7 +2432,7 @@ static Value *emit_arraysize(jl_codectx_t &ctx, const jl_cgval_t &tinfo, Value *
auto load = emit_nthptr_recast(ctx,
t,
ctx.builder.CreateAdd(dim, ConstantInt::get(dim->getType(), o)),
tbaa, T_psize);
tbaa, T_size);
MDBuilder MDB(jl_LLVMContext);
auto rng = MDB.createRange(V_size0, ConstantInt::get(T_size, arraytype_maxsize(tinfo.typ)));
load->setMetadata(LLVMContext::MD_range, rng);
Expand Down Expand Up @@ -2466,7 +2468,7 @@ static Value *emit_arraylen_prim(jl_codectx_t &ctx, const jl_cgval_t &tinfo)
Value *addr = ctx.builder.CreateStructGEP(jl_array_llvmt,
emit_bitcast(ctx, decay_derived(ctx, t), jl_parray_llvmt),
1); //index (not offset) of length field in jl_parray_llvmt
LoadInst *len = ctx.builder.CreateAlignedLoad(addr, Align(sizeof(size_t)));
LoadInst *len = ctx.builder.CreateAlignedLoad(T_size, addr, Align(sizeof(size_t)));
len->setOrdering(AtomicOrdering::NotAtomic);
MDBuilder MDB(jl_LLVMContext);
auto rng = MDB.createRange(V_size0, ConstantInt::get(T_size, arraytype_maxsize(tinfo.typ)));
Expand Down Expand Up @@ -2519,7 +2521,8 @@ static Value *emit_arrayptr_internal(jl_codectx_t &ctx, const jl_cgval_t &tinfo,
PointerType::get(PPT->getElementType(), AS),
PT->getAddressSpace()));
}
LoadInst *LI = ctx.builder.CreateAlignedLoad(addr, Align(sizeof(char*)));
LoadInst *LI = ctx.builder.CreateAlignedLoad(
cast<PointerType>(addr->getType())->getElementType(), addr, Align(sizeof(char*)));
LI->setOrdering(AtomicOrdering::NotAtomic);
LI->setMetadata(LLVMContext::MD_nonnull, MDNode::get(jl_LLVMContext, None));
tbaa_decorate(tbaa, LI);
Expand Down Expand Up @@ -2828,9 +2831,9 @@ static Value *as_value(jl_codectx_t &ctx, Type *to, const jl_cgval_t &v)
static Value *load_i8box(jl_codectx_t &ctx, Value *v, jl_datatype_t *ty)
{
auto jvar = ty == jl_int8_type ? jlboxed_int8_cache : jlboxed_uint8_cache;
Constant *gv = prepare_global_in(jl_Module, jvar);
GlobalVariable *gv = prepare_global_in(jl_Module, jvar);
Value *idx[] = {ConstantInt::get(T_int32, 0), ctx.builder.CreateZExt(v, T_int32)};
auto slot = ctx.builder.CreateInBoundsGEP(gv, idx);
auto slot = ctx.builder.CreateInBoundsGEP(gv->getType()->getElementType(), gv, idx);
return tbaa_decorate(tbaa_const, maybe_mark_load_dereferenceable(
ctx.builder.CreateAlignedLoad(T_pjlvalue, slot, Align(sizeof(void*))), false,
(jl_value_t*)ty));
Expand Down
Loading

0 comments on commit c36664e

Please sign in to comment.