comparison src/share/vm/opto/macro.cpp @ 247:02a35ad4adf8

6723160: Nightly failure: Error: meet not symmetric Summary: Add missing _instance_id settings and other EA fixes. Reviewed-by: rasbold
author kvn
date Wed, 16 Jul 2008 16:04:39 -0700
parents 9c2ecc2ffb12
children b0fe4deeb9fb
comparison
equal deleted inserted replaced
246:9b66e6287f4a 247:02a35ad4adf8
229 } 229 }
230 mem = mem->in(MemNode::Memory); 230 mem = mem->in(MemNode::Memory);
231 } else { 231 } else {
232 return mem; 232 return mem;
233 } 233 }
234 if (mem == orig_mem) 234 assert(mem != orig_mem, "dead memory loop");
235 return mem;
236 } 235 }
237 } 236 }
238 237
239 // 238 //
240 // Given a Memory Phi, compute a value Phi containing the values from stores 239 // Given a Memory Phi, compute a value Phi containing the values from stores
241 // on the input paths. 240 // on the input paths.
242 // Note: this function is recursive, its depth is limied by the "level" argument 241 // Note: this function is recursive, its depth is limied by the "level" argument
243 // Returns the computed Phi, or NULL if it cannot compute it. 242 // Returns the computed Phi, or NULL if it cannot compute it.
244 Node *PhaseMacroExpand::value_from_mem_phi(Node *mem, BasicType ft, const Type *phi_type, const TypeOopPtr *adr_t, Node *alloc, int level) { 243 Node *PhaseMacroExpand::value_from_mem_phi(Node *mem, BasicType ft, const Type *phi_type, const TypeOopPtr *adr_t, Node *alloc, Node_Stack *value_phis, int level) {
245 244 assert(mem->is_Phi(), "sanity");
246 if (level <= 0) {
247 return NULL;
248 }
249 int alias_idx = C->get_alias_index(adr_t); 245 int alias_idx = C->get_alias_index(adr_t);
250 int offset = adr_t->offset(); 246 int offset = adr_t->offset();
251 int instance_id = adr_t->instance_id(); 247 int instance_id = adr_t->instance_id();
252 248
249 // Check if an appropriate value phi already exists.
250 Node* region = mem->in(0);
251 for (DUIterator_Fast kmax, k = region->fast_outs(kmax); k < kmax; k++) {
252 Node* phi = region->fast_out(k);
253 if (phi->is_Phi() && phi != mem &&
254 phi->as_Phi()->is_same_inst_field(phi_type, instance_id, alias_idx, offset)) {
255 return phi;
256 }
257 }
258 // Check if an appropriate new value phi already exists.
259 Node* new_phi = NULL;
260 uint size = value_phis->size();
261 for (uint i=0; i < size; i++) {
262 if ( mem->_idx == value_phis->index_at(i) ) {
263 return value_phis->node_at(i);
264 }
265 }
266
267 if (level <= 0) {
268 return NULL;
269 }
253 Node *start_mem = C->start()->proj_out(TypeFunc::Memory); 270 Node *start_mem = C->start()->proj_out(TypeFunc::Memory);
254 Node *alloc_mem = alloc->in(TypeFunc::Memory); 271 Node *alloc_mem = alloc->in(TypeFunc::Memory);
255 272
256 uint length = mem->req(); 273 uint length = mem->req();
257 GrowableArray <Node *> values(length, length, NULL); 274 GrowableArray <Node *> values(length, length, NULL);
275
276 // create a new Phi for the value
277 PhiNode *phi = new (C, length) PhiNode(mem->in(0), phi_type, NULL, instance_id, alias_idx, offset);
278 transform_later(phi);
279 value_phis->push(phi, mem->_idx);
258 280
259 for (uint j = 1; j < length; j++) { 281 for (uint j = 1; j < length; j++) {
260 Node *in = mem->in(j); 282 Node *in = mem->in(j);
261 if (in == NULL || in->is_top()) { 283 if (in == NULL || in->is_top()) {
262 values.at_put(j, in); 284 values.at_put(j, in);
278 } else if (val->is_Store()) { 300 } else if (val->is_Store()) {
279 values.at_put(j, val->in(MemNode::ValueIn)); 301 values.at_put(j, val->in(MemNode::ValueIn));
280 } else if(val->is_Proj() && val->in(0) == alloc) { 302 } else if(val->is_Proj() && val->in(0) == alloc) {
281 values.at_put(j, _igvn.zerocon(ft)); 303 values.at_put(j, _igvn.zerocon(ft));
282 } else if (val->is_Phi()) { 304 } else if (val->is_Phi()) {
283 // Check if an appropriate node already exists. 305 val = value_from_mem_phi(val, ft, phi_type, adr_t, alloc, value_phis, level-1);
284 Node* region = val->in(0); 306 if (val == NULL) {
285 Node* old_phi = NULL; 307 return NULL;
286 for (DUIterator_Fast kmax, k = region->fast_outs(kmax); k < kmax; k++) { 308 }
287 Node* phi = region->fast_out(k); 309 values.at_put(j, val);
288 if (phi->is_Phi() && phi != val &&
289 phi->as_Phi()->is_same_inst_field(phi_type, instance_id, alias_idx, offset)) {
290 old_phi = phi;
291 break;
292 }
293 }
294 if (old_phi == NULL) {
295 val = value_from_mem_phi(val, ft, phi_type, adr_t, alloc, level-1);
296 if (val == NULL) {
297 return NULL;
298 }
299 values.at_put(j, val);
300 } else {
301 values.at_put(j, old_phi);
302 }
303 } else { 310 } else {
304 return NULL; // unknown node on this path 311 return NULL; // unknown node on this path
305 } 312 }
306 } 313 }
307 } 314 }
308 // create a new Phi for the value 315 // Set Phi's inputs
309 PhiNode *phi = new (C, length) PhiNode(mem->in(0), phi_type, NULL, instance_id, alias_idx, offset);
310 for (uint j = 1; j < length; j++) { 316 for (uint j = 1; j < length; j++) {
311 if (values.at(j) == mem) { 317 if (values.at(j) == mem) {
312 phi->init_req(j, phi); 318 phi->init_req(j, phi);
313 } else { 319 } else {
314 phi->init_req(j, values.at(j)); 320 phi->init_req(j, values.at(j));
315 } 321 }
316 } 322 }
317 transform_later(phi);
318 return phi; 323 return phi;
319 } 324 }
320 325
321 // Search the last value stored into the object's field. 326 // Search the last value stored into the object's field.
322 Node *PhaseMacroExpand::value_from_mem(Node *sfpt_mem, BasicType ft, const Type *ftype, const TypeOopPtr *adr_t, Node *alloc) { 327 Node *PhaseMacroExpand::value_from_mem(Node *sfpt_mem, BasicType ft, const Type *ftype, const TypeOopPtr *adr_t, Node *alloc) {
327 int alias_idx = C->get_alias_index(adr_t); 332 int alias_idx = C->get_alias_index(adr_t);
328 int offset = adr_t->offset(); 333 int offset = adr_t->offset();
329 Node *start_mem = C->start()->proj_out(TypeFunc::Memory); 334 Node *start_mem = C->start()->proj_out(TypeFunc::Memory);
330 Node *alloc_ctrl = alloc->in(TypeFunc::Control); 335 Node *alloc_ctrl = alloc->in(TypeFunc::Control);
331 Node *alloc_mem = alloc->in(TypeFunc::Memory); 336 Node *alloc_mem = alloc->in(TypeFunc::Memory);
332 VectorSet visited(Thread::current()->resource_area()); 337 Arena *a = Thread::current()->resource_area();
338 VectorSet visited(a);
333 339
334 340
335 bool done = sfpt_mem == alloc_mem; 341 bool done = sfpt_mem == alloc_mem;
336 Node *mem = sfpt_mem; 342 Node *mem = sfpt_mem;
337 while (!done) { 343 while (!done) {
387 return _igvn.zerocon(ft); 393 return _igvn.zerocon(ft);
388 } else if (mem->is_Store()) { 394 } else if (mem->is_Store()) {
389 return mem->in(MemNode::ValueIn); 395 return mem->in(MemNode::ValueIn);
390 } else if (mem->is_Phi()) { 396 } else if (mem->is_Phi()) {
391 // attempt to produce a Phi reflecting the values on the input paths of the Phi 397 // attempt to produce a Phi reflecting the values on the input paths of the Phi
392 Node * phi = value_from_mem_phi(mem, ft, ftype, adr_t, alloc, 8); 398 Node_Stack value_phis(a, 8);
399 Node * phi = value_from_mem_phi(mem, ft, ftype, adr_t, alloc, &value_phis, 8);
393 if (phi != NULL) { 400 if (phi != NULL) {
394 return phi; 401 return phi;
402 } else {
403 // Kill all new Phis
404 while(value_phis.is_nonempty()) {
405 Node* n = value_phis.node();
406 _igvn.hash_delete(n);
407 _igvn.subsume_node(n, C->top());
408 value_phis.pop();
409 }
395 } 410 }
396 } 411 }
397 } 412 }
398 // Something go wrong. 413 // Something go wrong.
399 return NULL; 414 return NULL;