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 } |