Skip to content

Commit

Permalink
(disabled) Revert "Revert "partially fix #2149, partially support more
Browse files Browse the repository at this point in the history
efficient struct return (disabled). unfortunately this would break some
struct returns while making other work -- this needs to be selectively
enabled for different possible return types"

This reverts commit 4fa9364.

Conflicts:
	src/ccall.cpp
  • Loading branch information
vtjnash committed Jun 15, 2013
1 parent 049bf7b commit 43816c8
Showing 1 changed file with 60 additions and 25 deletions.
85 changes: 60 additions & 25 deletions src/ccall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -315,14 +315,14 @@ typedef struct {
static native_sym_arg_t interpret_symbol_arg(jl_value_t *arg, jl_codectx_t *ctx, const char *fname)
{
jl_value_t *ptr = NULL;
Value *jl_ptr = NULL;
Value *jl_ptr=NULL;

ptr = static_eval(arg, ctx, true);
if (ptr == NULL) {
jl_value_t *ptr_ty = expr_type(arg, ctx);
Value *arg1 = emit_unboxed(arg, ctx);
if (!jl_is_cpointer_type(ptr_ty)) {
emit_cpointercheck(arg1,
emit_cpointercheck(arg1,
!strcmp(fname,"ccall") ?
"ccall: first argument not a pointer or valid constant expression" :
"cglobal: first argument not a pointer or valid constant expression",
Expand All @@ -331,8 +331,8 @@ static native_sym_arg_t interpret_symbol_arg(jl_value_t *arg, jl_codectx_t *ctx,
jl_ptr = emit_unbox(T_size, T_psize, arg1);
}

void *fptr = NULL;
char *f_name = NULL, *f_lib = NULL;
void *fptr=NULL;
char *f_name=NULL, *f_lib=NULL;
if (ptr != NULL) {
if (jl_is_tuple(ptr) && jl_tuple_len(ptr)==1) {
ptr = jl_tupleref(ptr,0);
Expand All @@ -344,8 +344,8 @@ static native_sym_arg_t interpret_symbol_arg(jl_value_t *arg, jl_codectx_t *ctx,
if (f_name != NULL) {
// just symbol, default to JuliaDLHandle
#ifdef _OS_WINDOWS_
//TODO: store the f_lib name instead of fptr
fptr = jl_dlsym_win32(f_name);
//TODO: store the f_lib name instead of fptr
fptr = jl_dlsym_win32(f_name);
#else
// will look in process symbol table
#endif
Expand Down Expand Up @@ -478,19 +478,30 @@ static Value *emit_ccall(jl_value_t **args, size_t nargs, jl_codectx_t *ctx)
JL_TYPECHK(ccall, type, rt);
JL_TYPECHK(ccall, tuple, at);
JL_TYPECHK(ccall, type, at);
jl_tuple_t *tt = (jl_tuple_t*)at;
std::vector<Type *> fargt(0);
std::vector<Type *> fargt_sig(0);
Type *lrt = julia_struct_to_llvm(rt);
if (lrt == NULL) {
JL_GC_POP();
emit_error("ccall: return type doesn't correspond to a C type", ctx);
return literal_pointer_val(jl_nothing);
}
jl_tuple_t *tt = (jl_tuple_t*)at;
std::vector<Type *> fargt(0);
std::vector<Type *> fargt_sig(0);
std::vector<AttributeWithIndex> attrs;
int sret = 0;
if (0 && lrt->isStructTy()) {
#ifdef LLVM32
attrs.push_back(AttributeWithIndex::get(getGlobalContext(), 1, Attributes::StructRet));
#else
attrs.push_back(AttributeWithIndex::get(1, Attribute::StructRet));
#endif
fargt_sig.push_back(PointerType::get(lrt,0));
lrt = T_void;
sret = 1;
}
size_t i;
bool isVa = false;
size_t nargt = jl_tuple_len(tt);
std::vector<AttributeWithIndex> attrs;

for(i=0; i < nargt; i++) {
jl_value_t *tti = jl_tupleref(tt,i);
Expand All @@ -514,15 +525,14 @@ static Value *emit_ccall(jl_value_t **args, size_t nargs, jl_codectx_t *ctx)
av = Attributes::SExt;
else
av = Attributes::ZExt;
attrs.push_back(AttributeWithIndex::get(getGlobalContext(), i+1,
ArrayRef<Attributes::AttrVal>(&av, 1)));
attrs.push_back(AttributeWithIndex::get(getGlobalContext(), i+1+sret, av));
#else
Attribute::AttrConst av;
if (jl_signed_type && jl_subtype(tti, jl_signed_type, 0))
av = Attribute::SExt;
else
av = Attribute::ZExt;
attrs.push_back(AttributeWithIndex::get(i+1, av));
attrs.push_back(AttributeWithIndex::get(i+1+sret, av));
#endif
}
}
Expand All @@ -536,6 +546,14 @@ static Value *emit_ccall(jl_value_t **args, size_t nargs, jl_codectx_t *ctx)
emit_error(msg.str(), ctx);
return literal_pointer_val(jl_nothing);
}
if (0 && t->isStructTy()) {
t = PointerType::get(t,0);
#ifdef LLVM32
attrs.push_back(AttributeWithIndex::get(getGlobalContext(), i+1+sret, Attributes::ByVal));
#else
attrs.push_back(AttributeWithIndex::get(i+1, Attribute::ByVal));
#endif
}
fargt.push_back(t);
if (!isVa)
fargt_sig.push_back(t);
Expand Down Expand Up @@ -640,7 +658,22 @@ static Value *emit_ccall(jl_value_t **args, size_t nargs, jl_codectx_t *ctx)
}

// emit arguments
Value *argvals[(nargs-3)/2];
Value *argvals[(nargs-3)/2 + sret];
Value *result;
if (sret) {
assert(jl_is_structtype(rt));
result = builder.CreateCall(
jlallocobj_func,
ConstantInt::get(T_size,
sizeof(void*)+((jl_datatype_t*)rt)->size));
//TODO: Fill type pointer fields with C_NULL's
builder.CreateStore(
literal_pointer_val((jl_value_t*)rt),
emit_nthptr_addr(result, (size_t)0));
argvals[0] = builder.CreateBitCast(
emit_nthptr_addr(result, (size_t)1),
fargt_sig[0]);
}
int last_depth = ctx->argDepth;
int nargty = jl_tuple_len(tt);
bool needTempSpace = false;
Expand All @@ -664,7 +697,7 @@ static Value *emit_ccall(jl_value_t **args, size_t nargs, jl_codectx_t *ctx)
}
Value *arg;
if (largty == jl_pvalue_llvmt ||
largty->isStructTy()) {
largty->isStructTy()) {
arg = emit_expr(argi, ctx, true);
}
else {
Expand All @@ -686,8 +719,8 @@ static Value *emit_ccall(jl_value_t **args, size_t nargs, jl_codectx_t *ctx)
#endif

bool mightNeed=false;
argvals[ai] = julia_to_native(largty, jargty, arg, argi, addressOf,
ai+1, ctx, &mightNeed);
argvals[ai+sret] = julia_to_native(largty, jargty, arg, argi, addressOf,
ai+1, ctx, &mightNeed);
needTempSpace |= mightNeed;
}
if (needTempSpace) {
Expand All @@ -703,16 +736,18 @@ static Value *emit_ccall(jl_value_t **args, size_t nargs, jl_codectx_t *ctx)
instList.insertAfter((Instruction*)saveloc, (Instruction*)stacksave);
}
// the actual call
Value *result = builder.CreateCall(llvmf,
ArrayRef<Value*>(&argvals[0],(nargs-3)/2));
if (cc != CallingConv::C)
((CallInst*)result)->setCallingConv(cc);

Value *ret = builder.CreateCall(
llvmf,
ArrayRef<Value*>(&argvals[0],(nargs-3)/2+sret));
#ifdef LLVM32
((CallInst*)result)->setAttributes(AttrListPtr::get(getGlobalContext(), ArrayRef<AttributeWithIndex>(attrs)));
((CallInst*)ret)->setAttributes(AttrListPtr::get(getGlobalContext(), ArrayRef<AttributeWithIndex>(attrs)));
#else
((CallInst*)result)->setAttributes(AttrListPtr::get(attrs.data(),attrs.size()));
((CallInst*)ret)->setAttributes(AttrListPtr::get(attrs.data(),attrs.size()));
#endif
if (cc != CallingConv::C)
((CallInst*)ret)->setCallingConv(cc);
if (!sret)
result = ret;
if (needTempSpace) {
// restore temp argument area stack pointer
assert(saveloc != NULL);
Expand All @@ -732,7 +767,7 @@ static Value *emit_ccall(jl_value_t **args, size_t nargs, jl_codectx_t *ctx)
}

JL_GC_POP();
if (lrt == T_void)
if (!sret && lrt == T_void)
return literal_pointer_val((jl_value_t*)jl_nothing);
if (lrt->isStructTy()) {
//fprintf(stderr, "ccall rt: %s -> %s\n", f_name, ((jl_tag_type_t*)rt)->name->name->name);
Expand Down

0 comments on commit 43816c8

Please sign in to comment.