Skip to content

Commit

Permalink
Merge pull request #22697 from JuliaLang/jn/compiler-fixup
Browse files Browse the repository at this point in the history
fix compile=all and codegen bugs

Ref #22697
(cherry picked from commit bdfe92f)
  • Loading branch information
vtjnash authored and ararslan committed Sep 11, 2017
1 parent 14c27d5 commit c78b071
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 88 deletions.
1 change: 0 additions & 1 deletion base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1027,7 +1027,6 @@ export
# loading source files
__precompile__,
evalfile,
include,
include_string,
include_dependency,
reload,
Expand Down
10 changes: 5 additions & 5 deletions src/ccall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -482,11 +482,11 @@ static Value *runtime_apply_type(jl_value_t *ty, jl_unionall_t *unionall, jl_cod
{
// box if concrete type was not statically known
Value *args[3];
args[0] = literal_pointer_val(ty);
args[1] = literal_pointer_val((jl_value_t*)ctx->linfo->def->sig);
args[2] = builder.CreateInBoundsGEP(
LLVM37_param(T_pjlvalue)
emit_bitcast(ctx->spvals_ptr, T_ppjlvalue),
args[0] = literal_pointer_val(ctx, ty);
args[1] = literal_pointer_val(ctx, (jl_value_t*)ctx.linfo->def.method->sig);
args[2] = ctx.builder.CreateInBoundsGEP(
T_prjlvalue,
ctx.spvals_ptr,
ConstantInt::get(T_size, sizeof(jl_svec_t) / sizeof(jl_value_t*)));
return builder.CreateCall(prepare_call(jlapplytype_func), makeArrayRef(args));
}
Expand Down
65 changes: 25 additions & 40 deletions src/cgutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,18 +114,15 @@ static DIType *julia_type_to_di(jl_value_t *jt, DIBuilder *dbuilder, bool isboxe
static DIType julia_type_to_di(jl_value_t *jt, DIBuilder *dbuilder, bool isboxed = false)
#endif
{
if (isboxed)
if (isboxed || !jl_is_datatype(jt))
return jl_pvalue_dillvmt;
jl_datatype_t *jdt = (jl_datatype_t*)jt;
// always return the boxed representation for types with hidden content
if (jl_is_abstracttype(jt) || !jl_is_datatype(jt) || jl_is_array_type(jt) ||
if (jl_is_abstracttype(jt) || jl_is_array_type(jt) ||
jt == (jl_value_t*)jl_sym_type || jt == (jl_value_t*)jl_module_type ||
jt == (jl_value_t*)jl_simplevector_type || jt == (jl_value_t*)jl_datatype_type ||
jt == (jl_value_t*)jl_method_instance_type)
return jl_pvalue_dillvmt;
if (jl_is_unionall(jt) || jl_is_typevar(jt))
return jl_pvalue_dillvmt;
assert(jl_is_datatype(jt));
jl_datatype_t *jdt = (jl_datatype_t*)jt;
if (jdt->ditype != NULL) {
#if JL_LLVM_VERSION >= 30700
DIType* t = (DIType*)jdt->ditype;
Expand Down Expand Up @@ -172,47 +169,35 @@ static DIType julia_type_to_di(jl_value_t *jt, DIBuilder *dbuilder, bool isboxed
return t;
#endif
}
#if JL_LLVM_VERSION >= 30700
else if (!jl_is_leaf_type(jt)) {
jdt->ditype = jl_pvalue_dillvmt;
return jl_pvalue_dillvmt;
}
else if (jl_is_structtype(jt)) {
jl_datatype_t *jst = (jl_datatype_t*)jt;
size_t ntypes = jl_datatype_nfields(jst);
if (jl_is_structtype(jt) && jdt->layout) {
size_t ntypes = jl_datatype_nfields(jdt);
const char *tname = jl_symbol_name(jdt->name->name);
std::stringstream unique_name;
unique_name << tname << "_" << globalUnique++;
llvm::DICompositeType *ct = dbuilder->createStructType(
NULL, // Scope
tname, // Name
NULL, // File
0, // LineNumber
jl_datatype_nbits(jdt), // SizeInBits
8 * jl_datatype_align(jdt), // AlignInBits
DIFlagZero, // Flags
NULL, // DerivedFrom
DINodeArray(), // Elements
dwarf::DW_LANG_Julia, // RuntimeLanguage
nullptr, // VTableHolder
unique_name.str() // UniqueIdentifier
);
NULL, // Scope
tname, // Name
NULL, // File
0, // LineNumber
jl_datatype_nbits(jdt), // SizeInBits
8 * jl_datatype_align(jdt), // AlignInBits
DIFlagZero, // Flags
NULL, // DerivedFrom
DINodeArray(), // Elements
dwarf::DW_LANG_Julia, // RuntimeLanguage
nullptr, // VTableHolder
unique_name.str() // UniqueIdentifier
);
jdt->ditype = ct;
std::vector<llvm::Metadata*> Elements;
for(unsigned i = 0; i < ntypes; i++)
Elements.push_back(julia_type_to_di(jl_svecref(jst->types,i),dbuilder,false));
for (unsigned i = 0; i < ntypes; i++)
Elements.push_back(julia_type_to_di(jl_svecref(jdt->types, i), dbuilder, false));
dbuilder->replaceArrays(ct, dbuilder->getOrCreateArray(ArrayRef<Metadata*>(Elements)));
return ct;
}
else {
assert(jl_is_datatype(jt));
jdt->ditype = dbuilder->createTypedef(jl_pvalue_dillvmt,
jdt->ditype = dbuilder->createTypedef(jl_pvalue_dillvmt,
jl_symbol_name(jdt->name->name), NULL, 0, NULL);
return (llvm::DIType*)jdt->ditype;
}
#endif
// TODO: Fixme
return jl_pvalue_dillvmt;
return (llvm::DIType*)jdt->ditype;
}

// --- emitting pointers directly into code ---
Expand Down Expand Up @@ -446,8 +431,8 @@ static Type *julia_struct_to_llvm(jl_value_t *jt, jl_unionall_t *ua, bool *isbox
if (jl_is_primitivetype(jt))
return bitstype_to_llvm(jt);
bool isTuple = jl_is_tuple_type(jt);
if ((isTuple || jl_is_structtype(jt)) && !jl_is_array_type(jt)) {
jl_datatype_t *jst = (jl_datatype_t*)jt;
jl_datatype_t *jst = (jl_datatype_t*)jt;
if (jl_is_structtype(jt) && !(jst->layout && jl_is_layout_opaque(jst->layout))) {
if (jst->struct_decl == NULL) {
size_t i, ntypes = jl_svec_len(jst->types);
if (ntypes == 0 || (jst->layout && jl_datatype_nbits(jst) == 0))
Expand Down Expand Up @@ -1084,7 +1069,7 @@ static void emit_typecheck(const jl_cgval_t &x, jl_value_t *type, const std::str

static void emit_leafcheck(Value *typ, const std::string &msg, jl_codectx_t *ctx)
{
assert(typ->getType() == T_pjlvalue);
assert(typ->getType() == T_prjlvalue);
emit_typecheck(mark_julia_type(typ, true, jl_any_type, ctx, false), (jl_value_t*)jl_datatype_type, msg, ctx);
Value *isleaf;
isleaf = builder.CreateConstInBoundsGEP1_32(LLVM37_param(T_int8) emit_bitcast(typ, T_pint8), offsetof(jl_datatype_t, isleaftype));
Expand Down
53 changes: 22 additions & 31 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3575,9 +3575,10 @@ static jl_cgval_t emit_sparam(size_t i, jl_codectx_t *ctx)
return mark_julia_const(e);
}
}
assert(ctx->spvals_ptr != NULL);
Value *bp = builder.CreateConstInBoundsGEP1_32(LLVM37_param(T_pjlvalue)
emit_bitcast(ctx->spvals_ptr, T_ppjlvalue),
assert(ctx.spvals_ptr != NULL);
Value *bp = ctx.builder.CreateConstInBoundsGEP1_32(
T_prjlvalue,
ctx.spvals_ptr,
i + sizeof(jl_svec_t) / sizeof(jl_value_t*));
return mark_julia_type(tbaa_decorate(tbaa_const, builder.CreateLoad(bp)), true, jl_any_type, ctx, false);
}
Expand Down Expand Up @@ -5098,26 +5099,15 @@ static jl_returninfo_t get_specsig_function(Module *M, const std::string &name,
return props;
}

#if JL_LLVM_VERSION >= 30700
static DISubroutineType *
#elif JL_LLVM_VERSION >= 30600
static DISubroutineType
#else
static DICompositeType
#endif
get_specsig_di(jl_value_t *sig,
#if JL_LLVM_VERSION >= 30700
DIFile *topfile,
#else
DIFile topfile,
#endif
DIBuilder &dbuilder)
get_specsig_di(jl_value_t *rt, jl_value_t *sig, DIFile *topfile, DIBuilder &dbuilder)
{
#if JL_LLVM_VERSION >= 30600
std::vector<Metadata*> ditypes(0);
#else
std::vector<Value*> ditypes(0);
#endif
Type *ty = julia_type_to_llvm(rt);
if (type_is_ghost(ty))
ditypes.push_back(nullptr);
else
ditypes.push_back(julia_type_to_di(rt, &dbuilder, false));
for (size_t i = 0; i < jl_nparams(sig); i++) {
jl_value_t *jt = jl_tparam(sig, i);
Type *ty = julia_type_to_llvm(jt);
Expand Down Expand Up @@ -5404,7 +5394,7 @@ static std::unique_ptr<Module> emit_function(
subrty = jl_di_func_sig;
}
else {
subrty = get_specsig_di(lam->specTypes, topfile, dbuilder);
subrty = get_specsig_di(lam->rettype, lam->specTypes, topfile, dbuilder);
}
SP = dbuilder.createFunction(CU,
dbgFuncName, // Name
Expand Down Expand Up @@ -5524,7 +5514,8 @@ static std::unique_ptr<Module> emit_function(
if (!specsig) {
Function::arg_iterator AI = f->arg_begin();
if (needsparams) {
ctx.spvals_ptr = &*AI++;
ctx.spvals_ptr = &*AI;
++AI;
}
fArg = &*AI++;
argArray = &*AI++;
Expand Down Expand Up @@ -6532,11 +6523,11 @@ static void init_julia_llvm_env(Module *m)
jl_init_jit(T_pjlvalue);

std::vector<Type*> ftargs(0);
ftargs.push_back(T_pjlvalue); // linfo->sparam_vals
ftargs.push_back(T_pjlvalue); // function
ftargs.push_back(T_ppjlvalue); // args[]
ftargs.push_back(T_int32); // nargs
jl_func_sig_sparams = FunctionType::get(T_pjlvalue, ftargs, false);
ftargs.push_back(T_pprjlvalue); // linfo->sparam_vals
ftargs.push_back(T_prjlvalue); // function
ftargs.push_back(T_pprjlvalue); // args[]
ftargs.push_back(T_int32); // nargs
jl_func_sig_sparams = FunctionType::get(T_prjlvalue, ftargs, false);
assert(jl_func_sig_sparams != NULL);
ftargs.erase(ftargs.begin()); // drop linfo->sparams_vals argument
jl_func_sig = FunctionType::get(T_pjlvalue, ftargs, false);
Expand Down Expand Up @@ -6939,11 +6930,11 @@ static void init_julia_llvm_env(Module *m)
add_named_global(jlsubtype_func, &jl_subtype);

std::vector<Type *> applytype_args(0);
applytype_args.push_back(T_pjlvalue);
applytype_args.push_back(T_pjlvalue);
applytype_args.push_back(T_ppjlvalue);
applytype_args.push_back(T_prjlvalue);
applytype_args.push_back(T_prjlvalue);
applytype_args.push_back(T_pprjlvalue);
jlapplytype_func =
Function::Create(FunctionType::get(T_pjlvalue, applytype_args, false),
Function::Create(FunctionType::get(T_prjlvalue, applytype_args, false),
Function::ExternalLinkage,
"jl_instantiate_type_in_env", m);
add_named_global(jlapplytype_func, &jl_instantiate_type_in_env);
Expand Down
2 changes: 1 addition & 1 deletion src/julia_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -933,8 +933,8 @@ STATIC_INLINE void *jl_get_frame_addr(void)
}

JL_DLLEXPORT jl_array_t *jl_array_cconvert_cstring(jl_array_t *a);
JL_DLLEXPORT void jl_depwarn_partial_indexing(size_t n);
void jl_depwarn(const char *msg, jl_value_t *sym);
void jl_depwarn_partial_indexing(size_t n);

int isabspath(const char *in);

Expand Down
28 changes: 19 additions & 9 deletions src/precompile.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,23 @@ void jl_write_compiler_output(void)
JL_GC_POP();
}

static int tupletype_any_bottom(jl_value_t *sig)
static int any_bottom_field(jl_value_t *typ)
{
sig = jl_unwrap_unionall(sig);
assert(jl_is_tuple_type(sig));
jl_svec_t *types = ((jl_tupletype_t*)sig)->types;
size_t i, l = jl_svec_len(types);
if (typ == jl_bottom_type)
return 1;
typ = jl_unwrap_unionall(typ);
if (jl_is_vararg_type(typ))
typ = jl_unwrap_vararg(typ);
if (!jl_is_datatype(typ))
return 0;
jl_svec_t *fields = ((jl_datatype_t*)typ)->types;
size_t i, l = jl_svec_len(fields);
if (l != ((jl_datatype_t*)typ)->ninitialized)
if (((jl_datatype_t*)typ)->name != jl_tuple_typename)
return 0;
for (i = 0; i < l; i++) {
if (jl_svecref(types, i) == jl_bottom_type)
jl_value_t *ft = jl_svecref(fields, i);
if (any_bottom_field(ft))
return 1;
}
return 0;
Expand Down Expand Up @@ -129,8 +138,7 @@ static void _compile_all_tvar_union(jl_value_t *methsig)
JL_CATCH {
goto getnext; // sigh, we found an invalid type signature. should we warn the user?
}
assert(jl_is_tuple_type(sig));
if (sig == jl_bottom_type || tupletype_any_bottom(sig))
if (any_bottom_field(sig))
goto getnext; // signature wouldn't be callable / is invalid -- skip it
if (jl_is_leaf_type(sig)) {
if (jl_compile_hint((jl_tupletype_t*)sig))
Expand Down Expand Up @@ -180,9 +188,11 @@ static void _compile_all_union(jl_value_t *sig)
++count_unions;
else if (ty == jl_bottom_type)
return; // why does this method exist?
else if (!jl_is_leaf_type(ty) && !jl_has_free_typevars(ty))
return; // no amount of union splitting will make this a leaftype signature
}

if (count_unions == 0) {
if (count_unions == 0 || count_unions >= 6) {
_compile_all_tvar_union(sig);
return;
}
Expand Down
2 changes: 1 addition & 1 deletion src/rtutils.c
Original file line number Diff line number Diff line change
Expand Up @@ -992,7 +992,7 @@ void jl_depwarn(const char *msg, jl_value_t *sym)
JL_GC_POP();
}

void jl_depwarn_partial_indexing(size_t n)
JL_DLLEXPORT void jl_depwarn_partial_indexing(size_t n)
{
static jl_value_t *depwarn_func = NULL;
if (!depwarn_func && jl_base_module) {
Expand Down

0 comments on commit c78b071

Please sign in to comment.