Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tuples made me sad (so I fixed them) #4042

Merged
merged 28 commits into from
Dec 7, 2013
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
9f2002c
Pass tuples unboxed if possible
Keno Aug 11, 2013
793562b
All tests pass
Keno Aug 12, 2013
9bfd041
Specialize more functions
Keno Aug 12, 2013
4917312
bugfixes
Keno Aug 13, 2013
2ffa794
Remove unnessecary pto argument from emit_unbox
Keno Aug 13, 2013
c802070
Adjust llvmcall for new tuple infrastructure
Keno Aug 13, 2013
91f8ae7
Some llvmcall bugfixes
Keno Aug 13, 2013
c343b5a
Address compiler warnings
Keno Aug 13, 2013
49217ff
Also remove PM initialization
Keno Aug 13, 2013
9cc2819
Handle nothingness correctly
Keno Aug 13, 2013
aec2612
Fix a performance regression
Keno Aug 14, 2013
6b567e1
tpl -> &tpl and don't use return value from unreachable
Keno Aug 15, 2013
1933ea7
Allow unboxed storing tupl purebits tuples
Keno Aug 15, 2013
c58e1ff
remove invalid check from store_unboxed_p
Keno Aug 16, 2013
17690a0
is_stable_expr for tuples
Keno Aug 16, 2013
10330fa
Fix tuples branch for some changes since it was introduced
Keno Oct 2, 2013
a93b442
Tuples branch bug-fixes
Keno Oct 5, 2013
0e2c3e6
Fix a missing JL_GC_POP
Keno Oct 25, 2013
f8b79c4
Fix ifelse on the tuple branch
Keno Oct 26, 2013
8217d70
Merge some bugfixes from MCJIT branch
Keno Nov 16, 2013
71a5def
Fix build failure after merge
Keno Nov 17, 2013
665ffe5
Cleanup
Keno Nov 19, 2013
e02db98
Separate out llvmcall
Keno Nov 19, 2013
9deb3a1
Simplify emit_tupleset, but disallowing non-constant ones
Keno Nov 20, 2013
ee26d21
Add a missing GC root
Keno Nov 21, 2013
f9999b1
Fix an improperly adjusted gc frame
Keno Nov 23, 2013
a7d99e6
Fix vararg root counting
Keno Nov 27, 2013
d5ad8e6
Fix a rebase conflict
Keno Nov 27, 2013
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Cleanup
  • Loading branch information
Keno committed Nov 29, 2013
commit 665ffe5ed021f574e16ebbab479c3bf0398b5775
2 changes: 1 addition & 1 deletion base/fftw.jl
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ Plan{T<:fftwNumber}(plan::Ptr{Void}, X::StridedArray{T}) = Plan{T}(plan, size(X)
# throw an informative error if not:
function assert_applicable{T<:fftwNumber}(p::Plan{T}, X::StridedArray{T})
if size(X) != p.sz
throw(ArgumentError("FFTW plan applied to wrong-size array (expected $(p.sz), got $(size(X))"))
throw(ArgumentError("FFTW plan applied to wrong-size array"))
elseif strides(X) != p.istride
throw(ArgumentError("FFTW plan applied to wrong-strides array"))
elseif alignment_of(X) != p.ialign
Expand Down
5 changes: 2 additions & 3 deletions src/ccall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,6 @@ static Value *emit_llvmcall(jl_value_t **args, size_t nargs, jl_codectx_t *ctx)
<< jl_string_data(ir) << "\n}";
SMDiagnostic Err = SMDiagnostic();
std::string ir_string = ir_stream.str();
JL_PUTS((char*)ir_string.data(),JL_STDERR);
Module *m = ParseAssemblyString(ir_string.data(),jl_Module,Err,jl_LLVMContext);
if (m == NULL) {
std::string message = "Failed to parse LLVM Assembly: \n";
Expand All @@ -616,8 +615,8 @@ static Value *emit_llvmcall(jl_value_t **args, size_t nargs, jl_codectx_t *ctx)
* function. This also has the benefit of looking exactly like we cut/pasted it in in `code_llvm`.
*/
f->setLinkage(GlobalValue::LinkOnceODRLinkage);
f->dump();
// the actual call

// the actual call
CallInst *inst = builder.CreateCall(f,ArrayRef<Value*>(&argvals[0],nargt));
ctx->to_inline.push_back(inst);

Expand Down
68 changes: 30 additions & 38 deletions src/cgutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ static Type *julia_type_to_llvm(jl_value_t *jt)
else
ret = ArrayType::get(type,ntypes);
return ret;
} else {
}
else {
Type *types[ntypes];
size_t j = 0;
for (size_t i = 0; i < ntypes; ++i) {
Expand Down Expand Up @@ -604,8 +605,7 @@ static Value *emit_tuplelen(Value *t,jl_value_t *jt)
if (t == NULL)
return ConstantInt::get(T_size,0);
Type *ty = t->getType();
if (ty == jl_pvalue_llvmt) //boxed
{
if (ty == jl_pvalue_llvmt) { //boxed
#ifdef OVERLAP_TUPLE_LEN
Value *lenbits = emit_nthptr(t, (size_t)0);
return builder.CreateLShr(builder.CreatePtrToInt(lenbits, T_int64),
Expand All @@ -614,7 +614,8 @@ static Value *emit_tuplelen(Value *t,jl_value_t *jt)
Value *lenbits = emit_nthptr(t, 1);
return builder.CreatePtrToInt(lenbits, T_size);
#endif
} else { //unboxedAg
}
else { //unboxed
return ConstantInt::get(T_size,jl_tuple_len(jt));
}
}
Expand All @@ -627,8 +628,7 @@ static Value *emit_tupleset(Value *tuple, Value *i, Value *x, jl_value_t *jt, jl
return NULL;
}
Type *ty = tuple->getType();
if (ty == jl_pvalue_llvmt) //boxed
{
if (ty == jl_pvalue_llvmt) { //boxed
#ifdef OVERLAP_TUPLE_LENCreateS
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like a typo here.

Value *slot = builder.CreateGEP(builder.CreateBitCast(tuple, jl_ppvalue_llvmt),
i);
Expand All @@ -638,7 +638,8 @@ static Value *emit_tupleset(Value *tuple, Value *i, Value *x, jl_value_t *jt, jl
#endif
builder.CreateStore(x,slot);
return tuple;
} else {
}
else {
Value *ret = NULL;
if (ty->isVectorTy()) {
Type *ity = i->getType();
Expand All @@ -650,16 +651,15 @@ static Value *emit_tupleset(Value *tuple, Value *i, Value *x, jl_value_t *jt, jl
else if(iity->getBitWidth() < 32)
i = builder.CreateZExt(i,T_int32);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

theres also a CreateZExtOrTrunc function, although it just implements this same logic

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, yes. Fair point. I was trying to remember what it was called, but then again as you noted it doesn't really matter.

ret = builder.CreateInsertElement(tuple,x,builder.CreateSub(i,ConstantInt::get(T_int32,1)));
} else {
}
else {
ConstantInt *idx = dyn_cast<ConstantInt>(i);
if (idx != 0) {
unsigned ci = (unsigned)idx->getZExtValue()-1;
size_t n = jl_tuple_len(jt);
for (size_t i=0,j = 0; i<n; ++i)
{
for (size_t i=0,j = 0; i<n; ++i) {
Type *ty = julia_struct_to_llvm(jl_tupleref(jt,i));
if (ci == i)
{
if (ci == i) {
if (ty == T_void)
return tuple;
else
Expand All @@ -669,8 +669,7 @@ static Value *emit_tupleset(Value *tuple, Value *i, Value *x, jl_value_t *jt, jl
++j;
}
}
else if (ty->isArrayTy())
{
else if (ty->isArrayTy()) {
ArrayType *at = dyn_cast<ArrayType>(ty);
Value *tempSpace = builder.CreateAlloca(at);
builder.CreateStore(tuple,tempSpace);
Expand All @@ -680,8 +679,7 @@ static Value *emit_tupleset(Value *tuple, Value *i, Value *x, jl_value_t *jt, jl
builder.CreateStore(x,builder.CreateGEP(tempSpace,ArrayRef<Value*>(&idxs[0],2)));
ret = builder.CreateLoad(tempSpace);
}
else
{
else {
assert(ty->isStructTy());
StructType *st = dyn_cast<StructType>(ty);
size_t n = st->getNumElements();
Expand All @@ -701,12 +699,12 @@ static Value *emit_tupleset(Value *tuple, Value *i, Value *x, jl_value_t *jt, jl
builder.SetInsertPoint(blk);
jl_value_t *jltype = jl_tupleref(jt,i);
Type *ty = julia_struct_to_llvm(jltype);
if (ty != T_void)
{
if (ty != T_void) {
Value *newAgg = builder.CreateInsertValue(tuple,x,ArrayRef<unsigned>(j));
builder.CreateStore(newAgg,ret);
j++;
} else {
}
else {
builder.CreateStore(tuple,ret);
}
builder.CreateBr(after);
Expand All @@ -729,16 +727,16 @@ static Value *emit_tupleref(Value *tuple, Value *ival, jl_value_t *jt, jl_codect
return NULL;
}
Type *ty = tuple->getType();
if (ty == jl_pvalue_llvmt) //boxed
{
if (ty == jl_pvalue_llvmt) { //boxed
#ifdef OVERLAP_TUPLE_LEN
Value *slot = builder.CreateGEP(builder.CreateBitCast(tuple, jl_ppvalue_llvmt),ival);
#else
Value *slot = builder.CreateGEP(builder.CreateBitCast(tuple, jl_ppvalue_llvmt),
builder.CreateAdd(ConstantInt::get(T_size,1),ival));
#endif
return builder.CreateLoad(slot);
} else {
}
else {
if (ty->isVectorTy()) {
Type *ity = ival->getType();
assert(ity->isIntegerTy());
Expand All @@ -754,11 +752,9 @@ static Value *emit_tupleref(Value *tuple, Value *ival, jl_value_t *jt, jl_codect
if (idx != 0) {
unsigned ci = (unsigned)idx->getZExtValue()-1;
size_t n = jl_tuple_len(jt);
for (size_t i = 0,j = 0; i<n; ++i)
{
for (size_t i = 0,j = 0; i<n; ++i) {
Type *ty = julia_struct_to_llvm(jl_tupleref(jt,i));
if (ci == i)
{
if (ci == i) {
if (ty == T_void)
return mark_julia_type(UndefValue::get(NoopType),jl_tupleref(jt,i));
else
Expand All @@ -770,8 +766,7 @@ static Value *emit_tupleref(Value *tuple, Value *ival, jl_value_t *jt, jl_codect
assert("Out of bounds!");
return NULL;
}
else if (ty->isArrayTy())
{
else if (ty->isArrayTy()) {
ArrayType *at = dyn_cast<ArrayType>(ty);
Value *tempSpace = builder.CreateAlloca(at);
builder.CreateStore(tuple,tempSpace);
Expand All @@ -780,8 +775,7 @@ static Value *emit_tupleref(Value *tuple, Value *ival, jl_value_t *jt, jl_codect
idxs[1] = builder.CreateSub(ival,ConstantInt::get(T_size,1));
return builder.CreateLoad(builder.CreateGEP(tempSpace,ArrayRef<Value*>(&idxs[0],2)));
}
else
{
else {
assert(ty->isStructTy());
StructType *st = dyn_cast<StructType>(ty);
size_t n = st->getNumElements();
Expand All @@ -803,11 +797,11 @@ static Value *emit_tupleref(Value *tuple, Value *ival, jl_value_t *jt, jl_codect
jl_value_t *jltype = jl_tupleref(jt,i);
Type *ty = julia_struct_to_llvm(jltype);
Value *val;
if (ty != T_void)
{
if (ty != T_void) {
val = boxed(builder.CreateExtractValue(tuple,ArrayRef<unsigned>(j)),ctx,jltype);
j++;
} else {
}
else {
val = boxed(NULL,ctx,jltype);
}
builder.CreateStore(val,ret);
Expand Down Expand Up @@ -1029,8 +1023,6 @@ static Value *allocate_box_dynamic(Value *jlty, int nb, Value *v)
return init_bits_value(newv, jlty, v->getType(), v);
}

bool isGhostType(jl_value_t*);

static jl_value_t *static_void_instance(jl_value_t *jt)
{
if (jl_is_datatype(jt)) {
Expand All @@ -1039,8 +1031,8 @@ static jl_value_t *static_void_instance(jl_value_t *jt)
jl_new_struct_uninit(jb);
assert(jb->instance != NULL);
return (jl_value_t*)jb->instance;
} else if (jt == jl_typeof(jl_nothing) || jt == jl_bottom_type)
{
}
else if (jt == jl_typeof(jl_nothing) || jt == jl_bottom_type) {
return (jl_value_t*)jl_nothing;
}
assert(jl_is_tuple(jt));
Expand Down Expand Up @@ -1140,7 +1132,7 @@ static Value *boxed(Value *v, jl_codectx_t *ctx, jl_value_t *jt)
jl_add_linfo_root(ctx->linfo, s);
return literal_pointer_val(s);
}
if jl_is_tuple(jt) {
if (jl_is_tuple(jt)) {
size_t n = jl_tuple_len(jt);
Value *tpl = builder.CreateCall(jl_alloc_tuple_func,ConstantInt::get(T_size,n));
make_gcroot(tpl,ctx);
Expand Down
59 changes: 23 additions & 36 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,6 @@ static Function *jlenter_func;
static Function *jlleave_func;
static Function *jlegal_func;
static Function *jlallocobj_func;
static Function *jlalloc1w_func;
static Function *jlalloc2w_func;
static Function *jlalloc3w_func;
static Function *jl_alloc_tuple_func;
Expand Down Expand Up @@ -267,14 +266,14 @@ static Function *to_function(jl_lambda_info_t *li, bool cstyle)
assert(f != NULL);
nested_compile = last_n_c;
//f->dump();
verifyFunction(*f);
//verifyFunction(*f);
FPM->run(*f);
//n_compile++;
// print out the function's LLVM code
//ios_printf(ios_stderr, "%s:%d\n",
// ((jl_sym_t*)li->file)->name, li->line);
//f->dump();
verifyFunction(*f);
//verifyFunction(*f);
if (old != NULL) {
builder.SetInsertPoint(old);
builder.SetCurrentDebugLocation(olddl);
Expand All @@ -297,9 +296,9 @@ extern "C" void jl_generate_fptr(jl_function_t *f)
if (li->cFunctionObject != NULL)
(void)jl_ExecutionEngine->getPointerToFunction((Function*)li->cFunctionObject);
JL_SIGATOMIC_END();
//llvmf->deleteBody();
//if (li->cFunctionObject != NULL)
//((Function*)li->cFunctionObject)->deleteBody();
llvmf->deleteBody();
if (li->cFunctionObject != NULL)
((Function*)li->cFunctionObject)->deleteBody();
}
f->fptr = li->fptr;
}
Expand Down Expand Up @@ -1679,16 +1678,6 @@ static Value *emit_known_call(jl_value_t *ff, jl_value_t **args, size_t nargs,
return NULL;
}

bool isGhostType(jl_value_t *jt)
{
if (jl_is_tuple(jt) && jl_tuple_len(jt) == 0)
return true;
else if (jl_is_datatype(jt) && !jl_is_abstracttype(jt) && (jl_datatype_t*)(jt) != jl_sym_type &&
!jl_is_array_type(jt) && jl_datatype_size(jt) == 0 && jl_tuple_len(((jl_datatype_t*)(jt))->names) == 0)
return true;
return false;
}

static Value *emit_jlcall(Value *theFptr, Value *theF, jl_value_t **args,
size_t nargs, jl_codectx_t *ctx)
{
Expand Down Expand Up @@ -1906,13 +1895,14 @@ static Value *emit_checked_var(Value *bp, jl_sym_t *name, jl_codectx_t *ctx)

static Value *ghostValue(jl_value_t *ty)
{
if (jl_is_datatype(ty))
{
if (jl_is_datatype(ty)) {
Type *llvmty = julia_struct_to_llvm(ty);
assert(llvmty != T_void);
return UndefValue::get(llvmty);
} else
}
else {
return mark_julia_type(UndefValue::get(NoopType),ty);
}
}

static Value *emit_var(jl_sym_t *sym, jl_value_t *ty, jl_codectx_t *ctx, bool isboxed)
Expand Down Expand Up @@ -2477,17 +2467,18 @@ static Value *alloc_local(jl_sym_t *s, jl_codectx_t *ctx)
Type *vtype = NULL;
if(store_unboxed_p(s,ctx) && s != ctx->vaName)
vtype = julia_type_to_llvm(jt);
if (vtype != T_void)
{
if (vtype != T_void) {
if (vtype == NULL)
vtype = jl_pvalue_llvmt;
lv = builder.CreateAlloca(vtype, 0, s->name);
if (vtype != jl_pvalue_llvmt)
mark_julia_type(lv, jt);
vi.isGhost = false;
assert(lv != NULL);
} else
}
else {
vi.isGhost = true;
}
vi.memvalue = lv;
return lv;
}
Expand Down Expand Up @@ -2553,7 +2544,7 @@ static void allocate_gc_frame(size_t n_roots, jl_codectx_t *ctx)

static void finalize_gc_frame(jl_codectx_t *ctx)
{
if (ctx->argSpaceOffs + ctx->maxDepth == 0) {
if (ctx->argSpaceOffs + ctx->maxDepth == 0) {
// 0 roots; remove gc frame entirely
// replace instruction uses with Undef first to avoid LLVM assertion failures
BasicBlock::iterator bbi = ctx->first_gcframe_inst;
Expand Down Expand Up @@ -2661,11 +2652,10 @@ static Function *gen_jlcall_wrapper(jl_lambda_info_t *lam, jl_expr_t *ast, Funct
if (lty == T_void)
continue;
theNewArg = emit_unbox(lty, theArg, ty);
} else if(jl_is_tuple(ty))
{
}
else if(jl_is_tuple(ty)) {
Type *lty = julia_struct_to_llvm(ty);
if (lty != jl_pvalue_llvmt)
{
if (lty != jl_pvalue_llvmt) {
if (lty == T_void)
continue;
theNewArg = emit_unbox(lty, theArg, ty);
Expand Down Expand Up @@ -2841,8 +2831,9 @@ static Function *emit_function(jl_lambda_info_t *lam, bool cstyle)
std::vector<Type*> fsig(0);
for(size_t i=0; i < jl_tuple_len(lam->specTypes); i++) {
Type *ty = julia_type_to_llvm(jl_tupleref(lam->specTypes,i));
if (ty != T_void)
if (ty != T_void) {
fsig.push_back(ty);
}
else {
ctx.vars[jl_decl_var(jl_cellref(largs,i))].isGhost = true;
}
Expand Down Expand Up @@ -3126,7 +3117,8 @@ static Function *emit_function(jl_lambda_info_t *lam, bool cstyle)
if (lv == NULL) {
if (ctx.vars[s].isGhost) {
ctx.vars[s].passedAs = NULL;
} else {
}
else {
// if this argument hasn't been given space yet, we've decided
// to leave it in the input argument array.
ctx.vars[s].passedAs = theArg;
Expand Down Expand Up @@ -3182,7 +3174,8 @@ static Function *emit_function(jl_lambda_info_t *lam, bool cstyle)
builder.CreateStore(builder.CreateCall(jlbox_func, restTuple), lv);
else
builder.CreateStore(restTuple, lv);
} else {
}
else {
// TODO: Perhaps allow this in the future, but for now sice varargs are always unspecialized
// we don't
assert(false);
Expand Down Expand Up @@ -3586,12 +3579,6 @@ static void init_julia_llvm_env(Module *m)
jl_ExecutionEngine->addGlobalMapping(jlallocobj_func, (void*)&allocobj);

std::vector<Type*> empty_args(0);
jlalloc1w_func =
Function::Create(FunctionType::get(jl_pvalue_llvmt, empty_args, false),
Function::ExternalLinkage,
"alloc_1w", jl_Module);
jl_ExecutionEngine->addGlobalMapping(jlalloc1w_func, (void*)&alloc_1w);

jlalloc2w_func =
Function::Create(FunctionType::get(jl_pvalue_llvmt, empty_args, false),
Function::ExternalLinkage,
Expand Down
Loading