提交 7939996d 编写于 作者: M mdoerr

8146612: C2: Precedence edges specification violated

Reviewed-by: kvn
上级 d8b2c553
/* /*
* Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -815,6 +815,13 @@ bool PhaseCFG::schedule_local(Block* block, GrowableArray<int>& ready_cnt, Vecto ...@@ -815,6 +815,13 @@ bool PhaseCFG::schedule_local(Block* block, GrowableArray<int>& ready_cnt, Vecto
// and the edge will be lost. This is why this code should be // and the edge will be lost. This is why this code should be
// executed only when Precedent (== TypeFunc::Parms) edge is present. // executed only when Precedent (== TypeFunc::Parms) edge is present.
Node *x = n->in(TypeFunc::Parms); Node *x = n->in(TypeFunc::Parms);
if (x != NULL && get_block_for_node(x) == block && n->find_prec_edge(x) != -1) {
// Old edge to node within same block will get removed, but no precedence
// edge will get added because it already exists. Update ready count.
int cnt = ready_cnt.at(n->_idx);
assert(cnt > 1, err_msg("MemBar node %d must not get ready here", n->_idx));
ready_cnt.at_put(n->_idx, cnt-1);
}
n->del_req(TypeFunc::Parms); n->del_req(TypeFunc::Parms);
n->add_prec(x); n->add_prec(x);
} }
......
/* /*
* Copyright (c) 1997, 2014, 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -818,8 +818,9 @@ void Node::del_req( uint idx ) { ...@@ -818,8 +818,9 @@ void Node::del_req( uint idx ) {
// First remove corresponding def-use edge // First remove corresponding def-use edge
Node *n = in(idx); Node *n = in(idx);
if (n != NULL) n->del_out((Node *)this); if (n != NULL) n->del_out((Node *)this);
_in[idx] = in(--_cnt); // Compact the array _in[idx] = in(--_cnt); // Compact the array
_in[_cnt] = NULL; // NULL out emptied slot // Avoid spec violation: Gap in prec edges.
close_prec_gap_at(_cnt);
} }
//------------------------------del_req_ordered-------------------------------- //------------------------------del_req_ordered--------------------------------
...@@ -831,10 +832,11 @@ void Node::del_req_ordered( uint idx ) { ...@@ -831,10 +832,11 @@ void Node::del_req_ordered( uint idx ) {
// First remove corresponding def-use edge // First remove corresponding def-use edge
Node *n = in(idx); Node *n = in(idx);
if (n != NULL) n->del_out((Node *)this); if (n != NULL) n->del_out((Node *)this);
if (idx < _cnt - 1) { // Not last edge ? if (idx < --_cnt) { // Not last edge ?
Copy::conjoint_words_to_lower((HeapWord*)&_in[idx+1], (HeapWord*)&_in[idx], ((_cnt-idx-1)*sizeof(Node*))); Copy::conjoint_words_to_lower((HeapWord*)&_in[idx+1], (HeapWord*)&_in[idx], ((_cnt-idx)*sizeof(Node*)));
} }
_in[--_cnt] = NULL; // NULL out emptied slot // Avoid spec violation: Gap in prec edges.
close_prec_gap_at(_cnt);
} }
//------------------------------ins_req---------------------------------------- //------------------------------ins_req----------------------------------------
...@@ -865,10 +867,12 @@ int Node::replace_edge(Node* old, Node* neww) { ...@@ -865,10 +867,12 @@ int Node::replace_edge(Node* old, Node* neww) {
uint nrep = 0; uint nrep = 0;
for (uint i = 0; i < len(); i++) { for (uint i = 0; i < len(); i++) {
if (in(i) == old) { if (in(i) == old) {
if (i < req()) if (i < req()) {
set_req(i, neww); set_req(i, neww);
else } else {
assert(find_prec_edge(neww) == -1, err_msg("spec violation: duplicated prec edge (node %d -> %d)", _idx, neww->_idx));
set_prec(i, neww); set_prec(i, neww);
}
nrep++; nrep++;
} }
} }
...@@ -974,24 +978,27 @@ void Node::add_prec( Node *n ) { ...@@ -974,24 +978,27 @@ void Node::add_prec( Node *n ) {
// Find a precedence edge to move // Find a precedence edge to move
uint i = _cnt; uint i = _cnt;
while( in(i) != NULL ) i++; while( in(i) != NULL ) {
if (in(i) == n) return; // Avoid spec violation: duplicated prec edge.
i++;
}
_in[i] = n; // Stuff prec edge over NULL _in[i] = n; // Stuff prec edge over NULL
if ( n != NULL) n->add_out((Node *)this); // Add mirror edge if ( n != NULL) n->add_out((Node *)this); // Add mirror edge
#ifdef ASSERT
while ((++i)<_max) { assert(_in[i] == NULL, err_msg("spec violation: Gap in prec edges (node %d)", _idx)); }
#endif
} }
//------------------------------rm_prec---------------------------------------- //------------------------------rm_prec----------------------------------------
// Remove a precedence input. Precedence inputs are unordered, with // Remove a precedence input. Precedence inputs are unordered, with
// duplicates removed and NULLs packed down at the end. // duplicates removed and NULLs packed down at the end.
void Node::rm_prec( uint j ) { void Node::rm_prec( uint j ) {
assert(j < _max, err_msg("oob: i=%d, _max=%d", j, _max));
// Find end of precedence list to pack NULLs assert(j >= _cnt, "not a precedence edge");
uint i; if (_in[j] == NULL) return; // Avoid spec violation: Gap in prec edges.
for( i=j; i<_max; i++ ) _in[j]->del_out((Node *)this);
if( !_in[i] ) // Find the NULL at end of prec edge list close_prec_gap_at(j);
break;
if (_in[j] != NULL) _in[j]->del_out((Node *)this);
_in[j] = _in[--i]; // Move last element over removed guy
_in[i] = NULL; // NULL out last element
} }
//------------------------------size_of---------------------------------------- //------------------------------size_of----------------------------------------
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -423,6 +423,16 @@ protected: ...@@ -423,6 +423,16 @@ protected:
} }
// Find first occurrence of n among my edges: // Find first occurrence of n among my edges:
int find_edge(Node* n); 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_edge(Node* old, Node* neww);
int replace_edges_in_range(Node* old, Node* neww, int start, int end); int replace_edges_in_range(Node* old, Node* neww, int start, int end);
// NULL out all inputs to eliminate incoming Def-Use edges. // NULL out all inputs to eliminate incoming Def-Use edges.
...@@ -469,6 +479,19 @@ private: ...@@ -469,6 +479,19 @@ private:
debug_only(_last_del = n; ++_del_tick); debug_only(_last_del = n; ++_del_tick);
#endif #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: public:
// Globally replace this node by a given new node, updating all uses. // Globally replace this node by a given new node, updating all uses.
...@@ -485,13 +508,23 @@ public: ...@@ -485,13 +508,23 @@ public:
// Add or remove precedence edges // Add or remove precedence edges
void add_prec( Node *n ); void add_prec( Node *n );
void rm_prec( uint i ); 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 ) { void set_prec( uint i, Node *n ) {
assert( is_not_dead(n), "can not use dead node"); assert(i < _max, err_msg("oob: i=%d, _max=%d", i, _max));
assert( i >= _cnt, "not a precedence edge"); 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); if (_in[i] != NULL) _in[i]->del_out((Node *)this);
_in[i] = n; _in[i] = n;
if (n != NULL) n->add_out((Node *)this); if (n != NULL) n->add_out((Node *)this);
} }
// Set this node's index, used by cisc_version to replace current node // Set this node's index, used by cisc_version to replace current node
void set_idx(uint new_idx) { void set_idx(uint new_idx) {
const node_idx_t* ref = &_idx; const node_idx_t* ref = &_idx;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册