< prev index next >

src/hotspot/share/opto/addnode.cpp

Print this page




 219 
 220   // Check for an addition involving the additive identity
 221   const Type *tadd = add_of_identity( t1, t2 );
 222   if( tadd ) return tadd;
 223 
 224   return add_ring(t1,t2);               // Local flavor of type addition
 225 }
 226 
 227 //------------------------------add_identity-----------------------------------
 228 // Check for addition of the identity
 229 const Type *AddNode::add_of_identity( const Type *t1, const Type *t2 ) const {
 230   const Type *zero = add_id();  // The additive identity
 231   if( t1->higher_equal( zero ) ) return t2;
 232   if( t2->higher_equal( zero ) ) return t1;
 233 
 234   return NULL;
 235 }
 236 
 237 
 238 //=============================================================================


































 239 //------------------------------Idealize---------------------------------------
 240 Node *AddINode::Ideal(PhaseGVN *phase, bool can_reshape) {
 241   Node* in1 = in(1);
 242   Node* in2 = in(2);
 243   int op1 = in1->Opcode();
 244   int op2 = in2->Opcode();
 245   // Fold (con1-x)+con2 into (con1+con2)-x
 246   if ( op1 == Op_AddI && op2 == Op_SubI ) {
 247     // Swap edges to try optimizations below
 248     in1 = in2;
 249     in2 = in(1);
 250     op1 = op2;
 251     op2 = in2->Opcode();
 252   }
 253   if( op1 == Op_SubI ) {
 254     const Type *t_sub1 = phase->type( in1->in(1) );
 255     const Type *t_2    = phase->type( in2        );
 256     if( t_sub1->singleton() && t_2->singleton() && t_sub1 != Type::TOP && t_2 != Type::TOP )
 257       return new SubINode(phase->makecon( add_ring( t_sub1, t_2 ) ), in1->in(2) );
 258     // Convert "(a-b)+(c-d)" into "(a+c)-(b+d)"


 301   // Unrestricted transformation is unsafe for some runtime values of 'x'
 302   // ( x ==  0, z == 1, y == -1 ) fails
 303   // ( x == -5, z == 1, y ==  1 ) fails
 304   // Transform works for small z and small negative y when the addition
 305   // (x + (y << z)) does not cross zero.
 306   // Implement support for negative y and (x >= -(y << z))
 307   // Have not observed cases where type information exists to support
 308   // positive y and (x <= -(y << z))
 309   if( op1 == Op_URShiftI && op2 == Op_ConI &&
 310       in1->in(2)->Opcode() == Op_ConI ) {
 311     jint z = phase->type( in1->in(2) )->is_int()->get_con() & 0x1f; // only least significant 5 bits matter
 312     jint y = phase->type( in2 )->is_int()->get_con();
 313 
 314     if( z < 5 && -5 < y && y < 0 ) {
 315       const Type *t_in11 = phase->type(in1->in(1));
 316       if( t_in11 != Type::TOP && (t_in11->is_int()->_lo >= -(y << z)) ) {
 317         Node *a = phase->transform( new AddINode( in1->in(1), phase->intcon(y<<z) ) );
 318         return new URShiftINode( a, in1->in(2) );
 319       }
 320     }





 321   }
 322 
 323   return AddNode::Ideal(phase, can_reshape);
 324 }
 325 
 326 
 327 //------------------------------Identity---------------------------------------
 328 // Fold (x-y)+y  OR  y+(x-y)  into  x
 329 Node* AddINode::Identity(PhaseGVN* phase) {
 330   if( in(1)->Opcode() == Op_SubI && phase->eqv(in(1)->in(2),in(2)) ) {
 331     return in(1)->in(1);
 332   }
 333   else if( in(2)->Opcode() == Op_SubI && phase->eqv(in(2)->in(2),in(1)) ) {
 334     return in(2)->in(1);
 335   }
 336   return AddNode::Identity(phase);
 337 }
 338 
 339 
 340 //------------------------------add_ring---------------------------------------




 219 
 220   // Check for an addition involving the additive identity
 221   const Type *tadd = add_of_identity( t1, t2 );
 222   if( tadd ) return tadd;
 223 
 224   return add_ring(t1,t2);               // Local flavor of type addition
 225 }
 226 
 227 //------------------------------add_identity-----------------------------------
 228 // Check for addition of the identity
 229 const Type *AddNode::add_of_identity( const Type *t1, const Type *t2 ) const {
 230   const Type *zero = add_id();  // The additive identity
 231   if( t1->higher_equal( zero ) ) return t2;
 232   if( t2->higher_equal( zero ) ) return t1;
 233 
 234   return NULL;
 235 }
 236 
 237 
 238 //=============================================================================
 239 
 240 static Node* convert_add_to_muladd(PhaseGVN *phase, Node* in1, Node* in2) {
 241   // Only convert to this type of node if backend supports and if vectorizer supports it as well.
 242   // The reason vectorizer is also checked is because this transformation is explicitly done
 243   // to make vectorizer analysis easier for forms where type transition happens during operation.
 244   if (Matcher::match_rule_supported(Op_MulAddS2I) &&
 245     Matcher::match_rule_supported(Op_MulAddVS2VI)) {
 246     if (in1->Opcode() == Op_MulI && in2->Opcode() == Op_MulI) {
 247       Node* mul_in1 = in1->in(1);
 248       Node* mul_in2 = in1->in(2);
 249       Node* mul_in3 = in2->in(1);
 250       Node* mul_in4 = in2->in(2);
 251 
 252       if (mul_in1->Opcode() == Op_LoadS &&
 253         mul_in2->Opcode() == Op_LoadS &&
 254         mul_in3->Opcode() == Op_LoadS &&
 255         mul_in4->Opcode() == Op_LoadS) {
 256         Node* adr1 = mul_in1->in(MemNode::Address);
 257         Node* adr2 = mul_in2->in(MemNode::Address);
 258         Node* adr3 = mul_in3->in(MemNode::Address);
 259         Node* adr4 = mul_in4->in(MemNode::Address);
 260 
 261         if (adr1->is_AddP() && adr2->is_AddP() && adr3->is_AddP() && adr4->is_AddP()) {
 262           if ((adr1->in(AddPNode::Base) == adr3->in(AddPNode::Base)) &&
 263             (adr2->in(AddPNode::Base) == adr4->in(AddPNode::Base))) {
 264             return new MulAddS2INode(mul_in1, mul_in2, mul_in3, mul_in4);
 265           }
 266         }
 267       }
 268     }
 269   }
 270   return NULL;
 271 }
 272 
 273 //------------------------------Idealize---------------------------------------
 274 Node *AddINode::Ideal(PhaseGVN *phase, bool can_reshape) {
 275   Node* in1 = in(1);
 276   Node* in2 = in(2);
 277   int op1 = in1->Opcode();
 278   int op2 = in2->Opcode();
 279   // Fold (con1-x)+con2 into (con1+con2)-x
 280   if ( op1 == Op_AddI && op2 == Op_SubI ) {
 281     // Swap edges to try optimizations below
 282     in1 = in2;
 283     in2 = in(1);
 284     op1 = op2;
 285     op2 = in2->Opcode();
 286   }
 287   if( op1 == Op_SubI ) {
 288     const Type *t_sub1 = phase->type( in1->in(1) );
 289     const Type *t_2    = phase->type( in2        );
 290     if( t_sub1->singleton() && t_2->singleton() && t_sub1 != Type::TOP && t_2 != Type::TOP )
 291       return new SubINode(phase->makecon( add_ring( t_sub1, t_2 ) ), in1->in(2) );
 292     // Convert "(a-b)+(c-d)" into "(a+c)-(b+d)"


 335   // Unrestricted transformation is unsafe for some runtime values of 'x'
 336   // ( x ==  0, z == 1, y == -1 ) fails
 337   // ( x == -5, z == 1, y ==  1 ) fails
 338   // Transform works for small z and small negative y when the addition
 339   // (x + (y << z)) does not cross zero.
 340   // Implement support for negative y and (x >= -(y << z))
 341   // Have not observed cases where type information exists to support
 342   // positive y and (x <= -(y << z))
 343   if( op1 == Op_URShiftI && op2 == Op_ConI &&
 344       in1->in(2)->Opcode() == Op_ConI ) {
 345     jint z = phase->type( in1->in(2) )->is_int()->get_con() & 0x1f; // only least significant 5 bits matter
 346     jint y = phase->type( in2 )->is_int()->get_con();
 347 
 348     if( z < 5 && -5 < y && y < 0 ) {
 349       const Type *t_in11 = phase->type(in1->in(1));
 350       if( t_in11 != Type::TOP && (t_in11->is_int()->_lo >= -(y << z)) ) {
 351         Node *a = phase->transform( new AddINode( in1->in(1), phase->intcon(y<<z) ) );
 352         return new URShiftINode( a, in1->in(2) );
 353       }
 354     }
 355   }
 356 
 357   Node* muladd = convert_add_to_muladd(phase, in1, in2);
 358   if (muladd != NULL) {
 359     return muladd;
 360   }
 361 
 362   return AddNode::Ideal(phase, can_reshape);
 363 }
 364 
 365 
 366 //------------------------------Identity---------------------------------------
 367 // Fold (x-y)+y  OR  y+(x-y)  into  x
 368 Node* AddINode::Identity(PhaseGVN* phase) {
 369   if( in(1)->Opcode() == Op_SubI && phase->eqv(in(1)->in(2),in(2)) ) {
 370     return in(1)->in(1);
 371   }
 372   else if( in(2)->Opcode() == Op_SubI && phase->eqv(in(2)->in(2),in(1)) ) {
 373     return in(2)->in(1);
 374   }
 375   return AddNode::Identity(phase);
 376 }
 377 
 378 
 379 //------------------------------add_ring---------------------------------------


< prev index next >