diff -r 6f33e450999c -r 97d09139b360 src/share/vm/opto/node.hpp --- a/src/share/vm/opto/node.hpp Tue May 05 18:39:57 2020 +0100 +++ b/src/share/vm/opto/node.hpp Tue Mar 10 10:46:35 2020 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, 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 @@ -423,6 +423,16 @@ } // Find first occurrence of n among my edges: int find_edge(Node* n); + int find_prec_edge(Node* n) { + for (uint i = req(); i < len(); i++) { + if (_in[i] == n) return i; + if (_in[i] == NULL) { + DEBUG_ONLY( while ((++i) < len()) assert(_in[i] == NULL, "Gap in prec edges!"); ) + break; + } + } + return -1; + } int replace_edge(Node* old, Node* neww); int replace_edges_in_range(Node* old, Node* neww, int start, int end); // NULL out all inputs to eliminate incoming Def-Use edges. @@ -469,6 +479,19 @@ debug_only(_last_del = n; ++_del_tick); #endif } + // Close gap after removing edge. + void close_prec_gap_at(uint gap) { + assert(_cnt <= gap && gap < _max, "no valid prec edge"); + uint i = gap; + Node *last = NULL; + for (; i < _max-1; ++i) { + Node *next = _in[i+1]; + if (next == NULL) break; + last = next; + } + _in[gap] = last; // Move last slot to empty one. + _in[i] = NULL; // NULL out last slot. + } public: // Globally replace this node by a given new node, updating all uses. @@ -485,13 +508,23 @@ // Add or remove precedence edges void add_prec( Node *n ); void rm_prec( uint i ); + + // Note: prec(i) will not necessarily point to n if edge already exists. void set_prec( uint i, Node *n ) { - assert( is_not_dead(n), "can not use dead node"); - assert( i >= _cnt, "not a precedence edge"); + assert(i < _max, err_msg("oob: i=%d, _max=%d", i, _max)); + assert(is_not_dead(n), "can not use dead node"); + assert(i >= _cnt, "not a precedence edge"); + // Avoid spec violation: duplicated prec edge. + if (_in[i] == n) return; + if (n == NULL || find_prec_edge(n) != -1) { + rm_prec(i); + return; + } if (_in[i] != NULL) _in[i]->del_out((Node *)this); _in[i] = n; if (n != NULL) n->add_out((Node *)this); } + // Set this node's index, used by cisc_version to replace current node void set_idx(uint new_idx) { const node_idx_t* ref = &_idx;