src/share/vm/c1/c1_Canonicalizer.cpp

Print this page
rev 3083 : 7126041: jdk7u4 b05 and b06 crash with RubyMine 3.2.4, works well with b04
Summary: Goto that replaces a If mistaken to be a back branch and triggers erroneous OSR compilation.
Reviewed-by:


 577 }
 578 void Canonicalizer::do_MonitorEnter   (MonitorEnter*    x) {}
 579 void Canonicalizer::do_MonitorExit    (MonitorExit*     x) {}
 580 void Canonicalizer::do_BlockBegin     (BlockBegin*      x) {}
 581 void Canonicalizer::do_Goto           (Goto*            x) {}
 582 
 583 
 584 static bool is_true(jlong x, If::Condition cond, jlong y) {
 585   switch (cond) {
 586     case If::eql: return x == y;
 587     case If::neq: return x != y;
 588     case If::lss: return x <  y;
 589     case If::leq: return x <= y;
 590     case If::gtr: return x >  y;
 591     case If::geq: return x >= y;
 592   }
 593   ShouldNotReachHere();
 594   return false;
 595 }
 596 



 597 
 598 void Canonicalizer::do_If(If* x) {
 599   // move const to right
 600   if (x->x()->type()->is_constant()) x->swap_operands();
 601   // simplify
 602   const Value l = x->x(); ValueType* lt = l->type();
 603   const Value r = x->y(); ValueType* rt = r->type();
 604 
 605   if (l == r && !lt->is_float_kind()) {
 606     // pattern: If (a cond a) => simplify to Goto
 607     BlockBegin* sux;
 608     switch (x->cond()) {
 609     case If::eql: sux = x->sux_for(true);  break;
 610     case If::neq: sux = x->sux_for(false); break;
 611     case If::lss: sux = x->sux_for(false); break;
 612     case If::leq: sux = x->sux_for(true);  break;
 613     case If::gtr: sux = x->sux_for(false); break;
 614     case If::geq: sux = x->sux_for(true);  break;
 615     }
 616     // If is a safepoint then the debug information should come from the state_before of the If.
 617     set_canonical(new Goto(sux, x->state_before(), x->is_safepoint()));
 618     return;
 619   }
 620 
 621   if (lt->is_constant() && rt->is_constant()) {
 622     if (x->x()->as_Constant() != NULL) {
 623       // pattern: If (lc cond rc) => simplify to: Goto
 624       BlockBegin* sux = x->x()->as_Constant()->compare(x->cond(), x->y(),
 625                                                        x->sux_for(true),
 626                                                        x->sux_for(false));
 627       if (sux != NULL) {
 628         // If is a safepoint then the debug information should come from the state_before of the If.
 629         set_canonical(new Goto(sux, x->state_before(), x->is_safepoint()));
 630       }
 631     }
 632   } else if (rt->as_IntConstant() != NULL) {
 633     // pattern: If (l cond rc) => investigate further
 634     const jint rc = rt->as_IntConstant()->value();
 635     if (l->as_CompareOp() != NULL) {
 636       // pattern: If ((a cmp b) cond rc) => simplify to: If (x cond y) or: Goto
 637       CompareOp* cmp = l->as_CompareOp();
 638       bool unordered_is_less = cmp->op() == Bytecodes::_fcmpl || cmp->op() == Bytecodes::_dcmpl;
 639       BlockBegin* lss_sux = x->sux_for(is_true(-1, x->cond(), rc)); // successor for a < b
 640       BlockBegin* eql_sux = x->sux_for(is_true( 0, x->cond(), rc)); // successor for a = b
 641       BlockBegin* gtr_sux = x->sux_for(is_true(+1, x->cond(), rc)); // successor for a > b
 642       BlockBegin* nan_sux = unordered_is_less ? lss_sux : gtr_sux ; // successor for unordered
 643       // Note: At this point all successors (lss_sux, eql_sux, gtr_sux, nan_sux) are
 644       //       equal to x->tsux() or x->fsux(). Furthermore, nan_sux equals either
 645       //       lss_sux or gtr_sux.
 646       if (lss_sux == eql_sux && eql_sux == gtr_sux) {
 647         // all successors identical => simplify to: Goto
 648         set_canonical(new Goto(lss_sux, x->state_before(), x->is_safepoint()));
 649       } else {


 677     } else if (l->as_InstanceOf() != NULL) {
 678       // NOTE: Code permanently disabled for now since it leaves the old InstanceOf
 679       //       instruction in the graph (it is pinned). Need to fix this at some point.
 680       //       It should also be left in the graph when generating a profiled method version or Goto
 681       //       has to know that it was an InstanceOf.
 682       return;
 683       // pattern: If ((obj instanceof klass) cond rc) => simplify to: IfInstanceOf or: Goto
 684       InstanceOf* inst = l->as_InstanceOf();
 685       BlockBegin* is_inst_sux = x->sux_for(is_true(1, x->cond(), rc)); // successor for instanceof == 1
 686       BlockBegin* no_inst_sux = x->sux_for(is_true(0, x->cond(), rc)); // successor for instanceof == 0
 687       if (is_inst_sux == no_inst_sux && inst->is_loaded()) {
 688         // both successors identical and klass is loaded => simplify to: Goto
 689         set_canonical(new Goto(is_inst_sux, x->state_before(), x->is_safepoint()));
 690       } else {
 691         // successors differ => simplify to: IfInstanceOf
 692         set_canonical(new IfInstanceOf(inst->klass(), inst->obj(), true, inst->state_before()->bci(), is_inst_sux, no_inst_sux));
 693       }
 694     }
 695   } else if (rt == objectNull && (l->as_NewInstance() || l->as_NewArray())) {
 696     if (x->cond() == Instruction::eql) {
 697       set_canonical(new Goto(x->fsux(), x->state_before(), x->is_safepoint()));

 698     } else {
 699       assert(x->cond() == Instruction::neq, "only other valid case");
 700       set_canonical(new Goto(x->tsux(), x->state_before(), x->is_safepoint()));

 701     }
 702   }
 703 }
 704 
 705 
 706 void Canonicalizer::do_TableSwitch(TableSwitch* x) {
 707   if (x->tag()->type()->is_constant()) {
 708     int v = x->tag()->type()->as_IntConstant()->value();
 709     BlockBegin* sux = x->default_sux();
 710     if (v >= x->lo_key() && v <= x->hi_key()) {
 711       sux = x->sux_at(v - x->lo_key());
 712     }
 713     set_canonical(new Goto(sux, x->state_before(), x->is_safepoint()));
 714   } else if (x->number_of_sux() == 1) {
 715     // NOTE: Code permanently disabled for now since the switch statement's
 716     //       tag expression may produce side-effects in which case it must
 717     //       be executed.
 718     return;
 719     // simplify to Goto
 720     set_canonical(new Goto(x->default_sux(), x->state_before(), x->is_safepoint()));
 721   } else if (x->number_of_sux() == 2) {
 722     // NOTE: Code permanently disabled for now since it produces two new nodes
 723     //       (Constant & If) and the Canonicalizer cannot return them correctly
 724     //       yet. For now we copied the corresponding code directly into the
 725     //       GraphBuilder (i.e., we should never reach here).
 726     return;
 727     // simplify to If
 728     assert(x->lo_key() == x->hi_key(), "keys must be the same");
 729     Constant* key = new Constant(new IntConstant(x->lo_key()));
 730     set_canonical(new If(x->tag(), If::eql, true, key, x->sux_at(0), x->default_sux(), x->state_before(), x->is_safepoint()));
 731   }
 732 }
 733 
 734 
 735 void Canonicalizer::do_LookupSwitch(LookupSwitch* x) {
 736   if (x->tag()->type()->is_constant()) {
 737     int v = x->tag()->type()->as_IntConstant()->value();
 738     BlockBegin* sux = x->default_sux();
 739     for (int i = 0; i < x->length(); i++) {
 740       if (v == x->key_at(i)) {
 741         sux = x->sux_at(i);
 742       }
 743     }
 744     set_canonical(new Goto(sux, x->state_before(), x->is_safepoint()));
 745   } else if (x->number_of_sux() == 1) {
 746     // NOTE: Code permanently disabled for now since the switch statement's
 747     //       tag expression may produce side-effects in which case it must
 748     //       be executed.
 749     return;
 750     // simplify to Goto
 751     set_canonical(new Goto(x->default_sux(), x->state_before(), x->is_safepoint()));
 752   } else if (x->number_of_sux() == 2) {
 753     // NOTE: Code permanently disabled for now since it produces two new nodes
 754     //       (Constant & If) and the Canonicalizer cannot return them correctly
 755     //       yet. For now we copied the corresponding code directly into the
 756     //       GraphBuilder (i.e., we should never reach here).
 757     return;
 758     // simplify to If
 759     assert(x->length() == 1, "length must be the same");
 760     Constant* key = new Constant(new IntConstant(x->key_at(0)));
 761     set_canonical(new If(x->tag(), If::eql, true, key, x->sux_at(0), x->default_sux(), x->state_before(), x->is_safepoint()));
 762   }
 763 }
 764 




 577 }
 578 void Canonicalizer::do_MonitorEnter   (MonitorEnter*    x) {}
 579 void Canonicalizer::do_MonitorExit    (MonitorExit*     x) {}
 580 void Canonicalizer::do_BlockBegin     (BlockBegin*      x) {}
 581 void Canonicalizer::do_Goto           (Goto*            x) {}
 582 
 583 
 584 static bool is_true(jlong x, If::Condition cond, jlong y) {
 585   switch (cond) {
 586     case If::eql: return x == y;
 587     case If::neq: return x != y;
 588     case If::lss: return x <  y;
 589     case If::leq: return x <= y;
 590     case If::gtr: return x >  y;
 591     case If::geq: return x >= y;
 592   }
 593   ShouldNotReachHere();
 594   return false;
 595 }
 596 
 597 static bool is_safepoint(BlockEnd* x, BlockBegin* sux) {
 598   return x->is_safepoint() && (sux->bci() < x->state_before()->bci());
 599 }
 600 
 601 void Canonicalizer::do_If(If* x) {
 602   // move const to right
 603   if (x->x()->type()->is_constant()) x->swap_operands();
 604   // simplify
 605   const Value l = x->x(); ValueType* lt = l->type();
 606   const Value r = x->y(); ValueType* rt = r->type();
 607 
 608   if (l == r && !lt->is_float_kind()) {
 609     // pattern: If (a cond a) => simplify to Goto
 610     BlockBegin* sux;
 611     switch (x->cond()) {
 612     case If::eql: sux = x->sux_for(true);  break;
 613     case If::neq: sux = x->sux_for(false); break;
 614     case If::lss: sux = x->sux_for(false); break;
 615     case If::leq: sux = x->sux_for(true);  break;
 616     case If::gtr: sux = x->sux_for(false); break;
 617     case If::geq: sux = x->sux_for(true);  break;
 618     }
 619     // If is a safepoint then the debug information should come from the state_before of the If.
 620     set_canonical(new Goto(sux, x->state_before(), is_safepoint(x, sux)));
 621     return;
 622   }
 623 
 624   if (lt->is_constant() && rt->is_constant()) {
 625     if (x->x()->as_Constant() != NULL) {
 626       // pattern: If (lc cond rc) => simplify to: Goto
 627       BlockBegin* sux = x->x()->as_Constant()->compare(x->cond(), x->y(),
 628                                                        x->sux_for(true),
 629                                                        x->sux_for(false));
 630       if (sux != NULL) {
 631         // If is a safepoint then the debug information should come from the state_before of the If.
 632         set_canonical(new Goto(sux, x->state_before(), is_safepoint(x, sux)));
 633       }
 634     }
 635   } else if (rt->as_IntConstant() != NULL) {
 636     // pattern: If (l cond rc) => investigate further
 637     const jint rc = rt->as_IntConstant()->value();
 638     if (l->as_CompareOp() != NULL) {
 639       // pattern: If ((a cmp b) cond rc) => simplify to: If (x cond y) or: Goto
 640       CompareOp* cmp = l->as_CompareOp();
 641       bool unordered_is_less = cmp->op() == Bytecodes::_fcmpl || cmp->op() == Bytecodes::_dcmpl;
 642       BlockBegin* lss_sux = x->sux_for(is_true(-1, x->cond(), rc)); // successor for a < b
 643       BlockBegin* eql_sux = x->sux_for(is_true( 0, x->cond(), rc)); // successor for a = b
 644       BlockBegin* gtr_sux = x->sux_for(is_true(+1, x->cond(), rc)); // successor for a > b
 645       BlockBegin* nan_sux = unordered_is_less ? lss_sux : gtr_sux ; // successor for unordered
 646       // Note: At this point all successors (lss_sux, eql_sux, gtr_sux, nan_sux) are
 647       //       equal to x->tsux() or x->fsux(). Furthermore, nan_sux equals either
 648       //       lss_sux or gtr_sux.
 649       if (lss_sux == eql_sux && eql_sux == gtr_sux) {
 650         // all successors identical => simplify to: Goto
 651         set_canonical(new Goto(lss_sux, x->state_before(), x->is_safepoint()));
 652       } else {


 680     } else if (l->as_InstanceOf() != NULL) {
 681       // NOTE: Code permanently disabled for now since it leaves the old InstanceOf
 682       //       instruction in the graph (it is pinned). Need to fix this at some point.
 683       //       It should also be left in the graph when generating a profiled method version or Goto
 684       //       has to know that it was an InstanceOf.
 685       return;
 686       // pattern: If ((obj instanceof klass) cond rc) => simplify to: IfInstanceOf or: Goto
 687       InstanceOf* inst = l->as_InstanceOf();
 688       BlockBegin* is_inst_sux = x->sux_for(is_true(1, x->cond(), rc)); // successor for instanceof == 1
 689       BlockBegin* no_inst_sux = x->sux_for(is_true(0, x->cond(), rc)); // successor for instanceof == 0
 690       if (is_inst_sux == no_inst_sux && inst->is_loaded()) {
 691         // both successors identical and klass is loaded => simplify to: Goto
 692         set_canonical(new Goto(is_inst_sux, x->state_before(), x->is_safepoint()));
 693       } else {
 694         // successors differ => simplify to: IfInstanceOf
 695         set_canonical(new IfInstanceOf(inst->klass(), inst->obj(), true, inst->state_before()->bci(), is_inst_sux, no_inst_sux));
 696       }
 697     }
 698   } else if (rt == objectNull && (l->as_NewInstance() || l->as_NewArray())) {
 699     if (x->cond() == Instruction::eql) {
 700       BlockBegin* sux = x->fsux();
 701       set_canonical(new Goto(sux, x->state_before(), is_safepoint(x, sux)));
 702     } else {
 703       assert(x->cond() == Instruction::neq, "only other valid case");
 704       BlockBegin* sux = x->tsux();
 705       set_canonical(new Goto(sux, x->state_before(), is_safepoint(x, sux)));
 706     }
 707   }
 708 }
 709 
 710 
 711 void Canonicalizer::do_TableSwitch(TableSwitch* x) {
 712   if (x->tag()->type()->is_constant()) {
 713     int v = x->tag()->type()->as_IntConstant()->value();
 714     BlockBegin* sux = x->default_sux();
 715     if (v >= x->lo_key() && v <= x->hi_key()) {
 716       sux = x->sux_at(v - x->lo_key());
 717     }
 718     set_canonical(new Goto(sux, x->state_before(), is_safepoint(x, sux)));
 719   } else if (x->number_of_sux() == 1) {
 720     // NOTE: Code permanently disabled for now since the switch statement's
 721     //       tag expression may produce side-effects in which case it must
 722     //       be executed.
 723     return;
 724     // simplify to Goto
 725     set_canonical(new Goto(x->default_sux(), x->state_before(), x->is_safepoint()));
 726   } else if (x->number_of_sux() == 2) {
 727     // NOTE: Code permanently disabled for now since it produces two new nodes
 728     //       (Constant & If) and the Canonicalizer cannot return them correctly
 729     //       yet. For now we copied the corresponding code directly into the
 730     //       GraphBuilder (i.e., we should never reach here).
 731     return;
 732     // simplify to If
 733     assert(x->lo_key() == x->hi_key(), "keys must be the same");
 734     Constant* key = new Constant(new IntConstant(x->lo_key()));
 735     set_canonical(new If(x->tag(), If::eql, true, key, x->sux_at(0), x->default_sux(), x->state_before(), x->is_safepoint()));
 736   }
 737 }
 738 
 739 
 740 void Canonicalizer::do_LookupSwitch(LookupSwitch* x) {
 741   if (x->tag()->type()->is_constant()) {
 742     int v = x->tag()->type()->as_IntConstant()->value();
 743     BlockBegin* sux = x->default_sux();
 744     for (int i = 0; i < x->length(); i++) {
 745       if (v == x->key_at(i)) {
 746         sux = x->sux_at(i);
 747       }
 748     }
 749     set_canonical(new Goto(sux, x->state_before(), is_safepoint(x, sux)));
 750   } else if (x->number_of_sux() == 1) {
 751     // NOTE: Code permanently disabled for now since the switch statement's
 752     //       tag expression may produce side-effects in which case it must
 753     //       be executed.
 754     return;
 755     // simplify to Goto
 756     set_canonical(new Goto(x->default_sux(), x->state_before(), x->is_safepoint()));
 757   } else if (x->number_of_sux() == 2) {
 758     // NOTE: Code permanently disabled for now since it produces two new nodes
 759     //       (Constant & If) and the Canonicalizer cannot return them correctly
 760     //       yet. For now we copied the corresponding code directly into the
 761     //       GraphBuilder (i.e., we should never reach here).
 762     return;
 763     // simplify to If
 764     assert(x->length() == 1, "length must be the same");
 765     Constant* key = new Constant(new IntConstant(x->key_at(0)));
 766     set_canonical(new If(x->tag(), If::eql, true, key, x->sux_at(0), x->default_sux(), x->state_before(), x->is_safepoint()));
 767   }
 768 }
 769