< prev index next >

src/share/vm/opto/subnode.cpp

Print this page
rev 8739 : 8004073: Implement C2 Ideal node specific dump() method
Summary: add Node::dump_rel() to dump a node and its related nodes (the notion of "related" depends on the node at hand); add Node::dump_comp() to dump a node in compact representation; add Node::dump_rel_comp() to dump a node and its related nodes in compact representation; add the required machinery; extend some C2 IR nodes with compact and related dumping
Reviewed-by:
   1 /*
   2  * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   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  *


 481   else if( g_isnan(t1->getd()) ) {
 482     return t1;
 483   }
 484   else if( g_isnan(t2->getd()) ) {
 485     return t2;
 486   }
 487   else {
 488     return Type::DOUBLE;
 489   }
 490 }
 491 
 492 //=============================================================================
 493 //------------------------------Idealize---------------------------------------
 494 // Unlike SubNodes, compare must still flatten return value to the
 495 // range -1, 0, 1.
 496 // And optimizations like those for (X + Y) - X fail if overflow happens.
 497 Node *CmpNode::Identity( PhaseTransform *phase ) {
 498   return this;
 499 }
 500 































 501 //=============================================================================
 502 //------------------------------cmp--------------------------------------------
 503 // Simplify a CmpI (compare 2 integers) node, based on local information.
 504 // If both inputs are constants, compare them.
 505 const Type *CmpINode::sub( const Type *t1, const Type *t2 ) const {
 506   const TypeInt *r0 = t1->is_int(); // Handy access
 507   const TypeInt *r1 = t2->is_int();
 508 
 509   if( r0->_hi < r1->_lo )       // Range is always low?
 510     return TypeInt::CC_LT;
 511   else if( r0->_lo > r1->_hi )  // Range is always high?
 512     return TypeInt::CC_GT;
 513 
 514   else if( r0->is_con() && r1->is_con() ) { // comparing constants?
 515     assert(r0->get_con() == r1->get_con(), "must be equal");
 516     return TypeInt::CC_EQ;      // Equal results.
 517   } else if( r0->_hi == r1->_lo ) // Range is never high?
 518     return TypeInt::CC_LE;
 519   else if( r0->_lo == r1->_hi ) // Range is never low?
 520     return TypeInt::CC_GE;


1379   //      else if( cmp2_op == Op_AddI &&
1380   //         phase->type( cmp2->in(2) ) == TypeInt::MINUS_1 )
1381   //        return clone_cmp( cmp, cmp1, cmp2->in(1), phase, BoolTest::lt );
1382   //    } else if( _test._test == BoolTest::lt ) {
1383   //      if( cmp1_op == Op_AddI &&
1384   //          phase->type( cmp1->in(2) ) == TypeInt::MINUS_1 )
1385   //        return clone_cmp( cmp, cmp1->in(1), cmp2, phase, BoolTest::le );
1386   //      else if( cmp2_op == Op_AddI &&
1387   //         phase->type( cmp2->in(2) ) == TypeInt::ONE )
1388   //        return clone_cmp( cmp, cmp1, cmp2->in(1), phase, BoolTest::le );
1389   //    }
1390 }
1391 
1392 //------------------------------Value------------------------------------------
1393 // Simplify a Bool (convert condition codes to boolean (1 or 0)) node,
1394 // based on local information.   If the input is constant, do it.
1395 const Type *BoolNode::Value( PhaseTransform *phase ) const {
1396   return _test.cc2logical( phase->type( in(1) ) );
1397 }
1398 

1399 //------------------------------dump_spec--------------------------------------
1400 // Dump special per-node info
1401 #ifndef PRODUCT
1402 void BoolNode::dump_spec(outputStream *st) const {
1403   st->print("[");
1404   _test.dump_on(st);
1405   st->print("]");
1406 }














1407 #endif
1408 
1409 //------------------------------is_counted_loop_exit_test--------------------------------------
1410 // Returns true if node is used by a counted loop node.
1411 bool BoolNode::is_counted_loop_exit_test() {
1412   for( DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++ ) {
1413     Node* use = fast_out(i);
1414     if (use->is_CountedLoopEnd()) {
1415       return true;
1416     }
1417   }
1418   return false;
1419 }
1420 
1421 //=============================================================================
1422 //------------------------------Value------------------------------------------
1423 // Compute sqrt
1424 const Type *SqrtDNode::Value( PhaseTransform *phase ) const {
1425   const Type *t1 = phase->type( in(1) );
1426   if( t1 == Type::TOP ) return Type::TOP;
1427   if( t1->base() != Type::DoubleCon ) return Type::DOUBLE;
1428   double d = t1->getd();
1429   if( d < 0.0 ) return Type::DOUBLE;


   1 /*
   2  * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   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  *


 481   else if( g_isnan(t1->getd()) ) {
 482     return t1;
 483   }
 484   else if( g_isnan(t2->getd()) ) {
 485     return t2;
 486   }
 487   else {
 488     return Type::DOUBLE;
 489   }
 490 }
 491 
 492 //=============================================================================
 493 //------------------------------Idealize---------------------------------------
 494 // Unlike SubNodes, compare must still flatten return value to the
 495 // range -1, 0, 1.
 496 // And optimizations like those for (X + Y) - X fail if overflow happens.
 497 Node *CmpNode::Identity( PhaseTransform *phase ) {
 498   return this;
 499 }
 500 
 501 #ifndef PRODUCT
 502 //------------------------------rel--------------------------------------------
 503 // Related nodes of comparison nodes include all data inputs (until hitting a
 504 // control boundary) as well as all outputs until and including control nodes
 505 // as well as their projections. In compact mode, data inputs till depth 1 and
 506 // all outputs till depth 1 are considered.
 507 void CmpNode::rel(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const {
 508   if (compact) {
 509     this->collect_nodes(in_rel, 1, false, true);
 510     this->collect_nodes(out_rel, -1, false, false);
 511   } else {
 512     this->collect_nodes_in_all_data(in_rel, false);
 513     this->collect_nodes_out_all_ctrl_boundary(out_rel);
 514     // Now, find all control nodes in out_rel, and include their projections
 515     // and projection targets (if any) in the result.
 516     GrowableArray<Node*> proj(Compile::current()->unique());
 517     for (GrowableArrayIterator<Node*> it = out_rel->begin(); it != out_rel->end(); ++it) {
 518       Node* n = *it;
 519       if (n->is_CFG() && !n->is_Proj()) {
 520         // Assume projections and projection targets are found at levels 1 and 2.
 521         n->collect_nodes(&proj, -2, false, false);
 522         for (GrowableArrayIterator<Node*> p = proj.begin(); p != proj.end(); ++p) {
 523           out_rel->append_if_missing(*p);
 524         }
 525         proj.clear();
 526       }
 527     }
 528   }
 529 }
 530 #endif
 531 
 532 //=============================================================================
 533 //------------------------------cmp--------------------------------------------
 534 // Simplify a CmpI (compare 2 integers) node, based on local information.
 535 // If both inputs are constants, compare them.
 536 const Type *CmpINode::sub( const Type *t1, const Type *t2 ) const {
 537   const TypeInt *r0 = t1->is_int(); // Handy access
 538   const TypeInt *r1 = t2->is_int();
 539 
 540   if( r0->_hi < r1->_lo )       // Range is always low?
 541     return TypeInt::CC_LT;
 542   else if( r0->_lo > r1->_hi )  // Range is always high?
 543     return TypeInt::CC_GT;
 544 
 545   else if( r0->is_con() && r1->is_con() ) { // comparing constants?
 546     assert(r0->get_con() == r1->get_con(), "must be equal");
 547     return TypeInt::CC_EQ;      // Equal results.
 548   } else if( r0->_hi == r1->_lo ) // Range is never high?
 549     return TypeInt::CC_LE;
 550   else if( r0->_lo == r1->_hi ) // Range is never low?
 551     return TypeInt::CC_GE;


1410   //      else if( cmp2_op == Op_AddI &&
1411   //         phase->type( cmp2->in(2) ) == TypeInt::MINUS_1 )
1412   //        return clone_cmp( cmp, cmp1, cmp2->in(1), phase, BoolTest::lt );
1413   //    } else if( _test._test == BoolTest::lt ) {
1414   //      if( cmp1_op == Op_AddI &&
1415   //          phase->type( cmp1->in(2) ) == TypeInt::MINUS_1 )
1416   //        return clone_cmp( cmp, cmp1->in(1), cmp2, phase, BoolTest::le );
1417   //      else if( cmp2_op == Op_AddI &&
1418   //         phase->type( cmp2->in(2) ) == TypeInt::ONE )
1419   //        return clone_cmp( cmp, cmp1, cmp2->in(1), phase, BoolTest::le );
1420   //    }
1421 }
1422 
1423 //------------------------------Value------------------------------------------
1424 // Simplify a Bool (convert condition codes to boolean (1 or 0)) node,
1425 // based on local information.   If the input is constant, do it.
1426 const Type *BoolNode::Value( PhaseTransform *phase ) const {
1427   return _test.cc2logical( phase->type( in(1) ) );
1428 }
1429 
1430 #ifndef PRODUCT
1431 //------------------------------dump_spec--------------------------------------
1432 // Dump special per-node info

1433 void BoolNode::dump_spec(outputStream *st) const {
1434   st->print("[");
1435   _test.dump_on(st);
1436   st->print("]");
1437 }
1438 
1439 //---------------------------------rel-----------------------------------------
1440 // A BoolNode's related nodes are all of its data inputs, and all of its
1441 // outputs until control nodes are hit, which are included. In compact
1442 // representation, inputs till level 3 and immediate outputs are included.
1443 void BoolNode::rel(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const {
1444   if (compact) {
1445     this->collect_nodes(in_rel, 3, false, true);
1446     this->collect_nodes(out_rel, -1, false, false);
1447   } else {
1448     this->collect_nodes_in_all_data(in_rel, false);
1449     this->collect_nodes_out_all_ctrl_boundary(out_rel);
1450   }
1451 }
1452 #endif
1453 
1454 //----------------------is_counted_loop_exit_test------------------------------
1455 // Returns true if node is used by a counted loop node.
1456 bool BoolNode::is_counted_loop_exit_test() {
1457   for( DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++ ) {
1458     Node* use = fast_out(i);
1459     if (use->is_CountedLoopEnd()) {
1460       return true;
1461     }
1462   }
1463   return false;
1464 }
1465 
1466 //=============================================================================
1467 //------------------------------Value------------------------------------------
1468 // Compute sqrt
1469 const Type *SqrtDNode::Value( PhaseTransform *phase ) const {
1470   const Type *t1 = phase->type( in(1) );
1471   if( t1 == Type::TOP ) return Type::TOP;
1472   if( t1->base() != Type::DoubleCon ) return Type::DOUBLE;
1473   double d = t1->getd();
1474   if( d < 0.0 ) return Type::DOUBLE;


< prev index next >