@@ -3616,61 +3616,6 @@ static Value *emit_bitsunion_compare(jl_codectx_t &ctx, const jl_cgval_t &arg1,
36163616 return phi;
36173617}
36183618
3619- struct egal_desc {
3620- size_t offset;
3621- size_t nrepeats;
3622- size_t data_bytes;
3623- size_t padding_bytes;
3624- };
3625-
3626- template <typename callback>
3627- static size_t emit_masked_bits_compare (callback &emit_desc, jl_datatype_t *aty, egal_desc ¤t_desc)
3628- {
3629- // Memcmp, but with masked padding
3630- size_t data_bytes = 0 ;
3631- size_t padding_bytes = 0 ;
3632- size_t nfields = jl_datatype_nfields (aty);
3633- size_t total_size = jl_datatype_size (aty);
3634- assert (aty->layout ->flags .isbitsegal );
3635- for (size_t i = 0 ; i < nfields; ++i) {
3636- size_t offset = jl_field_offset (aty, i);
3637- size_t fend = i == nfields - 1 ? total_size : jl_field_offset (aty, i + 1 );
3638- size_t fsz = jl_field_size (aty, i);
3639- jl_datatype_t *fty = (jl_datatype_t *)jl_field_type (aty, i);
3640- assert (jl_is_datatype (fty)); // union fields should never reach here
3641- assert (fty->layout ->flags .isbitsegal );
3642- if (jl_field_isptr (aty, i) || !fty->layout ->flags .haspadding ) {
3643- // The field has no internal padding
3644- data_bytes += fsz;
3645- if (offset + fsz == fend) {
3646- // The field has no padding after. Merge this into the current
3647- // comparison range and go to next field.
3648- } else {
3649- padding_bytes = fend - offset - fsz;
3650- // Found padding. Either merge this into the current comparison
3651- // range, or emit the old one and start a new one.
3652- if (current_desc.data_bytes == data_bytes &&
3653- current_desc.padding_bytes == padding_bytes) {
3654- // Same as the previous range, just note that down, so we
3655- // emit this as a loop.
3656- current_desc.nrepeats += 1 ;
3657- } else {
3658- if (current_desc.nrepeats != 0 )
3659- emit_desc (current_desc);
3660- current_desc.nrepeats = 1 ;
3661- current_desc.data_bytes = data_bytes;
3662- current_desc.padding_bytes = padding_bytes;
3663- }
3664- data_bytes = 0 ;
3665- }
3666- } else {
3667- // The field may have internal padding. Recurse this.
3668- data_bytes += emit_masked_bits_compare (emit_desc, fty, current_desc);
3669- }
3670- }
3671- return data_bytes;
3672- }
3673-
36743619static Value *emit_bits_compare (jl_codectx_t &ctx, jl_cgval_t arg1, jl_cgval_t arg2)
36753620{
36763621 ++EmittedBitsCompares;
@@ -3747,92 +3692,6 @@ static Value *emit_bits_compare(jl_codectx_t &ctx, jl_cgval_t arg1, jl_cgval_t a
37473692 }
37483693 return ctx.builder .CreateICmpEQ (answer, ConstantInt::get (getInt32Ty (ctx.builder .getContext ()), 0 ));
37493694 }
3750- else if (sz > 512 && jl_struct_try_layout (sty) && sty->layout ->flags .isbitsegal ) {
3751- Value *varg1 = arg1.inline_roots .empty () && arg1.ispointer () ? data_pointer (ctx, arg1) :
3752- value_to_pointer (ctx, arg1).V ;
3753- Value *varg2 = arg2.inline_roots .empty () && arg2.ispointer () ? data_pointer (ctx, arg2) :
3754- value_to_pointer (ctx, arg2).V ;
3755- varg1 = emit_pointer_from_objref (ctx, varg1);
3756- varg2 = emit_pointer_from_objref (ctx, varg2);
3757-
3758- // See above for why we want to do this
3759- SmallVector<Value*, 0 > gc_uses;
3760- gc_uses.append (get_gc_roots_for (ctx, arg1));
3761- gc_uses.append (get_gc_roots_for (ctx, arg2));
3762- OperandBundleDef OpBundle (" jl_roots" , gc_uses);
3763-
3764- Value *answer = nullptr ;
3765- auto emit_desc = [&](egal_desc desc) {
3766- Value *ptr1 = varg1;
3767- Value *ptr2 = varg2;
3768- if (desc.offset != 0 ) {
3769- ptr1 = emit_ptrgep (ctx, ptr1, desc.offset );
3770- ptr2 = emit_ptrgep (ctx, ptr2, desc.offset );
3771- }
3772-
3773- Value *new_ptr1 = ptr1;
3774- Value *endptr1 = nullptr ;
3775- BasicBlock *postBB = nullptr ;
3776- BasicBlock *loopBB = nullptr ;
3777- PHINode *answerphi = nullptr ;
3778- if (desc.nrepeats != 1 ) {
3779- // Set up loop
3780- endptr1 = emit_ptrgep (ctx, ptr1, desc.nrepeats * (desc.data_bytes + desc.padding_bytes ));;
3781-
3782- BasicBlock *currBB = ctx.builder .GetInsertBlock ();
3783- loopBB = BasicBlock::Create (ctx.builder .getContext (), " egal_loop" , ctx.f );
3784- postBB = BasicBlock::Create (ctx.builder .getContext (), " post" , ctx.f );
3785- ctx.builder .CreateBr (loopBB);
3786-
3787- ctx.builder .SetInsertPoint (loopBB);
3788- Type *TInt1 = getInt1Ty (ctx.builder .getContext ());
3789- answerphi = ctx.builder .CreatePHI (TInt1, 2 );
3790- answerphi->addIncoming (answer ? answer : ConstantInt::get (TInt1, 1 ), currBB);
3791- answer = answerphi;
3792-
3793- PHINode *itr1 = ctx.builder .CreatePHI (ptr1->getType (), 2 );
3794- PHINode *itr2 = ctx.builder .CreatePHI (ptr2->getType (), 2 );
3795-
3796- new_ptr1 = emit_ptrgep (ctx, itr1, desc.data_bytes + desc.padding_bytes );
3797- itr1->addIncoming (ptr1, currBB);
3798- itr1->addIncoming (new_ptr1, loopBB);
3799-
3800- Value *new_ptr2 = emit_ptrgep (ctx, itr2, desc.data_bytes + desc.padding_bytes );
3801- itr2->addIncoming (ptr2, currBB);
3802- itr2->addIncoming (new_ptr2, loopBB);
3803-
3804- ptr1 = itr1;
3805- ptr2 = itr2;
3806- }
3807-
3808- // Emit memcmp. TODO: LLVM has a pass to expand this for additional
3809- // performance.
3810- Value *this_answer = ctx.builder .CreateCall (prepare_call (memcmp_func),
3811- { ptr1,
3812- ptr2,
3813- ConstantInt::get (ctx.types ().T_size , desc.data_bytes ) },
3814- ArrayRef<OperandBundleDef>(&OpBundle, gc_uses.empty () ? 0 : 1 ));
3815- this_answer = ctx.builder .CreateICmpEQ (this_answer, ConstantInt::get (getInt32Ty (ctx.builder .getContext ()), 0 ));
3816- answer = answer ? ctx.builder .CreateAnd (answer, this_answer) : this_answer;
3817- if (endptr1) {
3818- answerphi->addIncoming (answer, loopBB);
3819- Value *loopend = ctx.builder .CreateICmpEQ (new_ptr1, endptr1);
3820- ctx.builder .CreateCondBr (loopend, postBB, loopBB);
3821- ctx.builder .SetInsertPoint (postBB);
3822- }
3823- };
3824- egal_desc current_desc = {0 };
3825- size_t trailing_data_bytes = emit_masked_bits_compare (emit_desc, sty, current_desc);
3826- assert (current_desc.nrepeats != 0 );
3827- emit_desc (current_desc);
3828- if (trailing_data_bytes != 0 ) {
3829- current_desc.nrepeats = 1 ;
3830- current_desc.data_bytes = trailing_data_bytes;
3831- current_desc.padding_bytes = 0 ;
3832- emit_desc (current_desc);
3833- }
3834- return answer;
3835- }
38363695 else {
38373696 jl_svec_t *types = sty->types ;
38383697 Value *answer = ConstantInt::get (getInt1Ty (ctx.builder .getContext ()), 1 );
0 commit comments