--- a/hotspot/src/share/vm/opto/node.hpp Fri Jan 08 11:39:47 2016 +0000
+++ b/hotspot/src/share/vm/opto/node.hpp Fri Jan 08 11:41:04 2016 +0100
@@ -1,5 +1,5 @@
/*
- * 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
@@ -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.
@@ -476,6 +486,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.
@@ -492,13 +515,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, "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;