246 } |
246 } |
247 if( op1 == Op_SubI ) { |
247 if( op1 == Op_SubI ) { |
248 const Type *t_sub1 = phase->type( in1->in(1) ); |
248 const Type *t_sub1 = phase->type( in1->in(1) ); |
249 const Type *t_2 = phase->type( in2 ); |
249 const Type *t_2 = phase->type( in2 ); |
250 if( t_sub1->singleton() && t_2->singleton() && t_sub1 != Type::TOP && t_2 != Type::TOP ) |
250 if( t_sub1->singleton() && t_2->singleton() && t_sub1 != Type::TOP && t_2 != Type::TOP ) |
251 return new (phase->C, 3) SubINode(phase->makecon( add_ring( t_sub1, t_2 ) ), |
251 return new (phase->C) SubINode(phase->makecon( add_ring( t_sub1, t_2 ) ), |
252 in1->in(2) ); |
252 in1->in(2) ); |
253 // Convert "(a-b)+(c-d)" into "(a+c)-(b+d)" |
253 // Convert "(a-b)+(c-d)" into "(a+c)-(b+d)" |
254 if( op2 == Op_SubI ) { |
254 if( op2 == Op_SubI ) { |
255 // Check for dead cycle: d = (a-b)+(c-d) |
255 // Check for dead cycle: d = (a-b)+(c-d) |
256 assert( in1->in(2) != this && in2->in(2) != this, |
256 assert( in1->in(2) != this && in2->in(2) != this, |
257 "dead loop in AddINode::Ideal" ); |
257 "dead loop in AddINode::Ideal" ); |
258 Node *sub = new (phase->C, 3) SubINode(NULL, NULL); |
258 Node *sub = new (phase->C) SubINode(NULL, NULL); |
259 sub->init_req(1, phase->transform(new (phase->C, 3) AddINode(in1->in(1), in2->in(1) ) )); |
259 sub->init_req(1, phase->transform(new (phase->C) AddINode(in1->in(1), in2->in(1) ) )); |
260 sub->init_req(2, phase->transform(new (phase->C, 3) AddINode(in1->in(2), in2->in(2) ) )); |
260 sub->init_req(2, phase->transform(new (phase->C) AddINode(in1->in(2), in2->in(2) ) )); |
261 return sub; |
261 return sub; |
262 } |
262 } |
263 // Convert "(a-b)+(b+c)" into "(a+c)" |
263 // Convert "(a-b)+(b+c)" into "(a+c)" |
264 if( op2 == Op_AddI && in1->in(2) == in2->in(1) ) { |
264 if( op2 == Op_AddI && in1->in(2) == in2->in(1) ) { |
265 assert(in1->in(1) != this && in2->in(2) != this,"dead loop in AddINode::Ideal"); |
265 assert(in1->in(1) != this && in2->in(2) != this,"dead loop in AddINode::Ideal"); |
266 return new (phase->C, 3) AddINode(in1->in(1), in2->in(2)); |
266 return new (phase->C) AddINode(in1->in(1), in2->in(2)); |
267 } |
267 } |
268 // Convert "(a-b)+(c+b)" into "(a+c)" |
268 // Convert "(a-b)+(c+b)" into "(a+c)" |
269 if( op2 == Op_AddI && in1->in(2) == in2->in(2) ) { |
269 if( op2 == Op_AddI && in1->in(2) == in2->in(2) ) { |
270 assert(in1->in(1) != this && in2->in(1) != this,"dead loop in AddINode::Ideal"); |
270 assert(in1->in(1) != this && in2->in(1) != this,"dead loop in AddINode::Ideal"); |
271 return new (phase->C, 3) AddINode(in1->in(1), in2->in(1)); |
271 return new (phase->C) AddINode(in1->in(1), in2->in(1)); |
272 } |
272 } |
273 // Convert "(a-b)+(b-c)" into "(a-c)" |
273 // Convert "(a-b)+(b-c)" into "(a-c)" |
274 if( op2 == Op_SubI && in1->in(2) == in2->in(1) ) { |
274 if( op2 == Op_SubI && in1->in(2) == in2->in(1) ) { |
275 assert(in1->in(1) != this && in2->in(2) != this,"dead loop in AddINode::Ideal"); |
275 assert(in1->in(1) != this && in2->in(2) != this,"dead loop in AddINode::Ideal"); |
276 return new (phase->C, 3) SubINode(in1->in(1), in2->in(2)); |
276 return new (phase->C) SubINode(in1->in(1), in2->in(2)); |
277 } |
277 } |
278 // Convert "(a-b)+(c-a)" into "(c-b)" |
278 // Convert "(a-b)+(c-a)" into "(c-b)" |
279 if( op2 == Op_SubI && in1->in(1) == in2->in(2) ) { |
279 if( op2 == Op_SubI && in1->in(1) == in2->in(2) ) { |
280 assert(in1->in(2) != this && in2->in(1) != this,"dead loop in AddINode::Ideal"); |
280 assert(in1->in(2) != this && in2->in(1) != this,"dead loop in AddINode::Ideal"); |
281 return new (phase->C, 3) SubINode(in2->in(1), in1->in(2)); |
281 return new (phase->C) SubINode(in2->in(1), in1->in(2)); |
282 } |
282 } |
283 } |
283 } |
284 |
284 |
285 // Convert "x+(0-y)" into "(x-y)" |
285 // Convert "x+(0-y)" into "(x-y)" |
286 if( op2 == Op_SubI && phase->type(in2->in(1)) == TypeInt::ZERO ) |
286 if( op2 == Op_SubI && phase->type(in2->in(1)) == TypeInt::ZERO ) |
287 return new (phase->C, 3) SubINode(in1, in2->in(2) ); |
287 return new (phase->C) SubINode(in1, in2->in(2) ); |
288 |
288 |
289 // Convert "(0-y)+x" into "(x-y)" |
289 // Convert "(0-y)+x" into "(x-y)" |
290 if( op1 == Op_SubI && phase->type(in1->in(1)) == TypeInt::ZERO ) |
290 if( op1 == Op_SubI && phase->type(in1->in(1)) == TypeInt::ZERO ) |
291 return new (phase->C, 3) SubINode( in2, in1->in(2) ); |
291 return new (phase->C) SubINode( in2, in1->in(2) ); |
292 |
292 |
293 // Convert (x>>>z)+y into (x+(y<<z))>>>z for small constant z and y. |
293 // Convert (x>>>z)+y into (x+(y<<z))>>>z for small constant z and y. |
294 // Helps with array allocation math constant folding |
294 // Helps with array allocation math constant folding |
295 // See 4790063: |
295 // See 4790063: |
296 // Unrestricted transformation is unsafe for some runtime values of 'x' |
296 // Unrestricted transformation is unsafe for some runtime values of 'x' |
379 // Fold (con1-x)+con2 into (con1+con2)-x |
379 // Fold (con1-x)+con2 into (con1+con2)-x |
380 if( op1 == Op_SubL ) { |
380 if( op1 == Op_SubL ) { |
381 const Type *t_sub1 = phase->type( in1->in(1) ); |
381 const Type *t_sub1 = phase->type( in1->in(1) ); |
382 const Type *t_2 = phase->type( in2 ); |
382 const Type *t_2 = phase->type( in2 ); |
383 if( t_sub1->singleton() && t_2->singleton() && t_sub1 != Type::TOP && t_2 != Type::TOP ) |
383 if( t_sub1->singleton() && t_2->singleton() && t_sub1 != Type::TOP && t_2 != Type::TOP ) |
384 return new (phase->C, 3) SubLNode(phase->makecon( add_ring( t_sub1, t_2 ) ), |
384 return new (phase->C) SubLNode(phase->makecon( add_ring( t_sub1, t_2 ) ), |
385 in1->in(2) ); |
385 in1->in(2) ); |
386 // Convert "(a-b)+(c-d)" into "(a+c)-(b+d)" |
386 // Convert "(a-b)+(c-d)" into "(a+c)-(b+d)" |
387 if( op2 == Op_SubL ) { |
387 if( op2 == Op_SubL ) { |
388 // Check for dead cycle: d = (a-b)+(c-d) |
388 // Check for dead cycle: d = (a-b)+(c-d) |
389 assert( in1->in(2) != this && in2->in(2) != this, |
389 assert( in1->in(2) != this && in2->in(2) != this, |
390 "dead loop in AddLNode::Ideal" ); |
390 "dead loop in AddLNode::Ideal" ); |
391 Node *sub = new (phase->C, 3) SubLNode(NULL, NULL); |
391 Node *sub = new (phase->C) SubLNode(NULL, NULL); |
392 sub->init_req(1, phase->transform(new (phase->C, 3) AddLNode(in1->in(1), in2->in(1) ) )); |
392 sub->init_req(1, phase->transform(new (phase->C) AddLNode(in1->in(1), in2->in(1) ) )); |
393 sub->init_req(2, phase->transform(new (phase->C, 3) AddLNode(in1->in(2), in2->in(2) ) )); |
393 sub->init_req(2, phase->transform(new (phase->C) AddLNode(in1->in(2), in2->in(2) ) )); |
394 return sub; |
394 return sub; |
395 } |
395 } |
396 // Convert "(a-b)+(b+c)" into "(a+c)" |
396 // Convert "(a-b)+(b+c)" into "(a+c)" |
397 if( op2 == Op_AddL && in1->in(2) == in2->in(1) ) { |
397 if( op2 == Op_AddL && in1->in(2) == in2->in(1) ) { |
398 assert(in1->in(1) != this && in2->in(2) != this,"dead loop in AddLNode::Ideal"); |
398 assert(in1->in(1) != this && in2->in(2) != this,"dead loop in AddLNode::Ideal"); |
399 return new (phase->C, 3) AddLNode(in1->in(1), in2->in(2)); |
399 return new (phase->C) AddLNode(in1->in(1), in2->in(2)); |
400 } |
400 } |
401 // Convert "(a-b)+(c+b)" into "(a+c)" |
401 // Convert "(a-b)+(c+b)" into "(a+c)" |
402 if( op2 == Op_AddL && in1->in(2) == in2->in(2) ) { |
402 if( op2 == Op_AddL && in1->in(2) == in2->in(2) ) { |
403 assert(in1->in(1) != this && in2->in(1) != this,"dead loop in AddLNode::Ideal"); |
403 assert(in1->in(1) != this && in2->in(1) != this,"dead loop in AddLNode::Ideal"); |
404 return new (phase->C, 3) AddLNode(in1->in(1), in2->in(1)); |
404 return new (phase->C) AddLNode(in1->in(1), in2->in(1)); |
405 } |
405 } |
406 // Convert "(a-b)+(b-c)" into "(a-c)" |
406 // Convert "(a-b)+(b-c)" into "(a-c)" |
407 if( op2 == Op_SubL && in1->in(2) == in2->in(1) ) { |
407 if( op2 == Op_SubL && in1->in(2) == in2->in(1) ) { |
408 assert(in1->in(1) != this && in2->in(2) != this,"dead loop in AddLNode::Ideal"); |
408 assert(in1->in(1) != this && in2->in(2) != this,"dead loop in AddLNode::Ideal"); |
409 return new (phase->C, 3) SubLNode(in1->in(1), in2->in(2)); |
409 return new (phase->C) SubLNode(in1->in(1), in2->in(2)); |
410 } |
410 } |
411 // Convert "(a-b)+(c-a)" into "(c-b)" |
411 // Convert "(a-b)+(c-a)" into "(c-b)" |
412 if( op2 == Op_SubL && in1->in(1) == in1->in(2) ) { |
412 if( op2 == Op_SubL && in1->in(1) == in1->in(2) ) { |
413 assert(in1->in(2) != this && in2->in(1) != this,"dead loop in AddLNode::Ideal"); |
413 assert(in1->in(2) != this && in2->in(1) != this,"dead loop in AddLNode::Ideal"); |
414 return new (phase->C, 3) SubLNode(in2->in(1), in1->in(2)); |
414 return new (phase->C) SubLNode(in2->in(1), in1->in(2)); |
415 } |
415 } |
416 } |
416 } |
417 |
417 |
418 // Convert "x+(0-y)" into "(x-y)" |
418 // Convert "x+(0-y)" into "(x-y)" |
419 if( op2 == Op_SubL && phase->type(in2->in(1)) == TypeLong::ZERO ) |
419 if( op2 == Op_SubL && phase->type(in2->in(1)) == TypeLong::ZERO ) |
420 return new (phase->C, 3) SubLNode( in1, in2->in(2) ); |
420 return new (phase->C) SubLNode( in1, in2->in(2) ); |
421 |
421 |
422 // Convert "(0-y)+x" into "(x-y)" |
422 // Convert "(0-y)+x" into "(x-y)" |
423 if( op1 == Op_SubL && phase->type(in1->in(1)) == TypeInt::ZERO ) |
423 if( op1 == Op_SubL && phase->type(in1->in(1)) == TypeInt::ZERO ) |
424 return new (phase->C, 3) SubLNode( in2, in1->in(2) ); |
424 return new (phase->C) SubLNode( in2, in1->in(2) ); |
425 |
425 |
426 // Convert "X+X+X+X+X...+X+Y" into "k*X+Y" or really convert "X+(X+Y)" |
426 // Convert "X+X+X+X+X...+X+Y" into "k*X+Y" or really convert "X+(X+Y)" |
427 // into "(X<<1)+Y" and let shift-folding happen. |
427 // into "(X<<1)+Y" and let shift-folding happen. |
428 if( op2 == Op_AddL && |
428 if( op2 == Op_AddL && |
429 in2->in(1) == in1 && |
429 in2->in(1) == in1 && |
430 op1 != Op_ConL && |
430 op1 != Op_ConL && |
431 0 ) { |
431 0 ) { |
432 Node *shift = phase->transform(new (phase->C, 3) LShiftLNode(in1,phase->intcon(1))); |
432 Node *shift = phase->transform(new (phase->C) LShiftLNode(in1,phase->intcon(1))); |
433 return new (phase->C, 3) AddLNode(shift,in2->in(2)); |
433 return new (phase->C) AddLNode(shift,in2->in(2)); |
434 } |
434 } |
435 |
435 |
436 return AddNode::Ideal(phase, can_reshape); |
436 return AddNode::Ideal(phase, can_reshape); |
437 } |
437 } |
438 |
438 |
893 y_off = t->is_int()->get_con(); |
893 y_off = t->is_int()->get_con(); |
894 y = y->in(1); |
894 y = y->in(1); |
895 } |
895 } |
896 |
896 |
897 if( x->_idx > y->_idx ) |
897 if( x->_idx > y->_idx ) |
898 return new (phase->C, 3) MinINode(r->in(1),phase->transform(new (phase->C, 3) MinINode(l,r->in(2)))); |
898 return new (phase->C) MinINode(r->in(1),phase->transform(new (phase->C) MinINode(l,r->in(2)))); |
899 |
899 |
900 // See if covers: MIN2(x+c0,MIN2(y+c1,z)) |
900 // See if covers: MIN2(x+c0,MIN2(y+c1,z)) |
901 if( !phase->eqv(x,y) ) return NULL; |
901 if( !phase->eqv(x,y) ) return NULL; |
902 // If (y == x) transform MIN2(x+c0, MIN2(x+c1,z)) into |
902 // If (y == x) transform MIN2(x+c0, MIN2(x+c1,z)) into |
903 // MIN2(x+c0 or x+c1 which less, z). |
903 // MIN2(x+c0 or x+c1 which less, z). |
904 return new (phase->C, 3) MinINode(phase->transform(new (phase->C, 3) AddINode(x,phase->intcon(MIN2(x_off,y_off)))),r->in(2)); |
904 return new (phase->C) MinINode(phase->transform(new (phase->C) AddINode(x,phase->intcon(MIN2(x_off,y_off)))),r->in(2)); |
905 } else { |
905 } else { |
906 // See if covers: MIN2(x+c0,y+c1) |
906 // See if covers: MIN2(x+c0,y+c1) |
907 if( !phase->eqv(x,y) ) return NULL; |
907 if( !phase->eqv(x,y) ) return NULL; |
908 // If (y == x) transform MIN2(x+c0,x+c1) into x+c0 or x+c1 which less. |
908 // If (y == x) transform MIN2(x+c0,x+c1) into x+c0 or x+c1 which less. |
909 return new (phase->C, 3) AddINode(x,phase->intcon(MIN2(x_off,y_off))); |
909 return new (phase->C) AddINode(x,phase->intcon(MIN2(x_off,y_off))); |
910 } |
910 } |
911 |
911 |
912 } |
912 } |
913 |
913 |
914 //------------------------------add_ring--------------------------------------- |
914 //------------------------------add_ring--------------------------------------- |