Mercurial > hg > graal-jvmci-8
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, ®nd); | 282 yank_if_dead(use, current_block, &value, ®nd); |
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,®nd); | 527 j -= yank_if_dead(n,b,&value,®nd); |
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,®nd); | 555 j -= yank_if_dead(n,b,&value,®nd); |
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 ); |