Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8285820: C2: LCM prioritizes locally dependent CreateEx nodes over projections after 8270090 #1179

Closed
wants to merge 3 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
40 changes: 21 additions & 19 deletions src/hotspot/share/opto/lcm.cpp
Expand Up @@ -490,9 +490,11 @@ void PhaseCFG::implicit_null_check(Block* block, Node *proj, Node *val, int allo

//------------------------------select-----------------------------------------
// Select a nice fellow from the worklist to schedule next. If there is only one
// choice, then use it. CreateEx nodes must start their blocks and are selected
// eagerly. After them, projections take top priority for correctness. Next
// after projections are constants and CheckCastPP nodes. There are a number of
// choice, then use it. CreateEx nodes that are initially ready must start their
// blocks and are given the highest priority, by being placed at the beginning
// of the worklist. Next after initially-ready CreateEx nodes are projections,
// which must follow their parents, and CreateEx nodes with local input
// dependencies. Next are constants and CheckCastPP nodes. There are a number of
// other special cases, for instructions that consume condition codes, et al.
// These are chosen immediately. Some instructions are required to immediately
// precede the last instruction in the block, and these are taken last. Of the
Expand Down Expand Up @@ -530,27 +532,21 @@ Node* PhaseCFG::select(
Node *n = worklist[i]; // Get Node on worklist

int iop = n->is_Mach() ? n->as_Mach()->ideal_Opcode() : 0;
if (iop == Op_CreateEx) {
// CreateEx must start the block (after Phi and Parm nodes which are
// pre-scheduled): select it right away.
if (iop == Op_CreateEx || n->is_Proj()) {
// CreateEx nodes that are initially ready must start the block (after Phi
// and Parm nodes which are pre-scheduled) and get top priority. This is
// currently enforced by placing them at the beginning of the initial
// worklist and selecting them eagerly here. After these, projections and
// other CreateEx nodes are selected with equal priority.
worklist.map(i,worklist.pop());
return n;
}

uint n_choice = 2;
if (n->is_Proj()) {
// Projections should follow their parents.
n_choice = 5;
} else if (n->Opcode() == Op_Con || iop == Op_CheckCastPP) {
if (n->Opcode() == Op_Con || iop == Op_CheckCastPP) {
// Constants and CheckCastPP nodes have higher priority than the rest of
// the nodes tested below.
n_choice = 4;
}

if (n_choice >= 4 && choice < n_choice) {
// n is a constant, a projection, or a CheckCastPP node: record as current
// winner, but keep looking for higher-priority nodes in the worklist.
choice = n_choice;
// the nodes tested below. Record as current winner, but keep looking for
// higher-priority nodes in the worklist.
choice = 4;
// Latency and score are only used to break ties among low-priority nodes.
latency = 0;
score = 0;
Expand All @@ -576,6 +572,8 @@ Node* PhaseCFG::select(
}
}

uint n_choice = 2;

// See if this instruction is consumed by a branch. If so, then (as the
// branch is the last instruction in the basic block) force it to the
// end of the basic block
Expand Down Expand Up @@ -1062,6 +1060,10 @@ bool PhaseCFG::schedule_local(Block* block, GrowableArray<int>& ready_cnt, Vecto
// of the phi to be scheduled first. The select() method breaks
// ties in scheduling by worklist order.
delay.push(m);
} else if (m->is_Mach() && m->as_Mach()->ideal_Opcode() == Op_CreateEx) {
// Place CreateEx nodes that are initially ready at the beginning of the
// worklist so they are selected first and scheduled at the block start.
worklist.insert(0, m);
} else {
worklist.push(m); // Then on to worklist!
}
Expand Down