Skip to content

Commit

Permalink
this reverts giving alloca it's own stack, and simply reuses the exis…
Browse files Browse the repository at this point in the history
…ting gc frame
  • Loading branch information
vtjnash committed Sep 10, 2014
1 parent cebf733 commit 2a922d9
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 86 deletions.
1 change: 0 additions & 1 deletion src/builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@ void jl_enter_handler(jl_handler_t *eh)
#ifdef JL_GC_MARKSWEEP
eh->gcstack = jl_pgcstack;
#endif
eh->alloca_stack = jl_alloca_stack;
jl_current_task->eh = eh;
// TODO: this should really go after setjmp(). see comment in
// ctx_switch in task.c.
Expand Down
10 changes: 6 additions & 4 deletions src/cgutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -618,10 +618,12 @@ static bool has_julia_type(Value *v)
static jl_value_t *julia_type_of_without_metadata(Value *v, bool err=true)
{
Type *T = v->getType();
if (dyn_cast<AllocaInst>(v) != NULL ||
dyn_cast<GetElementPtrInst>(v) != NULL) {
// an alloca always has llvm type pointer
return llvm_type_to_julia(T->getContainedType(0), err);
if (T != jl_pvalue_llvmt) {
if (dyn_cast<AllocaInst>(v) != NULL ||
dyn_cast<GetElementPtrInst>(v) != NULL) {
// an alloca always has llvm type pointer
return llvm_type_to_julia(T->getContainedType(0), err);
}
}
return llvm_type_to_julia(T, err);
}
Expand Down
76 changes: 23 additions & 53 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,6 @@ static GlobalVariable *jlfloattemp_var;
#ifdef JL_GC_MARKSWEEP
static GlobalVariable *jlpgcstack_var;
#endif
static GlobalVariable *jl_alloca_stack_var;
static GlobalVariable *jlexc_var;
static GlobalVariable *jldiverr_var;
static GlobalVariable *jlundeferr_var;
Expand Down Expand Up @@ -480,16 +479,14 @@ typedef struct {
std::string funcName;
jl_sym_t *vaName; // name of vararg argument
bool vaStack; // varargs stack-allocated
bool uses_alloca; // uses alloca-based gc allocation
int nReqArgs;
int lineno;
std::vector<bool> boundsCheck;
#ifdef JL_GC_MARKSWEEP
Instruction *gcframe;
Instruction *gcframe ;
Instruction *argSpaceInits;
StoreInst *storeFrameSize;
#endif
Instruction *alloca_frame;
BasicBlock::iterator first_gcframe_inst;
BasicBlock::iterator last_gcframe_inst;
llvm::DIBuilder *dbuilder;
Expand Down Expand Up @@ -1143,36 +1140,36 @@ static void simple_escape_analysis(jl_value_t *expr, bool varesc, bool envesc, j
simple_escape_analysis(f, true, false, ctx);
jl_value_t *fv = static_eval(f, ctx, false);
if (fv) {
if (jl_typeis(fv, jl_intrinsic_type)) {
JL_I::intrinsic fi = (JL_I::intrinsic)jl_unbox_int32(fv);
if (fi == JL_I::ccall) {
if (jl_typeis(fv, jl_intrinsic_type)) {
JL_I::intrinsic fi = (JL_I::intrinsic)jl_unbox_int32(fv);
if (fi == JL_I::ccall) {
varesc = true;
envesc = local_var_occurs(jl_exprarg(e,3),jl_any_type->name->name);
simple_escape_analysis(jl_exprarg(e,1), varesc, envesc, ctx);
// 2nd and 3d arguments are static
// 2nd and 3d arguments are static
i = 4;
}
}
else if (fi == JL_I::llvmcall) {
varesc = true;
envesc = false;
// 1st, 2nd and 3d arguments are static
i = 4;
}
}
else {
varesc = false;
envesc = false;
}
}
else if (jl_is_function(fv)) {
jl_function_t *ff = (jl_function_t*)fv;
if (ff->fptr == jl_f_tuplelen ||
ff->fptr == jl_f_tupleref ||
else if (jl_is_function(fv)) {
jl_function_t *ff = (jl_function_t*)fv;
if (ff->fptr == jl_f_tuplelen ||
ff->fptr == jl_f_tupleref ||
(ff->fptr == jl_f_apply && elen==3 &&
expr_type(jl_exprarg(e,1),ctx) == (jl_value_t*)jl_function_type &&
expr_type(jl_exprarg(e,2),ctx) == (jl_value_t*)jl_tuple_type)) {
varesc = false;
envesc = false;
}
}
else if (ff->fptr == jl_f_arrayref ||
ff->fptr == jl_f_arraylen ||
ff->fptr == jl_f_get_field ||
Expand All @@ -1188,21 +1185,21 @@ static void simple_escape_analysis(jl_value_t *expr, bool varesc, bool envesc, j
varesc = true;
envesc = true;
i = 2;
}
}
else if (ff->fptr == jl_f_typeassert) {
simple_escape_analysis(jl_exprarg(e,1), true, envesc, ctx);
simple_escape_analysis(jl_exprarg(e,2), true, false, ctx);
return;
}
}
else if ( ff->fptr == jl_f_convert_default) {
simple_escape_analysis(jl_exprarg(e,1), true, false, ctx);
simple_escape_analysis(jl_exprarg(e,2), true, envesc, ctx);
return;
}
}
else {
varesc = true;
envesc = true;
}
}
}
else {
varesc = true;
Expand All @@ -1223,13 +1220,13 @@ static void simple_escape_analysis(jl_value_t *expr, bool varesc, bool envesc, j
varesc = true;
envesc = true;
i = 1;
}
}
else if (e->head == amp_sym) {
i = 0;
}
else if (e->head == line_sym) {
return;
}
return;
}
else {
varesc = true;
envesc = true;
Expand Down Expand Up @@ -1949,12 +1946,8 @@ static Value *emit_known_call(jl_value_t *ff, jl_value_t **args, size_t nargs,
tup = builder.CreateCall(prepare_call(jlallocobj_func),
ConstantInt::get(T_size, sz));
} else {
tup = builder.CreateAlloca(T_pint8, ConstantInt::get(T_int32, 1+nwords));
ctx->uses_alloca = true;
builder.CreateStore(builder.CreateLoad(prepare_global(jl_alloca_stack_var)), tup);
builder.CreateStore(builder.CreatePointerCast(tup,T_pint8), prepare_global(jl_alloca_stack_var));
tup = builder.CreatePointerCast(builder.CreateConstGEP1_32(tup, 1), jl_pvalue_llvmt);
((Instruction*)tup)->setMetadata("isAlloca", MDNode::get(jl_LLVMContext, ArrayRef<Value*>()));
tup = builder.CreateAlloca(jl_value_llvmt, ConstantInt::get(T_int32, nwords));
// assert( dyn_cast<AllocaInst>(tup) != NULL );
}
#ifdef OVERLAP_TUPLE_LEN
builder.CreateStore(arg1, emit_nthptr_addr(tup, 1));
Expand Down Expand Up @@ -2122,8 +2115,6 @@ static Value *emit_known_call(jl_value_t *ff, jl_value_t **args, size_t nargs,
emit_expr(args[2],ctx,false,false);
}
else {
//Instruction *I = dyn_cast<Instruction>(ary);
//escapes = escapes || !I || !I->getMetadata("isAlloca");
typed_store(emit_arrayptr(ary,args[1],ctx), idx,
ety == (jl_value_t*)jl_any_type ?
emit_expr(args[2],ctx,true) :
Expand Down Expand Up @@ -2231,8 +2222,6 @@ static Value *emit_known_call(jl_value_t *ff, jl_value_t **args, size_t nargs,
Value *strct = emit_expr(args[1], ctx, false);
Value *rhs;
if (sty->fields[idx].isptr) {
//Instruction *I = dyn_cast<Instruction>(strct);
//escapes = escapes || !I || !I->getMetadata("isAlloca");
rhs = emit_expr(args[3], ctx, true);
}
else {
Expand Down Expand Up @@ -2919,12 +2908,8 @@ static Value *emit_expr(jl_value_t *expr, jl_codectx_t *ctx, bool escapes,
ConstantInt::get(T_size, sz));
}
else {
strct = builder.CreateAlloca(T_pint8, ConstantInt::get(T_int32, 1+sz/sizeof(void*)));
ctx->uses_alloca = true;
builder.CreateStore(builder.CreateLoad(prepare_global(jl_alloca_stack_var)), strct);
builder.CreateStore(builder.CreatePointerCast(strct,T_pint8), prepare_global(jl_alloca_stack_var));
strct = builder.CreatePointerCast(builder.CreateConstGEP1_32(strct, 1), jl_pvalue_llvmt);
((Instruction*)strct)->setMetadata("isAlloca", MDNode::get(jl_LLVMContext, ArrayRef<Value*>()));
strct = builder.CreateAlloca(jl_value_llvmt, ConstantInt::get(T_int32, sz/sizeof(void*)));
// assert( dyn_cast<AllocaInst>(strct) != NULL );
}
builder.CreateStore(literal_pointer_val((jl_value_t*)ty),
emit_nthptr_addr(strct, (size_t)0));
Expand Down Expand Up @@ -3176,7 +3161,6 @@ static void allocate_gc_frame(size_t n_roots, jl_codectx_t *ctx)
ctx->argTemp = builder.CreateAlloca(jl_pvalue_llvmt,
ConstantInt::get(T_int32, n_roots));
#endif
ctx->alloca_frame = builder.CreateLoad(prepare_global(jl_alloca_stack_var), false);

}

Expand Down Expand Up @@ -3210,8 +3194,6 @@ static void finalize_gc_frame(jl_codectx_t *ctx)
il.erase(ctx->first_gcframe_inst, ctx->last_gcframe_inst);
// erase() erases up *to* the end point; erase last inst too
il.erase(ctx->last_gcframe_inst);
//if (!ctx->uses_alloca)
// il.erase(ctx->alloca_frame);
for(size_t i=0; i < ctx->gc_frame_pops.size(); i++) {
Instruction *pop = ctx->gc_frame_pops[i];
BasicBlock::InstListType &il2 = pop->getParent()->getInstList();
Expand Down Expand Up @@ -3250,10 +3232,6 @@ static void finalize_gc_frame(jl_codectx_t *ctx)
after = new StoreInst(V_null, argTempi);
instList.insertAfter(argTempi, after);
}
//if (!ctx->uses_alloca) {
// BasicBlock::InstListType &il = ctx->gcframe->getParent()->getInstList();
// il.erase(ctx->alloca_frame);
//}
}
}

Expand Down Expand Up @@ -3330,7 +3308,6 @@ static Function *gen_jlcall_wrapper(jl_lambda_info_t *lam, jl_expr_t *ast, Funct
ctx.gc_frame_pops.push_back(gcpop);
builder.CreateStore(builder.CreateBitCast(builder.CreateLoad(gcpop, false), jl_ppvalue_llvmt),
prepare_global(jlpgcstack_var));
builder.CreateStore(ctx.alloca_frame, prepare_global(jl_alloca_stack_var)),

finalize_gc_frame(&ctx);
builder.CreateRet(r);
Expand Down Expand Up @@ -4004,7 +3981,6 @@ static Function *emit_function(jl_lambda_info_t *lam, bool cstyle)
builder.CreateStore(builder.CreateBitCast(builder.CreateLoad(gcpop, false), jl_ppvalue_llvmt),
prepare_global(jlpgcstack_var));
#endif
builder.CreateStore(ctx.alloca_frame, prepare_global(jl_alloca_stack_var));
if (do_malloc_log && lno != -1)
mallocVisitLine(filename, lno);
if (builder.GetInsertBlock()->getTerminator() == NULL) {
Expand Down Expand Up @@ -4215,12 +4191,6 @@ static void init_julia_llvm_env(Module *m)
NULL, "jl_pgcstack");
add_named_global(jlpgcstack_var, (void*)&jl_pgcstack);
#endif

jl_alloca_stack_var =
new GlobalVariable(*m, T_pint8,
false, GlobalVariable::ExternalLinkage,
NULL, "jl_alloca_stack");
add_named_global(jl_alloca_stack_var, (void*)&jl_alloca_stack);

global_to_llvm("__stack_chk_guard", (void*)&__stack_chk_guard, m);
Function *jl__stack_chk_fail =
Expand Down
49 changes: 29 additions & 20 deletions src/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -637,7 +637,7 @@ static size_t mark_stack_size = 0;
static size_t mark_sp = 0;

static struct {
void* *s;
jl_gcframe_t *s;
ptrint_t offset;
} *marked_stacks;
static size_t marked_stacks_size = 0;
Expand All @@ -656,18 +656,42 @@ static void gc_unmark_stacks()
{
size_t i;
for (i = 0; i < marked_stacks_sp; i++) {
void* *s = marked_stacks[i].s;
jl_gcframe_t *s = marked_stacks[i].s;
ptrint_t offset = marked_stacks[i].offset;
while (s != NULL) {
s = (void**)((char*)s + offset);
gc_clrmark(s+1);
s = (void**)(*s);
s = (jl_gcframe_t*)((char*)s + offset);
jl_value_t ***rts = (jl_value_t***)(((void**)s)+2);
size_t nr = s->nroots>>1;
if (s->nroots & 1) {
for(size_t i=0; i < nr; i++) {
jl_value_t **ptr = (jl_value_t**)((char*)rts[i] + offset);
if (*ptr != NULL && gc_marked(*ptr))
gc_clrmark(*ptr);
}
}
else {
for(size_t i=0; i < nr; i++) {
if (rts[i] != NULL && gc_marked(rts[i]))
gc_clrmark(rts[i]);
}
}
s = s->prev;
}
}
}

static void gc_mark_stack(jl_gcframe_t *s, ptrint_t offset, int d)
{
if (marked_stacks_sp >= marked_stacks_size) {
size_t newsz = marked_stacks_size>0 ? marked_stacks_size*2 : 8;
marked_stacks = (typeof(marked_stacks))realloc(marked_stacks,newsz*sizeof(*marked_stacks));
if (marked_stacks == NULL) exit(1);
marked_stacks_size = newsz;
}
marked_stacks[marked_stacks_sp].s = s;
marked_stacks[marked_stacks_sp].offset = offset;
marked_stacks_sp++;

while (s != NULL) {
s = (jl_gcframe_t*)((char*)s + offset);
jl_value_t ***rts = (jl_value_t***)(((void**)s)+2);
Expand Down Expand Up @@ -727,32 +751,17 @@ static void gc_mark_task(jl_task_t *ta, int d)
if (ta->stkbuf != NULL || ta == jl_current_task) {
if (ta->stkbuf != NULL)
gc_setmark_buf(ta->stkbuf);
if (marked_stacks_sp >= marked_stacks_size) {
size_t newsz = marked_stacks_size>0 ? marked_stacks_size*2 : 8;
marked_stacks = (typeof(marked_stacks))realloc(marked_stacks,newsz*sizeof(*marked_stacks));
if (marked_stacks == NULL) exit(1);
marked_stacks_size = newsz;
}
#ifdef COPY_STACKS
ptrint_t offset;
if (ta == jl_current_task) {
offset = 0;
marked_stacks[marked_stacks_sp].s = jl_alloca_stack;
marked_stacks[marked_stacks_sp].offset = offset;
marked_stacks_sp++;
gc_mark_stack(jl_pgcstack, offset, d);
}
else {
offset = (char *)ta->stkbuf - ((char *)ta->stackbase - ta->ssize);
marked_stacks[marked_stacks_sp].s = ta->alloca_stack;
marked_stacks[marked_stacks_sp].offset = offset;
marked_stacks_sp++;
gc_mark_stack(ta->gcstack, offset, d);
}
#else
marked_stacks[marked_stacks_sp].s = ta->alloca_stack;
marked_stacks[marked_stacks_sp].offset = offset;
marked_stacks_sp++;
gc_mark_stack(ta->gcstack, 0, d);
#endif
}
Expand Down
4 changes: 0 additions & 4 deletions src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -1022,7 +1022,6 @@ typedef struct _jl_gcframe_t {
// x = f(); y = g(); foo(x, y); JL_GC_POP();

extern DLLEXPORT jl_gcframe_t *jl_pgcstack;
extern DLLEXPORT void** jl_alloca_stack;

#define JL_GC_PUSH(...) \
void *__gc_stkf[] = {(void*)((VA_NARG(__VA_ARGS__)<<1)|1), jl_pgcstack, \
Expand Down Expand Up @@ -1129,7 +1128,6 @@ typedef struct _jl_handler_t {
#ifdef JL_GC_MARKSWEEP
jl_gcframe_t *gcstack;
#endif
void* *alloca_stack;
struct _jl_handler_t *prev;
} jl_handler_t;

Expand Down Expand Up @@ -1158,7 +1156,6 @@ typedef struct _jl_task_t {
jl_handler_t *eh;
// saved gc stack top for context switches
jl_gcframe_t *gcstack;
void* *alloca_stack;
// current module, or NULL if this task has not set one
jl_module_t *current_module;
} jl_task_t;
Expand All @@ -1181,7 +1178,6 @@ STATIC_INLINE void jl_eh_restore_state(jl_handler_t *eh)
#ifdef JL_GC_MARKSWEEP
jl_pgcstack = eh->gcstack;
#endif
jl_alloca_stack = eh->alloca_stack;
JL_SIGATOMIC_END();
}

Expand Down
4 changes: 0 additions & 4 deletions src/task.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,6 @@ jl_value_t *jl_exception_in_transit;
#ifdef JL_GC_MARKSWEEP
jl_gcframe_t *jl_pgcstack = NULL;
#endif
void* *jl_alloca_stack = NULL;

static void start_task(jl_task_t *t);

Expand Down Expand Up @@ -247,8 +246,6 @@ static void ctx_switch(jl_task_t *t, jl_jmp_buf *where)
jl_current_task->gcstack = jl_pgcstack;
jl_pgcstack = t->gcstack;
#endif
jl_current_task->alloca_stack = jl_alloca_stack;
jl_alloca_stack = t->alloca_stack;

// restore task's current module, looking at parent tasks
// if it hasn't set one.
Expand Down Expand Up @@ -787,7 +784,6 @@ jl_task_t *jl_new_task(jl_function_t *start, size_t ssize)
#ifdef JL_GC_MARKSWEEP
t->gcstack = NULL;
#endif
t->alloca_stack = NULL;
t->stkbuf = NULL;

#ifdef COPY_STACKS
Expand Down

0 comments on commit 2a922d9

Please sign in to comment.