Mercurial > hg > truffle
comparison src/share/vm/opto/node.cpp @ 85:f3b3fe64f59f
6692301: Side effect in NumberFormat tests with -server -Xcomp
Summary: Optimization in CmpPNode::sub() removed the valid compare instruction because of false positive answer from detect_dominating_control().
Reviewed-by: jrose, sgoldman
author | kvn |
---|---|
date | Tue, 15 Apr 2008 10:49:32 -0700 |
parents | 99269dbf4ba8 |
children | ec73d88d5b43 |
comparison
equal
deleted
inserted
replaced
84:6e085831cad7 | 85:f3b3fe64f59f |
---|---|
1014 // Condition for subI(x,subI(y,z)) ==> subI(addI(x,z),y) | 1014 // Condition for subI(x,subI(y,z)) ==> subI(addI(x,z),y) |
1015 return n->Opcode() == op && n->in(2) == this; | 1015 return n->Opcode() == op && n->in(2) == this; |
1016 } | 1016 } |
1017 return false; | 1017 return false; |
1018 }; | 1018 }; |
1019 | |
1020 //--------------------------find_exact_control--------------------------------- | |
1021 // Skip Proj and CatchProj nodes chains. Check for Null and Top. | |
1022 Node* Node::find_exact_control(Node* ctrl) { | |
1023 if (ctrl == NULL && this->is_Region()) | |
1024 ctrl = this->as_Region()->is_copy(); | |
1025 | |
1026 if (ctrl != NULL && ctrl->is_CatchProj()) { | |
1027 if (ctrl->as_CatchProj()->_con == CatchProjNode::fall_through_index) | |
1028 ctrl = ctrl->in(0); | |
1029 if (ctrl != NULL && !ctrl->is_top()) | |
1030 ctrl = ctrl->in(0); | |
1031 } | |
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 Node* orig_sub = sub; | |
1047 nlist.clear(); | |
1048 bool this_dominates = false; | |
1049 uint region_input = 0; | |
1050 while (sub != NULL) { // walk 'sub' up the chain to 'this' | |
1051 if (sub == this) { | |
1052 if (nlist.size() == 0) { | |
1053 // No Region nodes except loops were visited before and the EntryControl | |
1054 // path was taken for loops: it did not walk in a cycle. | |
1055 return true; | |
1056 } else if (!this_dominates) { | |
1057 // Region nodes were visited. Continue walk up to Start or Root | |
1058 // to make sure that it did not walk in a cycle. | |
1059 this_dominates = true; // first time meet | |
1060 } else { | |
1061 return false; // already met before: walk in a cycle | |
1062 } | |
1063 } | |
1064 if (sub->is_Start() || sub->is_Root()) | |
1065 return this_dominates; | |
1066 | |
1067 Node* up = sub->find_exact_control(sub->in(0)); | |
1068 if (up == NULL || up->is_top()) | |
1069 return false; // Conservative answer for dead code | |
1070 | |
1071 if (sub == up && sub->is_Loop()) { | |
1072 up = sub->in(0); // in(LoopNode::EntryControl); | |
1073 } else if (sub == up && sub->is_Region()) { | |
1074 uint i = 1; | |
1075 if (nlist.size() == 0) { | |
1076 // No Region nodes (except Loops) were visited before. | |
1077 // Take first valid path on the way up to 'this'. | |
1078 } else if (nlist.at(nlist.size() - 1) == sub) { | |
1079 // This Region node was just visited. Take other path. | |
1080 i = region_input + 1; | |
1081 nlist.pop(); | |
1082 } else { | |
1083 // Was this Region node visited before? | |
1084 uint size = nlist.size(); | |
1085 for (uint j = 0; j < size; j++) { | |
1086 if (nlist.at(j) == sub) { | |
1087 return false; // The Region node was visited before. Give up. | |
1088 } | |
1089 } | |
1090 // The Region node was not visited before. | |
1091 // Take first valid path on the way up to 'this'. | |
1092 } | |
1093 for (; i < sub->req(); i++) { | |
1094 Node* in = sub->in(i); | |
1095 if (in != NULL && !in->is_top() && in != sub) { | |
1096 break; | |
1097 } | |
1098 } | |
1099 if (i < sub->req()) { | |
1100 nlist.push(sub); | |
1101 up = sub->in(i); | |
1102 region_input = i; | |
1103 } | |
1104 } | |
1105 if (sub == up) | |
1106 return false; // some kind of tight cycle | |
1107 if (orig_sub == up) | |
1108 return false; // walk in a cycle | |
1109 | |
1110 sub = up; | |
1111 } | |
1112 return false; | |
1113 } | |
1019 | 1114 |
1020 //------------------------------remove_dead_region----------------------------- | 1115 //------------------------------remove_dead_region----------------------------- |
1021 // This control node is dead. Follow the subgraph below it making everything | 1116 // This control node is dead. Follow the subgraph below it making everything |
1022 // using it dead as well. This will happen normally via the usual IterGVN | 1117 // using it dead as well. This will happen normally via the usual IterGVN |
1023 // worklist but this call is more efficient. Do not update use-def info | 1118 // worklist but this call is more efficient. Do not update use-def info |