Mercurial > hg > graal-jvmci-8
diff src/cpu/sparc/vm/sparc.ad @ 17877:17b2fbdb6637
8038297: Avoid placing CTI immediately following cbcond instruction on T4
Summary: Insert a nop between cbcond and CTI
Reviewed-by: kvn, twisti
author | iveresov |
---|---|
date | Thu, 10 Apr 2014 23:15:13 -0700 |
parents | 62c54fcc0a35 |
children | 0bf37f737702 |
line wrap: on
line diff
--- a/src/cpu/sparc/vm/sparc.ad Mon Apr 14 20:56:48 2014 -0400 +++ b/src/cpu/sparc/vm/sparc.ad Thu Apr 10 23:15:13 2014 -0700 @@ -1268,7 +1268,7 @@ void MachEpilogNode::format( PhaseRegAlloc *ra_, outputStream *st ) const { Compile* C = ra_->C; - if( do_polling() && ra_->C->is_method_compilation() ) { + if(do_polling() && ra_->C->is_method_compilation()) { st->print("SETHI #PollAddr,L0\t! Load Polling address\n\t"); #ifdef _LP64 st->print("LDX [L0],G0\t!Poll for Safepointing\n\t"); @@ -1277,8 +1277,12 @@ #endif } - if( do_polling() ) + if(do_polling()) { + if (UseCBCond && !ra_->C->is_method_compilation()) { + st->print("NOP\n\t"); + } st->print("RET\n\t"); + } st->print("RESTORE"); } @@ -1291,15 +1295,20 @@ __ verify_thread(); // If this does safepoint polling, then do it here - if( do_polling() && ra_->C->is_method_compilation() ) { + if(do_polling() && ra_->C->is_method_compilation()) { AddressLiteral polling_page(os::get_polling_page()); __ sethi(polling_page, L0); __ relocate(relocInfo::poll_return_type); - __ ld_ptr( L0, 0, G0 ); + __ ld_ptr(L0, 0, G0); } // If this is a return, then stuff the restore in the delay slot - if( do_polling() ) { + if(do_polling()) { + if (UseCBCond && !ra_->C->is_method_compilation()) { + // Insert extra padding for the case when the epilogue is preceded by + // a cbcond jump, which can't be followed by a CTI instruction + __ nop(); + } __ ret(); __ delayed()->restore(); } else { @@ -3330,7 +3339,18 @@ //----------Instruction Attributes--------------------------------------------- ins_attrib ins_cost(DEFAULT_COST); // Required cost attribute ins_attrib ins_size(32); // Required size attribute (in bits) -ins_attrib ins_avoid_back_to_back(0); // instruction should not be generated back to back + +// avoid_back_to_back attribute is an expression that must return +// one of the following values defined in MachNode: +// AVOID_NONE - instruction can be placed anywhere +// AVOID_BEFORE - instruction cannot be placed after an +// instruction with MachNode::AVOID_AFTER +// AVOID_AFTER - the next instruction cannot be the one +// with MachNode::AVOID_BEFORE +// AVOID_BEFORE_AND_AFTER - BEFORE and AFTER attributes at +// the same time +ins_attrib ins_avoid_back_to_back(MachNode::AVOID_NONE); + ins_attrib ins_short_branch(0); // Required flag: is this instruction a // non-matching short branch variant of some // long branch? @@ -6630,6 +6650,7 @@ ins_encode %{ __ encode_heap_oop($src$$Register, $dst$$Register); %} + ins_avoid_back_to_back(Universe::narrow_oop_base() == NULL ? AVOID_NONE : AVOID_BEFORE); ins_pipe(ialu_reg); %} @@ -9199,6 +9220,7 @@ __ ba(*L); __ delayed()->nop(); %} + ins_avoid_back_to_back(AVOID_BEFORE); ins_pipe(br); %} @@ -9217,7 +9239,7 @@ __ ba_short(*L); %} ins_short_branch(1); - ins_avoid_back_to_back(1); + ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER); ins_pipe(cbcond_reg_imm); %} @@ -9231,6 +9253,7 @@ format %{ "BP$cmp $icc,$labl" %} // Prim = bits 24-22, Secnd = bits 31-30 ins_encode( enc_bp( labl, cmp, icc ) ); + ins_avoid_back_to_back(AVOID_BEFORE); ins_pipe(br_cc); %} @@ -9242,6 +9265,7 @@ format %{ "BP$cmp $icc,$labl" %} // Prim = bits 24-22, Secnd = bits 31-30 ins_encode( enc_bp( labl, cmp, icc ) ); + ins_avoid_back_to_back(AVOID_BEFORE); ins_pipe(br_cc); %} @@ -9260,6 +9284,7 @@ __ bp( (Assembler::Condition)($cmp$$cmpcode), false, Assembler::ptr_cc, predict_taken, *L); __ delayed()->nop(); %} + ins_avoid_back_to_back(AVOID_BEFORE); ins_pipe(br_cc); %} @@ -9278,6 +9303,7 @@ __ fbp( (Assembler::Condition)($cmp$$cmpcode), false, (Assembler::CC)($fcc$$reg), predict_taken, *L); __ delayed()->nop(); %} + ins_avoid_back_to_back(AVOID_BEFORE); ins_pipe(br_fcc); %} @@ -9290,6 +9316,7 @@ format %{ "BP$cmp $icc,$labl\t! Loop end" %} // Prim = bits 24-22, Secnd = bits 31-30 ins_encode( enc_bp( labl, cmp, icc ) ); + ins_avoid_back_to_back(AVOID_BEFORE); ins_pipe(br_cc); %} @@ -9302,6 +9329,7 @@ format %{ "BP$cmp $icc,$labl\t! Loop end" %} // Prim = bits 24-22, Secnd = bits 31-30 ins_encode( enc_bp( labl, cmp, icc ) ); + ins_avoid_back_to_back(AVOID_BEFORE); ins_pipe(br_cc); %} @@ -9552,7 +9580,7 @@ __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, $op2$$Register, *L); %} ins_short_branch(1); - ins_avoid_back_to_back(1); + ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER); ins_pipe(cbcond_reg_reg); %} @@ -9570,7 +9598,7 @@ __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, $op2$$constant, *L); %} ins_short_branch(1); - ins_avoid_back_to_back(1); + ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER); ins_pipe(cbcond_reg_imm); %} @@ -9588,7 +9616,7 @@ __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, $op2$$Register, *L); %} ins_short_branch(1); - ins_avoid_back_to_back(1); + ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER); ins_pipe(cbcond_reg_reg); %} @@ -9606,7 +9634,7 @@ __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, $op2$$constant, *L); %} ins_short_branch(1); - ins_avoid_back_to_back(1); + ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER); ins_pipe(cbcond_reg_imm); %} @@ -9624,7 +9652,7 @@ __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::xcc, $op1$$Register, $op2$$Register, *L); %} ins_short_branch(1); - ins_avoid_back_to_back(1); + ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER); ins_pipe(cbcond_reg_reg); %} @@ -9642,7 +9670,7 @@ __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::xcc, $op1$$Register, $op2$$constant, *L); %} ins_short_branch(1); - ins_avoid_back_to_back(1); + ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER); ins_pipe(cbcond_reg_imm); %} @@ -9665,7 +9693,7 @@ __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::ptr_cc, $op1$$Register, $op2$$Register, *L); %} ins_short_branch(1); - ins_avoid_back_to_back(1); + ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER); ins_pipe(cbcond_reg_reg); %} @@ -9687,7 +9715,7 @@ __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::ptr_cc, $op1$$Register, G0, *L); %} ins_short_branch(1); - ins_avoid_back_to_back(1); + ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER); ins_pipe(cbcond_reg_reg); %} @@ -9705,7 +9733,7 @@ __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, $op2$$Register, *L); %} ins_short_branch(1); - ins_avoid_back_to_back(1); + ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER); ins_pipe(cbcond_reg_reg); %} @@ -9723,7 +9751,7 @@ __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, G0, *L); %} ins_short_branch(1); - ins_avoid_back_to_back(1); + ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER); ins_pipe(cbcond_reg_reg); %} @@ -9742,7 +9770,7 @@ __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, $op2$$Register, *L); %} ins_short_branch(1); - ins_avoid_back_to_back(1); + ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER); ins_pipe(cbcond_reg_reg); %} @@ -9760,7 +9788,7 @@ __ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, $op2$$constant, *L); %} ins_short_branch(1); - ins_avoid_back_to_back(1); + ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER); ins_pipe(cbcond_reg_imm); %} @@ -9777,6 +9805,7 @@ ins_cost(BRANCH_COST); format %{ "BR$cmp $op1,$labl" %} ins_encode( enc_bpr( labl, cmp, op1 ) ); + ins_avoid_back_to_back(AVOID_BEFORE); ins_pipe(br_reg); %} @@ -9789,6 +9818,7 @@ ins_cost(BRANCH_COST); format %{ "BR$cmp $op1,$labl" %} ins_encode( enc_bpr( labl, cmp, op1 ) ); + ins_avoid_back_to_back(AVOID_BEFORE); ins_pipe(br_reg); %} @@ -9801,6 +9831,7 @@ ins_cost(BRANCH_COST); format %{ "BR$cmp $op1,$labl" %} ins_encode( enc_bpr( labl, cmp, op1 ) ); + ins_avoid_back_to_back(AVOID_BEFORE); ins_pipe(br_reg); %} @@ -9841,6 +9872,7 @@ __ bp( (Assembler::Condition)($cmp$$cmpcode), false, Assembler::xcc, predict_taken, *L); __ delayed()->nop(); %} + ins_avoid_back_to_back(AVOID_BEFORE); ins_pipe(br_cc); %} @@ -9968,6 +10000,7 @@ ins_cost(CALL_COST); format %{ "CALL,static ; NOP ==> " %} ins_encode( Java_Static_Call( meth ), call_epilog ); + ins_avoid_back_to_back(AVOID_BEFORE); ins_pipe(simple_call); %} @@ -10004,6 +10037,7 @@ format %{ "CALL,runtime" %} ins_encode( Java_To_Runtime( meth ), call_epilog, adjust_long_from_native_call ); + ins_avoid_back_to_back(AVOID_BEFORE); ins_pipe(simple_call); %} @@ -10016,6 +10050,7 @@ ins_encode( Java_To_Runtime( meth ), call_epilog, adjust_long_from_native_call ); + ins_avoid_back_to_back(AVOID_BEFORE); ins_pipe(simple_call); %} @@ -10028,6 +10063,7 @@ ins_encode( Java_To_Runtime( meth ), call_epilog, adjust_long_from_native_call ); + ins_avoid_back_to_back(AVOID_BEFORE); ins_pipe(simple_call); %} @@ -10041,6 +10077,7 @@ ins_cost(CALL_COST); format %{ "Jmp $jump_target ; NOP \t! $method_oop holds method oop" %} ins_encode(form_jmpl(jump_target)); + ins_avoid_back_to_back(AVOID_BEFORE); ins_pipe(tail_call); %} @@ -10072,6 +10109,7 @@ // opcode(Assembler::jmpl_op3, Assembler::arith_op); // The hack duplicates the exception oop into G3, so that CreateEx can use it there. // ins_encode( form3_rs1_simm13_rd( jump_target, 0x00, R_G0 ), move_return_pc_to_o1() ); + ins_avoid_back_to_back(AVOID_BEFORE); ins_pipe(tail_call); %} @@ -10102,6 +10140,7 @@ // use the following format syntax format %{ "Jmp rethrow_stub" %} ins_encode(enc_rethrow); + ins_avoid_back_to_back(AVOID_BEFORE); ins_pipe(tail_call); %} @@ -10130,6 +10169,7 @@ ins_cost(DEFAULT_COST*10); format %{ "CALL PartialSubtypeCheck\n\tNOP" %} ins_encode( enc_PartialSubtypeCheck() ); + ins_avoid_back_to_back(AVOID_BEFORE); ins_pipe(partial_subtype_check_pipe); %} @@ -10139,6 +10179,7 @@ ins_cost(DEFAULT_COST*10); format %{ "CALL PartialSubtypeCheck\n\tNOP\t# (sets condition codes)" %} ins_encode( enc_PartialSubtypeCheck() ); + ins_avoid_back_to_back(AVOID_BEFORE); ins_pipe(partial_subtype_check_pipe); %}