8204157: Compiler.sunflow hangs after JDK-8192992

Treat non-loop phis as stores

Reviewed-by: thartmann
This commit is contained in:
Nils Eliasson 2018-06-27 18:46:30 +02:00
parent 4029057547
commit 8e9f9e5583

View file

@ -683,38 +683,40 @@ Block* PhaseCFG::insert_anti_dependences(Block* LCA, Node* load, bool verify) {
Block* store_block = get_block_for_node(store); Block* store_block = get_block_for_node(store);
assert(store_block != NULL, "unused killing projections skipped above"); assert(store_block != NULL, "unused killing projections skipped above");
if (store->is_Phi()) { if (store->is_Phi() && store->in(0)->is_Loop()) {
if (store->in(0)->is_Loop()) { // Loop-phis need to raise load before input. (Other phis are treated
// 'load' uses memory which is one (or more) of the Phi's inputs. // as store below.)
// It must be scheduled not before the Phi, but rather before //
// each of the relevant Phi inputs. // 'load' uses memory which is one (or more) of the Phi's inputs.
// // It must be scheduled not before the Phi, but rather before
// Instead of finding the LCA of all inputs to a Phi that match 'mem', // each of the relevant Phi inputs.
// we mark each corresponding predecessor block and do a combined //
// hoisting operation later (raise_LCA_above_marks). // Instead of finding the LCA of all inputs to a Phi that match 'mem',
// // we mark each corresponding predecessor block and do a combined
// Do not assert(store_block != early, "Phi merging memory after access") // hoisting operation later (raise_LCA_above_marks).
// PhiNode may be at start of block 'early' with backedge to 'early' //
DEBUG_ONLY(bool found_match = false); // Do not assert(store_block != early, "Phi merging memory after access")
for (uint j = PhiNode::Input, jmax = store->req(); j < jmax; j++) { // PhiNode may be at start of block 'early' with backedge to 'early'
if (store->in(j) == mem) { // Found matching input? DEBUG_ONLY(bool found_match = false);
DEBUG_ONLY(found_match = true); for (uint j = PhiNode::Input, jmax = store->req(); j < jmax; j++) {
Block* pred_block = get_block_for_node(store_block->pred(j)); if (store->in(j) == mem) { // Found matching input?
if (pred_block != early) { DEBUG_ONLY(found_match = true);
// If any predecessor of the Phi matches the load's "early block", Block* pred_block = get_block_for_node(store_block->pred(j));
// we do not need a precedence edge between the Phi and 'load' if (pred_block != early) {
// since the load will be forced into a block preceding the Phi. // If any predecessor of the Phi matches the load's "early block",
pred_block->set_raise_LCA_mark(load_index); // we do not need a precedence edge between the Phi and 'load'
assert(!LCA_orig->dominates(pred_block) || // since the load will be forced into a block preceding the Phi.
early->dominates(pred_block), "early is high enough"); pred_block->set_raise_LCA_mark(load_index);
must_raise_LCA = true; assert(!LCA_orig->dominates(pred_block) ||
} else { early->dominates(pred_block), "early is high enough");
// anti-dependent upon PHI pinned below 'early', no edge needed must_raise_LCA = true;
LCA = early; // but can not schedule below 'early' } else {
} // anti-dependent upon PHI pinned below 'early', no edge needed
LCA = early; // but can not schedule below 'early'
} }
} }
assert(found_match, "no worklist bug"); }
assert(found_match, "no worklist bug");
#ifdef TRACK_PHI_INPUTS #ifdef TRACK_PHI_INPUTS
#ifdef ASSERT #ifdef ASSERT
// This assert asks about correct handling of PhiNodes, which may not // This assert asks about correct handling of PhiNodes, which may not
@ -728,7 +730,6 @@ Block* PhaseCFG::insert_anti_dependences(Block* LCA, Node* load, bool verify) {
"Expect at least one phi input will not be from original memory state"); "Expect at least one phi input will not be from original memory state");
#endif //ASSERT #endif //ASSERT
#endif //TRACK_PHI_INPUTS #endif //TRACK_PHI_INPUTS
}
} else if (store_block != early) { } else if (store_block != early) {
// 'store' is between the current LCA and earliest possible block. // 'store' is between the current LCA and earliest possible block.
// Label its block, and decide later on how to raise the LCA // Label its block, and decide later on how to raise the LCA