< prev index next >

src/hotspot/share/opto/ifnode.cpp

Print this page




  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 "ci/ciTypeFlow.hpp"
  27 #include "memory/allocation.inline.hpp"
  28 #include "memory/resourceArea.hpp"
  29 #include "opto/addnode.hpp"
  30 #include "opto/castnode.hpp"
  31 #include "opto/cfgnode.hpp"
  32 #include "opto/connode.hpp"
  33 #include "opto/loopnode.hpp"
  34 #include "opto/phaseX.hpp"
  35 #include "opto/runtime.hpp"
  36 #include "opto/rootnode.hpp"
  37 #include "opto/subnode.hpp"




  38 
  39 // Portions of code courtesy of Clifford Click
  40 
  41 // Optimization - Graph Style
  42 
  43 
  44 #ifndef PRODUCT
  45 extern int explicit_null_checks_elided;
  46 #endif
  47 
  48 //=============================================================================
  49 //------------------------------Value------------------------------------------
  50 // Return a tuple for whichever arm of the IF is reachable
  51 const Type* IfNode::Value(PhaseGVN* phase) const {
  52   if( !in(0) ) return Type::TOP;
  53   if( phase->type(in(0)) == Type::TOP )
  54     return Type::TOP;
  55   const Type *t = phase->type(in(1));
  56   if( t == Type::TOP )          // data is undefined
  57     return TypeTuple::IFNEITHER; // unreachable altogether


1443   if (in(0) == NULL) return NULL;     // Dead loop?
1444 
1445   PhaseIterGVN *igvn = phase->is_IterGVN();
1446   Node* result = fold_compares(igvn);
1447   if (result != NULL) {
1448     return result;
1449   }
1450 
1451   // Scan for an equivalent test
1452   Node *cmp;
1453   int dist = 0;               // Cutoff limit for search
1454   int op = Opcode();
1455   if( op == Op_If &&
1456       (cmp=in(1)->in(1))->Opcode() == Op_CmpP ) {
1457     if( cmp->in(2) != NULL && // make sure cmp is not already dead
1458         cmp->in(2)->bottom_type() == TypePtr::NULL_PTR ) {
1459       dist = 64;              // Limit for null-pointer scans
1460     } else {
1461       dist = 4;               // Do not bother for random pointer tests
1462     }




1463   } else {
1464     dist = 4;                 // Limit for random junky scans
1465   }
1466 
1467   Node* prev_dom = search_identical(dist);
1468 
1469   if (prev_dom == NULL) {
1470     return NULL;
1471   }
1472 
1473   // Replace dominated IfNode
1474   return dominated_by(prev_dom, igvn);
1475 }
1476 
1477 //------------------------------dominated_by-----------------------------------
1478 Node* IfNode::dominated_by(Node* prev_dom, PhaseIterGVN *igvn) {
1479 #ifndef PRODUCT
1480   if (TraceIterativeGVN) {
1481     tty->print("   Removing IfNode: "); this->dump();
1482   }


1531         igvn->replace_input_of(s, 0, data_target); // Move child to data-target
1532       }
1533     } // End for each child of a projection
1534 
1535     igvn->remove_dead_node(ifp);
1536   } // End for each IfTrue/IfFalse child of If
1537 
1538   // Kill the IfNode
1539   igvn->remove_dead_node(this);
1540 
1541   // Must return either the original node (now dead) or a new node
1542   // (Do not return a top here, since that would break the uniqueness of top.)
1543   return new ConINode(TypeInt::ZERO);
1544 }
1545 
1546 Node* IfNode::search_identical(int dist) {
1547   // Setup to scan up the CFG looking for a dominating test
1548   Node* dom = in(0);
1549   Node* prev_dom = this;
1550   int op = Opcode();



1551   // Search up the dominator tree for an If with an identical test
1552   while (dom->Opcode() != op    ||  // Not same opcode?
1553          dom->in(1)    != in(1) ||  // Not same input 1?
1554          (req() == 3 && dom->in(2) != in(2)) || // Not same input 2?
1555          prev_dom->in(0) != dom) {  // One path of test does not dominate?
1556     if (dist < 0) return NULL;
1557 
1558     dist--;
1559     prev_dom = dom;
1560     dom = up_one_dom(dom);
1561     if (!dom) return NULL;
1562   }
1563 
1564   // Check that we did not follow a loop back to ourselves
1565   if (this == dom) {
1566     return NULL;
1567   }
1568 
1569 #ifndef PRODUCT
1570   if (dist > 2) { // Add to count of NULL checks elided
1571     explicit_null_checks_elided++;
1572   }
1573 #endif
1574 




  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 "ci/ciTypeFlow.hpp"
  27 #include "memory/allocation.inline.hpp"
  28 #include "memory/resourceArea.hpp"
  29 #include "opto/addnode.hpp"
  30 #include "opto/castnode.hpp"
  31 #include "opto/cfgnode.hpp"
  32 #include "opto/connode.hpp"
  33 #include "opto/loopnode.hpp"
  34 #include "opto/phaseX.hpp"
  35 #include "opto/runtime.hpp"
  36 #include "opto/rootnode.hpp"
  37 #include "opto/subnode.hpp"
  38 #include "utilities/macros.hpp"
  39 #if INCLUDE_SHENANDOAHGC
  40 #include "gc/shenandoah/c2/shenandoahBarrierSetC2.hpp"
  41 #endif
  42 
  43 // Portions of code courtesy of Clifford Click
  44 
  45 // Optimization - Graph Style
  46 
  47 
  48 #ifndef PRODUCT
  49 extern int explicit_null_checks_elided;
  50 #endif
  51 
  52 //=============================================================================
  53 //------------------------------Value------------------------------------------
  54 // Return a tuple for whichever arm of the IF is reachable
  55 const Type* IfNode::Value(PhaseGVN* phase) const {
  56   if( !in(0) ) return Type::TOP;
  57   if( phase->type(in(0)) == Type::TOP )
  58     return Type::TOP;
  59   const Type *t = phase->type(in(1));
  60   if( t == Type::TOP )          // data is undefined
  61     return TypeTuple::IFNEITHER; // unreachable altogether


1447   if (in(0) == NULL) return NULL;     // Dead loop?
1448 
1449   PhaseIterGVN *igvn = phase->is_IterGVN();
1450   Node* result = fold_compares(igvn);
1451   if (result != NULL) {
1452     return result;
1453   }
1454 
1455   // Scan for an equivalent test
1456   Node *cmp;
1457   int dist = 0;               // Cutoff limit for search
1458   int op = Opcode();
1459   if( op == Op_If &&
1460       (cmp=in(1)->in(1))->Opcode() == Op_CmpP ) {
1461     if( cmp->in(2) != NULL && // make sure cmp is not already dead
1462         cmp->in(2)->bottom_type() == TypePtr::NULL_PTR ) {
1463       dist = 64;              // Limit for null-pointer scans
1464     } else {
1465       dist = 4;               // Do not bother for random pointer tests
1466     }
1467 #if INCLUDE_SHENANDOAHGC
1468   } else if (ShenandoahWriteBarrierNode::is_heap_stable_test(this)) {
1469     dist = 16;
1470 #endif
1471   } else {
1472     dist = 4;                 // Limit for random junky scans
1473   }
1474 
1475   Node* prev_dom = search_identical(dist);
1476 
1477   if (prev_dom == NULL) {
1478     return NULL;
1479   }
1480 
1481   // Replace dominated IfNode
1482   return dominated_by(prev_dom, igvn);
1483 }
1484 
1485 //------------------------------dominated_by-----------------------------------
1486 Node* IfNode::dominated_by(Node* prev_dom, PhaseIterGVN *igvn) {
1487 #ifndef PRODUCT
1488   if (TraceIterativeGVN) {
1489     tty->print("   Removing IfNode: "); this->dump();
1490   }


1539         igvn->replace_input_of(s, 0, data_target); // Move child to data-target
1540       }
1541     } // End for each child of a projection
1542 
1543     igvn->remove_dead_node(ifp);
1544   } // End for each IfTrue/IfFalse child of If
1545 
1546   // Kill the IfNode
1547   igvn->remove_dead_node(this);
1548 
1549   // Must return either the original node (now dead) or a new node
1550   // (Do not return a top here, since that would break the uniqueness of top.)
1551   return new ConINode(TypeInt::ZERO);
1552 }
1553 
1554 Node* IfNode::search_identical(int dist) {
1555   // Setup to scan up the CFG looking for a dominating test
1556   Node* dom = in(0);
1557   Node* prev_dom = this;
1558   int op = Opcode();
1559 #if INCLUDE_SHENANDOAHGC
1560   bool heap_stable = ShenandoahWriteBarrierNode::is_heap_stable_test(this);
1561 #endif
1562   // Search up the dominator tree for an If with an identical test
1563   while (dom->Opcode() != op    ||  // Not same opcode?
1564          (dom->in(1) != in(1) SHENANDOAHGC_ONLY(&& (!heap_stable || !ShenandoahWriteBarrierNode::is_heap_stable_test(dom->as_If())))) ||  // Not same input 1?

1565          prev_dom->in(0) != dom) {  // One path of test does not dominate?
1566     if (dist < 0) return NULL;
1567 
1568     dist--;
1569     prev_dom = dom;
1570     dom = up_one_dom(dom);
1571     if (!dom) return NULL;
1572   }
1573 
1574   // Check that we did not follow a loop back to ourselves
1575   if (this == dom) {
1576     return NULL;
1577   }
1578 
1579 #ifndef PRODUCT
1580   if (dist > 2) { // Add to count of NULL checks elided
1581     explicit_null_checks_elided++;
1582   }
1583 #endif
1584 


< prev index next >