aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornever <none@none>2008-08-18 23:17:51 -0700
committernever <none@none>2008-08-18 23:17:51 -0700
commit00685162833278853c0889caa0053b9ecec75d3a (patch)
treeea3fb6ed12db8d63329e0c3d9093b38318492635
parent3b05932b538e0c70919905f1dc2efc039acfce38 (diff)
6732194: Data corruption dependent on -server/-client/-Xbatch
Summary: rematerializing nodes results in incorrect inputs Reviewed-by: rasbold
-rw-r--r--src/share/vm/opto/chaitin.cpp6
-rw-r--r--src/share/vm/opto/chaitin.hpp5
-rw-r--r--src/share/vm/opto/coalesce.cpp4
-rw-r--r--src/share/vm/opto/ifg.cpp2
-rw-r--r--src/share/vm/opto/reg_split.cpp14
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<uint> splits, int slidx );
uint split_USE( Node *def, Block *b, Node *use, uint useidx, uint max, bool def_down, bool cisc_sp, GrowableArray<uint> 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<uint> splits, int slidx, uint *lrg2reach, Node **Reachblock, bool walkThru );
+ Node *split_Rematerialize(Node *def, Block *b, uint insidx, uint &maxlrg, GrowableArray<uint> 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;