Mercurial > hg > graal-jvmci-8
comparison src/share/vm/opto/loopPredicate.cpp @ 3845:c96c3eb1efae
7068051: SIGSEGV in PhaseIdealLoop::build_loop_late_post
Summary: Removed predicate cloning from loop peeling optimization and from split fall-in paths.
Reviewed-by: never
author | kvn |
---|---|
date | Fri, 29 Jul 2011 09:16:29 -0700 |
parents | 4e761e7e6e12 |
children | 6987871cfb9b |
comparison
equal
deleted
inserted
replaced
3844:ce3e1d4dc416 | 3845:c96c3eb1efae |
---|---|
325 igvn->hash_delete(iff); | 325 igvn->hash_delete(iff); |
326 iff->set_req(1, bol); | 326 iff->set_req(1, bol); |
327 return new_predicate_proj; | 327 return new_predicate_proj; |
328 } | 328 } |
329 | 329 |
330 //--------------------------move_predicate----------------------- | |
331 // Cut predicate from old place and move it to new. | |
332 ProjNode* PhaseIdealLoop::move_predicate(ProjNode* predicate_proj, Node* new_entry, | |
333 Deoptimization::DeoptReason reason, | |
334 PhaseIdealLoop* loop_phase, | |
335 PhaseIterGVN* igvn) { | |
336 assert(new_entry != NULL, "must be"); | |
337 assert(predicate_proj->in(0)->in(1)->in(1)->Opcode()==Op_Opaque1, "must be"); | |
338 IfNode* iff = predicate_proj->in(0)->as_If(); | |
339 Node* old_entry = iff->in(0); | |
340 | |
341 // Cut predicate from old place. | |
342 Node* old = predicate_proj; | |
343 igvn->_worklist.push(old); | |
344 for (DUIterator_Last imin, i = old->last_outs(imin); i >= imin;) { | |
345 Node* use = old->last_out(i); // for each use... | |
346 igvn->hash_delete(use); | |
347 igvn->_worklist.push(use); | |
348 // Update use-def info | |
349 uint uses_found = 0; | |
350 for (uint j = 0; j < use->req(); j++) { | |
351 if (use->in(j) == old) { | |
352 use->set_req(j, old_entry); | |
353 uses_found++; | |
354 if (loop_phase != NULL) { | |
355 if (use->is_CFG()) { | |
356 // When called from beautify_loops() idom is not constructed yet. | |
357 if (loop_phase->_idom != NULL) | |
358 loop_phase->set_idom(use, old_entry, loop_phase->dom_depth(use)); | |
359 } else { | |
360 loop_phase->set_ctrl(use, old_entry); | |
361 } | |
362 } | |
363 } | |
364 } | |
365 i -= uses_found; // we deleted 1 or more copies of this edge | |
366 } | |
367 | |
368 // Move predicate. | |
369 igvn->hash_delete(iff); | |
370 iff->set_req(0, new_entry); | |
371 igvn->_worklist.push(iff); | |
372 | |
373 if (loop_phase != NULL) { | |
374 // Fix up idom and ctrl. | |
375 loop_phase->set_ctrl(iff->in(1), new_entry); | |
376 loop_phase->set_ctrl(iff->in(1)->in(1), new_entry); | |
377 // When called from beautify_loops() idom is not constructed yet. | |
378 if (loop_phase->_idom != NULL) | |
379 loop_phase->set_idom(iff, new_entry, loop_phase->dom_depth(iff)); | |
380 } | |
381 | |
382 return predicate_proj; | |
383 } | |
384 | 330 |
385 //--------------------------clone_loop_predicates----------------------- | 331 //--------------------------clone_loop_predicates----------------------- |
386 // Interface from IGVN | 332 // Interface from IGVN |
387 Node* PhaseIterGVN::clone_loop_predicates(Node* old_entry, Node* new_entry, bool clone_limit_check) { | 333 Node* PhaseIterGVN::clone_loop_predicates(Node* old_entry, Node* new_entry, bool clone_limit_check) { |
388 return PhaseIdealLoop::clone_loop_predicates(old_entry, new_entry, false, clone_limit_check, NULL, this); | 334 return PhaseIdealLoop::clone_loop_predicates(old_entry, new_entry, clone_limit_check, NULL, this); |
389 } | |
390 Node* PhaseIterGVN::move_loop_predicates(Node* old_entry, Node* new_entry, bool clone_limit_check) { | |
391 return PhaseIdealLoop::clone_loop_predicates(old_entry, new_entry, true, clone_limit_check, NULL, this); | |
392 } | 335 } |
393 | 336 |
394 // Interface from PhaseIdealLoop | 337 // Interface from PhaseIdealLoop |
395 Node* PhaseIdealLoop::clone_loop_predicates(Node* old_entry, Node* new_entry, bool clone_limit_check) { | 338 Node* PhaseIdealLoop::clone_loop_predicates(Node* old_entry, Node* new_entry, bool clone_limit_check) { |
396 return clone_loop_predicates(old_entry, new_entry, false, clone_limit_check, this, &this->_igvn); | 339 return clone_loop_predicates(old_entry, new_entry, clone_limit_check, this, &this->_igvn); |
397 } | |
398 Node* PhaseIdealLoop::move_loop_predicates(Node* old_entry, Node* new_entry, bool clone_limit_check) { | |
399 return clone_loop_predicates(old_entry, new_entry, true, clone_limit_check, this, &this->_igvn); | |
400 } | 340 } |
401 | 341 |
402 // Clone loop predicates to cloned loops (peeled, unswitched, split_if). | 342 // Clone loop predicates to cloned loops (peeled, unswitched, split_if). |
403 Node* PhaseIdealLoop::clone_loop_predicates(Node* old_entry, Node* new_entry, | 343 Node* PhaseIdealLoop::clone_loop_predicates(Node* old_entry, Node* new_entry, |
404 bool move_predicates, | |
405 bool clone_limit_check, | 344 bool clone_limit_check, |
406 PhaseIdealLoop* loop_phase, | 345 PhaseIdealLoop* loop_phase, |
407 PhaseIterGVN* igvn) { | 346 PhaseIterGVN* igvn) { |
408 #ifdef ASSERT | 347 #ifdef ASSERT |
409 if (new_entry == NULL || !(new_entry->is_Proj() || new_entry->is_Region() || new_entry->is_SafePoint())) { | 348 if (new_entry == NULL || !(new_entry->is_Proj() || new_entry->is_Region() || new_entry->is_SafePoint())) { |
422 } | 361 } |
423 } | 362 } |
424 if (UseLoopPredicate) { | 363 if (UseLoopPredicate) { |
425 ProjNode* predicate_proj = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate); | 364 ProjNode* predicate_proj = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate); |
426 if (predicate_proj != NULL) { // right pattern that can be used by loop predication | 365 if (predicate_proj != NULL) { // right pattern that can be used by loop predication |
427 if (move_predicates) { | 366 // clone predicate |
428 new_entry = move_predicate(predicate_proj, new_entry, | 367 new_entry = clone_predicate(predicate_proj, new_entry, |
429 Deoptimization::Reason_predicate, | 368 Deoptimization::Reason_predicate, |
430 loop_phase, igvn); | 369 loop_phase, igvn); |
431 assert(new_entry == predicate_proj, "old predicate fall through projection"); | 370 assert(new_entry != NULL && new_entry->is_Proj(), "IfTrue or IfFalse after clone predicate"); |
432 } else { | |
433 // clone predicate | |
434 new_entry = clone_predicate(predicate_proj, new_entry, | |
435 Deoptimization::Reason_predicate, | |
436 loop_phase, igvn); | |
437 assert(new_entry != NULL && new_entry->is_Proj(), "IfTrue or IfFalse after clone predicate"); | |
438 } | |
439 if (TraceLoopPredicate) { | 371 if (TraceLoopPredicate) { |
440 tty->print_cr("Loop Predicate %s: ", move_predicates ? "moved" : "cloned"); | 372 tty->print("Loop Predicate cloned: "); |
441 debug_only( new_entry->in(0)->dump(); ) | 373 debug_only( new_entry->in(0)->dump(); ) |
442 } | 374 } |
443 } | 375 } |
444 } | 376 } |
445 if (limit_check_proj != NULL && clone_limit_check) { | 377 if (limit_check_proj != NULL && clone_limit_check) { |
446 // Clone loop limit check last to insert it before loop. | 378 // Clone loop limit check last to insert it before loop. |
447 // Don't clone a limit check which was already finalized | 379 // Don't clone a limit check which was already finalized |
448 // for this counted loop (only one limit check is needed). | 380 // for this counted loop (only one limit check is needed). |
449 if (move_predicates) { | 381 new_entry = clone_predicate(limit_check_proj, new_entry, |
450 new_entry = move_predicate(limit_check_proj, new_entry, | 382 Deoptimization::Reason_loop_limit_check, |
451 Deoptimization::Reason_loop_limit_check, | 383 loop_phase, igvn); |
452 loop_phase, igvn); | 384 assert(new_entry != NULL && new_entry->is_Proj(), "IfTrue or IfFalse after clone limit check"); |
453 assert(new_entry == limit_check_proj, "old limit check fall through projection"); | |
454 } else { | |
455 new_entry = clone_predicate(limit_check_proj, new_entry, | |
456 Deoptimization::Reason_loop_limit_check, | |
457 loop_phase, igvn); | |
458 assert(new_entry != NULL && new_entry->is_Proj(), "IfTrue or IfFalse after clone limit check"); | |
459 } | |
460 if (TraceLoopLimitCheck) { | 385 if (TraceLoopLimitCheck) { |
461 tty->print_cr("Loop Limit Check %s: ", move_predicates ? "moved" : "cloned"); | 386 tty->print("Loop Limit Check cloned: "); |
462 debug_only( new_entry->in(0)->dump(); ) | 387 debug_only( new_entry->in(0)->dump(); ) |
463 } | 388 } |
464 } | 389 } |
465 return new_entry; | 390 return new_entry; |
466 } | |
467 | |
468 //--------------------------eliminate_loop_predicates----------------------- | |
469 void PhaseIdealLoop::eliminate_loop_predicates(Node* entry) { | |
470 if (LoopLimitCheck) { | |
471 Node* predicate = find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check); | |
472 if (predicate != NULL) { | |
473 entry = entry->in(0)->in(0); | |
474 } | |
475 } | |
476 if (UseLoopPredicate) { | |
477 ProjNode* predicate_proj = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate); | |
478 if (predicate_proj != NULL) { // right pattern that can be used by loop predication | |
479 Node* n = entry->in(0)->in(1)->in(1); | |
480 assert(n->Opcode()==Op_Opaque1, "must be"); | |
481 // Remove Opaque1 node from predicates list. | |
482 // IGVN will remove this predicate check. | |
483 _igvn.replace_node(n, n->in(1)); | |
484 } | |
485 } | |
486 } | 391 } |
487 | 392 |
488 //--------------------------skip_loop_predicates------------------------------ | 393 //--------------------------skip_loop_predicates------------------------------ |
489 // Skip related predicates. | 394 // Skip related predicates. |
490 Node* PhaseIdealLoop::skip_loop_predicates(Node* entry) { | 395 Node* PhaseIdealLoop::skip_loop_predicates(Node* entry) { |