Skip to content

Commit

Permalink
fix JuliaLang#7836, speed bump due to unreachable code
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffBezanson authored and skumagai committed Aug 18, 2014
1 parent a0b0d88 commit 3b03bb8
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 10 deletions.
5 changes: 4 additions & 1 deletion base/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1681,7 +1681,10 @@ function type_annotate(ast::Expr, states::Array{Any,1}, sv::ANY, rettype::ANY,
body = ast.args[3].args::Array{Any,1}
for i=1:length(body)
st_i = states[i]
body[i] = eval_annotate(body[i], (st_i === () ? emptydict : st_i), sv, decls, closures)
if st_i !== ()
# st_i === () => unreached statement (see issue #7836)
body[i] = eval_annotate(body[i], st_i, sv, decls, closures)
end
end
ast.args[3].typ = rettype

Expand Down
23 changes: 14 additions & 9 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2362,15 +2362,20 @@ static Value *var_binding_pointer(jl_sym_t *s, jl_binding_t **pbnd,
static Value *emit_checked_var(Value *bp, jl_sym_t *name, jl_codectx_t *ctx)
{
Value *v = tpropagate(bp, builder.CreateLoad(bp, false));
Value *ok = builder.CreateICmpNE(v, V_null);
BasicBlock *err = BasicBlock::Create(getGlobalContext(), "err", ctx->f);
BasicBlock *ifok = BasicBlock::Create(getGlobalContext(), "ok");
builder.CreateCondBr(ok, ifok, err);
builder.SetInsertPoint(err);
builder.CreateCall(prepare_call(jlundefvarerror_func), literal_pointer_val((jl_value_t*)name));
builder.CreateBr(ifok);
ctx->f->getBasicBlockList().push_back(ifok);
builder.SetInsertPoint(ifok);
// in unreachable code, there might be a poorly-typed instance of a variable
// that has a concrete type everywhere it's actually used. tolerate this
// situation by just skipping the NULL check if it wouldn't be valid. (issue #7836)
if (v->getType() == jl_pvalue_llvmt) {
Value *ok = builder.CreateICmpNE(v, V_null);
BasicBlock *err = BasicBlock::Create(getGlobalContext(), "err", ctx->f);
BasicBlock *ifok = BasicBlock::Create(getGlobalContext(), "ok");
builder.CreateCondBr(ok, ifok, err);
builder.SetInsertPoint(err);
builder.CreateCall(prepare_call(jlundefvarerror_func), literal_pointer_val((jl_value_t*)name));
builder.CreateBr(ifok);
ctx->f->getBasicBlockList().push_back(ifok);
builder.SetInsertPoint(ifok);
}
return v;
}

Expand Down

0 comments on commit 3b03bb8

Please sign in to comment.