8254369: Node::disconnect_inputs may skip precedences

disconnect_inputs() needs to iterate precedences edges in reverse order because rm_prec(i) may backfill _in[i] with a value afterward.
also remove the predicate if (n != NULL) in set_prec because it's always true.

Reviewed-by: kvn, redestad
This commit is contained in:
Xin Liu 2020-10-16 01:59:07 +00:00 committed by Vladimir Kozlov
parent 96bb6e76bf
commit bdda2058c2
2 changed files with 18 additions and 3 deletions

View File

@ -895,6 +895,14 @@ int Node::replace_edges_in_range(Node* old, Node* neww, int start, int end) {
//-------------------------disconnect_inputs-----------------------------------
// NULL out all inputs to eliminate incoming Def-Use edges.
void Node::disconnect_inputs(Compile* C) {
// the layout of Node::_in
// r: a required input, null is allowed
// p: a precedence, null values are all at the end
// -----------------------------------
// |r|...|r|p|...|p|null|...|null|
// | |
// req() len()
// -----------------------------------
for (uint i = 0; i < req(); ++i) {
if (in(i) != nullptr) {
set_req(i, nullptr);
@ -903,10 +911,17 @@ void Node::disconnect_inputs(Compile* C) {
// Remove precedence edges if any exist
// Note: Safepoints may have precedence edges, even during parsing
for (uint i = req(); i < len(); ++i) {
set_prec(i, nullptr);
for (uint i = len(); i > req(); ) {
rm_prec(--i); // no-op if _in[i] is nullptr
}
#ifdef ASSERT
// sanity check
for (uint i = 0; i < len(); ++i) {
assert(_in[i] == nullptr, "disconnect_inputs() failed!");
}
#endif
// Node::destruct requires all out edges be deleted first
// debug_only(destruct();) // no reuse benefit expected
C->record_dead_node(_idx);

View File

@ -541,7 +541,7 @@ public:
}
if (_in[i] != NULL) _in[i]->del_out((Node *)this);
_in[i] = n;
if (n != NULL) n->add_out((Node *)this);
n->add_out((Node *)this);
}
// Set this node's index, used by cisc_version to replace current node