//============================================================================= //------------------------------Ideal------------------------------------------ Node *SubINode::Ideal(PhaseGVN *phase, bool can_reshape){ Node *in1 = in(1); Node *in2 = in(2); if( in1 == this ) return NULL; if( in2 == this ) return NULL; uint op1 = in1->Opcode(); uint op2 = in2->Opcode(); const Type *t2 = phase->type( in2 ); // Convert "x-c0" into "x+ -c0". if( t2->base() == Type::Int ){ // Might be bottom or top... const TypeInt *i = t2->is_int(); if( i->is_con() ) return new (3) AddINode(in(1), phase->intcon(-i->get_con())); } // Convert "(x+c0) - y" into (x-y) + c0" if( op1 == Op_AddI && in1->in(1) != in1 ) { // Do not collapse (x+y)-y if "+" is a loop increment, because the // "-" is loop invariant and collapsing extends the live-range of "x" // to overlap with the "+", forcing another register to be used in // the loop. const PhiNode *phi; CountedLoopNode *l; // This test will be clearer with '&&' (apply DeMorgan's rule) // but I like the early cutouts that happen here. if( !(phi=in1->in(1)->is_Phi()) || phi->is_copy() || !(l=phi->region()->is_CountedLoop()) || in1 != l->incr() ) { const Type *tadd = phase->type( in1->in(2) ); if( tadd->singleton() ) { Node *sub2 = phase->transform( new (3) SubINode( in1->in(1), in2 )); return new (3) AddINode( sub2, in1->in(2) ); } } } // Convert "x - (x+y)" into "-y" if( op2 == Op_AddI && phase->eqv( in1, in2->in(1) ) ) return new (3) SubINode( phase->intcon(0),in2->in(2)); // Convert "(x-y) - x" into "-y" if( op1 == Op_SubI && phase->eqv( in1->in(1), in2 ) ) return new (3) SubINode( phase->intcon(0),in1->in(2)); // Convert "x - (y+x)" into "-y" if( op2 == Op_AddI && phase->eqv( in1, in2->in(2) ) ) return new (3) SubINode( phase->intcon(0),in2->in(1)); // Convert "0 - (x-y)" into "y-x" if( phase->type( in1 ) == TypeInt::ZERO && op2 == Op_SubI ) return new (3) SubINode( in2->in(2), in2->in(1) ); // Convert "0 - (x+con)" into "-con-x" jint con; if( phase->type( in1 ) == TypeInt::ZERO && op2 == Op_AddI && in2->in(2)->get_int(&con) ) return new (3) SubINode( phase->intcon(-con), in2->in(1) ); // Convert "(X+A) - (X+B)" into "A - B" if( op1 == Op_AddI && op2 == Op_AddI && in1->in(1) == in2->in(1) ) return new (3) SubINode( in1->in(2), in2->in(2) ); // Convert "(A+X) - (B+X)" into "A - B" if( op1 == Op_AddI && op2 == Op_AddI && in1->in(2) == in2->in(2) ) return new (3) SubINode( in1->in(1), in2->in(1) ); // Convert "A-(B-C)" into (A+C)-B", since add is commutative and generally // nicer to optimize than subtract. if( op2 == Op_SubI && in2->in(1) != this && in2->in(1) != in2) { Node *add1 = phase->transform( new (3) AddINode( in1, in2->in(2) ) ); return new (3) SubINode( add1, in2->in(1) ); } return NULL; }
//============================================================================= //------------------------------Ideal------------------------------------------ Node *SubLNode::Ideal(PhaseGVN *phase, bool can_reshape) { Node *in1 = in(1); Node *in2 = in(2); if( in1 == this ) return NULL; if( in2 == this ) return NULL; uint op1 = in1->Opcode(); uint op2 = in2->Opcode(); const TypeLong *i = phase->type( in2 )->isa_long(); // Convert "x-c0" into "x+ -c0". if( i && // Might be bottom or top... i->is_con() ) return new (3) AddLNode(in(1), phase->makecon(TypeLong::make(-i->get_con()))); // Convert "(x+c0) - y" into (x-y) + c0" if( op1 == Op_AddL && in1->in(1) != in1 ) { // Do not collapse (x+y)-y if "+" is a loop increment, because the // "-" is loop invariant and collapsing extends the live-range of "x" // to overlap with the "+", forcing another register to be used in // the loop. const PhiNode *phi; CountedLoopNode *l; if( !(phi=in1->in(1)->is_Phi()) || !phi->in(0) || !(l=phi->in(0)->is_CountedLoop()) || in1 != l->incr() ) { const Type *tadd = phase->type( in1->in(2) ); if( tadd->singleton() ) { Node *sub2 = phase->transform( new (3) SubLNode( in1->in(1), in2 )); return new (3) AddLNode( sub2, in1->in(2) ); } } } // Convert "x - (x+y)" into "-y" if( op2 == Op_AddL && phase->eqv( in1, in2->in(1) ) ) return new (3) SubLNode( phase->makecon(TypeLong::ZERO), in2->in(2)); // Convert "x - (y+x)" into "-y" if( op2 == Op_AddL && phase->eqv( in1, in2->in(2) ) ) return new (3) SubLNode( phase->makecon(TypeLong::ZERO),in2->in(1)); // Convert "0 - (x-y)" into "y-x" if( phase->type( in1 ) == TypeLong::ZERO && op2 == Op_SubL ) return new (3) SubLNode( in2->in(2), in2->in(1) ); // Convert "(X+A) - (X+B)" into "A - B" if( op1 == Op_AddL && op2 == Op_AddL && in1->in(1) == in2->in(1) ) return new (3) SubLNode( in1->in(2), in2->in(2) ); // Convert "(A+X) - (B+X)" into "A - B" if( op1 == Op_AddL && op2 == Op_AddL && in1->in(2) == in2->in(2) ) return new (3) SubLNode( in1->in(1), in2->in(1) ); // Convert "A-(B-C)" into (A+C)-B" if( op2 == Op_SubL && in2->in(1) != this ) { Node *add1 = phase->transform( new (3) AddLNode( in1, in2->in(2) ) ); return new (3) SubLNode( add1, in2->in(1) ); } return NULL; }