提交 d8b36aa5 编写于 作者: K kvn

7160161: Missed safepoint in non-Counted loop

Summary: Do not remove safepoints during peeling optimization.
Reviewed-by: twisti
上级 71e471aa
...@@ -547,11 +547,6 @@ void PhaseIdealLoop::do_peeling( IdealLoopTree *loop, Node_List &old_new ) { ...@@ -547,11 +547,6 @@ void PhaseIdealLoop::do_peeling( IdealLoopTree *loop, Node_List &old_new ) {
Node *nnn = old_new[old->_idx]; Node *nnn = old_new[old->_idx];
if (!has_ctrl(nnn)) if (!has_ctrl(nnn))
set_idom(nnn, idom(nnn), dd-1); set_idom(nnn, idom(nnn), dd-1);
// While we're at it, remove any SafePoints from the peeled code
if (old->Opcode() == Op_SafePoint) {
Node *nnn = old_new[old->_idx];
lazy_replace(nnn,nnn->in(TypeFunc::Control));
}
} }
// Now force out all loop-invariant dominating tests. The optimizer // Now force out all loop-invariant dominating tests. The optimizer
......
...@@ -577,6 +577,9 @@ bool PhaseIdealLoop::is_counted_loop( Node *x, IdealLoopTree *loop ) { ...@@ -577,6 +577,9 @@ bool PhaseIdealLoop::is_counted_loop( Node *x, IdealLoopTree *loop ) {
Node *sfpt = x->in(LoopNode::LoopBackControl); Node *sfpt = x->in(LoopNode::LoopBackControl);
if (sfpt->Opcode() == Op_SafePoint && is_deleteable_safept(sfpt)) { if (sfpt->Opcode() == Op_SafePoint && is_deleteable_safept(sfpt)) {
lazy_replace( sfpt, iftrue ); lazy_replace( sfpt, iftrue );
if (loop->_safepts != NULL) {
loop->_safepts->yank(sfpt);
}
loop->_tail = iftrue; loop->_tail = iftrue;
} }
...@@ -668,8 +671,12 @@ bool PhaseIdealLoop::is_counted_loop( Node *x, IdealLoopTree *loop ) { ...@@ -668,8 +671,12 @@ bool PhaseIdealLoop::is_counted_loop( Node *x, IdealLoopTree *loop ) {
// Check for immediately preceding SafePoint and remove // Check for immediately preceding SafePoint and remove
Node *sfpt2 = le->in(0); Node *sfpt2 = le->in(0);
if (sfpt2->Opcode() == Op_SafePoint && is_deleteable_safept(sfpt2)) if (sfpt2->Opcode() == Op_SafePoint && is_deleteable_safept(sfpt2)) {
lazy_replace( sfpt2, sfpt2->in(TypeFunc::Control)); lazy_replace( sfpt2, sfpt2->in(TypeFunc::Control));
if (loop->_safepts != NULL) {
loop->_safepts->yank(sfpt2);
}
}
// Free up intermediate goo // Free up intermediate goo
_igvn.remove_dead_node(hook); _igvn.remove_dead_node(hook);
...@@ -1526,10 +1533,8 @@ void IdealLoopTree::allpaths_check_safepts(VectorSet &visited, Node_List &stack) ...@@ -1526,10 +1533,8 @@ void IdealLoopTree::allpaths_check_safepts(VectorSet &visited, Node_List &stack)
void IdealLoopTree::check_safepts(VectorSet &visited, Node_List &stack) { void IdealLoopTree::check_safepts(VectorSet &visited, Node_List &stack) {
// Bottom up traversal // Bottom up traversal
IdealLoopTree* ch = _child; IdealLoopTree* ch = _child;
while (ch != NULL) { if (_child) _child->check_safepts(visited, stack);
ch->check_safepts(visited, stack); if (_next) _next ->check_safepts(visited, stack);
ch = ch->_next;
}
if (!_head->is_CountedLoop() && !_has_sfpt && _parent != NULL && !_irreducible) { if (!_head->is_CountedLoop() && !_has_sfpt && _parent != NULL && !_irreducible) {
bool has_call = false; // call on dom-path bool has_call = false; // call on dom-path
...@@ -1702,29 +1707,39 @@ void IdealLoopTree::counted_loop( PhaseIdealLoop *phase ) { ...@@ -1702,29 +1707,39 @@ void IdealLoopTree::counted_loop( PhaseIdealLoop *phase ) {
phase->is_counted_loop(_head, this)) { phase->is_counted_loop(_head, this)) {
_has_sfpt = 1; // Indicate we do not need a safepoint here _has_sfpt = 1; // Indicate we do not need a safepoint here
// Look for a safepoint to remove // Look for safepoints to remove.
for (Node* n = tail(); n != _head; n = phase->idom(n)) Node_List* sfpts = _safepts;
if (n->Opcode() == Op_SafePoint && phase->get_loop(n) == this && if (sfpts != NULL) {
phase->is_deleteable_safept(n)) for (uint i = 0; i < sfpts->size(); i++) {
phase->lazy_replace(n,n->in(TypeFunc::Control)); Node* n = sfpts->at(i);
assert(phase->get_loop(n) == this, "");
if (phase->is_deleteable_safept(n)) {
phase->lazy_replace(n, n->in(TypeFunc::Control));
}
}
}
// Look for induction variables // Look for induction variables
phase->replace_parallel_iv(this); phase->replace_parallel_iv(this);
} else if (_parent != NULL && !_irreducible) { } else if (_parent != NULL && !_irreducible) {
// Not a counted loop. // Not a counted loop.
// Look for a safepoint on the idom-path to remove, preserving the first one // Look for a safepoint on the idom-path.
bool found = false; Node* sfpt = tail();
Node* n = tail(); for (; sfpt != _head; sfpt = phase->idom(sfpt)) {
for (; n != _head && !found; n = phase->idom(n)) { if (sfpt->Opcode() == Op_SafePoint && phase->get_loop(sfpt) == this)
if (n->Opcode() == Op_SafePoint && phase->get_loop(n) == this) break; // Found one
found = true; // Found one }
// Delete other safepoints in this loop.
Node_List* sfpts = _safepts;
if (sfpts != NULL && sfpt != _head && sfpt->Opcode() == Op_SafePoint) {
for (uint i = 0; i < sfpts->size(); i++) {
Node* n = sfpts->at(i);
assert(phase->get_loop(n) == this, "");
if (n != sfpt && phase->is_deleteable_safept(n)) {
phase->lazy_replace(n, n->in(TypeFunc::Control));
}
} }
// Skip past it and delete the others
for (; n != _head; n = phase->idom(n)) {
if (n->Opcode() == Op_SafePoint && phase->get_loop(n) == this &&
phase->is_deleteable_safept(n))
phase->lazy_replace(n,n->in(TypeFunc::Control));
} }
} }
...@@ -2766,6 +2781,10 @@ int PhaseIdealLoop::build_loop_tree_impl( Node *n, int pre_order ) { ...@@ -2766,6 +2781,10 @@ int PhaseIdealLoop::build_loop_tree_impl( Node *n, int pre_order ) {
// if the allocation is not eliminated for some reason. // if the allocation is not eliminated for some reason.
innermost->_allow_optimizations = false; innermost->_allow_optimizations = false;
innermost->_has_call = 1; // = true innermost->_has_call = 1; // = true
} else if (n->Opcode() == Op_SafePoint) {
// Record all safepoints in this loop.
if (innermost->_safepts == NULL) innermost->_safepts = new Node_List();
innermost->_safepts->push(n);
} }
} }
} }
...@@ -2816,6 +2835,9 @@ void PhaseIdealLoop::build_loop_early( VectorSet &visited, Node_List &worklist, ...@@ -2816,6 +2835,9 @@ void PhaseIdealLoop::build_loop_early( VectorSet &visited, Node_List &worklist,
is_deleteable_safept(n)) { is_deleteable_safept(n)) {
Node *in = n->in(TypeFunc::Control); Node *in = n->in(TypeFunc::Control);
lazy_replace(n,in); // Pull safepoint now lazy_replace(n,in); // Pull safepoint now
if (ilt->_safepts != NULL) {
ilt->_safepts->yank(n);
}
// Carry on with the recursion "as if" we are walking // Carry on with the recursion "as if" we are walking
// only the control input // only the control input
if( !visited.test_set( in->_idx ) ) { if( !visited.test_set( in->_idx ) ) {
......
...@@ -336,6 +336,7 @@ public: ...@@ -336,6 +336,7 @@ public:
_has_sfpt:1, // True if has non-call safepoint _has_sfpt:1, // True if has non-call safepoint
_rce_candidate:1; // True if candidate for range check elimination _rce_candidate:1; // True if candidate for range check elimination
Node_List* _safepts; // List of safepoints in this loop
Node_List* _required_safept; // A inner loop cannot delete these safepts; Node_List* _required_safept; // A inner loop cannot delete these safepts;
bool _allow_optimizations; // Allow loop optimizations bool _allow_optimizations; // Allow loop optimizations
...@@ -343,6 +344,7 @@ public: ...@@ -343,6 +344,7 @@ public:
: _parent(0), _next(0), _child(0), : _parent(0), _next(0), _child(0),
_head(head), _tail(tail), _head(head), _tail(tail),
_phase(phase), _phase(phase),
_safepts(NULL),
_required_safept(NULL), _required_safept(NULL),
_allow_optimizations(true), _allow_optimizations(true),
_nest(0), _irreducible(0), _has_call(0), _has_sfpt(0), _rce_candidate(0) _nest(0), _irreducible(0), _has_call(0), _has_sfpt(0), _rce_candidate(0)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册