comparison src/share/vm/opto/gcm.cpp @ 31:6152cbb08ce9

6590177: jck60019 test assert(!repeated,"do not walk merges twice") Summary: A mergemem node could be not in worklist_store but in should_not_repeat vectorset since it was processed and removed from worklist_store before. Reviewed-by: jrose, never
author kvn
date Thu, 28 Feb 2008 10:45:15 -0800
parents a61af66fc99e
children d1605aabd0a1 273eaa04d9a1
comparison
equal deleted inserted replaced
30:65a06b4a51b8 31:6152cbb08ce9
446 } 446 }
447 447
448 ResourceArea *area = Thread::current()->resource_area(); 448 ResourceArea *area = Thread::current()->resource_area();
449 Node_List worklist_mem(area); // prior memory state to store 449 Node_List worklist_mem(area); // prior memory state to store
450 Node_List worklist_store(area); // possible-def to explore 450 Node_List worklist_store(area); // possible-def to explore
451 Node_List worklist_visited(area); // visited mergemem nodes
451 Node_List non_early_stores(area); // all relevant stores outside of early 452 Node_List non_early_stores(area); // all relevant stores outside of early
452 bool must_raise_LCA = false; 453 bool must_raise_LCA = false;
453 DEBUG_ONLY(VectorSet should_not_repeat(area));
454 454
455 #ifdef TRACK_PHI_INPUTS 455 #ifdef TRACK_PHI_INPUTS
456 // %%% This extra checking fails because MergeMem nodes are not GVNed. 456 // %%% This extra checking fails because MergeMem nodes are not GVNed.
457 // Provide "phi_inputs" to check if every input to a PhiNode is from the 457 // Provide "phi_inputs" to check if every input to a PhiNode is from the
458 // original memory state. This indicates a PhiNode for which should not 458 // original memory state. This indicates a PhiNode for which should not
477 // initial_mem -> (MergeMem ->)* store 477 // initial_mem -> (MergeMem ->)* store
478 // The anti-dependence constraints apply only to the fringe of this tree. 478 // The anti-dependence constraints apply only to the fringe of this tree.
479 479
480 Node* initial_mem = load->in(MemNode::Memory); 480 Node* initial_mem = load->in(MemNode::Memory);
481 worklist_store.push(initial_mem); 481 worklist_store.push(initial_mem);
482 worklist_visited.push(initial_mem);
482 worklist_mem.push(NULL); 483 worklist_mem.push(NULL);
483 DEBUG_ONLY(should_not_repeat.test_set(initial_mem->_idx));
484 while (worklist_store.size() > 0) { 484 while (worklist_store.size() > 0) {
485 // Examine a nearby store to see if it might interfere with our load. 485 // Examine a nearby store to see if it might interfere with our load.
486 Node* mem = worklist_mem.pop(); 486 Node* mem = worklist_mem.pop();
487 Node* store = worklist_store.pop(); 487 Node* store = worklist_store.pop();
488 uint op = store->Opcode(); 488 uint op = store->Opcode();
492 // the leaves of which are each a 'possible-def'. 492 // the leaves of which are each a 'possible-def'.
493 if (store == initial_mem // root (exclusive) of tree we are searching 493 if (store == initial_mem // root (exclusive) of tree we are searching
494 || op == Op_MergeMem // internal node of tree we are searching 494 || op == Op_MergeMem // internal node of tree we are searching
495 ) { 495 ) {
496 mem = store; // It's not a possibly interfering store. 496 mem = store; // It's not a possibly interfering store.
497 if (store == initial_mem)
498 initial_mem = NULL; // only process initial memory once
499
497 for (DUIterator_Fast imax, i = mem->fast_outs(imax); i < imax; i++) { 500 for (DUIterator_Fast imax, i = mem->fast_outs(imax); i < imax; i++) {
498 store = mem->fast_out(i); 501 store = mem->fast_out(i);
499 if (store->is_MergeMem()) { 502 if (store->is_MergeMem()) {
500 // Be sure we don't get into combinatorial problems. 503 // Be sure we don't get into combinatorial problems.
501 // (Allow phis to be repeated; they can merge two relevant states.) 504 // (Allow phis to be repeated; they can merge two relevant states.)
502 uint i = worklist_store.size(); 505 uint j = worklist_visited.size();
503 for (; i > 0; i--) { 506 for (; j > 0; j--) {
504 if (worklist_store.at(i-1) == store) break; 507 if (worklist_visited.at(j-1) == store) break;
505 } 508 }
506 if (i > 0) continue; // already on work list; do not repeat 509 if (j > 0) continue; // already on work list; do not repeat
507 DEBUG_ONLY(int repeated = should_not_repeat.test_set(store->_idx)); 510 worklist_visited.push(store);
508 assert(!repeated, "do not walk merges twice");
509 } 511 }
510 worklist_mem.push(mem); 512 worklist_mem.push(mem);
511 worklist_store.push(store); 513 worklist_store.push(store);
512 } 514 }
513 continue; 515 continue;