@@ -602,20 +602,6 @@ static bool for_each_uniontype_small(
602
602
603
603
static Value *emit_typeof_boxed (const jl_cgval_t &p, jl_codectx_t *ctx);
604
604
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
-
619
605
static unsigned get_box_tindex (jl_datatype_t *jt, jl_value_t *ut)
620
606
{
621
607
unsigned new_idx = 0 ;
@@ -686,6 +672,7 @@ static Value* mask_gc_bits(Value *tag)
686
672
687
673
static Value *emit_typeof (Value *tt)
688
674
{
675
+ assert (tt != NULL && !isa<AllocaInst>(tt) && " expected a conditionally boxed value" );
689
676
// given p, a jl_value_t*, compute its type tag
690
677
tt = tbaa_decorate (tbaa_tag, builder.CreateLoad (emit_typeptr_addr (tt)));
691
678
return mask_gc_bits (tt);
@@ -700,13 +687,19 @@ static jl_cgval_t emit_typeof(const jl_cgval_t &p, jl_codectx_t *ctx)
700
687
return mark_julia_type (emit_typeof (p.V ), true , jl_datatype_type, ctx, /* needsroot*/ false );
701
688
}
702
689
if (p.TIndex ) {
703
- Value *tindex = p.TIndex ;
690
+ Value *tindex = builder. CreateAnd ( p.TIndex , ConstantInt::get (T_int8, 0x7f )) ;
704
691
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)
708
699
pdatatype = Constant::getNullValue (T_ppjlvalue);
709
- unsigned counter = 0 ;
700
+ else
701
+ pdatatype = emit_typeptr_addr (p.V );
702
+ counter = 0 ;
710
703
for_each_uniontype_small (
711
704
[&](unsigned idx, jl_datatype_t *jt) {
712
705
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)
715
708
p.typ ,
716
709
counter);
717
710
Value *datatype;
718
- if (p. V == NULL || isa<AllocaInst>(p. V ) ) {
711
+ if (allunboxed ) {
719
712
datatype = tbaa_decorate (tbaa_const, builder.CreateLoad (pdatatype));
720
713
}
721
714
else {
@@ -774,21 +767,23 @@ static Value *emit_datatype_size(Value *dt)
774
767
static Value *emit_sizeof (const jl_cgval_t &p, jl_codectx_t *ctx)
775
768
{
776
769
if (p.TIndex ) {
777
- Value *tindex = p.TIndex ;
770
+ Value *tindex = builder. CreateAnd ( p.TIndex , ConstantInt::get (T_int8, 0x7f )) ;
778
771
Value *size = ConstantInt::get (T_int32, -1 );
779
772
unsigned counter = 0 ;
780
- for_each_uniontype_small (
773
+ bool allunboxed = for_each_uniontype_small (
781
774
[&](unsigned idx, jl_datatype_t *jt) {
782
775
Value *cmp = builder.CreateICmpEQ (tindex, ConstantInt::get (T_int8, idx));
783
776
size = builder.CreateSelect (cmp, ConstantInt::get (T_int32, jl_datatype_size (jt)), size);
784
777
},
785
778
p.typ ,
786
779
counter);
787
- if (p. V != NULL && !isa<AllocaInst>(p.V )) {
780
+ if (!allunboxed && p. ispointer () && p. V && !isa<AllocaInst>(p.V )) {
788
781
BasicBlock *currBB = builder.GetInsertBlock ();
789
782
BasicBlock *dynloadBB = BasicBlock::Create (jl_LLVMContext, " dyn_sizeof" , ctx->f );
790
783
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 ));
792
787
builder.CreateCondBr (isboxed, dynloadBB, postBB);
793
788
builder.SetInsertPoint (dynloadBB);
794
789
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
984
979
if (jl_is_leaf_type (type)) {
985
980
if (x.TIndex ) {
986
981
unsigned tindex = get_box_tindex ((jl_datatype_t *)type, x.typ );
987
- if (!x. V || isa<AllocaInst>(x. V ) ) {
982
+ if (tindex > 0 ) {
988
983
// 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));
991
986
}
992
987
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 ));
1000
990
BasicBlock *currBB = builder.GetInsertBlock ();
1001
991
BasicBlock *isaBB = BasicBlock::Create (jl_LLVMContext, " isa" , ctx->f );
1002
992
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
1006
996
builder.CreateBr (postBB);
1007
997
builder.SetInsertPoint (postBB);
1008
998
PHINode *istype = builder.CreatePHI (T_int1, 2 );
1009
- istype->addIncoming (istype_union , currBB);
999
+ istype->addIncoming (ConstantInt::get (T_int1, 0 ) , currBB);
1010
1000
istype->addIncoming (istype_boxed, isaBB);
1011
1001
return istype;
1012
1002
}
@@ -1906,6 +1896,8 @@ static Value *box_union(const jl_cgval_t &vinfo, jl_codectx_t *ctx, const SmallB
1906
1896
counter);
1907
1897
builder.SetInsertPoint (defaultBB);
1908
1898
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
1909
1901
box_merge->addIncoming (V_null, defaultBB);
1910
1902
builder.CreateBr (postBB);
1911
1903
}
0 commit comments