Skip to content

Commit 12fe44f

Browse files
committed
move alloca boxes to the first basic block, so they get reused
1 parent d926698 commit 12fe44f

File tree

1 file changed

+22
-19
lines changed

1 file changed

+22
-19
lines changed

src/codegen.cpp

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,7 @@ typedef struct {
497497
Instruction *argSpaceInits;
498498
StoreInst *storeFrameSize;
499499
#endif
500+
BasicBlock *allocaBB;
500501
BasicBlock::iterator first_gcframe_inst;
501502
BasicBlock::iterator last_gcframe_inst;
502503
llvm::DIBuilder *dbuilder;
@@ -1975,37 +1976,39 @@ static Value *emit_known_call(jl_value_t *ff, jl_value_t **args, size_t nargs,
19751976
make_gcroot(arg1, ctx);
19761977
bool rooted = false;
19771978
Value *tup;
1979+
IRBuilderBase::InsertPoint ip;
19781980
if (escapes) {
19791981
tup = builder.CreateCall(prepare_call(jlallocobj_func),
19801982
ConstantInt::get(T_size, sz));
19811983
} else {
1984+
ip = builder.saveIP();
1985+
builder.SetInsertPoint(ctx->allocaBB, ctx->allocaBB->getFirstInsertionPt());
19821986
tup = builder.CreateAlloca(jl_value_llvmt, ConstantInt::get(T_int32, nwords));
19831987
// assert( dyn_cast<AllocaInst>(tup) != NULL );
19841988
}
1985-
#ifdef OVERLAP_TUPLE_LEN
1986-
builder.CreateStore(arg1, emit_nthptr_addr(tup, 1));
1987-
#else
1988-
builder.CreateStore(arg1, emit_nthptr_addr(tup, 2));
1989-
#endif
1990-
ctx->argDepth = last_depth;
19911989
#ifdef OVERLAP_TUPLE_LEN
19921990
builder.
19931991
CreateStore(builder.
19941992
CreateOr(builder.CreatePtrToInt(literal_pointer_val((jl_value_t*)jl_tuple_type), T_int64),
19951993
ConstantInt::get(T_int64, nargs<<52)),
19961994
builder.CreateBitCast(emit_nthptr_addr(tup, (size_t)0),
19971995
T_pint64));
1996+
if (!escapes)
1997+
builder.restoreIP(ip);
1998+
builder.CreateStore(arg1, emit_nthptr_addr(tup, 1));
1999+
size_t offs = 1;
19982000
#else
19992001
builder.CreateStore(literal_pointer_val((jl_value_t*)jl_tuple_type),
20002002
emit_nthptr_addr(tup, (size_t)0));
20012003
builder.CreateStore(ConstantInt::get(T_size, nargs),
20022004
builder.CreateBitCast(emit_nthptr_addr(tup, (size_t)1), T_psize));
2003-
#endif
2004-
#ifdef OVERLAP_TUPLE_LEN
2005-
size_t offs = 1;
2006-
#else
2005+
if (!escapes)
2006+
builder.restoreIP(ip);
2007+
builder.CreateStore(arg1, emit_nthptr_addr(tup, 2));
20072008
size_t offs = 2;
20082009
#endif
2010+
2011+
ctx->argDepth = last_depth;
20092012
for(i=1; i < nargs; i++) {
20102013
builder.CreateStore(V_null,
20112014
emit_nthptr_addr(tup, i+offs));
@@ -2218,21 +2221,15 @@ static Value *emit_known_call(jl_value_t *ff, jl_value_t **args, size_t nargs,
22182221
}
22192222
else if (is_tupletype_homogeneous(stt->types)) {
22202223
assert(llvm_st->isStructTy());
2221-
// TODO: move these allocas to the first basic block instead of
2222-
// frobbing the stack
2223-
Instruction *stacksave =
2224-
CallInst::Create(Intrinsic::getDeclaration(jl_Module,
2225-
Intrinsic::stacksave));
2226-
builder.Insert(stacksave);
2224+
IRBuilderBase::InsertPoint ip = builder.saveIP();
2225+
builder.SetInsertPoint(ctx->allocaBB, ctx->allocaBB->getFirstInsertionPt());
22272226
Value *tempSpace = builder.CreateAlloca(llvm_st);
2227+
builder.restoreIP(ip);
22282228
builder.CreateStore(strct, tempSpace);
22292229
jl_value_t *jt = jl_t0(stt->types);
22302230
idx = emit_bounds_check(idx, ConstantInt::get(T_size, nfields), ctx);
22312231
Value *ptr = builder.CreateGEP(tempSpace, ConstantInt::get(T_size, 0));
22322232
Value *fld = typed_load(ptr, idx, jt, ctx);
2233-
builder.CreateCall(Intrinsic::getDeclaration(jl_Module,
2234-
Intrinsic::stackrestore),
2235-
stacksave);
22362233
JL_GC_POP();
22372234
return fld;
22382235
}
@@ -2952,16 +2949,21 @@ static Value *emit_expr(jl_value_t *expr, jl_codectx_t *ctx, bool escapes,
29522949
make_gcroot(f1, ctx);
29532950
}
29542951
Value *strct;
2952+
IRBuilderBase::InsertPoint ip;
29552953
if (escapes) {
29562954
strct = builder.CreateCall(prepare_call(jlallocobj_func),
29572955
ConstantInt::get(T_size, sz));
29582956
}
29592957
else {
2958+
ip = builder.saveIP();
2959+
builder.SetInsertPoint(ctx->allocaBB, ctx->allocaBB->getFirstInsertionPt());
29602960
strct = builder.CreateAlloca(jl_value_llvmt, ConstantInt::get(T_int32, sz/sizeof(void*)));
29612961
// assert( dyn_cast<AllocaInst>(strct) != NULL );
29622962
}
29632963
builder.CreateStore(literal_pointer_val((jl_value_t*)ty),
29642964
emit_nthptr_addr(strct, (size_t)0));
2965+
if (!escapes)
2966+
builder.restoreIP(ip);
29652967
if (f1) {
29662968
if (!jl_subtype(expr_type(args[1],ctx), jl_t0(sty->types), 0))
29672969
emit_typecheck(f1, jl_t0(sty->types), "new", ctx);
@@ -3736,6 +3738,7 @@ static Function *emit_function(jl_lambda_info_t *lam, bool cstyle)
37363738
}
37373739
maybe_alloc_arrayvar(s, &ctx);
37383740
}
3741+
ctx.allocaBB = builder.GetInsertBlock();
37393742

37403743
// fetch env out of function object if we need it
37413744
if (hasCapt) {

0 commit comments

Comments
 (0)