< prev index next >

src/share/vm/opto/ifnode.cpp

Print this page




   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"

  26 #include "memory/allocation.inline.hpp"
  27 #include "opto/addnode.hpp"
  28 #include "opto/cfgnode.hpp"
  29 #include "opto/connode.hpp"
  30 #include "opto/loopnode.hpp"
  31 #include "opto/phaseX.hpp"
  32 #include "opto/runtime.hpp"
  33 #include "opto/subnode.hpp"
  34 
  35 // Portions of code courtesy of Clifford Click
  36 
  37 // Optimization - Graph Style
  38 
  39 
  40 extern int explicit_null_checks_elided;
  41 
  42 //=============================================================================
  43 //------------------------------Value------------------------------------------
  44 // Return a tuple for whichever arm of the IF is reachable
  45 const Type *IfNode::Value( PhaseTransform *phase ) const {


 590 
 591   // Check for small diamonds
 592   Node *din1, *din2, *din3, *din4;
 593   if( dom->req() == 3 &&        // 2-path merge point
 594       (din1 = dom ->in(1)) &&   // Left  path exists
 595       (din2 = dom ->in(2)) &&   // Right path exists
 596       (din3 = din1->in(0)) &&   // Left  path up one
 597       (din4 = din2->in(0)) ) {  // Right path up one
 598     if( din3->is_Call() &&      // Handle a slow-path call on either arm
 599         (din3 = din3->in(0)) )
 600       din3 = din3->in(0);
 601     if( din4->is_Call() &&      // Handle a slow-path call on either arm
 602         (din4 = din4->in(0)) )
 603       din4 = din4->in(0);
 604     if( din3 == din4 && din3->is_If() )
 605       return din3;              // Skip around diamonds
 606   }
 607 
 608   // Give up the search at true merges
 609   return NULL;                  // Dead loop?  Or hit root?























 610 }
 611 
 612 
 613 //------------------------------filtered_int_type--------------------------------
 614 // Return a possibly more restrictive type for val based on condition control flow for an if
 615 const TypeInt* IfNode::filtered_int_type(PhaseGVN* gvn, Node *val, Node* if_proj) {
 616   assert(if_proj &&
 617          (if_proj->Opcode() == Op_IfTrue || if_proj->Opcode() == Op_IfFalse), "expecting an if projection");
 618   if (if_proj->in(0) && if_proj->in(0)->is_If()) {
 619     IfNode* iff = if_proj->in(0)->as_If();
 620     if (iff->in(1) && iff->in(1)->is_Bool()) {
 621       BoolNode* bol = iff->in(1)->as_Bool();
 622       if (bol->in(1) && bol->in(1)->is_Cmp()) {
 623         const CmpNode* cmp  = bol->in(1)->as_Cmp();
 624         if (cmp->in(1) == val) {
 625           const TypeInt* cmp2_t = gvn->type(cmp->in(2))->isa_int();
 626           if (cmp2_t != NULL) {
 627             jint lo = cmp2_t->_lo;
 628             jint hi = cmp2_t->_hi;
 629             BoolTest::mask msk = if_proj->Opcode() == Op_IfTrue ? bol->_test._test : bol->_test.negate();




   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "gc_implementation/shenandoah/shenandoahHeap.hpp"
  27 #include "memory/allocation.inline.hpp"
  28 #include "opto/addnode.hpp"
  29 #include "opto/cfgnode.hpp"
  30 #include "opto/connode.hpp"
  31 #include "opto/loopnode.hpp"
  32 #include "opto/phaseX.hpp"
  33 #include "opto/runtime.hpp"
  34 #include "opto/subnode.hpp"
  35 
  36 // Portions of code courtesy of Clifford Click
  37 
  38 // Optimization - Graph Style
  39 
  40 
  41 extern int explicit_null_checks_elided;
  42 
  43 //=============================================================================
  44 //------------------------------Value------------------------------------------
  45 // Return a tuple for whichever arm of the IF is reachable
  46 const Type *IfNode::Value( PhaseTransform *phase ) const {


 591 
 592   // Check for small diamonds
 593   Node *din1, *din2, *din3, *din4;
 594   if( dom->req() == 3 &&        // 2-path merge point
 595       (din1 = dom ->in(1)) &&   // Left  path exists
 596       (din2 = dom ->in(2)) &&   // Right path exists
 597       (din3 = din1->in(0)) &&   // Left  path up one
 598       (din4 = din2->in(0)) ) {  // Right path up one
 599     if( din3->is_Call() &&      // Handle a slow-path call on either arm
 600         (din3 = din3->in(0)) )
 601       din3 = din3->in(0);
 602     if( din4->is_Call() &&      // Handle a slow-path call on either arm
 603         (din4 = din4->in(0)) )
 604       din4 = din4->in(0);
 605     if( din3 == din4 && din3->is_If() )
 606       return din3;              // Skip around diamonds
 607   }
 608 
 609   // Give up the search at true merges
 610   return NULL;                  // Dead loop?  Or hit root?
 611 }
 612 
 613 bool IfNode::is_shenandoah_marking_if(PhaseTransform *phase) const {
 614   if (!UseShenandoahGC) {
 615     return false;
 616   }
 617 
 618   if (Opcode() != Op_If) {
 619     return false;
 620   }
 621 
 622   Node* bol = in(1);
 623   assert(bol->is_Bool(), "");
 624   Node* cmpx = bol->in(1);
 625   if (bol->as_Bool()->_test._test == BoolTest::ne &&
 626       cmpx->is_Cmp() && cmpx->in(2) == phase->intcon(0) &&
 627       cmpx->in(1)->in(1)->is_shenandoah_state_load() &&
 628       cmpx->in(1)->in(2)->is_Con() &&
 629       cmpx->in(1)->in(2) == phase->intcon(ShenandoahHeap::MARKING)) {
 630     return true;
 631   }
 632 
 633   return false;
 634 }
 635 
 636 
 637 //------------------------------filtered_int_type--------------------------------
 638 // Return a possibly more restrictive type for val based on condition control flow for an if
 639 const TypeInt* IfNode::filtered_int_type(PhaseGVN* gvn, Node *val, Node* if_proj) {
 640   assert(if_proj &&
 641          (if_proj->Opcode() == Op_IfTrue || if_proj->Opcode() == Op_IfFalse), "expecting an if projection");
 642   if (if_proj->in(0) && if_proj->in(0)->is_If()) {
 643     IfNode* iff = if_proj->in(0)->as_If();
 644     if (iff->in(1) && iff->in(1)->is_Bool()) {
 645       BoolNode* bol = iff->in(1)->as_Bool();
 646       if (bol->in(1) && bol->in(1)->is_Cmp()) {
 647         const CmpNode* cmp  = bol->in(1)->as_Cmp();
 648         if (cmp->in(1) == val) {
 649           const TypeInt* cmp2_t = gvn->type(cmp->in(2))->isa_int();
 650           if (cmp2_t != NULL) {
 651             jint lo = cmp2_t->_lo;
 652             jint hi = cmp2_t->_hi;
 653             BoolTest::mask msk = if_proj->Opcode() == Op_IfTrue ? bol->_test._test : bol->_test.negate();


< prev index next >