Mercurial > hg > truffle
comparison src/share/vm/opto/reg_split.cpp @ 295:ea18057223c4
6732194: Data corruption dependent on -server/-client/-Xbatch
Summary: rematerializing nodes results in incorrect inputs
Reviewed-by: rasbold
author | never |
---|---|
date | Mon, 18 Aug 2008 23:17:51 -0700 |
parents | a61af66fc99e |
children | 1c6e3bfb543a |
comparison
equal
deleted
inserted
replaced
294:616a07a75c3c | 295:ea18057223c4 |
---|---|
282 for( uint i = 1; i < def->req(); i++ ) { | 282 for( uint i = 1; i < def->req(); i++ ) { |
283 Node *in = def->in(i); | 283 Node *in = def->in(i); |
284 // Check for single-def (LRG cannot redefined) | 284 // Check for single-def (LRG cannot redefined) |
285 uint lidx = n2lidx(in); | 285 uint lidx = n2lidx(in); |
286 if( lidx >= _maxlrg ) continue; // Value is a recent spill-copy | 286 if( lidx >= _maxlrg ) continue; // Value is a recent spill-copy |
287 if( lrgs(lidx)._def != NodeSentinel ) continue; | 287 if (lrgs(lidx).is_singledef()) continue; |
288 | 288 |
289 Block *b_def = _cfg._bbs[def->_idx]; | 289 Block *b_def = _cfg._bbs[def->_idx]; |
290 int idx_def = b_def->find_node(def); | 290 int idx_def = b_def->find_node(def); |
291 Node *in_spill = get_spillcopy_wide( in, def, i ); | 291 Node *in_spill = get_spillcopy_wide( in, def, i ); |
292 if( !in_spill ) return 0; // Bailed out | 292 if( !in_spill ) return 0; // Bailed out |
309 for( uint i = 1; i < spill->req(); i++ ) { | 309 for( uint i = 1; i < spill->req(); i++ ) { |
310 Node *in = spill->in(i); | 310 Node *in = spill->in(i); |
311 uint lidx = Find_id(in); | 311 uint lidx = Find_id(in); |
312 | 312 |
313 // Walk backwards thru spill copy node intermediates | 313 // Walk backwards thru spill copy node intermediates |
314 if( walkThru ) | 314 if (walkThru) { |
315 while ( in->is_SpillCopy() && lidx >= _maxlrg ) { | 315 while ( in->is_SpillCopy() && lidx >= _maxlrg ) { |
316 in = in->in(1); | 316 in = in->in(1); |
317 lidx = Find_id(in); | 317 lidx = Find_id(in); |
318 } | 318 } |
319 | |
320 if (lidx < _maxlrg && lrgs(lidx).is_multidef()) { | |
321 // walkThru found a multidef LRG, which is unsafe to use, so | |
322 // just keep the original def used in the clone. | |
323 in = spill->in(i); | |
324 lidx = Find_id(in); | |
325 } | |
326 } | |
319 | 327 |
320 if( lidx < _maxlrg && lrgs(lidx).reg() >= LRG::SPILL_REG ) { | 328 if( lidx < _maxlrg && lrgs(lidx).reg() >= LRG::SPILL_REG ) { |
321 Node *rdef = Reachblock[lrg2reach[lidx]]; | 329 Node *rdef = Reachblock[lrg2reach[lidx]]; |
322 if( rdef ) spill->set_req(i,rdef); | 330 if( rdef ) spill->set_req(i,rdef); |
323 } | 331 } |
503 // Grab the live range number | 511 // Grab the live range number |
504 uint lidx = lidxs.at(slidx); | 512 uint lidx = lidxs.at(slidx); |
505 // Do not bother splitting or putting in Phis for single-def | 513 // Do not bother splitting or putting in Phis for single-def |
506 // rematerialized live ranges. This happens alot to constants | 514 // rematerialized live ranges. This happens alot to constants |
507 // with long live ranges. | 515 // with long live ranges. |
508 if( lrgs(lidx)._def != NodeSentinel && | 516 if( lrgs(lidx).is_singledef() && |
509 lrgs(lidx)._def->rematerialize() ) { | 517 lrgs(lidx)._def->rematerialize() ) { |
510 // reset the Reaches & UP entries | 518 // reset the Reaches & UP entries |
511 Reachblock[slidx] = lrgs(lidx)._def; | 519 Reachblock[slidx] = lrgs(lidx)._def; |
512 UPblock[slidx] = true; | 520 UPblock[slidx] = true; |
513 // Record following instruction in case 'n' rematerializes and | 521 // Record following instruction in case 'n' rematerializes and |