Skip to content

Commit

Permalink
fix latest LLVM 11 compatibility issues (JuliaLang#35329)
Browse files Browse the repository at this point in the history
* fix latest LLVM 11 compatibility issues

Changes in LLVM:
- `CompositeType` and `SequentialType` classes have been removed
- `FileLineInfoSpecifier::Default` has been renamed to `RawValue`
- `CreateMemCpy` now takes `MaybeAlign`s instead of `unsigned`s
- deprecated overloads of `IRBuilder::CreateCall` and `CallInst::Create` have
  been removed
- `CallSite` class has been removed

Co-authored-by: Valentin Churavy <[email protected]>
  • Loading branch information
yhls and vchuravy committed Apr 22, 2020
1 parent de04210 commit 098ef24
Show file tree
Hide file tree
Showing 8 changed files with 166 additions and 90 deletions.
14 changes: 12 additions & 2 deletions src/ccall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,9 @@ static GlobalVariable *emit_plt_thunk(
SmallVector<Value*, 16> args;
for (Function::arg_iterator arg = plt->arg_begin(), arg_e = plt->arg_end(); arg != arg_e; ++arg)
args.push_back(&*arg);
CallInst *ret = irbuilder.CreateCall(ptr, ArrayRef<Value*>(args));
CallInst *ret = irbuilder.CreateCall(
cast<FunctionType>(ptr->getType()->getPointerElementType()),
ptr, ArrayRef<Value*>(args));
ret->setAttributes(attrs);
if (cc != CallingConv::C)
ret->setCallingConv(cc);
Expand Down Expand Up @@ -1029,7 +1031,7 @@ static jl_cgval_t emit_llvmcall(jl_codectx_t &ctx, jl_value_t **args, size_t nar
std::stringstream name;
name << "jl_llvmcall" << llvmcallnumbering++;
f->setName(name.str());
f = cast<Function>(prepare_call(function_proto(f)));
f = cast<Function>(prepare_call(function_proto(f)).getCallee());
}
else {
f->setLinkage(GlobalValue::LinkOnceODRLinkage);
Expand Down Expand Up @@ -1710,11 +1712,19 @@ static jl_cgval_t emit_ccall(jl_codectx_t &ctx, jl_value_t **args, size_t nargs)

ctx.builder.CreateMemCpy(
ctx.builder.CreateIntToPtr(destp, T_pint8),
#if JL_LLVM_VERSION >= 110000
MaybeAlign(1),
#else
1,
#endif
ctx.builder.CreateIntToPtr(
emit_unbox(ctx, T_size, src, (jl_value_t*)jl_voidpointer_type),
T_pint8),
#if JL_LLVM_VERSION >= 110000
MaybeAlign(0),
#else
0,
#endif
emit_unbox(ctx, T_size, n, (jl_value_t*)jl_ulong_type),
false);
JL_GC_POP();
Expand Down
29 changes: 23 additions & 6 deletions src/cgutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,18 @@ static Function *function_proto(Function *F, Module *M = nullptr)
}

#define prepare_call(Callee) prepare_call_in(jl_Module, (Callee))
static Value *prepare_call_in(Module *M, Value *Callee)
static FunctionCallee prepare_call_in(Module *M, Value *Callee)
{
if (Function *F = dyn_cast<Function>(Callee)) {
GlobalValue *local = M->getNamedValue(Callee->getName());
if (!local) {
local = function_proto(F, M);
}
return local;
Callee = local;
}
return Callee;
FunctionType *FnTy = cast<FunctionType>(
Callee->getType()->getPointerElementType());
return {FnTy, Callee};
}

// Take an arbitrary untracked value and make it gc-tracked
Expand Down Expand Up @@ -1341,9 +1343,16 @@ static void emit_write_multibarrier(jl_codectx_t&, Value*, Value*);

std::vector<unsigned> first_ptr(Type *T)
{
if (isa<CompositeType>(T)) {
if (!isa<StructType>(T) && cast<SequentialType>(T)->getNumElements() == 0)
return {};
if (isa<StructType>(T) || isa<ArrayType>(T) || isa<VectorType>(T)) {
if (!isa<StructType>(T)) {
uint64_t num_elements;
if (auto *AT = dyn_cast<ArrayType>(T))
num_elements = AT->getNumElements();
else
num_elements = cast<VectorType>(T)->getNumElements();
if (num_elements == 0)
return {};
}
unsigned i = 0;
for (Type *ElTy : T->subtypes()) {
if (isa<PointerType>(ElTy) && ElTy->getPointerAddressSpace() == AddressSpace::Tracked) {
Expand Down Expand Up @@ -1524,7 +1533,11 @@ static void emit_memcpy_llvm(jl_codectx_t &ctx, Value *dst, MDNode *tbaa_dst, Va
// for the load part (x.tbaa) and the store part (tbaa_stack).
// since the tbaa lattice has to be a tree we have unfortunately
// x.tbaa ∪ tbaa_stack = tbaa_root if x.tbaa != tbaa_stack
#if JL_LLVM_VERSION >= 110000
ctx.builder.CreateMemCpy(dst, MaybeAlign(align), src, MaybeAlign(0), sz, is_volatile, MDNode::getMostGenericTBAA(tbaa_dst, tbaa_src));
#else
ctx.builder.CreateMemCpy(dst, align, src, 0, sz, is_volatile, MDNode::getMostGenericTBAA(tbaa_dst, tbaa_src));
#endif
}

static void emit_memcpy_llvm(jl_codectx_t &ctx, Value *dst, MDNode *tbaa_dst, Value *src, MDNode *tbaa_src,
Expand All @@ -1534,7 +1547,11 @@ static void emit_memcpy_llvm(jl_codectx_t &ctx, Value *dst, MDNode *tbaa_dst, Va
emit_memcpy_llvm(ctx, dst, tbaa_dst, src, tbaa_src, const_sz->getZExtValue(), align, is_volatile);
return;
}
#if JL_LLVM_VERSION >= 110000
ctx.builder.CreateMemCpy(dst, MaybeAlign(align), src, MaybeAlign(0), sz, is_volatile, MDNode::getMostGenericTBAA(tbaa_dst, tbaa_src));
#else
ctx.builder.CreateMemCpy(dst, align, src, 0, sz, is_volatile, MDNode::getMostGenericTBAA(tbaa_dst, tbaa_src));
#endif
}

template<typename T1>
Expand Down
41 changes: 24 additions & 17 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2616,7 +2616,7 @@ static CallInst *emit_jlcall(jl_codectx_t &ctx, Value *theFptr, Value *theF,
}
FunctionType *FTy = FunctionType::get(T_prjlvalue, argsT, false);
CallInst *result = ctx.builder.CreateCall(FTy,
ctx.builder.CreateBitCast(prepare_call(theFptr), FTy->getPointerTo()),
ctx.builder.CreateBitCast(prepare_call(theFptr).getCallee(), FTy->getPointerTo()),
theArgs);
add_return_attr(result, Attribute::NonNull);
result->setCallingConv(cc);
Expand Down Expand Up @@ -2838,7 +2838,7 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, jl_expr_t *ex, jl_value_t *rt)
}
}
if (!handled) {
Value *r = emit_jlcall(ctx, prepare_call(jlinvoke_func), boxed(ctx, lival), argv, nargs, JLCALL_F2_CC);
Value *r = emit_jlcall(ctx, prepare_call(jlinvoke_func).getCallee(), boxed(ctx, lival), argv, nargs, JLCALL_F2_CC);
result = mark_julia_type(ctx, r, true, rt);
}
if (result.typ == jl_bottom_type)
Expand Down Expand Up @@ -3266,7 +3266,11 @@ static void emit_phinode_assign(jl_codectx_t &ctx, ssize_t idx, jl_value_t *r)
Value *isboxed = ctx.builder.CreateICmpNE(
ctx.builder.CreateAnd(Tindex_phi, ConstantInt::get(T_int8, 0x80)),
ConstantInt::get(T_int8, 0));
#if JL_LLVM_VERSION >= 110000
ctx.builder.CreateMemCpy(phi, MaybeAlign(min_align), dest, MaybeAlign(0), nbytes, false);
#else
ctx.builder.CreateMemCpy(phi, min_align, dest, 0, nbytes, false);
#endif
ctx.builder.CreateLifetimeEnd(dest);
Value *ptr = ctx.builder.CreateSelect(isboxed,
maybe_bitcast(ctx, decay_derived(ptr_phi), T_pint8),
Expand Down Expand Up @@ -3306,9 +3310,15 @@ static void emit_phinode_assign(jl_codectx_t &ctx, ssize_t idx, jl_value_t *r)
// here it's moved into phi in the successor (from dest)
dest = emit_static_alloca(ctx, vtype);
Value *phi = emit_static_alloca(ctx, vtype);
#if JL_LLVM_VERSION >= 110000
ctx.builder.CreateMemCpy(phi, MaybeAlign(julia_alignment(phiType)),
dest, MaybeAlign(0),
jl_datatype_size(phiType), false);
#else
ctx.builder.CreateMemCpy(phi, julia_alignment(phiType),
dest, 0,
jl_datatype_size(phiType), false);
#endif
ctx.builder.CreateLifetimeEnd(dest);
slot = mark_julia_slot(phi, phiType, NULL, tbaa_stack);
}
Expand Down Expand Up @@ -3893,26 +3903,21 @@ static Function *emit_tojlinvoke(jl_code_instance_t *codeinst, Module *M, jl_cod
ctx.f = f; // for jl_Module
BasicBlock *b0 = BasicBlock::Create(jl_LLVMContext, "top", f);
ctx.builder.SetInsertPoint(b0);
Value *theFptr;
FunctionCallee theFunc;
Value *theFarg;
if (codeinst->invoke != NULL) {
StringRef theFptrName = jl_ExecutionEngine->getFunctionAtAddress((uintptr_t)codeinst->invoke, codeinst);
theFptr = M->getOrInsertFunction(theFptrName, jlinvoke_func->getFunctionType())
#if JL_LLVM_VERSION >= 90000
.getCallee();
#else
;
#endif
theFunc = M->getOrInsertFunction(theFptrName, jlinvoke_func->getFunctionType());
theFarg = literal_pointer_val(ctx, (jl_value_t*)codeinst);
}
else {
theFptr = prepare_call(jlinvoke_func);
theFunc = prepare_call(jlinvoke_func);
theFarg = literal_pointer_val(ctx, (jl_value_t*)codeinst->def);
}
theFarg = maybe_decay_untracked(theFarg);
auto args = f->arg_begin();
CallInst *r = ctx.builder.CreateCall(theFptr, { &*args, &*++args, &*++args, theFarg });
r->setAttributes(cast<Function>(theFptr)->getAttributes());
CallInst *r = ctx.builder.CreateCall(theFunc, { &*args, &*++args, &*++args, theFarg });
r->setAttributes(cast<Function>(theFunc.getCallee())->getAttributes());
ctx.builder.CreateRet(r);
return f;
}
Expand Down Expand Up @@ -4336,7 +4341,7 @@ static Function* gen_cfun_wrapper(
ctx.builder.CreateBr(b_after);
ctx.builder.SetInsertPoint(b_generic);
}
Value *ret = emit_jlcall(ctx, prepare_call(jlapplygeneric_func), NULL, inputargs, nargs + 1, JLCALL_F_CC);
Value *ret = emit_jlcall(ctx, prepare_call(jlapplygeneric_func).getCallee(), NULL, inputargs, nargs + 1, JLCALL_F_CC);
if (age_ok) {
ctx.builder.CreateBr(b_after);
ctx.builder.SetInsertPoint(b_after);
Expand Down Expand Up @@ -4418,7 +4423,9 @@ static Function* gen_cfun_wrapper(
emit_cfunc_invalidate(gf_thunk, returninfo.cc, returninfo.return_roots, lam->specTypes, codeinst->rettype, nargs + 1, ctx.emission_context);
theFptr = ctx.builder.CreateSelect(age_ok, theFptr, gf_thunk);
}
CallInst *call = ctx.builder.CreateCall(theFptr, ArrayRef<Value*>(args));
CallInst *call = ctx.builder.CreateCall(
cast<FunctionType>(theFptr->getType()->getPointerElementType()),
theFptr, ArrayRef<Value*>(args));
call->setAttributes(returninfo.decl->getAttributes());
switch (returninfo.cc) {
case jl_returninfo_t::Boxed:
Expand Down Expand Up @@ -5691,7 +5698,7 @@ static std::pair<std::unique_ptr<Module>, jl_llvm_functions_t>
emit_varinfo_assign(ctx, vi, tuple);
}
else {
restTuple = emit_jlcall(ctx, prepare_call(jltuple_func), maybe_decay_untracked(V_null),
restTuple = emit_jlcall(ctx, prepare_call(jltuple_func).getCallee(), maybe_decay_untracked(V_null),
vargs, ctx.nvargs, JLCALL_F_CC);
jl_cgval_t tuple = mark_julia_type(ctx, restTuple, true, vi.value.typ);
emit_varinfo_assign(ctx, vi, tuple);
Expand Down Expand Up @@ -6400,12 +6407,12 @@ static std::pair<std::unique_ptr<Module>, jl_llvm_functions_t>
bool in_prologue = true;
for (auto &BB : *ctx.f) {
for (auto &I : BB) {
CallSite call(&I);
CallBase *call = dyn_cast<CallBase>(&I);
if (call && !I.getDebugLoc()) {
// LLVM Verifier: inlinable function call in a function with debug info must have a !dbg location
// make sure that anything we attempt to call has some inlining info, just in case optimization messed up
// (except if we know that it is an intrinsic used in our prologue, which should never have its own debug subprogram)
Function *F = call.getCalledFunction();
Function *F = call->getCalledFunction();
if (!in_prologue || !F || !(F->isIntrinsic() || F->getName().startswith("julia.") || &I == restTuple)) {
I.setDebugLoc(topdebugloc);
}
Expand Down
9 changes: 7 additions & 2 deletions src/disasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -900,8 +900,13 @@ static void jl_dump_asm_internal(
if (pass != 0 && nextLineAddr != (uint64_t)-1 && Index + Fptr + slide == nextLineAddr) {
if (di_ctx) {
std::string buf;
DILineInfoSpecifier infoSpec(DILineInfoSpecifier::FileLineInfoKind::Default,
DILineInfoSpecifier::FunctionNameKind::ShortName);
DILineInfoSpecifier infoSpec(
#if JL_LLVM_VERSION >= 110000
DILineInfoSpecifier::FileLineInfoKind::RawValue,
#else
DILineInfoSpecifier::FileLineInfoKind::Default,
#endif
DILineInfoSpecifier::FunctionNameKind::ShortName);
DIInliningInfo dbg = di_ctx->getInliningInfoForAddress(makeAddress(Section, Index + Fptr + slide), infoSpec);
if (dbg.getNumberOfFrames()) {
dbgctx.emit_lineinfo(buf, dbg);
Expand Down
42 changes: 23 additions & 19 deletions src/intrinsics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,6 @@ static Constant *julia_const_to_llvm(jl_codectx_t &ctx, const void *ptr, jl_data
return ConstantInt::get(lt, val);
}

CompositeType *lct = cast<CompositeType>(lt);
size_t nf = jl_datatype_nfields(bt);
std::vector<Constant*> fields(0);
for (size_t i = 0; i < nf; i++) {
Expand All @@ -200,7 +199,12 @@ static Constant *julia_const_to_llvm(jl_codectx_t &ctx, const void *ptr, jl_data
assert(!jl_field_isptr(bt, i));
unsigned llvm_idx = isa<StructType>(lt) ? convert_struct_offset(lt, offs) : i;
while (fields.size() < llvm_idx)
fields.push_back(UndefValue::get(lct->getTypeAtIndex(fields.size())));
fields.push_back(
#if JL_LLVM_VERSION >= 110000
UndefValue::get(GetElementPtrInst::getTypeAtIndex(lt, fields.size())));
#else
UndefValue::get(cast<CompositeType>(lt)->getTypeAtIndex(fields.size())));
#endif
const uint8_t *ov = (const uint8_t*)ptr + offs;
if (jl_is_uniontype(ft)) {
// compute the same type layout as julia_struct_to_llvm
Expand Down Expand Up @@ -255,11 +259,11 @@ static Constant *julia_const_to_llvm(jl_codectx_t &ctx, const void *ptr, jl_data
}
}

if (lct->isVectorTy())
if (lt->isVectorTy())
return ConstantVector::get(fields);
if (StructType *st = dyn_cast<StructType>(lct))
if (StructType *st = dyn_cast<StructType>(lt))
return ConstantStruct::get(st, fields);
ArrayType *at = cast<ArrayType>(lct);
ArrayType *at = cast<ArrayType>(lt);
return ConstantArray::get(at, fields);
}

Expand Down Expand Up @@ -410,7 +414,7 @@ static jl_value_t *staticeval_bitstype(const jl_cgval_t &targ)

static jl_cgval_t emit_runtime_call(jl_codectx_t &ctx, JL_I::intrinsic f, const jl_cgval_t *argv, size_t nargs)
{
Value *func = prepare_call(runtime_func[f]);
FunctionCallee func = prepare_call(runtime_func[f]);
Value **argvalues = (Value**)alloca(sizeof(Value*) * nargs);
for (size_t i = 0; i < nargs; ++i) {
argvalues[i] = boxed(ctx, argv[i]);
Expand Down Expand Up @@ -1055,7 +1059,7 @@ static Value *emit_untyped_intrinsic(jl_codectx_t &ctx, intrinsic f, Value **arg
case fma_float: {
assert(y->getType() == x->getType());
assert(z->getType() == y->getType());
Value *fmaintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::fma, makeArrayRef(t));
FunctionCallee fmaintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::fma, makeArrayRef(t));
return ctx.builder.CreateCall(fmaintr, {x, y, z});
}
case muladd_float: {
Expand Down Expand Up @@ -1085,7 +1089,7 @@ static Value *emit_untyped_intrinsic(jl_codectx_t &ctx, intrinsic f, Value **arg
(f == checked_smul_int ?
Intrinsic::smul_with_overflow :
Intrinsic::umul_with_overflow)))));
Value *intr = Intrinsic::getDeclaration(jl_Module, intr_id, makeArrayRef(t));
FunctionCallee intr = Intrinsic::getDeclaration(jl_Module, intr_id, makeArrayRef(t));
Value *res = ctx.builder.CreateCall(intr, {x, y});
Value *val = ctx.builder.CreateExtractValue(res, ArrayRef<unsigned>(0));
Value *obit = ctx.builder.CreateExtractValue(res, ArrayRef<unsigned>(1));
Expand Down Expand Up @@ -1202,26 +1206,26 @@ static Value *emit_untyped_intrinsic(jl_codectx_t &ctx, intrinsic f, Value **arg
ctx.builder.CreateAShr(x, uint_cnvt(ctx, t, y)));

case bswap_int: {
Value *bswapintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::bswap, makeArrayRef(t));
FunctionCallee bswapintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::bswap, makeArrayRef(t));
return ctx.builder.CreateCall(bswapintr, x);
}
case ctpop_int: {
Value *ctpopintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::ctpop, makeArrayRef(t));
FunctionCallee ctpopintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::ctpop, makeArrayRef(t));
return ctx.builder.CreateCall(ctpopintr, x);
}
case ctlz_int: {
Value *ctlz = Intrinsic::getDeclaration(jl_Module, Intrinsic::ctlz, makeArrayRef(t));
FunctionCallee ctlz = Intrinsic::getDeclaration(jl_Module, Intrinsic::ctlz, makeArrayRef(t));
y = ConstantInt::get(T_int1, 0);
return ctx.builder.CreateCall(ctlz, {x, y});
}
case cttz_int: {
Value *cttz = Intrinsic::getDeclaration(jl_Module, Intrinsic::cttz, makeArrayRef(t));
FunctionCallee cttz = Intrinsic::getDeclaration(jl_Module, Intrinsic::cttz, makeArrayRef(t));
y = ConstantInt::get(T_int1, 0);
return ctx.builder.CreateCall(cttz, {x, y});
}

case abs_float: {
Value *absintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::fabs, makeArrayRef(t));
FunctionCallee absintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::fabs, makeArrayRef(t));
return ctx.builder.CreateCall(absintr, x);
}
case copysign_float: {
Expand Down Expand Up @@ -1250,27 +1254,27 @@ static Value *emit_untyped_intrinsic(jl_codectx_t &ctx, intrinsic f, Value **arg
return ctx.builder.CreateXor(ctx.builder.CreateAdd(x, tmp), tmp);
}
case ceil_llvm: {
Value *ceilintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::ceil, makeArrayRef(t));
FunctionCallee ceilintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::ceil, makeArrayRef(t));
return ctx.builder.CreateCall(ceilintr, x);
}
case floor_llvm: {
Value *floorintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::floor, makeArrayRef(t));
FunctionCallee floorintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::floor, makeArrayRef(t));
return ctx.builder.CreateCall(floorintr, x);
}
case trunc_llvm: {
Value *truncintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::trunc, makeArrayRef(t));
FunctionCallee truncintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::trunc, makeArrayRef(t));
return ctx.builder.CreateCall(truncintr, x);
}
case rint_llvm: {
Value *rintintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::rint, makeArrayRef(t));
FunctionCallee rintintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::rint, makeArrayRef(t));
return ctx.builder.CreateCall(rintintr, x);
}
case sqrt_llvm: {
Value *sqrtintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::sqrt, makeArrayRef(t));
FunctionCallee sqrtintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::sqrt, makeArrayRef(t));
return ctx.builder.CreateCall(sqrtintr, x);
}
case sqrt_llvm_fast: {
Value *sqrtintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::sqrt, makeArrayRef(t));
FunctionCallee sqrtintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::sqrt, makeArrayRef(t));
return math_builder(ctx, true)().CreateCall(sqrtintr, x);
}

Expand Down
6 changes: 5 additions & 1 deletion src/jitlayers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,11 @@ void JuliaOJIT::DebugObjectRegistrar::registerObject(RTDyldObjHandleT H, const O
// record all of the exported symbols defined in this object
// in the primary hash table for the enclosing JIT
for (auto &Symbol : Object->symbols()) {
auto Flags = Symbol.getFlags();
#if JL_LLVM_VERSION >= 110000
uint32_t Flags = Symbol.getFlags().get();
#else
uint32_t Flags = Symbol.getFlags();
#endif
if (Flags & object::BasicSymbolRef::SF_Undefined)
continue;
if (!(Flags & object::BasicSymbolRef::SF_Exported))
Expand Down
Loading

0 comments on commit 098ef24

Please sign in to comment.