Esempio n. 1
0
//=============================================================================
//------------------------------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;
}
Esempio n. 2
0
//=============================================================================
//------------------------------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;
}