< prev index next >
src/share/vm/opto/node.hpp
Print this page
rev 9822 : 8146612: C2: Precedence edges specification violated
Reviewed-by: kvn
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 1997, 2015, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
@@ -421,10 +421,20 @@
if (n != NULL) n->add_out((Node *)this);
Compile::current()->record_modified_node(this);
}
// 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.
// Return the number of edges between 'n' and 'this'
int disconnect_inputs(Node *n, Compile *c);
@@ -474,10 +484,23 @@
// Record that a change happened here.
#if OPTO_DU_ITERATOR_ASSERT
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.
void replace_by(Node* new_node);
// Globally replace this node by a given new node, updating all uses
@@ -490,17 +513,27 @@
// Find the one non-null required input. RegionNode only
Node *nonnull_req() const;
// 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, "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;
*(node_idx_t*)ref = new_idx;
}
< prev index next >