src/share/vm/opto/node.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File 6695810 Sdiff src/share/vm/opto

src/share/vm/opto/node.cpp

Print this page




1032 
1033   if (ctrl != NULL && ctrl->is_Proj())
1034     ctrl = ctrl->in(0);
1035 
1036   return ctrl;
1037 }
1038 
1039 //--------------------------dominates------------------------------------------
1040 // Helper function for MemNode::all_controls_dominate().
1041 // Check if 'this' control node dominates or equal to 'sub' control node.
1042 bool Node::dominates(Node* sub, Node_List &nlist) {
1043   assert(this->is_CFG(), "expecting control");
1044   assert(sub != NULL && sub->is_CFG(), "expecting control");
1045 
1046   // detect dead cycle without regions
1047   int iterations_without_region_limit = DominatorSearchLimit;
1048 
1049   Node* orig_sub = sub;
1050   nlist.clear();
1051   bool this_dominates = false;
1052   uint region_input = 0;

1053   while (sub != NULL) {        // walk 'sub' up the chain to 'this'
1054     if (sub == this) {
1055       if (nlist.size() == 0) {
1056         // No Region nodes except loops were visited before and the EntryControl
1057         // path was taken for loops: it did not walk in a cycle.
1058         return true;
1059       } else if (!this_dominates) {




1060         // Region nodes were visited. Continue walk up to Start or Root
1061         // to make sure that it did not walk in a cycle.
1062         this_dominates = true; // first time meet
1063         iterations_without_region_limit = DominatorSearchLimit; // Reset
1064       } else {
1065         return false;          // already met before: walk in a cycle
1066       }
1067     }
1068     if (sub->is_Start() || sub->is_Root())
1069       return this_dominates;
1070 

1071     Node* up = sub->find_exact_control(sub->in(0));
1072     if (up == NULL || up->is_top())
1073       return false; // Conservative answer for dead code
1074 
1075     if (sub == up && sub->is_Loop()) {


1076       up = sub->in(1); // in(LoopNode::EntryControl);
1077     } else if (sub == up && sub->is_Region() && sub->req() == 3) {

1078       iterations_without_region_limit = DominatorSearchLimit; // Reset






1079       uint i = 1;
1080       uint size = nlist.size();
1081       if (size == 0) {
1082         // No Region nodes (except Loops) were visited before.
1083         // Take first valid path on the way up to 'this'.
1084       } else if (nlist.at(size - 1) == sub) {
1085         // This Region node was just visited. Take other path.
1086         i = region_input + 1;
1087         nlist.pop();
1088       } else {
1089         // Was this Region node visited before?
1090         for (uint j = 0; j < size; j++) {
1091           if (nlist.at(j) == sub) {
1092             return false; // The Region node was visited before. Give up.












1093           }
1094         }









1095         // The Region node was not visited before.
1096         // Take first valid path on the way up to 'this'.
1097       }
1098       for (; i < sub->req(); i++) {
1099         Node* in = sub->in(i);
1100         if (in != NULL && !in->is_top() && in != sub) {
1101           break;
1102         }
1103       }
1104       if (i < sub->req()) {
1105         nlist.push(sub);
1106         up = sub->in(i);
1107         region_input = i;




1108       }
1109     }
1110     if (sub == up)
1111       return false;    // some kind of tight cycle
1112 
1113     if (--iterations_without_region_limit < 0)
1114       return false;    // dead cycle
1115 



1116     sub = up;
1117   }
1118   return false;
1119 }
1120 
1121 //------------------------------remove_dead_region-----------------------------
1122 // This control node is dead.  Follow the subgraph below it making everything
1123 // using it dead as well.  This will happen normally via the usual IterGVN
1124 // worklist but this call is more efficient.  Do not update use-def info
1125 // inside the dead region, just at the borders.
1126 static bool kill_dead_code( Node *dead, PhaseIterGVN *igvn ) {
1127   // Con's are a popular node to re-hit in the hash table again.
1128   if( dead->is_Con() ) return false;
1129 
1130   // Can't put ResourceMark here since igvn->_worklist uses the same arena
1131   // for verify pass with +VerifyOpto and we add/remove elements in it here.
1132   Node_List  nstack(Thread::current()->resource_area());
1133 
1134   Node *top = igvn->C->top();
1135   bool progress = false;
1136   nstack.push(dead);
1137 
1138   while (nstack.size() > 0) {




1032 
1033   if (ctrl != NULL && ctrl->is_Proj())
1034     ctrl = ctrl->in(0);
1035 
1036   return ctrl;
1037 }
1038 
1039 //--------------------------dominates------------------------------------------
1040 // Helper function for MemNode::all_controls_dominate().
1041 // Check if 'this' control node dominates or equal to 'sub' control node.
1042 bool Node::dominates(Node* sub, Node_List &nlist) {
1043   assert(this->is_CFG(), "expecting control");
1044   assert(sub != NULL && sub->is_CFG(), "expecting control");
1045 
1046   // detect dead cycle without regions
1047   int iterations_without_region_limit = DominatorSearchLimit;
1048 
1049   Node* orig_sub = sub;
1050   nlist.clear();
1051   bool this_dominates = false;
1052   bool result = false; // Conservative answer
1053 
1054   while (sub != NULL) {        // walk 'sub' up the chain to 'this'
1055     if (sub == this) {
1056       if (nlist.size() == 0) {
1057         // No Region nodes except loops were visited before and the EntryControl
1058         // path was taken for loops: it did not walk in a cycle.
1059         result = true;
1060         break;
1061       } else if (this_dominates) {
1062         result = false;          // already met before: walk in a cycle
1063         break;
1064       } else {
1065         // Region nodes were visited. Continue walk up to Start or Root
1066         // to make sure that it did not walk in a cycle.
1067         this_dominates = true; // first time meet
1068         iterations_without_region_limit = DominatorSearchLimit; // Reset


1069      }
1070     }
1071     if (sub->is_Start() || sub->is_Root()) {
1072       result = this_dominates;
1073       break;
1074     }
1075     Node* up = sub->find_exact_control(sub->in(0));
1076     if (up == NULL || up->is_top()) {
1077       result = false; // Conservative answer for dead code
1078       break;
1079     }
1080     if (sub == up && (sub->is_Loop() || sub->is_Region() && sub->req() != 3)) {
1081       // Take first valid path on the way up to 'this'.
1082       up = sub->in(1); // in(LoopNode::EntryControl);
1083     } else if (sub == up && sub->is_Region()) {
1084       assert(sub->req() == 3, "sanity");
1085       iterations_without_region_limit = DominatorSearchLimit; // Reset
1086 
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;
1092       uint i = 1;
1093       uint size = nlist.size();
1094       if (size == 0) {
1095         // No such Region nodes were visited before.
1096         // Take first valid path on the way up to 'this'.




1097       } else {
1098         // Was this Region node visited before?
1099         intptr_t ni;
1100         int j = size - 1;
1101         for (; j >= 0; j--) {
1102           ni = (intptr_t)nlist.at(j);
1103           if ((Node*)(ni & ~1) == sub) {
1104             if ((ni & 1) != 0) {
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           }
1120         }
1121         if (j >= 0 && (ni & 1) != 0) {
1122           result = false; // Visited 2 paths. Give up.
1123           break;
1124         }
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;
1131         }
1132       }
1133       if (i < sub->req()) {

1134         up = sub->in(i);
1135         if (region_was_visited_before && sub != up) {
1136           // Set 0 bit to indicate that both paths were taken.
1137           nlist.push((Node*)((intptr_t)sub + 1));
1138         } else {
1139           nlist.push(sub);
1140         }
1141       }
1142     }
1143     if (sub == up) {
1144       result = false;    // some kind of tight cycle
1145       break;
1146     }
1147     if (--iterations_without_region_limit < 0) {
1148       result = false;    // dead cycle
1149       break;
1150     }
1151     sub = up;
1152   }
1153   return result;
1154 }
1155 
1156 //------------------------------remove_dead_region-----------------------------
1157 // 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
1159 // worklist but this call is more efficient.  Do not update use-def info
1160 // inside the dead region, just at the borders.
1161 static bool kill_dead_code( Node *dead, PhaseIterGVN *igvn ) {
1162   // Con's are a popular node to re-hit in the hash table again.
1163   if( dead->is_Con() ) return false;
1164 
1165   // Can't put ResourceMark here since igvn->_worklist uses the same arena
1166   // for verify pass with +VerifyOpto and we add/remove elements in it here.
1167   Node_List  nstack(Thread::current()->resource_area());
1168 
1169   Node *top = igvn->C->top();
1170   bool progress = false;
1171   nstack.push(dead);
1172 
1173   while (nstack.size() > 0) {


src/share/vm/opto/node.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File