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 ) {