Skip to content

Commit 592e996

Browse files
committed
change union tindex representation to have the high bit indicate boxed
this allows (tindex & 0x7f) to always be exact, saving the need for any dynamic loads in many cases
1 parent ad27253 commit 592e996

File tree

2 files changed

+166
-96
lines changed

2 files changed

+166
-96
lines changed

src/cgutils.cpp

Lines changed: 27 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -602,20 +602,6 @@ static bool for_each_uniontype_small(
602602

603603
static Value *emit_typeof_boxed(const jl_cgval_t &p, jl_codectx_t *ctx);
604604

605-
static Value *compute_box_tindex(Value *datatype, jl_value_t *ut, jl_codectx_t *ctx)
606-
{
607-
Value *tindex = ConstantInt::get(T_int8, 0);
608-
unsigned counter = 0;
609-
for_each_uniontype_small(
610-
[&](unsigned idx, jl_datatype_t *jt) {
611-
Value *cmp = builder.CreateICmpEQ(literal_pointer_val((jl_value_t*)jt), datatype);
612-
tindex = builder.CreateSelect(cmp, ConstantInt::get(T_int8, idx), tindex);
613-
},
614-
ut,
615-
counter);
616-
return tindex;
617-
}
618-
619605
static unsigned get_box_tindex(jl_datatype_t *jt, jl_value_t *ut)
620606
{
621607
unsigned new_idx = 0;
@@ -686,6 +672,7 @@ static Value* mask_gc_bits(Value *tag)
686672

687673
static Value *emit_typeof(Value *tt)
688674
{
675+
assert(tt != NULL && !isa<AllocaInst>(tt) && "expected a conditionally boxed value");
689676
// given p, a jl_value_t*, compute its type tag
690677
tt = tbaa_decorate(tbaa_tag, builder.CreateLoad(emit_typeptr_addr(tt)));
691678
return mask_gc_bits(tt);
@@ -700,13 +687,19 @@ static jl_cgval_t emit_typeof(const jl_cgval_t &p, jl_codectx_t *ctx)
700687
return mark_julia_type(emit_typeof(p.V), true, jl_datatype_type, ctx, /*needsroot*/false);
701688
}
702689
if (p.TIndex) {
703-
Value *tindex = p.TIndex;
690+
Value *tindex = builder.CreateAnd(p.TIndex, ConstantInt::get(T_int8, 0x7f));
704691
Value *pdatatype;
705-
if (p.V && !isa<AllocaInst>(p.V))
706-
pdatatype = emit_typeptr_addr(p.V);
707-
else
692+
unsigned counter;
693+
counter = 0;
694+
bool allunboxed = for_each_uniontype_small(
695+
[&](unsigned idx, jl_datatype_t *jt) { },
696+
p.typ,
697+
counter);
698+
if (allunboxed)
708699
pdatatype = Constant::getNullValue(T_ppjlvalue);
709-
unsigned counter = 0;
700+
else
701+
pdatatype = emit_typeptr_addr(p.V);
702+
counter = 0;
710703
for_each_uniontype_small(
711704
[&](unsigned idx, jl_datatype_t *jt) {
712705
Value *cmp = builder.CreateICmpEQ(tindex, ConstantInt::get(T_int8, idx));
@@ -715,7 +708,7 @@ static jl_cgval_t emit_typeof(const jl_cgval_t &p, jl_codectx_t *ctx)
715708
p.typ,
716709
counter);
717710
Value *datatype;
718-
if (p.V == NULL || isa<AllocaInst>(p.V)) {
711+
if (allunboxed) {
719712
datatype = tbaa_decorate(tbaa_const, builder.CreateLoad(pdatatype));
720713
}
721714
else {
@@ -774,21 +767,23 @@ static Value *emit_datatype_size(Value *dt)
774767
static Value *emit_sizeof(const jl_cgval_t &p, jl_codectx_t *ctx)
775768
{
776769
if (p.TIndex) {
777-
Value *tindex = p.TIndex;
770+
Value *tindex = builder.CreateAnd(p.TIndex, ConstantInt::get(T_int8, 0x7f));
778771
Value *size = ConstantInt::get(T_int32, -1);
779772
unsigned counter = 0;
780-
for_each_uniontype_small(
773+
bool allunboxed = for_each_uniontype_small(
781774
[&](unsigned idx, jl_datatype_t *jt) {
782775
Value *cmp = builder.CreateICmpEQ(tindex, ConstantInt::get(T_int8, idx));
783776
size = builder.CreateSelect(cmp, ConstantInt::get(T_int32, jl_datatype_size(jt)), size);
784777
},
785778
p.typ,
786779
counter);
787-
if (p.V != NULL && !isa<AllocaInst>(p.V)) {
780+
if (!allunboxed && p.ispointer() && p.V && !isa<AllocaInst>(p.V)) {
788781
BasicBlock *currBB = builder.GetInsertBlock();
789782
BasicBlock *dynloadBB = BasicBlock::Create(jl_LLVMContext, "dyn_sizeof", ctx->f);
790783
BasicBlock *postBB = BasicBlock::Create(jl_LLVMContext, "post_sizeof", ctx->f);
791-
Value *isboxed = builder.CreateICmpEQ(tindex, ConstantInt::get(T_int8, 0));
784+
Value *isboxed = builder.CreateICmpNE(
785+
builder.CreateAnd(p.TIndex, ConstantInt::get(T_int8, 0x80)),
786+
ConstantInt::get(T_int8, 0));
792787
builder.CreateCondBr(isboxed, dynloadBB, postBB);
793788
builder.SetInsertPoint(dynloadBB);
794789
Value *datatype = emit_typeof(p.V);
@@ -984,19 +979,14 @@ static Value *emit_isa(const jl_cgval_t &x, jl_value_t *type, const std::string
984979
if (jl_is_leaf_type(type)) {
985980
if (x.TIndex) {
986981
unsigned tindex = get_box_tindex((jl_datatype_t*)type, x.typ);
987-
if (!x.V || isa<AllocaInst>(x.V)) {
982+
if (tindex > 0) {
988983
// optimize more when we know that this is a split union-type where tindex = 0 is invalid
989-
assert(tindex > 0 && "x.typ should have been a union of leaftypes at this point");
990-
return builder.CreateICmpEQ(x.TIndex, ConstantInt::get(T_int8, tindex));
984+
Value *xtindex = builder.CreateAnd(x.TIndex, ConstantInt::get(T_int8, 0x7f));
985+
return builder.CreateICmpEQ(xtindex, ConstantInt::get(T_int8, tindex));
991986
}
992987
else {
993-
// test for ((tindex > 0 && x.TIndex == tindex) || (x.TIndex == 0 && typeof(x.V) == type))
994-
Value *istype_union = NULL;
995-
if (tindex > 0)
996-
istype_union = builder.CreateICmpEQ(x.TIndex, ConstantInt::get(T_int8, tindex));
997-
else
998-
istype_union = ConstantInt::get(T_int1, 0);
999-
Value *isboxed = builder.CreateICmpEQ(x.TIndex, ConstantInt::get(T_int8, 0));
988+
// test for (x.TIndex == 0x80 && typeof(x.V) == type)
989+
Value *isboxed = builder.CreateICmpEQ(x.TIndex, ConstantInt::get(T_int8, 0x80));
1000990
BasicBlock *currBB = builder.GetInsertBlock();
1001991
BasicBlock *isaBB = BasicBlock::Create(jl_LLVMContext, "isa", ctx->f);
1002992
BasicBlock *postBB = BasicBlock::Create(jl_LLVMContext, "post_isa", ctx->f);
@@ -1006,7 +996,7 @@ static Value *emit_isa(const jl_cgval_t &x, jl_value_t *type, const std::string
1006996
builder.CreateBr(postBB);
1007997
builder.SetInsertPoint(postBB);
1008998
PHINode *istype = builder.CreatePHI(T_int1, 2);
1009-
istype->addIncoming(istype_union, currBB);
999+
istype->addIncoming(ConstantInt::get(T_int1, 0), currBB);
10101000
istype->addIncoming(istype_boxed, isaBB);
10111001
return istype;
10121002
}
@@ -1906,6 +1896,8 @@ static Value *box_union(const jl_cgval_t &vinfo, jl_codectx_t *ctx, const SmallB
19061896
counter);
19071897
builder.SetInsertPoint(defaultBB);
19081898
if (skip.size() > 0 && skip[0]) {
1899+
// skip[0] specifies where to return NULL or the original pointer
1900+
// if the value was not handled above
19091901
box_merge->addIncoming(V_null, defaultBB);
19101902
builder.CreateBr(postBB);
19111903
}

0 commit comments

Comments
 (0)