--- old/src/hotspot/share/opto/compile.cpp 2020-01-17 17:14:31.275116088 +0100 +++ new/src/hotspot/share/opto/compile.cpp 2020-01-17 17:14:31.176116093 +0100 @@ -82,6 +82,9 @@ #if INCLUDE_ZGC #include "gc/z/c2/zBarrierSetC2.hpp" #endif +#if INCLUDE_SHENANDOAHGC +#include "gc/shenandoah/c2/shenandoahBarrierSetC2.hpp" +#endif // -------------------- Compile::mach_constant_base_node ----------------------- @@ -2104,7 +2107,7 @@ // PhaseIdealLoop is expensive so we only try it once we are // out of live nodes and we only try it again if the previous // helped got the number of nodes down significantly - PhaseIdealLoop ideal_loop( igvn, false, true ); + PhaseIdealLoop ideal_loop(igvn, LoopOptsNone); if (failing()) return; low_live_nodes = live_nodes(); _major_progress = true; @@ -2155,6 +2158,21 @@ } +bool Compile::optimize_loops(int& loop_opts_cnt, PhaseIterGVN& igvn, LoopOptsMode mode) { + if(loop_opts_cnt > 0) { + debug_only( int cnt = 0; ); + while(major_progress() && (loop_opts_cnt > 0)) { + TracePhase tp("idealLoop", &timers[_t_idealLoop]); + assert( cnt++ < 40, "infinite cycle in loop optimization" ); + PhaseIdealLoop ideal_loop(igvn, mode); + loop_opts_cnt--; + if (failing()) return false; + if (major_progress()) print_method(PHASE_PHASEIDEALLOOP_ITERATIONS, 2); + } + } + return true; +} + //------------------------------Optimize--------------------------------------- // Given a graph, optimize it. void Compile::Optimize() { @@ -2193,10 +2211,10 @@ igvn.optimize(); } - print_method(PHASE_ITER_GVN1, 2); - if (failing()) return; + print_method(PHASE_ITER_GVN1, 2); + inline_incrementally(igvn); print_method(PHASE_INCREMENTAL_INLINE, 2); @@ -2245,7 +2263,7 @@ if (has_loops()) { // Cleanup graph (remove dead nodes). TracePhase tp("idealLoop", &timers[_t_idealLoop]); - PhaseIdealLoop ideal_loop( igvn, false, true ); + PhaseIdealLoop ideal_loop(igvn, LoopOptsNone); if (major_progress()) print_method(PHASE_PHASEIDEAL_BEFORE_EA, 2); if (failing()) return; } @@ -2280,7 +2298,7 @@ if((loop_opts_cnt > 0) && (has_loops() || has_split_ifs())) { { TracePhase tp("idealLoop", &timers[_t_idealLoop]); - PhaseIdealLoop ideal_loop( igvn, true ); + PhaseIdealLoop ideal_loop(igvn, LoopOptsDefault); loop_opts_cnt--; if (major_progress()) print_method(PHASE_PHASEIDEALLOOP1, 2); if (failing()) return; @@ -2288,7 +2306,7 @@ // Loop opts pass if partial peeling occurred in previous pass if(PartialPeelLoop && major_progress() && (loop_opts_cnt > 0)) { TracePhase tp("idealLoop", &timers[_t_idealLoop]); - PhaseIdealLoop ideal_loop( igvn, false ); + PhaseIdealLoop ideal_loop(igvn, LoopOptsSkipSplitIf); loop_opts_cnt--; if (major_progress()) print_method(PHASE_PHASEIDEALLOOP2, 2); if (failing()) return; @@ -2296,7 +2314,7 @@ // Loop opts pass for loop-unrolling before CCP if(major_progress() && (loop_opts_cnt > 0)) { TracePhase tp("idealLoop", &timers[_t_idealLoop]); - PhaseIdealLoop ideal_loop( igvn, false ); + PhaseIdealLoop ideal_loop(igvn, LoopOptsSkipSplitIf); loop_opts_cnt--; if (major_progress()) print_method(PHASE_PHASEIDEALLOOP3, 2); } @@ -2332,16 +2350,8 @@ // Loop transforms on the ideal graph. Range Check Elimination, // peeling, unrolling, etc. - if(loop_opts_cnt > 0) { - debug_only( int cnt = 0; ); - while(major_progress() && (loop_opts_cnt > 0)) { - TracePhase tp("idealLoop", &timers[_t_idealLoop]); - assert( cnt++ < 40, "infinite cycle in loop optimization" ); - PhaseIdealLoop ideal_loop( igvn, true); - loop_opts_cnt--; - if (major_progress()) print_method(PHASE_PHASEIDEALLOOP_ITERATIONS, 2); - if (failing()) return; - } + if (!optimize_loops(loop_opts_cnt, igvn, LoopOptsDefault)) { + return; } #if INCLUDE_ZGC @@ -2383,6 +2393,15 @@ } } + print_method(PHASE_BEFORE_BARRIER_EXPAND, 2); + +#if INCLUDE_SHENANDOAHGC + if (UseShenandoahGC && ((ShenandoahBarrierSetC2*)BarrierSet::barrier_set()->barrier_set_c2())->expand_barriers(this, igvn)) { + assert(failing(), "must bail out w/ explicit message"); + return; + } +#endif + if (opaque4_count() > 0) { C->remove_opaque4_nodes(igvn); igvn.optimize(); @@ -2823,6 +2842,17 @@ case Op_CallLeafNoFP: { assert (n->is_Call(), ""); CallNode *call = n->as_Call(); +#if INCLUDE_SHENANDOAHGC + if (UseShenandoahGC && ShenandoahBarrierSetC2::is_shenandoah_wb_pre_call(call)) { + uint cnt = ShenandoahBarrierSetC2::write_ref_field_pre_entry_Type()->domain()->cnt(); + if (call->req() > cnt) { + assert(call->req() == cnt+1, "only one extra input"); + Node* addp = call->in(cnt); + assert(!ShenandoahBarrierSetC2::has_only_shenandoah_wb_pre_uses(addp), "useless address computation?"); + call->del_req(cnt); + } + } +#endif // Count call sites where the FP mode bit would have to be flipped. // Do not count uncommon runtime calls: // uncommon_trap, _complete_monitor_locking, _complete_monitor_unlocking, @@ -3387,6 +3417,28 @@ } break; } +#if INCLUDE_SHENANDOAHGC + case Op_ShenandoahCompareAndSwapP: + case Op_ShenandoahCompareAndSwapN: + case Op_ShenandoahWeakCompareAndSwapN: + case Op_ShenandoahWeakCompareAndSwapP: + case Op_ShenandoahCompareAndExchangeP: + case Op_ShenandoahCompareAndExchangeN: +#ifdef ASSERT + if( VerifyOptoOopOffsets ) { + MemNode* mem = n->as_Mem(); + // Check to see if address types have grounded out somehow. + const TypeInstPtr *tp = mem->in(MemNode::Address)->bottom_type()->isa_instptr(); + ciInstanceKlass *k = tp->klass()->as_instance_klass(); + bool oop_offset_is_sane = k->contains_field_offset(tp->offset()); + assert( !tp || oop_offset_is_sane, "" ); + } +#endif + break; + case Op_ShenandoahLoadReferenceBarrier: + assert(false, "should have been expanded already"); + break; +#endif case Op_RangeCheck: { RangeCheckNode* rc = n->as_RangeCheck(); Node* iff = new IfNode(rc->in(0), rc->in(1), rc->_prob, rc->_fcnt); @@ -3823,10 +3875,18 @@ // Currently supported: // - G1 pre-barriers (see GraphKit::g1_write_barrier_pre()) void Compile::verify_barriers() { -#if INCLUDE_G1GC - if (UseG1GC) { +#if INCLUDE_G1GC || INCLUDE_SHENANDOAHGC + if (UseG1GC || UseShenandoahGC) { // Verify G1 pre-barriers + +#if INCLUDE_G1GC && INCLUDE_SHENANDOAHGC + const int marking_offset = in_bytes(UseG1GC ? G1ThreadLocalData::satb_mark_queue_active_offset() + : ShenandoahThreadLocalData::satb_mark_queue_active_offset()); +#elif INCLUDE_G1GC const int marking_offset = in_bytes(G1ThreadLocalData::satb_mark_queue_active_offset()); +#else + const int marking_offset = in_bytes(ShenandoahThreadLocalData::satb_mark_queue_active_offset()); +#endif ResourceArea *area = Thread::current()->resource_area(); Unique_Node_List visited(area);