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 2 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: 28 additions & 12 deletions src/hotspot/share/opto/lcm.cpp
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -489,9 +489,12 @@ 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. Projections take top priority for correctness
// reasons - if I see a projection, then it is next. There are a number of
// Select a nice fellow from the worklist to schedule next. If there is only one
// 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 @@ -529,15 +532,28 @@ Node* PhaseCFG::select(
Node *n = worklist[i]; // Get Node on worklist

int iop = n->is_Mach() ? n->as_Mach()->ideal_Opcode() : 0;
if( n->is_Proj() || // Projections always win
n->Opcode()== Op_Con || // So does constant 'Top'
iop == Op_CreateEx || // Create-exception must start block
iop == Op_CheckCastPP
) {
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;
}

if (n->Opcode() == Op_Con || iop == Op_CheckCastPP) {
// Constants and CheckCastPP nodes have higher priority than the rest of
// 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;
idx = i;
continue;
}

// Final call in a block must be adjacent to 'catch'
Node *e = block->end();
if( e->is_Catch() && e->in(0)->in(0) == n )
Expand All @@ -556,7 +572,7 @@ Node* PhaseCFG::select(
}
}

uint n_choice = 2;
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
Expand Down Expand Up @@ -1045,8 +1061,8 @@ bool PhaseCFG::schedule_local(Block* block, GrowableArray<int>& ready_cnt, Vecto
// ties in scheduling by worklist order.
delay.push(m);
} else if (m->is_Mach() && m->as_Mach()->ideal_Opcode() == Op_CreateEx) {
// Force the CreateEx to the top of the list so it's processed
// first and ends up at the start of the block.
// 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