< prev index next >

src/share/vm/opto/movenode.cpp

Print this page




 104      (phase->eqv(cmp->in(2),f) &&
 105       phase->eqv(cmp->in(1),t)) ) {
 106        // Give up this identity check for floating points because it may choose incorrect
 107        // value around 0.0 and -0.0
 108        if ( cmp->Opcode()==Op_CmpF || cmp->Opcode()==Op_CmpD )
 109        return NULL;
 110        // Check for "(t==f)?t:f;" and replace with "f"
 111        if( b->_test._test == BoolTest::eq )
 112        return f;
 113        // Allow the inverted case as well
 114        // Check for "(t!=f)?t:f;" and replace with "t"
 115        if( b->_test._test == BoolTest::ne )
 116        return t;
 117      }
 118   return NULL;
 119 }
 120 
 121 //------------------------------Identity---------------------------------------
 122 // Conditional-move is an identity if both inputs are the same, or the test
 123 // true or false.
 124 Node *CMoveNode::Identity( PhaseTransform *phase ) {
 125   if( phase->eqv(in(IfFalse),in(IfTrue)) ) // C-moving identical inputs?
 126   return in(IfFalse);         // Then it doesn't matter
 127   if( phase->type(in(Condition)) == TypeInt::ZERO )
 128   return in(IfFalse);         // Always pick left(false) input
 129   if( phase->type(in(Condition)) == TypeInt::ONE )
 130   return in(IfTrue);          // Always pick right(true) input
 131 
 132   // Check for CMove'ing a constant after comparing against the constant.
 133   // Happens all the time now, since if we compare equality vs a constant in
 134   // the parser, we "know" the variable is constant on one path and we force
 135   // it.  Thus code like "if( x==0 ) {/*EMPTY*/}" ends up inserting a
 136   // conditional move: "x = (x==0)?0:x;".  Yucko.  This fix is slightly more
 137   // general in that we don't need constants.
 138   if( in(Condition)->is_Bool() ) {
 139     BoolNode *b = in(Condition)->as_Bool();
 140     Node *cmp = b->in(1);
 141     if( cmp->is_Cmp() ) {
 142       Node *id = is_cmove_id( phase, cmp, in(IfTrue), in(IfFalse), b );
 143       if( id ) return id;
 144     }
 145   }
 146 
 147   return this;
 148 }
 149 
 150 //------------------------------Value------------------------------------------
 151 // Result is the meet of inputs
 152 const Type *CMoveNode::Value( PhaseTransform *phase ) const {
 153   if( phase->type(in(Condition)) == Type::TOP )
 154   return Type::TOP;
 155   return phase->type(in(IfFalse))->meet_speculative(phase->type(in(IfTrue)));
 156 }
 157 
 158 //------------------------------make-------------------------------------------
 159 // Make a correctly-flavored CMove.  Since _type is directly determined
 160 // from the inputs we do not need to specify it here.
 161 CMoveNode *CMoveNode::make(Node *c, Node *bol, Node *left, Node *right, const Type *t) {
 162   switch( t->basic_type() ) {
 163     case T_INT:     return new CMoveINode( bol, left, right, t->is_int() );
 164     case T_FLOAT:   return new CMoveFNode( bol, left, right, t );
 165     case T_DOUBLE:  return new CMoveDNode( bol, left, right, t );
 166     case T_LONG:    return new CMoveLNode( bol, left, right, t->is_long() );
 167     case T_OBJECT:  return new CMovePNode( c, bol, left, right, t->is_oopptr() );
 168     case T_ADDRESS: return new CMovePNode( c, bol, left, right, t->is_ptr() );
 169     case T_NARROWOOP: return new CMoveNNode( c, bol, left, right, t );
 170     default:
 171     ShouldNotReachHere();
 172     return NULL;


 334   }
 335 
 336   // If X is found on the appropriate phi input, find the subtract on the other
 337   if( X != in(phi_x_idx) ) return NULL;
 338   int phi_sub_idx = phi_x_idx == IfTrue ? IfFalse : IfTrue;
 339   Node *sub = in(phi_sub_idx);
 340 
 341   // Allow only SubD(0,X) and fail out for all others; NegD is not OK
 342   if( sub->Opcode() != Op_SubD ||
 343      sub->in(2) != X ||
 344      phase->type(sub->in(1)) != TypeD::ZERO ) return NULL;
 345 
 346   Node *abs = new AbsDNode( X );
 347   if( flip )
 348   abs = new SubDNode(sub->in(1), phase->transform(abs));
 349 
 350   return abs;
 351 }
 352 
 353 //------------------------------Value------------------------------------------
 354 const Type *MoveL2DNode::Value( PhaseTransform *phase ) const {
 355   const Type *t = phase->type( in(1) );
 356   if( t == Type::TOP ) return Type::TOP;
 357   const TypeLong *tl = t->is_long();
 358   if( !tl->is_con() ) return bottom_type();
 359   JavaValue v;
 360   v.set_jlong(tl->get_con());
 361   return TypeD::make( v.get_jdouble() );
 362 }
 363 
 364 //------------------------------Value------------------------------------------
 365 const Type *MoveI2FNode::Value( PhaseTransform *phase ) const {
 366   const Type *t = phase->type( in(1) );
 367   if( t == Type::TOP ) return Type::TOP;
 368   const TypeInt *ti = t->is_int();
 369   if( !ti->is_con() )   return bottom_type();
 370   JavaValue v;
 371   v.set_jint(ti->get_con());
 372   return TypeF::make( v.get_jfloat() );
 373 }
 374 
 375 //------------------------------Value------------------------------------------
 376 const Type *MoveF2INode::Value( PhaseTransform *phase ) const {
 377   const Type *t = phase->type( in(1) );
 378   if( t == Type::TOP )       return Type::TOP;
 379   if( t == Type::FLOAT ) return TypeInt::INT;
 380   const TypeF *tf = t->is_float_constant();
 381   JavaValue v;
 382   v.set_jfloat(tf->getf());
 383   return TypeInt::make( v.get_jint() );
 384 }
 385 
 386 //------------------------------Value------------------------------------------
 387 const Type *MoveD2LNode::Value( PhaseTransform *phase ) const {
 388   const Type *t = phase->type( in(1) );
 389   if( t == Type::TOP ) return Type::TOP;
 390   if( t == Type::DOUBLE ) return TypeLong::LONG;
 391   const TypeD *td = t->is_double_constant();
 392   JavaValue v;
 393   v.set_jdouble(td->getd());
 394   return TypeLong::make( v.get_jlong() );
 395 }
 396 
 397 #ifndef PRODUCT
 398 //----------------------------BinaryNode---------------------------------------
 399 // The set of related nodes for a BinaryNode is all data inputs and all outputs
 400 // till level 2 (i.e., one beyond the associated CMoveNode). In compact mode,
 401 // it's the inputs till level 1 and the outputs till level 2.
 402 void BinaryNode::related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const {
 403   if (compact) {
 404     this->collect_nodes(in_rel, 1, false, true);
 405   } else {
 406     this->collect_nodes_in_all_data(in_rel, false);
 407   }


 104      (phase->eqv(cmp->in(2),f) &&
 105       phase->eqv(cmp->in(1),t)) ) {
 106        // Give up this identity check for floating points because it may choose incorrect
 107        // value around 0.0 and -0.0
 108        if ( cmp->Opcode()==Op_CmpF || cmp->Opcode()==Op_CmpD )
 109        return NULL;
 110        // Check for "(t==f)?t:f;" and replace with "f"
 111        if( b->_test._test == BoolTest::eq )
 112        return f;
 113        // Allow the inverted case as well
 114        // Check for "(t!=f)?t:f;" and replace with "t"
 115        if( b->_test._test == BoolTest::ne )
 116        return t;
 117      }
 118   return NULL;
 119 }
 120 
 121 //------------------------------Identity---------------------------------------
 122 // Conditional-move is an identity if both inputs are the same, or the test
 123 // true or false.
 124 Node* CMoveNode::Identity(PhaseGVN* phase) {
 125   if( phase->eqv(in(IfFalse),in(IfTrue)) ) // C-moving identical inputs?
 126   return in(IfFalse);         // Then it doesn't matter
 127   if( phase->type(in(Condition)) == TypeInt::ZERO )
 128   return in(IfFalse);         // Always pick left(false) input
 129   if( phase->type(in(Condition)) == TypeInt::ONE )
 130   return in(IfTrue);          // Always pick right(true) input
 131 
 132   // Check for CMove'ing a constant after comparing against the constant.
 133   // Happens all the time now, since if we compare equality vs a constant in
 134   // the parser, we "know" the variable is constant on one path and we force
 135   // it.  Thus code like "if( x==0 ) {/*EMPTY*/}" ends up inserting a
 136   // conditional move: "x = (x==0)?0:x;".  Yucko.  This fix is slightly more
 137   // general in that we don't need constants.
 138   if( in(Condition)->is_Bool() ) {
 139     BoolNode *b = in(Condition)->as_Bool();
 140     Node *cmp = b->in(1);
 141     if( cmp->is_Cmp() ) {
 142       Node *id = is_cmove_id( phase, cmp, in(IfTrue), in(IfFalse), b );
 143       if( id ) return id;
 144     }
 145   }
 146 
 147   return this;
 148 }
 149 
 150 //------------------------------Value------------------------------------------
 151 // Result is the meet of inputs
 152 const Type* CMoveNode::Value(PhaseGVN* phase) const {
 153   if( phase->type(in(Condition)) == Type::TOP )
 154   return Type::TOP;
 155   return phase->type(in(IfFalse))->meet_speculative(phase->type(in(IfTrue)));
 156 }
 157 
 158 //------------------------------make-------------------------------------------
 159 // Make a correctly-flavored CMove.  Since _type is directly determined
 160 // from the inputs we do not need to specify it here.
 161 CMoveNode *CMoveNode::make(Node *c, Node *bol, Node *left, Node *right, const Type *t) {
 162   switch( t->basic_type() ) {
 163     case T_INT:     return new CMoveINode( bol, left, right, t->is_int() );
 164     case T_FLOAT:   return new CMoveFNode( bol, left, right, t );
 165     case T_DOUBLE:  return new CMoveDNode( bol, left, right, t );
 166     case T_LONG:    return new CMoveLNode( bol, left, right, t->is_long() );
 167     case T_OBJECT:  return new CMovePNode( c, bol, left, right, t->is_oopptr() );
 168     case T_ADDRESS: return new CMovePNode( c, bol, left, right, t->is_ptr() );
 169     case T_NARROWOOP: return new CMoveNNode( c, bol, left, right, t );
 170     default:
 171     ShouldNotReachHere();
 172     return NULL;


 334   }
 335 
 336   // If X is found on the appropriate phi input, find the subtract on the other
 337   if( X != in(phi_x_idx) ) return NULL;
 338   int phi_sub_idx = phi_x_idx == IfTrue ? IfFalse : IfTrue;
 339   Node *sub = in(phi_sub_idx);
 340 
 341   // Allow only SubD(0,X) and fail out for all others; NegD is not OK
 342   if( sub->Opcode() != Op_SubD ||
 343      sub->in(2) != X ||
 344      phase->type(sub->in(1)) != TypeD::ZERO ) return NULL;
 345 
 346   Node *abs = new AbsDNode( X );
 347   if( flip )
 348   abs = new SubDNode(sub->in(1), phase->transform(abs));
 349 
 350   return abs;
 351 }
 352 
 353 //------------------------------Value------------------------------------------
 354 const Type* MoveL2DNode::Value(PhaseGVN* phase) const {
 355   const Type *t = phase->type( in(1) );
 356   if( t == Type::TOP ) return Type::TOP;
 357   const TypeLong *tl = t->is_long();
 358   if( !tl->is_con() ) return bottom_type();
 359   JavaValue v;
 360   v.set_jlong(tl->get_con());
 361   return TypeD::make( v.get_jdouble() );
 362 }
 363 
 364 //------------------------------Value------------------------------------------
 365 const Type* MoveI2FNode::Value(PhaseGVN* phase) const {
 366   const Type *t = phase->type( in(1) );
 367   if( t == Type::TOP ) return Type::TOP;
 368   const TypeInt *ti = t->is_int();
 369   if( !ti->is_con() )   return bottom_type();
 370   JavaValue v;
 371   v.set_jint(ti->get_con());
 372   return TypeF::make( v.get_jfloat() );
 373 }
 374 
 375 //------------------------------Value------------------------------------------
 376 const Type* MoveF2INode::Value(PhaseGVN* phase) const {
 377   const Type *t = phase->type( in(1) );
 378   if( t == Type::TOP )       return Type::TOP;
 379   if( t == Type::FLOAT ) return TypeInt::INT;
 380   const TypeF *tf = t->is_float_constant();
 381   JavaValue v;
 382   v.set_jfloat(tf->getf());
 383   return TypeInt::make( v.get_jint() );
 384 }
 385 
 386 //------------------------------Value------------------------------------------
 387 const Type* MoveD2LNode::Value(PhaseGVN* phase) const {
 388   const Type *t = phase->type( in(1) );
 389   if( t == Type::TOP ) return Type::TOP;
 390   if( t == Type::DOUBLE ) return TypeLong::LONG;
 391   const TypeD *td = t->is_double_constant();
 392   JavaValue v;
 393   v.set_jdouble(td->getd());
 394   return TypeLong::make( v.get_jlong() );
 395 }
 396 
 397 #ifndef PRODUCT
 398 //----------------------------BinaryNode---------------------------------------
 399 // The set of related nodes for a BinaryNode is all data inputs and all outputs
 400 // till level 2 (i.e., one beyond the associated CMoveNode). In compact mode,
 401 // it's the inputs till level 1 and the outputs till level 2.
 402 void BinaryNode::related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const {
 403   if (compact) {
 404     this->collect_nodes(in_rel, 1, false, true);
 405   } else {
 406     this->collect_nodes_in_all_data(in_rel, false);
 407   }
< prev index next >