Mercurial > hg > truffle
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; |