From 4051964fe2f1bb2a7dbd8b8868f02616881e63fb Mon Sep 17 00:00:00 2001 From: never Date: Mon, 18 Aug 2008 23:17:51 -0700 Subject: [PATCH] 6732194: Data corruption dependent on -server/-client/-Xbatch Summary: rematerializing nodes results in incorrect inputs Reviewed-by: rasbold --- src/share/vm/opto/chaitin.cpp | 6 +++--- src/share/vm/opto/chaitin.hpp | 5 ++++- src/share/vm/opto/coalesce.cpp | 4 ++-- src/share/vm/opto/ifg.cpp | 2 +- src/share/vm/opto/reg_split.cpp | 14 +++++++++++--- 5 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/share/vm/opto/chaitin.cpp b/src/share/vm/opto/chaitin.cpp index 5d7efdb76..74a0fce90 100644 --- a/src/share/vm/opto/chaitin.cpp +++ b/src/share/vm/opto/chaitin.cpp @@ -43,7 +43,7 @@ void LRG::dump( ) const { if( _degree_valid ) tty->print( "%d ", _eff_degree ); else tty->print("? "); - if( _def == NodeSentinel ) { + if( is_multidef() ) { tty->print("MultiDef "); if (_defs != NULL) { tty->print("("); @@ -765,7 +765,7 @@ void PhaseChaitin::gather_lrg_masks( bool after_aggressive ) { // if the LRG is an unaligned pair, we will have to spill // so clear the LRG's register mask if it is not already spilled if ( !n->is_SpillCopy() && - (lrg._def == NULL || lrg._def == NodeSentinel || !lrg._def->is_SpillCopy()) && + (lrg._def == NULL || lrg.is_multidef() || !lrg._def->is_SpillCopy()) && lrgmask.is_misaligned_Pair()) { lrg.Clear(); } @@ -1282,7 +1282,7 @@ uint PhaseChaitin::Select( ) { // Live range is live and no colors available else { assert( lrg->alive(), "" ); - assert( !lrg->_fat_proj || lrg->_def == NodeSentinel || + assert( !lrg->_fat_proj || lrg->is_multidef() || lrg->_def->outcnt() > 0, "fat_proj cannot spill"); assert( !orig_mask.is_AllStack(), "All Stack does not spill" ); diff --git a/src/share/vm/opto/chaitin.hpp b/src/share/vm/opto/chaitin.hpp index 273fb0320..9c7cc593e 100644 --- a/src/share/vm/opto/chaitin.hpp +++ b/src/share/vm/opto/chaitin.hpp @@ -156,6 +156,8 @@ public: // Alive if non-zero, dead if zero bool alive() const { return _def != NULL; } + bool is_multidef() const { return _def == NodeSentinel; } + bool is_singledef() const { return _def != NodeSentinel; } #ifndef PRODUCT void dump( ) const; @@ -320,7 +322,8 @@ class PhaseChaitin : public PhaseRegAlloc { uint split_DEF( Node *def, Block *b, int loc, uint max, Node **Reachblock, Node **debug_defs, GrowableArray splits, int slidx ); uint split_USE( Node *def, Block *b, Node *use, uint useidx, uint max, bool def_down, bool cisc_sp, GrowableArray splits, int slidx ); int clone_projs( Block *b, uint idx, Node *con, Node *copy, uint &maxlrg ); - Node *split_Rematerialize( Node *def, Block *b, uint insidx, uint &maxlrg, GrowableArray splits, int slidx, uint *lrg2reach, Node **Reachblock, bool walkThru ); + Node *split_Rematerialize(Node *def, Block *b, uint insidx, uint &maxlrg, GrowableArray splits, + int slidx, uint *lrg2reach, Node **Reachblock, bool walkThru); // True if lidx is used before any real register is def'd in the block bool prompt_use( Block *b, uint lidx ); Node *get_spillcopy_wide( Node *def, Node *use, uint uidx ); diff --git a/src/share/vm/opto/coalesce.cpp b/src/share/vm/opto/coalesce.cpp index 20e9bd179..b7e8a85dc 100644 --- a/src/share/vm/opto/coalesce.cpp +++ b/src/share/vm/opto/coalesce.cpp @@ -604,8 +604,8 @@ void PhaseConservativeCoalesce::union_helper( Node *lr1_node, Node *lr2_node, ui // If both are single def, then src_def powers one live range // and def_copy powers the other. After merging, src_def powers // the combined live range. - lrgs(lr1)._def = (lrgs(lr1)._def == NodeSentinel || - lrgs(lr2)._def == NodeSentinel ) + lrgs(lr1)._def = (lrgs(lr1).is_multidef() || + lrgs(lr2).is_multidef() ) ? NodeSentinel : src_def; lrgs(lr2)._def = NULL; // No def for lrg 2 lrgs(lr2).Clear(); // Force empty mask for LRG 2 diff --git a/src/share/vm/opto/ifg.cpp b/src/share/vm/opto/ifg.cpp index 2c6cd665f..e7f55aa5b 100644 --- a/src/share/vm/opto/ifg.cpp +++ b/src/share/vm/opto/ifg.cpp @@ -594,7 +594,7 @@ uint PhaseChaitin::build_ifg_physical( ResourceArea *a ) { // Insure high score for immediate-use spill copies so they get a color if( n->is_SpillCopy() - && lrgs(r)._def != NodeSentinel // MultiDef live range can still split + && lrgs(r).is_singledef() // MultiDef live range can still split && n->outcnt() == 1 // and use must be in this block && _cfg._bbs[n->unique_out()->_idx] == b ) { // All single-use MachSpillCopy(s) that immediately precede their diff --git a/src/share/vm/opto/reg_split.cpp b/src/share/vm/opto/reg_split.cpp index 5101eb2e7..a562eacc2 100644 --- a/src/share/vm/opto/reg_split.cpp +++ b/src/share/vm/opto/reg_split.cpp @@ -284,7 +284,7 @@ Node *PhaseChaitin::split_Rematerialize( Node *def, Block *b, uint insidx, uint // Check for single-def (LRG cannot redefined) uint lidx = n2lidx(in); if( lidx >= _maxlrg ) continue; // Value is a recent spill-copy - if( lrgs(lidx)._def != NodeSentinel ) continue; + if (lrgs(lidx).is_singledef()) continue; Block *b_def = _cfg._bbs[def->_idx]; int idx_def = b_def->find_node(def); @@ -311,12 +311,20 @@ Node *PhaseChaitin::split_Rematerialize( Node *def, Block *b, uint insidx, uint uint lidx = Find_id(in); // Walk backwards thru spill copy node intermediates - if( walkThru ) + if (walkThru) { while ( in->is_SpillCopy() && lidx >= _maxlrg ) { in = in->in(1); lidx = Find_id(in); } + if (lidx < _maxlrg && lrgs(lidx).is_multidef()) { + // walkThru found a multidef LRG, which is unsafe to use, so + // just keep the original def used in the clone. + in = spill->in(i); + lidx = Find_id(in); + } + } + if( lidx < _maxlrg && lrgs(lidx).reg() >= LRG::SPILL_REG ) { Node *rdef = Reachblock[lrg2reach[lidx]]; if( rdef ) spill->set_req(i,rdef); @@ -505,7 +513,7 @@ uint PhaseChaitin::Split( uint maxlrg ) { // Do not bother splitting or putting in Phis for single-def // rematerialized live ranges. This happens alot to constants // with long live ranges. - if( lrgs(lidx)._def != NodeSentinel && + if( lrgs(lidx).is_singledef() && lrgs(lidx)._def->rematerialize() ) { // reset the Reaches & UP entries Reachblock[slidx] = lrgs(lidx)._def; -- GitLab