Mercurial > hg > truffle
comparison src/share/vm/opto/node.cpp @ 193:44a553b2809d
6714406: Node::dominates() does not always check for TOP
Summary: Add missed checks for TOP and missed checks for non-dominating cases
Reviewed-by: rasbold, jrose, never
author | kvn |
---|---|
date | Fri, 13 Jun 2008 15:08:56 -0700 |
parents | 885ed790ecf0 |
children | d1605aabd0a1 2a1a77d3458f |
comparison
equal
deleted
inserted
replaced
192:6d13fcb3663f | 193:44a553b2809d |
---|---|
1037 } | 1037 } |
1038 | 1038 |
1039 //--------------------------dominates------------------------------------------ | 1039 //--------------------------dominates------------------------------------------ |
1040 // Helper function for MemNode::all_controls_dominate(). | 1040 // Helper function for MemNode::all_controls_dominate(). |
1041 // Check if 'this' control node dominates or equal to 'sub' control node. | 1041 // Check if 'this' control node dominates or equal to 'sub' control node. |
1042 // We already know that if any path back to Root or Start reaches 'this', | |
1043 // then all paths so, so this is a simple search for one example, | |
1044 // not an exhaustive search for a counterexample. | |
1042 bool Node::dominates(Node* sub, Node_List &nlist) { | 1045 bool Node::dominates(Node* sub, Node_List &nlist) { |
1043 assert(this->is_CFG(), "expecting control"); | 1046 assert(this->is_CFG(), "expecting control"); |
1044 assert(sub != NULL && sub->is_CFG(), "expecting control"); | 1047 assert(sub != NULL && sub->is_CFG(), "expecting control"); |
1045 | 1048 |
1046 // detect dead cycle without regions | 1049 // detect dead cycle without regions |
1047 int iterations_without_region_limit = DominatorSearchLimit; | 1050 int iterations_without_region_limit = DominatorSearchLimit; |
1048 | 1051 |
1049 Node* orig_sub = sub; | 1052 Node* orig_sub = sub; |
1053 Node* dom = this; | |
1054 bool met_dom = false; | |
1050 nlist.clear(); | 1055 nlist.clear(); |
1051 bool this_dominates = false; | 1056 |
1052 bool result = false; // Conservative answer | 1057 // Walk 'sub' backward up the chain to 'dom', watching for regions. |
1053 | 1058 // After seeing 'dom', continue up to Root or Start. |
1054 while (sub != NULL) { // walk 'sub' up the chain to 'this' | 1059 // If we hit a region (backward split point), it may be a loop head. |
1055 if (sub == this) { | 1060 // Keep going through one of the region's inputs. If we reach the |
1061 // same region again, go through a different input. Eventually we | |
1062 // will either exit through the loop head, or give up. | |
1063 // (If we get confused, break out and return a conservative 'false'.) | |
1064 while (sub != NULL) { | |
1065 if (sub->is_top()) break; // Conservative answer for dead code. | |
1066 if (sub == dom) { | |
1056 if (nlist.size() == 0) { | 1067 if (nlist.size() == 0) { |
1057 // No Region nodes except loops were visited before and the EntryControl | 1068 // No Region nodes except loops were visited before and the EntryControl |
1058 // path was taken for loops: it did not walk in a cycle. | 1069 // path was taken for loops: it did not walk in a cycle. |
1059 result = true; | 1070 return true; |
1060 break; | 1071 } else if (met_dom) { |
1061 } else if (this_dominates) { | 1072 break; // already met before: walk in a cycle |
1062 result = false; // already met before: walk in a cycle | |
1063 break; | |
1064 } else { | 1073 } else { |
1065 // Region nodes were visited. Continue walk up to Start or Root | 1074 // Region nodes were visited. Continue walk up to Start or Root |
1066 // to make sure that it did not walk in a cycle. | 1075 // to make sure that it did not walk in a cycle. |
1067 this_dominates = true; // first time meet | 1076 met_dom = true; // first time meet |
1068 iterations_without_region_limit = DominatorSearchLimit; // Reset | 1077 iterations_without_region_limit = DominatorSearchLimit; // Reset |
1069 } | 1078 } |
1070 } | 1079 } |
1071 if (sub->is_Start() || sub->is_Root()) { | 1080 if (sub->is_Start() || sub->is_Root()) { |
1072 result = this_dominates; | 1081 // Success if we met 'dom' along a path to Start or Root. |
1073 break; | 1082 // We assume there are no alternative paths that avoid 'dom'. |
1074 } | 1083 // (This assumption is up to the caller to ensure!) |
1075 Node* up = sub->find_exact_control(sub->in(0)); | 1084 return met_dom; |
1076 if (up == NULL || up->is_top()) { | 1085 } |
1077 result = false; // Conservative answer for dead code | 1086 Node* up = sub->in(0); |
1078 break; | 1087 // Normalize simple pass-through regions and projections: |
1079 } | 1088 up = sub->find_exact_control(up); |
1080 if (sub == up && (sub->is_Loop() || sub->is_Region() && sub->req() != 3)) { | 1089 // If sub == up, we found a self-loop. Try to push past it. |
1081 // Take first valid path on the way up to 'this'. | 1090 if (sub == up && sub->is_Loop()) { |
1091 // Take loop entry path on the way up to 'dom'. | |
1082 up = sub->in(1); // in(LoopNode::EntryControl); | 1092 up = sub->in(1); // in(LoopNode::EntryControl); |
1093 } else if (sub == up && sub->is_Region() && sub->req() != 3) { | |
1094 // Always take in(1) path on the way up to 'dom' for clone regions | |
1095 // (with only one input) or regions which merge > 2 paths | |
1096 // (usually used to merge fast/slow paths). | |
1097 up = sub->in(1); | |
1083 } else if (sub == up && sub->is_Region()) { | 1098 } else if (sub == up && sub->is_Region()) { |
1084 assert(sub->req() == 3, "sanity"); | 1099 // Try both paths for Regions with 2 input paths (it may be a loop head). |
1100 // It could give conservative 'false' answer without information | |
1101 // which region's input is the entry path. | |
1085 iterations_without_region_limit = DominatorSearchLimit; // Reset | 1102 iterations_without_region_limit = DominatorSearchLimit; // Reset |
1086 | 1103 |
1087 // Try both paths for such Regions. | |
1088 // It is not accurate without regions dominating information. | |
1089 // With such information the other path should be checked for | |
1090 // the most dominating Region which was visited before. | |
1091 bool region_was_visited_before = false; | 1104 bool region_was_visited_before = false; |
1092 uint i = 1; | 1105 // Was this Region node visited before? |
1093 uint size = nlist.size(); | 1106 // If so, we have reached it because we accidentally took a |
1094 if (size == 0) { | 1107 // loop-back edge from 'sub' back into the body of the loop, |
1095 // No such Region nodes were visited before. | 1108 // and worked our way up again to the loop header 'sub'. |
1096 // Take first valid path on the way up to 'this'. | 1109 // So, take the first unexplored path on the way up to 'dom'. |
1097 } else { | 1110 for (int j = nlist.size() - 1; j >= 0; j--) { |
1098 // Was this Region node visited before? | 1111 intptr_t ni = (intptr_t)nlist.at(j); |
1099 intptr_t ni; | 1112 Node* visited = (Node*)(ni & ~1); |
1100 int j = size - 1; | 1113 bool visited_twice_already = ((ni & 1) != 0); |
1101 for (; j >= 0; j--) { | 1114 if (visited == sub) { |
1102 ni = (intptr_t)nlist.at(j); | 1115 if (visited_twice_already) { |
1103 if ((Node*)(ni & ~1) == sub) { | 1116 // Visited 2 paths, but still stuck in loop body. Give up. |
1104 if ((ni & 1) != 0) { | 1117 return false; |
1105 break; // Visited 2 paths. Give up. | |
1106 } else { | |
1107 // The Region node was visited before only once. | |
1108 nlist.remove(j); | |
1109 region_was_visited_before = true; | |
1110 for (; i < sub->req(); i++) { | |
1111 Node* in = sub->in(i); | |
1112 if (in != NULL && !in->is_top() && in != sub) { | |
1113 break; | |
1114 } | |
1115 } | |
1116 i++; // Take other path. | |
1117 break; | |
1118 } | |
1119 } | 1118 } |
1120 } | 1119 // The Region node was visited before only once. |
1121 if (j >= 0 && (ni & 1) != 0) { | 1120 // (We will repush with the low bit set, below.) |
1122 result = false; // Visited 2 paths. Give up. | 1121 nlist.remove(j); |
1123 break; | 1122 // We will find a new edge and re-insert. |
1124 } | 1123 region_was_visited_before = true; |
1125 // The Region node was not visited before. | |
1126 } | |
1127 for (; i < sub->req(); i++) { | |
1128 Node* in = sub->in(i); | |
1129 if (in != NULL && !in->is_top() && in != sub) { | |
1130 break; | 1124 break; |
1131 } | 1125 } |
1132 } | 1126 } |
1133 if (i < sub->req()) { | 1127 |
1134 up = sub->in(i); | 1128 // Find an incoming edge which has not been seen yet; walk through it. |
1135 if (region_was_visited_before && sub != up) { | 1129 assert(up == sub, ""); |
1136 // Set 0 bit to indicate that both paths were taken. | 1130 uint skip = region_was_visited_before ? 1 : 0; |
1137 nlist.push((Node*)((intptr_t)sub + 1)); | 1131 for (uint i = 1; i < sub->req(); i++) { |
1138 } else { | 1132 Node* in = sub->in(i); |
1139 nlist.push(sub); | 1133 if (in != NULL && !in->is_top() && in != sub) { |
1134 if (skip == 0) { | |
1135 up = in; | |
1136 break; | |
1137 } | |
1138 --skip; // skip this nontrivial input | |
1140 } | 1139 } |
1141 } | 1140 } |
1142 } | 1141 |
1143 if (sub == up) { | 1142 // Set 0 bit to indicate that both paths were taken. |
1144 result = false; // some kind of tight cycle | 1143 nlist.push((Node*)((intptr_t)sub + (region_was_visited_before ? 1 : 0))); |
1145 break; | 1144 } |
1145 | |
1146 if (up == sub) { | |
1147 break; // some kind of tight cycle | |
1148 } | |
1149 if (up == orig_sub && met_dom) { | |
1150 // returned back after visiting 'dom' | |
1151 break; // some kind of cycle | |
1146 } | 1152 } |
1147 if (--iterations_without_region_limit < 0) { | 1153 if (--iterations_without_region_limit < 0) { |
1148 result = false; // dead cycle | 1154 break; // dead cycle |
1149 break; | |
1150 } | 1155 } |
1151 sub = up; | 1156 sub = up; |
1152 } | 1157 } |
1153 return result; | 1158 |
1159 // Did not meet Root or Start node in pred. chain. | |
1160 // Conservative answer for dead code. | |
1161 return false; | |
1154 } | 1162 } |
1155 | 1163 |
1156 //------------------------------remove_dead_region----------------------------- | 1164 //------------------------------remove_dead_region----------------------------- |
1157 // This control node is dead. Follow the subgraph below it making everything | 1165 // This control node is dead. Follow the subgraph below it making everything |
1158 // using it dead as well. This will happen normally via the usual IterGVN | 1166 // using it dead as well. This will happen normally via the usual IterGVN |