提交 e0205e1d 编写于 作者: N never

6862863: C2 compiler fails in elide_copy()

Reviewed-by: kvn
上级 dca1970a
...@@ -458,6 +458,16 @@ private: ...@@ -458,6 +458,16 @@ private:
// Post-Allocation peephole copy removal // Post-Allocation peephole copy removal
void post_allocate_copy_removal(); void post_allocate_copy_removal();
Node *skip_copies( Node *c ); Node *skip_copies( Node *c );
// Replace the old node with the current live version of that value
// and yank the old value if it's dead.
int replace_and_yank_if_dead( Node *old, OptoReg::Name nreg,
Block *current_block, Node_List& value, Node_List& regnd ) {
Node* v = regnd[nreg];
assert(v->outcnt() != 0, "no dead values");
old->replace_by(v);
return yank_if_dead(old, current_block, &value, &regnd);
}
int yank_if_dead( Node *old, Block *current_block, Node_List *value, Node_List *regnd ); int yank_if_dead( Node *old, Block *current_block, Node_List *value, Node_List *regnd );
int elide_copy( Node *n, int k, Block *current_block, Node_List &value, Node_List &regnd, bool can_change_regs ); int elide_copy( Node *n, int k, Block *current_block, Node_List &value, Node_List &regnd, bool can_change_regs );
int use_prior_register( Node *copy, uint idx, Node *def, Block *current_block, Node_List &value, Node_List &regnd ); int use_prior_register( Node *copy, uint idx, Node *def, Block *current_block, Node_List &value, Node_List &regnd );
......
...@@ -88,6 +88,7 @@ int PhaseChaitin::yank_if_dead( Node *old, Block *current_block, Node_List *valu ...@@ -88,6 +88,7 @@ int PhaseChaitin::yank_if_dead( Node *old, Block *current_block, Node_List *valu
value->map(old_reg,NULL); // Yank from value/regnd maps value->map(old_reg,NULL); // Yank from value/regnd maps
regnd->map(old_reg,NULL); // This register's value is now unknown regnd->map(old_reg,NULL); // This register's value is now unknown
} }
assert(old->req() <= 2, "can't handle more inputs");
Node *tmp = old->req() > 1 ? old->in(1) : NULL; Node *tmp = old->req() > 1 ? old->in(1) : NULL;
old->disconnect_inputs(NULL); old->disconnect_inputs(NULL);
if( !tmp ) break; if( !tmp ) break;
...@@ -530,6 +531,16 @@ void PhaseChaitin::post_allocate_copy_removal() { ...@@ -530,6 +531,16 @@ void PhaseChaitin::post_allocate_copy_removal() {
// Do not change from int to pointer // Do not change from int to pointer
Node *val = skip_copies(n); Node *val = skip_copies(n);
// Clear out a dead definition before starting so that the
// elimination code doesn't have to guard against it. The
// definition could in fact be a kill projection with a count of
// 0 which is safe but since those are uninteresting for copy
// elimination just delete them as well.
if (regnd[nreg] != NULL && regnd[nreg]->outcnt() == 0) {
regnd.map(nreg, NULL);
value.map(nreg, NULL);
}
uint n_ideal_reg = n->ideal_reg(); uint n_ideal_reg = n->ideal_reg();
if( is_single_register(n_ideal_reg) ) { if( is_single_register(n_ideal_reg) ) {
// If Node 'n' does not change the value mapped by the register, // If Node 'n' does not change the value mapped by the register,
...@@ -537,8 +548,7 @@ void PhaseChaitin::post_allocate_copy_removal() { ...@@ -537,8 +548,7 @@ void PhaseChaitin::post_allocate_copy_removal() {
// mapping so 'n' will go dead. // mapping so 'n' will go dead.
if( value[nreg] != val ) { if( value[nreg] != val ) {
if (eliminate_copy_of_constant(val, n, b, value, regnd, nreg, OptoReg::Bad)) { if (eliminate_copy_of_constant(val, n, b, value, regnd, nreg, OptoReg::Bad)) {
n->replace_by(regnd[nreg]); j -= replace_and_yank_if_dead(n, nreg, b, value, regnd);
j -= yank_if_dead(n,b,&value,&regnd);
} else { } else {
// Update the mapping: record new Node defined by the register // Update the mapping: record new Node defined by the register
regnd.map(nreg,n); regnd.map(nreg,n);
...@@ -546,10 +556,9 @@ void PhaseChaitin::post_allocate_copy_removal() { ...@@ -546,10 +556,9 @@ void PhaseChaitin::post_allocate_copy_removal() {
// Node after skipping all copies. // Node after skipping all copies.
value.map(nreg,val); value.map(nreg,val);
} }
} else if( !may_be_copy_of_callee(n) && regnd[nreg]->outcnt() != 0 ) { } else if( !may_be_copy_of_callee(n) ) {
assert( n->is_Copy(), "" ); assert( n->is_Copy(), "" );
n->replace_by(regnd[nreg]); j -= replace_and_yank_if_dead(n, nreg, b, value, regnd);
j -= yank_if_dead(n,b,&value,&regnd);
} }
} else { } else {
// If the value occupies a register pair, record same info // If the value occupies a register pair, record same info
...@@ -565,18 +574,16 @@ void PhaseChaitin::post_allocate_copy_removal() { ...@@ -565,18 +574,16 @@ void PhaseChaitin::post_allocate_copy_removal() {
} }
if( value[nreg] != val || value[nreg_lo] != val ) { if( value[nreg] != val || value[nreg_lo] != val ) {
if (eliminate_copy_of_constant(val, n, b, value, regnd, nreg, nreg_lo)) { if (eliminate_copy_of_constant(val, n, b, value, regnd, nreg, nreg_lo)) {
n->replace_by(regnd[nreg]); j -= replace_and_yank_if_dead(n, nreg, b, value, regnd);
j -= yank_if_dead(n,b,&value,&regnd);
} else { } else {
regnd.map(nreg , n ); regnd.map(nreg , n );
regnd.map(nreg_lo, n ); regnd.map(nreg_lo, n );
value.map(nreg ,val); value.map(nreg ,val);
value.map(nreg_lo,val); value.map(nreg_lo,val);
} }
} else if( !may_be_copy_of_callee(n) && regnd[nreg]->outcnt() != 0 ) { } else if( !may_be_copy_of_callee(n) ) {
assert( n->is_Copy(), "" ); assert( n->is_Copy(), "" );
n->replace_by(regnd[nreg]); j -= replace_and_yank_if_dead(n, nreg, b, value, regnd);
j -= yank_if_dead(n,b,&value,&regnd);
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册