6732194: Data corruption dependent on -server/-client/-Xbatch
Rematerializing nodes results in incorrect inputs Reviewed-by: rasbold
This commit is contained in:
parent
1e49d39e6b
commit
45f8e241e3
@ -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" );
|
||||
|
||||
|
@ -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 );
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user