357 // range obtained by subtracting y's range from the asserted range 358 // of the I2L conversion. Here's the interval arithmetic algebra: 359 // x == z-y == [zlo,zhi]-[ylo,yhi] == [zlo,zhi]+[-yhi,-ylo] 360 // => x in [zlo-yhi, zhi-ylo] 361 // => x in [zlo-yhi, zhi-ylo] INTERSECT [xlo,xhi] 362 // => x in [xlo MAX zlo-yhi, xhi MIN zhi-ylo] 363 jlong rxlo = MAX2(xlo, zlo - yhi); 364 jlong rxhi = MIN2(xhi, zhi - ylo); 365 // And similarly, x changing place with y: 366 jlong rylo = MAX2(ylo, zlo - xhi); 367 jlong ryhi = MIN2(yhi, zhi - xlo); 368 if (rxlo > rxhi || rylo > ryhi) { 369 return this_changed; // x or y is dying; don't mess w/ it 370 } 371 if (op == Op_SubI) { 372 jlong rylo0 = rylo; 373 rylo = -ryhi; 374 ryhi = -rylo0; 375 } 376 377 Node* cx = phase->transform( new (phase->C) ConvI2LNode(x, TypeLong::make(rxlo, rxhi, widen)) ); 378 Node* cy = phase->transform( new (phase->C) ConvI2LNode(y, TypeLong::make(rylo, ryhi, widen)) ); 379 switch (op) { 380 case Op_AddI: return new (phase->C) AddLNode(cx, cy); 381 case Op_SubI: return new (phase->C) SubLNode(cx, cy); 382 default: ShouldNotReachHere(); 383 } 384 } 385 #endif //_LP64 386 387 return this_changed; 388 } 389 390 //============================================================================= 391 //------------------------------Value------------------------------------------ 392 const Type *ConvL2DNode::Value( PhaseTransform *phase ) const { 393 const Type *t = phase->type( in(1) ); 394 if( t == Type::TOP ) return Type::TOP; 395 const TypeLong *tl = t->is_long(); 396 if( tl->is_con() ) return TypeD::make( (double)tl->get_con() ); 397 return bottom_type(); 398 } 399 400 //============================================================================= 401 //------------------------------Value------------------------------------------ 435 if( andl_op == Op_AndL ) { 436 // Blow off prior masking to int 437 if( phase->type(andl->in(2)) == TypeLong::make( 0xFFFFFFFF ) ) { 438 set_req(1,andl->in(1)); 439 return this; 440 } 441 } 442 443 // Swap with a prior add: convL2I(addL(x,y)) ==> addI(convL2I(x),convL2I(y)) 444 // This replaces an 'AddL' with an 'AddI'. 445 if( andl_op == Op_AddL ) { 446 // Don't do this for nodes which have more than one user since 447 // we'll end up computing the long add anyway. 448 if (andl->outcnt() > 1) return NULL; 449 450 Node* x = andl->in(1); 451 Node* y = andl->in(2); 452 assert( x != andl && y != andl, "dead loop in ConvL2INode::Ideal" ); 453 if (phase->type(x) == Type::TOP) return NULL; 454 if (phase->type(y) == Type::TOP) return NULL; 455 Node *add1 = phase->transform(new (phase->C) ConvL2INode(x)); 456 Node *add2 = phase->transform(new (phase->C) ConvL2INode(y)); 457 return new (phase->C) AddINode(add1,add2); 458 } 459 460 // Disable optimization: LoadL->ConvL2I ==> LoadI. 461 // It causes problems (sizes of Load and Store nodes do not match) 462 // in objects initialization code and Escape Analysis. 463 return NULL; 464 } 465 466 467 468 //============================================================================= 469 //------------------------------Identity--------------------------------------- 470 // Remove redundant roundings 471 Node *RoundFloatNode::Identity( PhaseTransform *phase ) { 472 assert(Matcher::strict_fp_requires_explicit_rounding, "should only generate for Intel"); 473 // Do not round constants 474 if (phase->type(in(1))->base() == Type::FloatCon) return in(1); 475 int op = in(1)->Opcode(); 476 // Redundant rounding 477 if( op == Op_RoundFloat ) return in(1); | 357 // range obtained by subtracting y's range from the asserted range 358 // of the I2L conversion. Here's the interval arithmetic algebra: 359 // x == z-y == [zlo,zhi]-[ylo,yhi] == [zlo,zhi]+[-yhi,-ylo] 360 // => x in [zlo-yhi, zhi-ylo] 361 // => x in [zlo-yhi, zhi-ylo] INTERSECT [xlo,xhi] 362 // => x in [xlo MAX zlo-yhi, xhi MIN zhi-ylo] 363 jlong rxlo = MAX2(xlo, zlo - yhi); 364 jlong rxhi = MIN2(xhi, zhi - ylo); 365 // And similarly, x changing place with y: 366 jlong rylo = MAX2(ylo, zlo - xhi); 367 jlong ryhi = MIN2(yhi, zhi - xlo); 368 if (rxlo > rxhi || rylo > ryhi) { 369 return this_changed; // x or y is dying; don't mess w/ it 370 } 371 if (op == Op_SubI) { 372 jlong rylo0 = rylo; 373 rylo = -ryhi; 374 ryhi = -rylo0; 375 } 376 377 Node* cx = phase->transform( new ConvI2LNode(x, TypeLong::make(rxlo, rxhi, widen)) ); 378 Node* cy = phase->transform( new ConvI2LNode(y, TypeLong::make(rylo, ryhi, widen)) ); 379 switch (op) { 380 case Op_AddI: return new AddLNode(cx, cy); 381 case Op_SubI: return new SubLNode(cx, cy); 382 default: ShouldNotReachHere(); 383 } 384 } 385 #endif //_LP64 386 387 return this_changed; 388 } 389 390 //============================================================================= 391 //------------------------------Value------------------------------------------ 392 const Type *ConvL2DNode::Value( PhaseTransform *phase ) const { 393 const Type *t = phase->type( in(1) ); 394 if( t == Type::TOP ) return Type::TOP; 395 const TypeLong *tl = t->is_long(); 396 if( tl->is_con() ) return TypeD::make( (double)tl->get_con() ); 397 return bottom_type(); 398 } 399 400 //============================================================================= 401 //------------------------------Value------------------------------------------ 435 if( andl_op == Op_AndL ) { 436 // Blow off prior masking to int 437 if( phase->type(andl->in(2)) == TypeLong::make( 0xFFFFFFFF ) ) { 438 set_req(1,andl->in(1)); 439 return this; 440 } 441 } 442 443 // Swap with a prior add: convL2I(addL(x,y)) ==> addI(convL2I(x),convL2I(y)) 444 // This replaces an 'AddL' with an 'AddI'. 445 if( andl_op == Op_AddL ) { 446 // Don't do this for nodes which have more than one user since 447 // we'll end up computing the long add anyway. 448 if (andl->outcnt() > 1) return NULL; 449 450 Node* x = andl->in(1); 451 Node* y = andl->in(2); 452 assert( x != andl && y != andl, "dead loop in ConvL2INode::Ideal" ); 453 if (phase->type(x) == Type::TOP) return NULL; 454 if (phase->type(y) == Type::TOP) return NULL; 455 Node *add1 = phase->transform(new ConvL2INode(x)); 456 Node *add2 = phase->transform(new ConvL2INode(y)); 457 return new AddINode(add1,add2); 458 } 459 460 // Disable optimization: LoadL->ConvL2I ==> LoadI. 461 // It causes problems (sizes of Load and Store nodes do not match) 462 // in objects initialization code and Escape Analysis. 463 return NULL; 464 } 465 466 467 468 //============================================================================= 469 //------------------------------Identity--------------------------------------- 470 // Remove redundant roundings 471 Node *RoundFloatNode::Identity( PhaseTransform *phase ) { 472 assert(Matcher::strict_fp_requires_explicit_rounding, "should only generate for Intel"); 473 // Do not round constants 474 if (phase->type(in(1))->base() == Type::FloatCon) return in(1); 475 int op = in(1)->Opcode(); 476 // Redundant rounding 477 if( op == Op_RoundFloat ) return in(1); |