aboutsummaryrefslogtreecommitdiff
path: root/src/share
diff options
context:
space:
mode:
authorkvn <none@none>2009-02-06 13:31:03 -0800
committerkvn <none@none>2009-02-06 13:31:03 -0800
commit370ced2059af8ea7185e13ba0a8d6a6cb73542f8 (patch)
treedeed0ff4bcd880677e5ebd12fc2f671664eb0c0b /src/share
parent4ebd0c3762db446bd36e88b1b372cd4f56a7e001 (diff)
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
Diffstat (limited to 'src/share')
-rw-r--r--src/share/vm/opto/block.cpp18
-rw-r--r--src/share/vm/opto/chaitin.cpp26
-rw-r--r--src/share/vm/opto/chaitin.hpp2
-rw-r--r--src/share/vm/opto/ifg.cpp26
-rw-r--r--src/share/vm/opto/live.cpp20
-rw-r--r--src/share/vm/opto/reg_split.cpp4
6 files changed, 70 insertions, 26 deletions
diff --git a/src/share/vm/opto/block.cpp b/src/share/vm/opto/block.cpp
index 1de186518..cf15fa7c4 100644
--- a/src/share/vm/opto/block.cpp
+++ b/src/share/vm/opto/block.cpp
@@ -880,6 +880,7 @@ void PhaseCFG::dump_headers() {
}
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 @@ void PhaseCFG::verify( ) const {
"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 @@ void PhaseCFG::verify( ) const {
assert( b->_num_succs == 2, "Conditional branch must have two targets");
}
}
+#endif
}
#endif
diff --git a/src/share/vm/opto/chaitin.cpp b/src/share/vm/opto/chaitin.cpp
index 3d98f65d6..82558d8f5 100644
--- a/src/share/vm/opto/chaitin.cpp
+++ b/src/share/vm/opto/chaitin.cpp
@@ -228,6 +228,11 @@ void PhaseChaitin::Register_Allocate() {
// 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 @@ void PhaseChaitin::Register_Allocate() {
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 @@ void PhaseChaitin::Register_Allocate() {
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 @@ void PhaseChaitin::Register_Allocate() {
// 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 @@ void PhaseChaitin::Register_Allocate() {
}
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 @@ void PhaseChaitin::Register_Allocate() {
// 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 --git a/src/share/vm/opto/chaitin.hpp b/src/share/vm/opto/chaitin.hpp
index 9c7cc593e..307d6110c 100644
--- a/src/share/vm/opto/chaitin.hpp
+++ b/src/share/vm/opto/chaitin.hpp
@@ -491,6 +491,8 @@ private:
// 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 --git a/src/share/vm/opto/ifg.cpp b/src/share/vm/opto/ifg.cpp
index 1a352de72..b3250513d 100644
--- a/src/share/vm/opto/ifg.cpp
+++ b/src/share/vm/opto/ifg.cpp
@@ -471,12 +471,28 @@ uint PhaseChaitin::build_ifg_physical( ResourceArea *a ) {
// 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 @@ uint PhaseChaitin::build_ifg_physical( ResourceArea *a ) {
// 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 --git a/src/share/vm/opto/live.cpp b/src/share/vm/opto/live.cpp
index 48717fc66..d2ff51505 100644
--- a/src/share/vm/opto/live.cpp
+++ b/src/share/vm/opto/live.cpp
@@ -329,8 +329,12 @@ void PhaseChaitin::verify_base_ptrs( ResourceArea *a ) const {
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 @@ void PhaseChaitin::verify_base_ptrs( ResourceArea *a ) const {
} // 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 --git a/src/share/vm/opto/reg_split.cpp b/src/share/vm/opto/reg_split.cpp
index 709db17d9..003df4c48 100644
--- a/src/share/vm/opto/reg_split.cpp
+++ b/src/share/vm/opto/reg_split.cpp
@@ -96,9 +96,7 @@ void PhaseChaitin::insert_proj( Block *b, uint i, Node *spill, uint maxlrg ) {
// 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