# HG changeset patch # User kvn # Date 1233955863 28800 # Node ID 91263420e1c63420603fa891c12bd7da4ea2bf6f # Parent 7fe62bb75bf4ae8bb9bf2a27fc0d8a5282509bbe 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly") Summary: Move the CreateEx up before each round of IFG construction Reviewed-by: never, phh diff -r 7fe62bb75bf4 -r 91263420e1c6 src/share/vm/opto/block.cpp --- a/src/share/vm/opto/block.cpp Thu Feb 05 14:43:58 2009 -0800 +++ b/src/share/vm/opto/block.cpp Fri Feb 06 13:31:03 2009 -0800 @@ -880,6 +880,7 @@ } void PhaseCFG::verify( ) const { +#ifdef ASSERT // Verify sane CFG for( uint i = 0; i < _num_blocks; i++ ) { Block *b = _blocks[i]; @@ -894,10 +895,20 @@ "CreateEx must be first instruction in block" ); } for( uint k = 0; k < n->req(); k++ ) { - Node *use = n->in(k); - if( use && use != n ) { - assert( _bbs[use->_idx] || use->is_Con(), + Node *def = n->in(k); + if( def && def != n ) { + assert( _bbs[def->_idx] || def->is_Con(), "must have block; constants for debug info ok" ); + // Verify that instructions in the block is in correct order. + // Uses must follow their definition if they are at the same block. + // Mostly done to check that MachSpillCopy nodes are placed correctly + // when CreateEx node is moved in build_ifg_physical(). + if( _bbs[def->_idx] == b && + !(b->head()->is_Loop() && n->is_Phi()) && + // See (+++) comment in reg_split.cpp + !(n->jvms() != NULL && n->jvms()->is_monitor_use(k)) ) { + assert( b->find_node(def) < j, "uses must follow definitions" ); + } } } } @@ -914,6 +925,7 @@ assert( b->_num_succs == 2, "Conditional branch must have two targets"); } } +#endif } #endif diff -r 7fe62bb75bf4 -r 91263420e1c6 src/share/vm/opto/chaitin.cpp --- a/src/share/vm/opto/chaitin.cpp Thu Feb 05 14:43:58 2009 -0800 +++ b/src/share/vm/opto/chaitin.cpp Fri Feb 06 13:31:03 2009 -0800 @@ -228,6 +228,11 @@ // them for real. de_ssa(); +#ifdef ASSERT + // Veify the graph before RA. + verify(&live_arena); +#endif + { NOT_PRODUCT( Compile::TracePhase t3("computeLive", &_t_computeLive, TimeCompiler); ) _live = NULL; // Mark live as being not available @@ -306,12 +311,6 @@ C->check_node_count(2*NodeLimitFudgeFactor, "out of nodes after physical split"); if (C->failing()) return; -#ifdef ASSERT - if( VerifyOpto || VerifyRegisterAllocator ) { - _cfg.verify(); - verify_base_ptrs(&live_arena); - } -#endif NOT_PRODUCT( C->verify_graph_edges(); ) compact(); // Compact LRGs; return new lower max lrg @@ -340,7 +339,7 @@ compress_uf_map_for_nodes(); #ifdef ASSERT - if( VerifyOpto || VerifyRegisterAllocator ) _ifg->verify(this); + verify(&live_arena, true); #endif } else { ifg.SquareUp(); @@ -376,12 +375,6 @@ // Bail out if unique gets too large (ie - unique > MaxNodeLimit - 2*NodeLimitFudgeFactor) C->check_node_count(2*NodeLimitFudgeFactor, "out of nodes after split"); if (C->failing()) return; -#ifdef ASSERT - if( VerifyOpto || VerifyRegisterAllocator ) { - _cfg.verify(); - verify_base_ptrs(&live_arena); - } -#endif compact(); // Compact LRGs; return new lower max lrg @@ -412,7 +405,7 @@ } compress_uf_map_for_nodes(); #ifdef ASSERT - if( VerifyOpto || VerifyRegisterAllocator ) _ifg->verify(this); + verify(&live_arena, true); #endif cache_lrg_info(); // Count degree of LRGs @@ -432,6 +425,11 @@ // Peephole remove copies post_allocate_copy_removal(); +#ifdef ASSERT + // Veify the graph after RA. + verify(&live_arena); +#endif + // max_reg is past the largest *register* used. // Convert that to a frame_slot number. if( _max_reg <= _matcher._new_SP ) diff -r 7fe62bb75bf4 -r 91263420e1c6 src/share/vm/opto/chaitin.hpp --- a/src/share/vm/opto/chaitin.hpp Thu Feb 05 14:43:58 2009 -0800 +++ b/src/share/vm/opto/chaitin.hpp Fri Feb 06 13:31:03 2009 -0800 @@ -491,6 +491,8 @@ // Verify that base pointers and derived pointers are still sane void verify_base_ptrs( ResourceArea *a ) const; + void verify( ResourceArea *a, bool verify_ifg = false ) const; + void dump_for_spill_split_recycle() const; public: diff -r 7fe62bb75bf4 -r 91263420e1c6 src/share/vm/opto/ifg.cpp --- a/src/share/vm/opto/ifg.cpp Thu Feb 05 14:43:58 2009 -0800 +++ b/src/share/vm/opto/ifg.cpp Fri Feb 06 13:31:03 2009 -0800 @@ -471,12 +471,28 @@ // for the "collect_gc_info" phase later. IndexSet liveout(_live->live(b)); uint last_inst = b->end_idx(); - // Compute last phi index - uint last_phi; - for( last_phi = 1; last_phi < last_inst; last_phi++ ) - if( !b->_nodes[last_phi]->is_Phi() ) + // Compute first nonphi node index + uint first_inst; + for( first_inst = 1; first_inst < last_inst; first_inst++ ) + if( !b->_nodes[first_inst]->is_Phi() ) break; + // Spills could be inserted before CreateEx node which should be + // first instruction in block after Phis. Move CreateEx up. + for( uint insidx = first_inst; insidx < last_inst; insidx++ ) { + Node *ex = b->_nodes[insidx]; + if( ex->is_SpillCopy() ) continue; + if( insidx > first_inst && ex->is_Mach() && + ex->as_Mach()->ideal_Opcode() == Op_CreateEx ) { + // If the CreateEx isn't above all the MachSpillCopies + // then move it to the top. + b->_nodes.remove(insidx); + b->_nodes.insert(first_inst, ex); + } + // Stop once a CreateEx or any other node is found + break; + } + // Reset block's register pressure values for each ifg construction uint pressure[2], hrp_index[2]; pressure[0] = pressure[1] = 0; @@ -485,7 +501,7 @@ // Liveout things are presumed live for the whole block. We accumulate // 'area' accordingly. If they get killed in the block, we'll subtract // the unused part of the block from the area. - int inst_count = last_inst - last_phi; + int inst_count = last_inst - first_inst; double cost = (inst_count <= 0) ? 0.0 : b->_freq * double(inst_count); assert(!(cost < 0.0), "negative spill cost" ); IndexSetIterator elements(&liveout); diff -r 7fe62bb75bf4 -r 91263420e1c6 src/share/vm/opto/live.cpp --- a/src/share/vm/opto/live.cpp Thu Feb 05 14:43:58 2009 -0800 +++ b/src/share/vm/opto/live.cpp Fri Feb 06 13:31:03 2009 -0800 @@ -329,8 +329,12 @@ UseCompressedOops && check->as_Mach()->ideal_Opcode() == Op_DecodeN || #endif check->as_Mach()->ideal_Opcode() == Op_LoadP || - check->as_Mach()->ideal_Opcode() == Op_LoadKlass)) + check->as_Mach()->ideal_Opcode() == Op_LoadKlass)) { + // Valid nodes + } else { + check->dump(); assert(false,"Bad base or derived pointer"); + } } else { assert(is_derived,"Bad base pointer"); assert(check->is_Mach() && check->as_Mach()->ideal_Opcode() == Op_AddP,"Bad derived pointer"); @@ -346,4 +350,18 @@ } // End of forall blocks #endif } + +//------------------------------verify------------------------------------- +// Verify that graphs and base pointers are still sane. +void PhaseChaitin::verify( ResourceArea *a, bool verify_ifg ) const { +#ifdef ASSERT + if( VerifyOpto || VerifyRegisterAllocator ) { + _cfg.verify(); + verify_base_ptrs(a); + if(verify_ifg) + _ifg->verify(this); + } #endif +} + +#endif diff -r 7fe62bb75bf4 -r 91263420e1c6 src/share/vm/opto/reg_split.cpp --- a/src/share/vm/opto/reg_split.cpp Thu Feb 05 14:43:58 2009 -0800 +++ b/src/share/vm/opto/reg_split.cpp Fri Feb 06 13:31:03 2009 -0800 @@ -96,9 +96,7 @@ // its definer. while( i < b->_nodes.size() && (b->_nodes[i]->is_Proj() || - b->_nodes[i]->is_Phi() || - (b->_nodes[i]->is_Mach() && - b->_nodes[i]->as_Mach()->ideal_Opcode() == Op_CreateEx)) ) + b->_nodes[i]->is_Phi() ) ) i++; // Do not insert between a call and his Catch