comparison src/share/vm/opto/postaloc.cpp @ 70:b683f557224b

6661247: Internal bug in 32-bit HotSpot optimizer while bit manipulations Summary: copy elimination of a constant value results in incorrect execution Reviewed-by: kvn, sgoldman, rasbold
author never
date Wed, 19 Mar 2008 15:14:36 -0700
parents a61af66fc99e
children d1605aabd0a1
comparison
equal deleted inserted replaced
69:8bb88f9877e5 70:b683f557224b
251 // Check if nreg already contains the constant value val. Normal copy 251 // Check if nreg already contains the constant value val. Normal copy
252 // elimination doesn't doesn't work on constants because multiple 252 // elimination doesn't doesn't work on constants because multiple
253 // nodes can represent the same constant so the type and rule of the 253 // nodes can represent the same constant so the type and rule of the
254 // MachNode must be checked to ensure equivalence. 254 // MachNode must be checked to ensure equivalence.
255 // 255 //
256 bool PhaseChaitin::eliminate_copy_of_constant(Node* val, Block *current_block, 256 bool PhaseChaitin::eliminate_copy_of_constant(Node* val, Node* n,
257 Block *current_block,
257 Node_List& value, Node_List& regnd, 258 Node_List& value, Node_List& regnd,
258 OptoReg::Name nreg, OptoReg::Name nreg2) { 259 OptoReg::Name nreg, OptoReg::Name nreg2) {
259 if (value[nreg] != val && val->is_Con() && 260 if (value[nreg] != val && val->is_Con() &&
260 value[nreg] != NULL && value[nreg]->is_Con() && 261 value[nreg] != NULL && value[nreg]->is_Con() &&
261 (nreg2 == OptoReg::Bad || value[nreg] == value[nreg2]) && 262 (nreg2 == OptoReg::Bad || value[nreg] == value[nreg2]) &&
267 // objectively true unless there are hidden inputs to the nodes 268 // objectively true unless there are hidden inputs to the nodes
268 // but if that were to change this code would need to updated. 269 // but if that were to change this code would need to updated.
269 // Since they are equivalent the second one if redundant and can 270 // Since they are equivalent the second one if redundant and can
270 // be removed. 271 // be removed.
271 // 272 //
272 // val will be replaced with the old value but val might have 273 // n will be replaced with the old value but n might have
273 // kills projections associated with it so remove them now so that 274 // kills projections associated with it so remove them now so that
274 // yank_if_dead will be able to elminate the copy once the uses 275 // yank_if_dead will be able to elminate the copy once the uses
275 // have been transferred to the old[value]. 276 // have been transferred to the old[value].
276 for (DUIterator_Fast imax, i = val->fast_outs(imax); i < imax; i++) { 277 for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
277 Node* use = val->fast_out(i); 278 Node* use = n->fast_out(i);
278 if (use->is_Proj() && use->outcnt() == 0) { 279 if (use->is_Proj() && use->outcnt() == 0) {
279 // Kill projections have no users and one input 280 // Kill projections have no users and one input
280 use->set_req(0, C->top()); 281 use->set_req(0, C->top());
281 yank_if_dead(use, current_block, &value, &regnd); 282 yank_if_dead(use, current_block, &value, &regnd);
282 --i; --imax; 283 --i; --imax;
519 if( is_single_register(n_ideal_reg) ) { 520 if( is_single_register(n_ideal_reg) ) {
520 // If Node 'n' does not change the value mapped by the register, 521 // If Node 'n' does not change the value mapped by the register,
521 // then 'n' is a useless copy. Do not update the register->node 522 // then 'n' is a useless copy. Do not update the register->node
522 // mapping so 'n' will go dead. 523 // mapping so 'n' will go dead.
523 if( value[nreg] != val ) { 524 if( value[nreg] != val ) {
524 if (eliminate_copy_of_constant(val, b, value, regnd, nreg, OptoReg::Bad)) { 525 if (eliminate_copy_of_constant(val, n, b, value, regnd, nreg, OptoReg::Bad)) {
525 n->replace_by(regnd[nreg]); 526 n->replace_by(regnd[nreg]);
526 j -= yank_if_dead(n,b,&value,&regnd); 527 j -= yank_if_dead(n,b,&value,&regnd);
527 } else { 528 } else {
528 // Update the mapping: record new Node defined by the register 529 // Update the mapping: record new Node defined by the register
529 regnd.map(nreg,n); 530 regnd.map(nreg,n);
547 RegMask tmp = lrgs(lidx).mask(); 548 RegMask tmp = lrgs(lidx).mask();
548 tmp.Remove(nreg); 549 tmp.Remove(nreg);
549 nreg_lo = tmp.find_first_elem(); 550 nreg_lo = tmp.find_first_elem();
550 } 551 }
551 if( value[nreg] != val || value[nreg_lo] != val ) { 552 if( value[nreg] != val || value[nreg_lo] != val ) {
552 if (eliminate_copy_of_constant(n, b, value, regnd, nreg, nreg_lo)) { 553 if (eliminate_copy_of_constant(val, n, b, value, regnd, nreg, nreg_lo)) {
553 n->replace_by(regnd[nreg]); 554 n->replace_by(regnd[nreg]);
554 j -= yank_if_dead(n,b,&value,&regnd); 555 j -= yank_if_dead(n,b,&value,&regnd);
555 } else { 556 } else {
556 regnd.map(nreg , n ); 557 regnd.map(nreg , n );
557 regnd.map(nreg_lo, n ); 558 regnd.map(nreg_lo, n );