src/share/vm/opto/node.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File
6695810 Cdiff src/share/vm/opto/node.cpp
src/share/vm/opto/node.cpp
Print this page
*** 1047,1123 ****
int iterations_without_region_limit = DominatorSearchLimit;
Node* orig_sub = sub;
nlist.clear();
bool this_dominates = false;
! uint region_input = 0;
while (sub != NULL) { // walk 'sub' up the chain to 'this'
if (sub == this) {
if (nlist.size() == 0) {
// No Region nodes except loops were visited before and the EntryControl
// path was taken for loops: it did not walk in a cycle.
! return true;
! } else if (!this_dominates) {
// Region nodes were visited. Continue walk up to Start or Root
// to make sure that it did not walk in a cycle.
this_dominates = true; // first time meet
iterations_without_region_limit = DominatorSearchLimit; // Reset
- } else {
- return false; // already met before: walk in a cycle
}
}
! if (sub->is_Start() || sub->is_Root())
! return this_dominates;
!
Node* up = sub->find_exact_control(sub->in(0));
! if (up == NULL || up->is_top())
! return false; // Conservative answer for dead code
!
! if (sub == up && sub->is_Loop()) {
up = sub->in(1); // in(LoopNode::EntryControl);
! } else if (sub == up && sub->is_Region() && sub->req() == 3) {
iterations_without_region_limit = DominatorSearchLimit; // Reset
uint i = 1;
uint size = nlist.size();
if (size == 0) {
! // No Region nodes (except Loops) were visited before.
// Take first valid path on the way up to 'this'.
- } else if (nlist.at(size - 1) == sub) {
- // This Region node was just visited. Take other path.
- i = region_input + 1;
- nlist.pop();
} else {
// Was this Region node visited before?
! for (uint j = 0; j < size; j++) {
! if (nlist.at(j) == sub) {
! return false; // The Region node was visited before. Give up.
}
}
// The Region node was not visited before.
- // Take first valid path on the way up to 'this'.
}
for (; i < sub->req(); i++) {
Node* in = sub->in(i);
if (in != NULL && !in->is_top() && in != sub) {
break;
}
}
if (i < sub->req()) {
- nlist.push(sub);
up = sub->in(i);
! region_input = i;
}
}
! if (sub == up)
! return false; // some kind of tight cycle
!
! if (--iterations_without_region_limit < 0)
! return false; // dead cycle
!
sub = up;
}
! return false;
}
//------------------------------remove_dead_region-----------------------------
// This control node is dead. Follow the subgraph below it making everything
// using it dead as well. This will happen normally via the usual IterGVN
--- 1047,1158 ----
int iterations_without_region_limit = DominatorSearchLimit;
Node* orig_sub = sub;
nlist.clear();
bool this_dominates = false;
! bool result = false; // Conservative answer
!
while (sub != NULL) { // walk 'sub' up the chain to 'this'
if (sub == this) {
if (nlist.size() == 0) {
// No Region nodes except loops were visited before and the EntryControl
// path was taken for loops: it did not walk in a cycle.
! result = true;
! break;
! } else if (this_dominates) {
! result = false; // already met before: walk in a cycle
! break;
! } else {
// Region nodes were visited. Continue walk up to Start or Root
// to make sure that it did not walk in a cycle.
this_dominates = true; // first time meet
iterations_without_region_limit = DominatorSearchLimit; // Reset
}
}
! if (sub->is_Start() || sub->is_Root()) {
! result = this_dominates;
! break;
! }
Node* up = sub->find_exact_control(sub->in(0));
! if (up == NULL || up->is_top()) {
! result = false; // Conservative answer for dead code
! break;
! }
! if (sub == up && (sub->is_Loop() || sub->is_Region() && sub->req() != 3)) {
! // Take first valid path on the way up to 'this'.
up = sub->in(1); // in(LoopNode::EntryControl);
! } else if (sub == up && sub->is_Region()) {
! assert(sub->req() == 3, "sanity");
iterations_without_region_limit = DominatorSearchLimit; // Reset
+
+ // Try both paths for such Regions.
+ // It is not accurate without regions dominating information.
+ // With such information the other path should be checked for
+ // the most dominating Region which was visited before.
+ bool region_was_visited_before = false;
uint i = 1;
uint size = nlist.size();
if (size == 0) {
! // No such Region nodes were visited before.
// Take first valid path on the way up to 'this'.
} else {
// Was this Region node visited before?
! intptr_t ni;
! int j = size - 1;
! for (; j >= 0; j--) {
! ni = (intptr_t)nlist.at(j);
! if ((Node*)(ni & ~1) == sub) {
! if ((ni & 1) != 0) {
! break; // Visited 2 paths. Give up.
! } else {
! // The Region node was visited before only once.
! nlist.remove(j);
! region_was_visited_before = true;
! for (; i < sub->req(); i++) {
! Node* in = sub->in(i);
! if (in != NULL && !in->is_top() && in != sub) {
! break;
}
}
+ i++; // Take other path.
+ break;
+ }
+ }
+ }
+ if (j >= 0 && (ni & 1) != 0) {
+ result = false; // Visited 2 paths. Give up.
+ break;
+ }
// The Region node was not visited before.
}
for (; i < sub->req(); i++) {
Node* in = sub->in(i);
if (in != NULL && !in->is_top() && in != sub) {
break;
}
}
if (i < sub->req()) {
up = sub->in(i);
! if (region_was_visited_before && sub != up) {
! // Set 0 bit to indicate that both paths were taken.
! nlist.push((Node*)((intptr_t)sub + 1));
! } else {
! nlist.push(sub);
}
}
! }
! if (sub == up) {
! result = false; // some kind of tight cycle
! break;
! }
! if (--iterations_without_region_limit < 0) {
! result = false; // dead cycle
! break;
! }
sub = up;
}
! return result;
}
//------------------------------remove_dead_region-----------------------------
// This control node is dead. Follow the subgraph below it making everything
// using it dead as well. This will happen normally via the usual IterGVN
src/share/vm/opto/node.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File