Mercurial > hg > graal-compiler
comparison src/share/vm/opto/phaseX.cpp @ 8868:30f42e691e70
8004640: C2 assert failure in memnode.cpp: NULL+offs not RAW address
Summary: always transform AddP nodes in IdealKit by calling _gvn.transform().
Reviewed-by: roland, twisti
author | kvn |
---|---|
date | Tue, 26 Mar 2013 12:55:26 -0700 |
parents | 6931f425c517 |
children | 6f3fd5150b67 |
comparison
equal
deleted
inserted
replaced
8867:b808febcad9a | 8868:30f42e691e70 |
---|---|
1164 assert(!dead->is_top(), "add check for top when pushing"); | 1164 assert(!dead->is_top(), "add check for top when pushing"); |
1165 NOT_PRODUCT( set_progress(); ) | 1165 NOT_PRODUCT( set_progress(); ) |
1166 if (progress_state == PROCESS_INPUTS) { | 1166 if (progress_state == PROCESS_INPUTS) { |
1167 // After following inputs, continue to outputs | 1167 // After following inputs, continue to outputs |
1168 _stack.set_index(PROCESS_OUTPUTS); | 1168 _stack.set_index(PROCESS_OUTPUTS); |
1169 // Remove from iterative worklist | |
1170 _worklist.remove(dead); | |
1171 if (!dead->is_Con()) { // Don't kill cons but uses | 1169 if (!dead->is_Con()) { // Don't kill cons but uses |
1172 bool recurse = false; | 1170 bool recurse = false; |
1173 // Remove from hash table | 1171 // Remove from hash table |
1174 _table.hash_delete( dead ); | 1172 _table.hash_delete( dead ); |
1175 // Smash all inputs to 'dead', isolating him completely | 1173 // Smash all inputs to 'dead', isolating him completely |
1176 for( uint i = 0; i < dead->req(); i++ ) { | 1174 for (uint i = 0; i < dead->req(); i++) { |
1177 Node *in = dead->in(i); | 1175 Node *in = dead->in(i); |
1178 if( in ) { // Points to something? | 1176 if (in != NULL && in != C->top()) { // Points to something? |
1179 dead->set_req(i,NULL); // Kill the edge | 1177 int nrep = dead->replace_edge(in, NULL); // Kill edges |
1180 if (in->outcnt() == 0 && in != C->top()) {// Made input go dead? | 1178 assert((nrep > 0), "sanity"); |
1179 if (in->outcnt() == 0) { // Made input go dead? | |
1181 _stack.push(in, PROCESS_INPUTS); // Recursively remove | 1180 _stack.push(in, PROCESS_INPUTS); // Recursively remove |
1182 recurse = true; | 1181 recurse = true; |
1183 } else if (in->outcnt() == 1 && | 1182 } else if (in->outcnt() == 1 && |
1184 in->has_special_unique_user()) { | 1183 in->has_special_unique_user()) { |
1185 _worklist.push(in->unique_out()); | 1184 _worklist.push(in->unique_out()); |
1186 } else if (in->outcnt() <= 2 && dead->is_Phi()) { | 1185 } else if (in->outcnt() <= 2 && dead->is_Phi()) { |
1187 if( in->Opcode() == Op_Region ) | 1186 if (in->Opcode() == Op_Region) { |
1188 _worklist.push(in); | 1187 _worklist.push(in); |
1189 else if( in->is_Store() ) { | 1188 } else if (in->is_Store()) { |
1190 DUIterator_Fast imax, i = in->fast_outs(imax); | 1189 DUIterator_Fast imax, i = in->fast_outs(imax); |
1191 _worklist.push(in->fast_out(i)); | 1190 _worklist.push(in->fast_out(i)); |
1192 i++; | 1191 i++; |
1193 if(in->outcnt() == 2) { | 1192 if (in->outcnt() == 2) { |
1194 _worklist.push(in->fast_out(i)); | 1193 _worklist.push(in->fast_out(i)); |
1195 i++; | 1194 i++; |
1196 } | 1195 } |
1197 assert(!(i < imax), "sanity"); | 1196 assert(!(i < imax), "sanity"); |
1198 } | 1197 } |
1207 if (n->is_Store()) { | 1206 if (n->is_Store()) { |
1208 _worklist.push(n); | 1207 _worklist.push(n); |
1209 } | 1208 } |
1210 } | 1209 } |
1211 } | 1210 } |
1212 } | 1211 } // if (in != NULL && in != C->top()) |
1213 } | 1212 } // for (uint i = 0; i < dead->req(); i++) |
1214 C->record_dead_node(dead->_idx); | |
1215 if (dead->is_macro()) { | |
1216 C->remove_macro_node(dead); | |
1217 } | |
1218 if (dead->is_expensive()) { | |
1219 C->remove_expensive_node(dead); | |
1220 } | |
1221 | |
1222 if (recurse) { | 1213 if (recurse) { |
1223 continue; | 1214 continue; |
1224 } | 1215 } |
1225 } | 1216 } // if (!dead->is_Con()) |
1217 } // if (progress_state == PROCESS_INPUTS) | |
1218 | |
1219 // Aggressively kill globally dead uses | |
1220 // (Rather than pushing all the outs at once, we push one at a time, | |
1221 // plus the parent to resume later, because of the indefinite number | |
1222 // of edge deletions per loop trip.) | |
1223 if (dead->outcnt() > 0) { | |
1224 // Recursively remove output edges | |
1225 _stack.push(dead->raw_out(0), PROCESS_INPUTS); | |
1226 } else { | |
1227 // Finished disconnecting all input and output edges. | |
1228 _stack.pop(); | |
1229 // Remove dead node from iterative worklist | |
1230 _worklist.remove(dead); | |
1226 // Constant node that has no out-edges and has only one in-edge from | 1231 // Constant node that has no out-edges and has only one in-edge from |
1227 // root is usually dead. However, sometimes reshaping walk makes | 1232 // root is usually dead. However, sometimes reshaping walk makes |
1228 // it reachable by adding use edges. So, we will NOT count Con nodes | 1233 // it reachable by adding use edges. So, we will NOT count Con nodes |
1229 // as dead to be conservative about the dead node count at any | 1234 // as dead to be conservative about the dead node count at any |
1230 // given time. | 1235 // given time. |
1231 } | 1236 if (!dead->is_Con()) { |
1232 | 1237 C->record_dead_node(dead->_idx); |
1233 // Aggressively kill globally dead uses | 1238 } |
1234 // (Rather than pushing all the outs at once, we push one at a time, | 1239 if (dead->is_macro()) { |
1235 // plus the parent to resume later, because of the indefinite number | 1240 C->remove_macro_node(dead); |
1236 // of edge deletions per loop trip.) | 1241 } |
1237 if (dead->outcnt() > 0) { | 1242 if (dead->is_expensive()) { |
1238 // Recursively remove | 1243 C->remove_expensive_node(dead); |
1239 _stack.push(dead->raw_out(0), PROCESS_INPUTS); | 1244 } |
1240 } else { | 1245 } |
1241 _stack.pop(); | 1246 } // while (_stack.is_nonempty()) |
1242 } | |
1243 } | |
1244 } | 1247 } |
1245 | 1248 |
1246 //------------------------------subsume_node----------------------------------- | 1249 //------------------------------subsume_node----------------------------------- |
1247 // Remove users from node 'old' and add them to node 'nn'. | 1250 // Remove users from node 'old' and add them to node 'nn'. |
1248 void PhaseIterGVN::subsume_node( Node *old, Node *nn ) { | 1251 void PhaseIterGVN::subsume_node( Node *old, Node *nn ) { |