< prev index next >

src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp

Print this page
rev 13098 : 8182161: aarch64: combine andr+cbnz into tbnz when possible
Summary: Combine andr+cbnz into tbnz when possible to save one instruction
Reviewed-by: aph


2723       __ cbz(rscratch1, ok);
2724       __ stop("exact klass and actual klass differ");
2725       __ bind(ok);
2726     }
2727 #endif
2728     if (!no_conflict) {
2729       if (exact_klass == NULL || TypeEntries::is_type_none(current_klass)) {
2730         if (exact_klass != NULL) {
2731           __ mov_metadata(tmp, exact_klass->constant_encoding());
2732         } else {
2733           __ load_klass(tmp, tmp);
2734         }
2735 
2736         __ ldr(rscratch2, mdo_addr);
2737         __ eor(tmp, tmp, rscratch2);
2738         __ andr(rscratch1, tmp, TypeEntries::type_klass_mask);
2739         // klass seen before, nothing to do. The unknown bit may have been
2740         // set already but no need to check.
2741         __ cbz(rscratch1, next);
2742 
2743         __ andr(rscratch1, tmp, TypeEntries::type_unknown);
2744         __ cbnz(rscratch1, next); // already unknown. Nothing to do anymore.
2745 
2746         if (TypeEntries::is_type_none(current_klass)) {
2747           __ cbz(rscratch2, none);
2748           __ cmp(rscratch2, TypeEntries::null_seen);
2749           __ br(Assembler::EQ, none);
2750           // There is a chance that the checks above (re-reading profiling
2751           // data from memory) fail if another thread has just set the
2752           // profiling to this obj's klass
2753           __ dmb(Assembler::ISHLD);
2754           __ ldr(rscratch2, mdo_addr);
2755           __ eor(tmp, tmp, rscratch2);
2756           __ andr(rscratch1, tmp, TypeEntries::type_klass_mask);
2757           __ cbz(rscratch1, next);
2758         }
2759       } else {
2760         assert(ciTypeEntries::valid_ciklass(current_klass) != NULL &&
2761                ciTypeEntries::valid_ciklass(current_klass) != exact_klass, "conflict only");
2762 
2763         __ ldr(tmp, mdo_addr);
2764         __ andr(rscratch1, tmp, TypeEntries::type_unknown);
2765         __ cbnz(rscratch1, next); // already unknown. Nothing to do anymore.
2766       }
2767 
2768       // different than before. Cannot keep accurate profile.
2769       __ ldr(rscratch2, mdo_addr);
2770       __ orr(rscratch2, rscratch2, TypeEntries::type_unknown);
2771       __ str(rscratch2, mdo_addr);
2772 
2773       if (TypeEntries::is_type_none(current_klass)) {
2774         __ b(next);
2775 
2776         __ bind(none);
2777         // first time here. Set profile type.
2778         __ str(tmp, mdo_addr);
2779       }
2780     } else {
2781       // There's a single possible klass at this profile point
2782       assert(exact_klass != NULL, "should be");
2783       if (TypeEntries::is_type_none(current_klass)) {
2784         __ mov_metadata(tmp, exact_klass->constant_encoding());
2785         __ ldr(rscratch2, mdo_addr);


2795           __ br(Assembler::EQ, ok);
2796           // may have been set by another thread
2797           __ dmb(Assembler::ISHLD);
2798           __ mov_metadata(rscratch1, exact_klass->constant_encoding());
2799           __ ldr(rscratch2, mdo_addr);
2800           __ eor(rscratch2, rscratch1, rscratch2);
2801           __ andr(rscratch2, rscratch2, TypeEntries::type_mask);
2802           __ cbz(rscratch2, ok);
2803 
2804           __ stop("unexpected profiling mismatch");
2805           __ bind(ok);
2806         }
2807 #endif
2808         // first time here. Set profile type.
2809         __ ldr(tmp, mdo_addr);
2810       } else {
2811         assert(ciTypeEntries::valid_ciklass(current_klass) != NULL &&
2812                ciTypeEntries::valid_ciklass(current_klass) != exact_klass, "inconsistent");
2813 
2814         __ ldr(tmp, mdo_addr);
2815         __ andr(rscratch1, tmp, TypeEntries::type_unknown);
2816         __ cbnz(rscratch1, next); // already unknown. Nothing to do anymore.
2817 
2818         __ orr(tmp, tmp, TypeEntries::type_unknown);
2819         __ str(tmp, mdo_addr);
2820         // FIXME: Write barrier needed here?
2821       }
2822     }
2823 
2824     __ bind(next);
2825   }
2826   COMMENT("} emit_profile_type");
2827 }
2828 
2829 
2830 void LIR_Assembler::align_backward_branch_target() {
2831 }
2832 
2833 
2834 void LIR_Assembler::negate(LIR_Opr left, LIR_Opr dest) {
2835   if (left->is_single_cpu()) {
2836     assert(dest->is_single_cpu(), "expect single result reg");




2723       __ cbz(rscratch1, ok);
2724       __ stop("exact klass and actual klass differ");
2725       __ bind(ok);
2726     }
2727 #endif
2728     if (!no_conflict) {
2729       if (exact_klass == NULL || TypeEntries::is_type_none(current_klass)) {
2730         if (exact_klass != NULL) {
2731           __ mov_metadata(tmp, exact_klass->constant_encoding());
2732         } else {
2733           __ load_klass(tmp, tmp);
2734         }
2735 
2736         __ ldr(rscratch2, mdo_addr);
2737         __ eor(tmp, tmp, rscratch2);
2738         __ andr(rscratch1, tmp, TypeEntries::type_klass_mask);
2739         // klass seen before, nothing to do. The unknown bit may have been
2740         // set already but no need to check.
2741         __ cbz(rscratch1, next);
2742 
2743         __ tbnz(tmp, exact_log2(TypeEntries::type_unknown), next); // already unknown. Nothing to do anymore.

2744 
2745         if (TypeEntries::is_type_none(current_klass)) {
2746           __ cbz(rscratch2, none);
2747           __ cmp(rscratch2, TypeEntries::null_seen);
2748           __ br(Assembler::EQ, none);
2749           // There is a chance that the checks above (re-reading profiling
2750           // data from memory) fail if another thread has just set the
2751           // profiling to this obj's klass
2752           __ dmb(Assembler::ISHLD);
2753           __ ldr(rscratch2, mdo_addr);
2754           __ eor(tmp, tmp, rscratch2);
2755           __ andr(rscratch1, tmp, TypeEntries::type_klass_mask);
2756           __ cbz(rscratch1, next);
2757         }
2758       } else {
2759         assert(ciTypeEntries::valid_ciklass(current_klass) != NULL &&
2760                ciTypeEntries::valid_ciklass(current_klass) != exact_klass, "conflict only");
2761 
2762         __ ldr(tmp, mdo_addr);
2763         __ tbnz(tmp, exact_log2(TypeEntries::type_unknown), next); // already unknown. Nothing to do anymore.

2764       }
2765 
2766       // different than before. Cannot keep accurate profile.
2767       __ ldr(rscratch2, mdo_addr);
2768       __ orr(rscratch2, rscratch2, TypeEntries::type_unknown);
2769       __ str(rscratch2, mdo_addr);
2770 
2771       if (TypeEntries::is_type_none(current_klass)) {
2772         __ b(next);
2773 
2774         __ bind(none);
2775         // first time here. Set profile type.
2776         __ str(tmp, mdo_addr);
2777       }
2778     } else {
2779       // There's a single possible klass at this profile point
2780       assert(exact_klass != NULL, "should be");
2781       if (TypeEntries::is_type_none(current_klass)) {
2782         __ mov_metadata(tmp, exact_klass->constant_encoding());
2783         __ ldr(rscratch2, mdo_addr);


2793           __ br(Assembler::EQ, ok);
2794           // may have been set by another thread
2795           __ dmb(Assembler::ISHLD);
2796           __ mov_metadata(rscratch1, exact_klass->constant_encoding());
2797           __ ldr(rscratch2, mdo_addr);
2798           __ eor(rscratch2, rscratch1, rscratch2);
2799           __ andr(rscratch2, rscratch2, TypeEntries::type_mask);
2800           __ cbz(rscratch2, ok);
2801 
2802           __ stop("unexpected profiling mismatch");
2803           __ bind(ok);
2804         }
2805 #endif
2806         // first time here. Set profile type.
2807         __ ldr(tmp, mdo_addr);
2808       } else {
2809         assert(ciTypeEntries::valid_ciklass(current_klass) != NULL &&
2810                ciTypeEntries::valid_ciklass(current_klass) != exact_klass, "inconsistent");
2811 
2812         __ ldr(tmp, mdo_addr);
2813         __ tbnz(tmp, exact_log2(TypeEntries::type_unknown), next); // already unknown. Nothing to do anymore.

2814 
2815         __ orr(tmp, tmp, TypeEntries::type_unknown);
2816         __ str(tmp, mdo_addr);
2817         // FIXME: Write barrier needed here?
2818       }
2819     }
2820 
2821     __ bind(next);
2822   }
2823   COMMENT("} emit_profile_type");
2824 }
2825 
2826 
2827 void LIR_Assembler::align_backward_branch_target() {
2828 }
2829 
2830 
2831 void LIR_Assembler::negate(LIR_Opr left, LIR_Opr dest) {
2832   if (left->is_single_cpu()) {
2833     assert(dest->is_single_cpu(), "expect single result reg");


< prev index next >