8262341: Refine identical code in AddI/LNode.

Reviewed-by: thartmann, eliu
This commit is contained in:
Roland Westrelin 2021-12-08 07:55:12 +00:00
parent b334d9680b
commit 5dcdee4bcd
14 changed files with 186 additions and 315 deletions

View File

@ -263,66 +263,69 @@ AddNode* AddNode::make(Node* in1, Node* in2, BasicType bt) {
//=============================================================================
//------------------------------Idealize---------------------------------------
Node *AddINode::Ideal(PhaseGVN *phase, bool can_reshape) {
Node* AddNode::IdealIL(PhaseGVN* phase, bool can_reshape, BasicType bt) {
Node* in1 = in(1);
Node* in2 = in(2);
int op1 = in1->Opcode();
int op2 = in2->Opcode();
// Fold (con1-x)+con2 into (con1+con2)-x
if ( op1 == Op_AddI && op2 == Op_SubI ) {
if (op1 == Op_Add(bt) && op2 == Op_Sub(bt)) {
// Swap edges to try optimizations below
in1 = in2;
in2 = in(1);
op1 = op2;
op2 = in2->Opcode();
}
if( op1 == Op_SubI ) {
const Type *t_sub1 = phase->type( in1->in(1) );
const Type *t_2 = phase->type( in2 );
if( t_sub1->singleton() && t_2->singleton() && t_sub1 != Type::TOP && t_2 != Type::TOP )
return new SubINode(phase->makecon( add_ring( t_sub1, t_2 ) ), in1->in(2) );
if (op1 == Op_Sub(bt)) {
const Type* t_sub1 = phase->type(in1->in(1));
const Type* t_2 = phase->type(in2 );
if (t_sub1->singleton() && t_2->singleton() && t_sub1 != Type::TOP && t_2 != Type::TOP) {
return SubNode::make(phase->makecon(add_ring(t_sub1, t_2)), in1->in(2), bt);
}
// Convert "(a-b)+(c-d)" into "(a+c)-(b+d)"
if( op2 == Op_SubI ) {
if (op2 == Op_Sub(bt)) {
// Check for dead cycle: d = (a-b)+(c-d)
assert( in1->in(2) != this && in2->in(2) != this,
"dead loop in AddINode::Ideal" );
Node *sub = new SubINode(NULL, NULL);
sub->init_req(1, phase->transform(new AddINode(in1->in(1), in2->in(1) ) ));
sub->init_req(2, phase->transform(new AddINode(in1->in(2), in2->in(2) ) ));
Node* sub = SubNode::make(NULL, NULL, bt);
sub->init_req(1, phase->transform(AddNode::make(in1->in(1), in2->in(1), bt)));
sub->init_req(2, phase->transform(AddNode::make(in1->in(2), in2->in(2), bt)));
return sub;
}
// Convert "(a-b)+(b+c)" into "(a+c)"
if( op2 == Op_AddI && in1->in(2) == in2->in(1) ) {
assert(in1->in(1) != this && in2->in(2) != this,"dead loop in AddINode::Ideal");
return new AddINode(in1->in(1), in2->in(2));
if (op2 == Op_Add(bt) && in1->in(2) == in2->in(1)) {
assert(in1->in(1) != this && in2->in(2) != this,"dead loop in AddINode::Ideal/AddLNode::Ideal");
return AddNode::make(in1->in(1), in2->in(2), bt);
}
// Convert "(a-b)+(c+b)" into "(a+c)"
if( op2 == Op_AddI && in1->in(2) == in2->in(2) ) {
assert(in1->in(1) != this && in2->in(1) != this,"dead loop in AddINode::Ideal");
return new AddINode(in1->in(1), in2->in(1));
if (op2 == Op_Add(bt) && in1->in(2) == in2->in(2)) {
assert(in1->in(1) != this && in2->in(1) != this,"dead loop in AddINode::Ideal/AddLNode::Ideal");
return AddNode::make(in1->in(1), in2->in(1), bt);
}
// Convert "(a-b)+(b-c)" into "(a-c)"
if( op2 == Op_SubI && in1->in(2) == in2->in(1) ) {
assert(in1->in(1) != this && in2->in(2) != this,"dead loop in AddINode::Ideal");
return new SubINode(in1->in(1), in2->in(2));
if (op2 == Op_Sub(bt) && in1->in(2) == in2->in(1)) {
assert(in1->in(1) != this && in2->in(2) != this,"dead loop in AddINode::Ideal/AddLNode::Ideal");
return SubNode::make(in1->in(1), in2->in(2), bt);
}
// Convert "(a-b)+(c-a)" into "(c-b)"
if( op2 == Op_SubI && in1->in(1) == in2->in(2) ) {
assert(in1->in(2) != this && in2->in(1) != this,"dead loop in AddINode::Ideal");
return new SubINode(in2->in(1), in1->in(2));
if (op2 == Op_Sub(bt) && in1->in(1) == in2->in(2)) {
assert(in1->in(2) != this && in2->in(1) != this,"dead loop in AddINode::Ideal/AddLNode::Ideal");
return SubNode::make(in2->in(1), in1->in(2), bt);
}
}
// Convert "x+(0-y)" into "(x-y)"
if( op2 == Op_SubI && phase->type(in2->in(1)) == TypeInt::ZERO )
return new SubINode(in1, in2->in(2) );
if (op2 == Op_Sub(bt) && phase->type(in2->in(1)) == TypeInteger::zero(bt)) {
return SubNode::make(in1, in2->in(2), bt);
}
// Convert "(0-y)+x" into "(x-y)"
if( op1 == Op_SubI && phase->type(in1->in(1)) == TypeInt::ZERO )
return new SubINode( in2, in1->in(2) );
if (op1 == Op_Sub(bt) && phase->type(in1->in(1)) == TypeInteger::zero(bt)) {
return SubNode::make(in2, in1->in(2), bt);
}
// Associative
if (op1 == Op_MulI && op2 == Op_MulI) {
if (op1 == Op_Mul(bt) && op2 == Op_Mul(bt)) {
Node* add_in1 = NULL;
Node* add_in2 = NULL;
Node* mul_in = NULL;
@ -350,11 +353,47 @@ Node *AddINode::Ideal(PhaseGVN *phase, bool can_reshape) {
}
if (mul_in != NULL) {
Node* add = phase->transform(new AddINode(add_in1, add_in2));
return new MulINode(mul_in, add);
Node* add = phase->transform(AddNode::make(add_in1, add_in2, bt));
return MulNode::make(mul_in, add, bt);
}
}
// Convert (x >>> rshift) + (x << lshift) into RotateRight(x, rshift)
if (Matcher::match_rule_supported(Op_RotateRight) &&
((op1 == Op_URShift(bt) && op2 == Op_LShift(bt)) || (op1 == Op_LShift(bt) && op2 == Op_URShift(bt))) &&
in1->in(1) != NULL && in1->in(1) == in2->in(1)) {
Node* rshift = op1 == Op_URShift(bt) ? in1->in(2) : in2->in(2);
Node* lshift = op1 == Op_URShift(bt) ? in2->in(2) : in1->in(2);
if (rshift != NULL && lshift != NULL) {
const TypeInt* rshift_t = phase->type(rshift)->isa_int();
const TypeInt* lshift_t = phase->type(lshift)->isa_int();
int bits = bt == T_INT ? 32 : 64;
int mask = bt == T_INT ? 0x1F : 0x3F;
if (lshift_t != NULL && lshift_t->is_con() &&
rshift_t != NULL && rshift_t->is_con() &&
((lshift_t->get_con() & mask) == (bits - (rshift_t->get_con() & mask)))) {
return new RotateRightNode(in1->in(1), phase->intcon(rshift_t->get_con() & mask), TypeInteger::bottom(bt));
}
}
}
// Convert (~x+1) into -x. Note there isn't a bitwise not bytecode,
// "~x" would typically represented as "x^(-1)", so (~x+1) will
// be (x^(-1))+1.
if (op1 == Op_Xor(bt) && phase->type(in2) == TypeInteger::one(bt) &&
phase->type(in1->in(2)) == TypeInteger::minus_1(bt)) {
return SubNode::make(phase->makecon(TypeInteger::zero(bt)), in1->in(1), bt);
}
return AddNode::Ideal(phase, can_reshape);
}
Node* AddINode::Ideal(PhaseGVN* phase, bool can_reshape) {
Node* in1 = in(1);
Node* in2 = in(2);
int op1 = in1->Opcode();
int op2 = in2->Opcode();
// Convert (x>>>z)+y into (x+(y<<z))>>>z for small constant z and y.
// Helps with array allocation math constant folding
// See 4790063:
@ -366,45 +405,21 @@ Node *AddINode::Ideal(PhaseGVN *phase, bool can_reshape) {
// Implement support for negative y and (x >= -(y << z))
// Have not observed cases where type information exists to support
// positive y and (x <= -(y << z))
if( op1 == Op_URShiftI && op2 == Op_ConI &&
in1->in(2)->Opcode() == Op_ConI ) {
jint z = phase->type( in1->in(2) )->is_int()->get_con() & 0x1f; // only least significant 5 bits matter
jint y = phase->type( in2 )->is_int()->get_con();
if (op1 == Op_URShiftI && op2 == Op_ConI &&
in1->in(2)->Opcode() == Op_ConI) {
jint z = phase->type(in1->in(2))->is_int()->get_con() & 0x1f; // only least significant 5 bits matter
jint y = phase->type(in2)->is_int()->get_con();
if( z < 5 && -5 < y && y < 0 ) {
const Type *t_in11 = phase->type(in1->in(1));
if( t_in11 != Type::TOP && (t_in11->is_int()->_lo >= -(y << z)) ) {
Node *a = phase->transform( new AddINode( in1->in(1), phase->intcon(y<<z) ) );
return new URShiftINode( a, in1->in(2) );
if (z < 5 && -5 < y && y < 0) {
const Type* t_in11 = phase->type(in1->in(1));
if( t_in11 != Type::TOP && (t_in11->is_int()->_lo >= -(y << z))) {
Node* a = phase->transform(new AddINode( in1->in(1), phase->intcon(y<<z)));
return new URShiftINode(a, in1->in(2));
}
}
}
// Convert (x >>> rshift) + (x << lshift) into RotateRight(x, rshift)
if (Matcher::match_rule_supported(Op_RotateRight) &&
((op1 == Op_URShiftI && op2 == Op_LShiftI) || (op1 == Op_LShiftI && op2 == Op_URShiftI)) &&
in1->in(1) != NULL && in1->in(1) == in2->in(1)) {
Node* rshift = op1 == Op_URShiftI ? in1->in(2) : in2->in(2);
Node* lshift = op1 == Op_URShiftI ? in2->in(2) : in1->in(2);
if (rshift != NULL && lshift != NULL) {
const TypeInt* rshift_t = phase->type(rshift)->isa_int();
const TypeInt* lshift_t = phase->type(lshift)->isa_int();
if (lshift_t != NULL && lshift_t->is_con() &&
rshift_t != NULL && rshift_t->is_con() &&
((lshift_t->get_con() & 0x1F) == (32 - (rshift_t->get_con() & 0x1F)))) {
return new RotateRightNode(in1->in(1), phase->intcon(rshift_t->get_con() & 0x1F), TypeInt::INT);
}
}
}
// Convert (~x+1) into -x. Note there isn't a bitwise not bytecode,
// "~x" would typically represented as "x^(-1)", so (~x+1) will
// be (x^(-1))+1.
if (op1 == Op_XorI && phase->type(in2) == TypeInt::ONE &&
phase->type(in1->in(2)) == TypeInt::MINUS_1) {
return new SubINode(phase->makecon(TypeInt::ZERO), in1->in(1));
}
return AddNode::Ideal(phase, can_reshape);
return AddNode::IdealIL(phase, can_reshape, T_INT);
}
@ -451,124 +466,8 @@ const Type *AddINode::add_ring( const Type *t0, const Type *t1 ) const {
//=============================================================================
//------------------------------Idealize---------------------------------------
Node *AddLNode::Ideal(PhaseGVN *phase, bool can_reshape) {
Node* in1 = in(1);
Node* in2 = in(2);
int op1 = in1->Opcode();
int op2 = in2->Opcode();
// Fold (con1-x)+con2 into (con1+con2)-x
if ( op1 == Op_AddL && op2 == Op_SubL ) {
// Swap edges to try optimizations below
in1 = in2;
in2 = in(1);
op1 = op2;
op2 = in2->Opcode();
}
// Fold (con1-x)+con2 into (con1+con2)-x
if( op1 == Op_SubL ) {
const Type *t_sub1 = phase->type( in1->in(1) );
const Type *t_2 = phase->type( in2 );
if( t_sub1->singleton() && t_2->singleton() && t_sub1 != Type::TOP && t_2 != Type::TOP )
return new SubLNode(phase->makecon( add_ring( t_sub1, t_2 ) ), in1->in(2) );
// Convert "(a-b)+(c-d)" into "(a+c)-(b+d)"
if( op2 == Op_SubL ) {
// Check for dead cycle: d = (a-b)+(c-d)
assert( in1->in(2) != this && in2->in(2) != this,
"dead loop in AddLNode::Ideal" );
Node *sub = new SubLNode(NULL, NULL);
sub->init_req(1, phase->transform(new AddLNode(in1->in(1), in2->in(1) ) ));
sub->init_req(2, phase->transform(new AddLNode(in1->in(2), in2->in(2) ) ));
return sub;
}
// Convert "(a-b)+(b+c)" into "(a+c)"
if( op2 == Op_AddL && in1->in(2) == in2->in(1) ) {
assert(in1->in(1) != this && in2->in(2) != this,"dead loop in AddLNode::Ideal");
return new AddLNode(in1->in(1), in2->in(2));
}
// Convert "(a-b)+(c+b)" into "(a+c)"
if( op2 == Op_AddL && in1->in(2) == in2->in(2) ) {
assert(in1->in(1) != this && in2->in(1) != this,"dead loop in AddLNode::Ideal");
return new AddLNode(in1->in(1), in2->in(1));
}
// Convert "(a-b)+(b-c)" into "(a-c)"
if( op2 == Op_SubL && in1->in(2) == in2->in(1) ) {
assert(in1->in(1) != this && in2->in(2) != this,"dead loop in AddLNode::Ideal");
return new SubLNode(in1->in(1), in2->in(2));
}
// Convert "(a-b)+(c-a)" into "(c-b)"
if( op2 == Op_SubL && in1->in(1) == in2->in(2) ) {
assert(in1->in(2) != this && in2->in(1) != this,"dead loop in AddLNode::Ideal");
return new SubLNode(in2->in(1), in1->in(2));
}
}
// Convert "x+(0-y)" into "(x-y)"
if( op2 == Op_SubL && phase->type(in2->in(1)) == TypeLong::ZERO )
return new SubLNode( in1, in2->in(2) );
// Convert "(0-y)+x" into "(x-y)"
if( op1 == Op_SubL && phase->type(in1->in(1)) == TypeLong::ZERO )
return new SubLNode( in2, in1->in(2) );
// Associative
if (op1 == Op_MulL && op2 == Op_MulL) {
Node* add_in1 = NULL;
Node* add_in2 = NULL;
Node* mul_in = NULL;
if (in1->in(1) == in2->in(1)) {
// Convert "a*b+a*c into a*(b+c)
add_in1 = in1->in(2);
add_in2 = in2->in(2);
mul_in = in1->in(1);
} else if (in1->in(2) == in2->in(1)) {
// Convert a*b+b*c into b*(a+c)
add_in1 = in1->in(1);
add_in2 = in2->in(2);
mul_in = in1->in(2);
} else if (in1->in(2) == in2->in(2)) {
// Convert a*c+b*c into (a+b)*c
add_in1 = in1->in(1);
add_in2 = in2->in(1);
mul_in = in1->in(2);
} else if (in1->in(1) == in2->in(2)) {
// Convert a*b+c*a into a*(b+c)
add_in1 = in1->in(2);
add_in2 = in2->in(1);
mul_in = in1->in(1);
}
if (mul_in != NULL) {
Node* add = phase->transform(new AddLNode(add_in1, add_in2));
return new MulLNode(mul_in, add);
}
}
// Convert (x >>> rshift) + (x << lshift) into RotateRight(x, rshift)
if (Matcher::match_rule_supported(Op_RotateRight) &&
((op1 == Op_URShiftL && op2 == Op_LShiftL) || (op1 == Op_LShiftL && op2 == Op_URShiftL)) &&
in1->in(1) != NULL && in1->in(1) == in2->in(1)) {
Node* rshift = op1 == Op_URShiftL ? in1->in(2) : in2->in(2);
Node* lshift = op1 == Op_URShiftL ? in2->in(2) : in1->in(2);
if (rshift != NULL && lshift != NULL) {
const TypeInt* rshift_t = phase->type(rshift)->isa_int();
const TypeInt* lshift_t = phase->type(lshift)->isa_int();
if (lshift_t != NULL && lshift_t->is_con() &&
rshift_t != NULL && rshift_t->is_con() &&
((lshift_t->get_con() & 0x3F) == (64 - (rshift_t->get_con() & 0x3F)))) {
return new RotateRightNode(in1->in(1), phase->intcon(rshift_t->get_con() & 0x3F), TypeLong::LONG);
}
}
}
// Convert (~x+1) into -x. Note there isn't a bitwise not bytecode,
// "~x" would typically represented as "x^(-1)", so (~x+1) will
// be (x^(-1))+1
if (op1 == Op_XorL && phase->type(in2) == TypeLong::ONE &&
phase->type(in1->in(2)) == TypeLong::MINUS_1) {
return new SubLNode(phase->makecon(TypeLong::ZERO), in1->in(1));
}
return AddNode::Ideal(phase, can_reshape);
Node* AddLNode::Ideal(PhaseGVN* phase, bool can_reshape) {
return AddNode::IdealIL(phase, can_reshape, T_LONG);
}

View File

@ -51,7 +51,8 @@ public:
// We also canonicalize the Node, moving constants to the right input,
// and flatten expressions (so that 1+x+2 becomes x+3).
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
Node* IdealIL(PhaseGVN* phase, bool can_reshape, BasicType bt);
// Compute a new Type for this node. Basically we just do the pre-check,
// then call the virtual add() to set the type.
@ -74,10 +75,6 @@ public:
// Supplied function to return the multiplicative opcode
virtual int min_opcode() const = 0;
virtual bool operates_on(BasicType bt, bool signed_int) const {
assert(bt == T_INT || bt == T_LONG, "unsupported");
return false;
}
static AddNode* make(Node* in1, Node* in2, BasicType bt);
};
@ -92,12 +89,9 @@ public:
virtual const Type *bottom_type() const { return TypeInt::INT; }
int max_opcode() const { return Op_MaxI; }
int min_opcode() const { return Op_MinI; }
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
virtual Node* Identity(PhaseGVN* phase);
virtual bool operates_on(BasicType bt, bool signed_int) const {
assert(bt == T_INT || bt == T_LONG, "unsupported");
return bt == T_INT;
}
virtual uint ideal_reg() const { return Op_RegI; }
};
@ -112,12 +106,9 @@ public:
virtual const Type *bottom_type() const { return TypeLong::LONG; }
int max_opcode() const { return Op_MaxL; }
int min_opcode() const { return Op_MinL; }
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
virtual Node* Identity(PhaseGVN* phase);
virtual bool operates_on(BasicType bt, bool signed_int) const {
assert(bt == T_INT || bt == T_LONG, "unsupported");
return bt == T_LONG;
}
virtual uint ideal_reg() const { return Op_RegL; }
};

View File

@ -60,10 +60,6 @@ public:
TypeNode* dominating_cast(PhaseGVN* gvn, PhaseTransform* pt) const;
static Node* make_cast(int opcode, Node* c, Node *n, const Type *t, DependencyType dependency);
static Node* make(Node* c, Node *n, const Type *t, BasicType bt);
virtual bool operates_on(BasicType bt, bool signed_int) const {
assert(bt == T_INT || bt == T_LONG, "unsupported");
return false;
}
#ifndef PRODUCT
virtual void dump_spec(outputStream *st) const;
@ -104,10 +100,6 @@ class CastIINode: public ConstraintCastNode {
return false;
#endif
}
virtual bool operates_on(BasicType bt, bool signed_int) const {
assert(bt == T_INT || bt == T_LONG, "unsupported");
return bt == T_INT;
}
#ifndef PRODUCT
virtual void dump_spec(outputStream* st) const;
@ -125,10 +117,7 @@ public:
: ConstraintCastNode(n, t, dependency){
init_class_id(Class_CastLL);
}
virtual bool operates_on(BasicType bt, bool signed_int) const {
assert(bt == T_INT || bt == T_LONG, "unsupported");
return bt == T_LONG;
}
virtual int Opcode() const;
virtual uint ideal_reg() const { return Op_RegL; }
};

View File

@ -2521,7 +2521,7 @@ bool PhiNode::is_data_loop(RegionNode* r, Node* uin, const PhaseGVN* phase) {
//------------------------------is_tripcount-----------------------------------
bool PhiNode::is_tripcount(BasicType bt) const {
return (in(0) != NULL && in(0)->is_BaseCountedLoop() &&
in(0)->as_BaseCountedLoop()->operates_on(bt, true) &&
in(0)->as_BaseCountedLoop()->bt() == bt &&
in(0)->as_BaseCountedLoop()->phi() == this);
}

View File

@ -741,7 +741,7 @@ bool IdealLoopTree::is_range_check_if(IfNode *iff, PhaseIdealLoop *phase, BasicT
return false;
}
const CmpNode *cmp = bol->in(1)->as_Cmp();
if (!(cmp->is_Cmp() && cmp->operates_on(bt, false))) {
if (cmp->Opcode() != Op_Cmp_unsigned(bt)) {
return false;
}
range = cmp->in(2);

View File

@ -2521,7 +2521,7 @@ bool PhaseIdealLoop::is_scaled_iv(Node* exp, Node* iv, jlong* p_scale, BasicType
}
int opc = exp->Opcode();
// Can't use is_Mul() here as it's true for AndI and AndL
if ((opc == Op_MulI || opc == Op_MulL) && exp->operates_on(bt, true)) {
if (opc == Op_Mul(bt)) {
if (exp->in(1)->uncast() == iv && exp->in(2)->is_Con()) {
if (p_scale != NULL) {
*p_scale = exp->in(2)->get_integer_as_long(bt);
@ -2534,7 +2534,7 @@ bool PhaseIdealLoop::is_scaled_iv(Node* exp, Node* iv, jlong* p_scale, BasicType
}
return true;
}
} else if (exp->is_LShift() && exp->operates_on(bt, true)) {
} else if (opc == Op_LShift(bt)) {
if (exp->in(1)->uncast() == iv && exp->in(2)->is_Con()) {
if (p_scale != NULL) {
jint shift_amount = exp->in(2)->get_int();
@ -2563,7 +2563,8 @@ bool PhaseIdealLoop::is_scaled_iv_plus_offset(Node* exp, Node* iv, jlong* p_scal
return true;
}
exp = exp->uncast();
if (exp->is_Add() && exp->operates_on(bt, true)) {
int opc = exp->Opcode();
if (opc == Op_Add(bt)) {
if (is_scaled_iv(exp->in(1), iv, p_scale, bt)) {
if (p_offset != NULL) {
*p_offset = exp->in(2);
@ -2590,7 +2591,7 @@ bool PhaseIdealLoop::is_scaled_iv_plus_offset(Node* exp, Node* iv, jlong* p_scal
return true;
}
}
} else if (exp->is_Sub() && exp->operates_on(bt, true)) {
} else if (opc == Op_Sub(bt)) {
if (is_scaled_iv(exp->in(1), iv, p_scale, bt)) {
if (p_offset != NULL) {
Node *zero = _igvn.integercon(0, bt);

View File

@ -71,7 +71,7 @@ void LoopNode::dump_spec(outputStream *st) const {
//------------------------------is_valid_counted_loop-------------------------
bool LoopNode::is_valid_counted_loop(BasicType bt) const {
if (is_BaseCountedLoop() && operates_on(bt, false)) {
if (is_BaseCountedLoop() && as_BaseCountedLoop()->bt() == bt) {
BaseCountedLoopNode* l = as_BaseCountedLoop();
BaseCountedLoopEndNode* le = l->loopexit_or_null();
if (le != NULL &&
@ -1433,12 +1433,12 @@ bool PhaseIdealLoop::is_counted_loop(Node* x, IdealLoopTree*&loop, BasicType iv_
Node* incr = NULL;
Node* limit = NULL;
Node* cmp = loop_exit_test(back_control, loop, incr, limit, bt, cl_prob);
if (cmp == NULL || !(cmp->is_Cmp() && cmp->operates_on(iv_bt, true))) {
if (cmp == NULL || cmp->Opcode() != Op_Cmp(iv_bt)) {
return false; // Avoid pointer & float & 64-bit compares
}
// Trip-counter increment must be commutative & associative.
if (incr->is_ConstraintCast() && incr->operates_on(iv_bt, false)) {
if (incr->Opcode() == Op_Cast(iv_bt)) {
incr = incr->in(1);
}
@ -1455,7 +1455,7 @@ bool PhaseIdealLoop::is_counted_loop(Node* x, IdealLoopTree*&loop, BasicType iv_
if (!(incr = CountedLoopNode::match_incr_with_optional_truncation(incr, &trunc1, &trunc2, &iv_trunc_t, iv_bt))) {
return false; // Funny increment opcode
}
assert(incr->is_Add() && incr->operates_on(iv_bt, false), "wrong increment code");
assert(incr->Opcode() == Op_Add(iv_bt), "wrong increment code");
Node* xphi = NULL;
Node* stride = loop_iv_stride(incr, loop, xphi);
@ -1464,7 +1464,7 @@ bool PhaseIdealLoop::is_counted_loop(Node* x, IdealLoopTree*&loop, BasicType iv_
return false;
}
if (xphi->is_ConstraintCast() && xphi->operates_on(iv_bt, false)) {
if (xphi->Opcode() == Op_Cast(iv_bt)) {
xphi = xphi->in(1);
}
@ -2272,7 +2272,7 @@ Node* CountedLoopNode::match_incr_with_optional_truncation(Node* expr, Node** tr
}
// If (maybe after stripping) it is an AddI, we won:
if (n1->is_Add() && n1->operates_on(bt, true)) {
if (n1op == Op_Add(bt)) {
*trunc1 = t1;
*trunc2 = t2;
*trunc_type = trunc_t;

View File

@ -215,10 +215,6 @@ public:
BaseCountedLoopEndNode* loopexit() const;
virtual BasicType bt() const = 0;
virtual bool operates_on(BasicType bt, bool signed_int) const {
assert(bt == T_INT || bt == T_LONG, "unsupported");
return false;
}
static BaseCountedLoopNode* make(Node* entry, Node* backedge, BasicType bt);
};
@ -342,10 +338,6 @@ public:
static Node* skip_predicates_from_entry(Node* ctrl);
Node* skip_predicates();
virtual bool operates_on(BasicType bt, bool signed_int) const {
assert(bt == T_INT || bt == T_LONG, "unsupported");
return bt == T_INT;
}
virtual BasicType bt() const {
return T_INT;
}
@ -366,11 +358,6 @@ public:
virtual int Opcode() const;
virtual bool operates_on(BasicType bt, bool signed_int) const {
assert(bt == T_INT || bt == T_LONG, "unsupported");
return bt == T_LONG;
}
virtual BasicType bt() const {
return T_LONG;
}
@ -423,17 +410,13 @@ public:
if (!ln->is_BaseCountedLoop() || ln->as_BaseCountedLoop()->loopexit_or_null() != this) {
return NULL;
}
if (!ln->operates_on(bt(), true)) {
if (ln->as_BaseCountedLoop()->bt() != bt()) {
return NULL;
}
return ln->as_BaseCountedLoop();
}
BoolTest::mask test_trip() const { return in(TestValue)->as_Bool()->_test._test; }
virtual bool operates_on(BasicType bt, bool signed_int) const {
assert(bt == T_INT || bt == T_LONG, "unsupported");
return false;
}
jlong stride_con() const;
virtual BasicType bt() const = 0;
@ -453,10 +436,6 @@ public:
CountedLoopNode* loopnode() const {
return (CountedLoopNode*) BaseCountedLoopEndNode::loopnode();
}
virtual bool operates_on(BasicType bt, bool signed_int) const {
assert(bt == T_INT || bt == T_LONG, "unsupported");
return bt == T_INT;
}
virtual BasicType bt() const {
return T_INT;
@ -477,10 +456,7 @@ public:
LongCountedLoopNode* loopnode() const {
return (LongCountedLoopNode*) BaseCountedLoopEndNode::loopnode();
}
virtual bool operates_on(BasicType bt, bool signed_int) const {
assert(bt == T_INT || bt == T_LONG, "unsupported");
return bt == T_LONG;
}
virtual int Opcode() const;
virtual BasicType bt() const {
@ -498,7 +474,7 @@ inline BaseCountedLoopEndNode* BaseCountedLoopNode::loopexit_or_null() const {
return NULL;
}
BaseCountedLoopEndNode* result = lexit->as_BaseCountedLoopEnd();
if (!result->operates_on(bt(), true)) {
if (result->bt() != bt()) {
return NULL;
}
return result;

View File

@ -222,6 +222,19 @@ const Type* MulNode::Value(PhaseGVN* phase) const {
return mul_ring(t1,t2); // Local flavor of type multiplication
}
MulNode* MulNode::make(Node* in1, Node* in2, BasicType bt) {
switch (bt) {
case T_INT:
return new MulINode(in1, in2);
case T_LONG:
return new MulLNode(in1, in2);
default:
fatal("Not implemented for %s", type2name(bt));
}
return NULL;
}
//=============================================================================
//------------------------------Ideal------------------------------------------
// Check for power-of-2 multiply, then try the regular MulNode::Ideal

View File

@ -75,16 +75,13 @@ public:
// Supplied function to return the multiplicative opcode
virtual int mul_opcode() const = 0;
virtual bool operates_on(BasicType bt, bool signed_int) const {
assert(bt == T_INT || bt == T_LONG, "unsupported");
return false;
}
// Supplied function to return the additive opcode
virtual int max_opcode() const = 0;
// Supplied function to return the multiplicative opcode
virtual int min_opcode() const = 0;
static MulNode* make(Node* in1, Node* in2, BasicType bt);
};
//------------------------------MulINode---------------------------------------
@ -103,10 +100,6 @@ public:
int min_opcode() const { return Op_MinI; }
const Type *bottom_type() const { return TypeInt::INT; }
virtual uint ideal_reg() const { return Op_RegI; }
virtual bool operates_on(BasicType bt, bool signed_int) const {
assert(bt == T_INT || bt == T_LONG, "unsupported");
return bt == T_INT;
}
};
//------------------------------MulLNode---------------------------------------
@ -125,10 +118,6 @@ public:
int min_opcode() const { return Op_MinL; }
const Type *bottom_type() const { return TypeLong::LONG; }
virtual uint ideal_reg() const { return Op_RegL; }
virtual bool operates_on(BasicType bt, bool signed_int) const {
assert(bt == T_INT || bt == T_LONG, "unsupported");
return bt == T_LONG;
}
};
@ -234,10 +223,6 @@ public:
LShiftNode(Node *in1, Node *in2) : Node(NULL,in1,in2) {
init_class_id(Class_LShift);
}
virtual bool operates_on(BasicType bt, bool signed_int) const {
assert(bt == T_INT || bt == T_LONG, "unsupported");
return false;
}
};
//------------------------------LShiftINode------------------------------------
@ -251,10 +236,6 @@ public:
virtual const Type* Value(PhaseGVN* phase) const;
const Type *bottom_type() const { return TypeInt::INT; }
virtual uint ideal_reg() const { return Op_RegI; }
virtual bool operates_on(BasicType bt, bool signed_int) const {
assert(bt == T_INT || bt == T_LONG, "unsupported");
return bt == T_INT;
}
};
//------------------------------LShiftLNode------------------------------------
@ -268,10 +249,6 @@ public:
virtual const Type* Value(PhaseGVN* phase) const;
const Type *bottom_type() const { return TypeLong::LONG; }
virtual uint ideal_reg() const { return Op_RegL; }
virtual bool operates_on(BasicType bt, bool signed_int) const {
assert(bt == T_INT || bt == T_LONG, "unsupported");
return bt == T_LONG;
}
};

View File

@ -1265,12 +1265,6 @@ public:
uint _del_tick; // Bumped when a deletion happens..
#endif
#endif
public:
virtual bool operates_on(BasicType bt, bool signed_int) const {
assert(bt == T_INT || bt == T_LONG, "unsupported");
Unimplemented();
return false;
}
};
inline bool not_a_node(const Node* n) {
@ -1835,4 +1829,39 @@ public:
#endif
};
#include "opto/opcodes.hpp"
#define Op_IL(op) \
inline int Op_ ## op(BasicType bt) { \
assert(bt == T_INT || bt == T_LONG, "only for int or longs"); \
if (bt == T_INT) { \
return Op_## op ## I; \
} \
return Op_## op ## L; \
}
Op_IL(Add)
Op_IL(Sub)
Op_IL(Mul)
Op_IL(URShift)
Op_IL(LShift)
Op_IL(Xor)
Op_IL(Cmp)
inline int Op_Cmp_unsigned(BasicType bt) {
assert(bt == T_INT || bt == T_LONG, "only for int or longs");
if (bt == T_INT) {
return Op_CmpU;
}
return Op_CmpUL;
}
inline int Op_Cast(BasicType bt) {
assert(bt == T_INT || bt == T_LONG, "only for int or longs");
if (bt == T_INT) {
return Op_CastII;
}
return Op_CastLL;
}
#endif // SHARE_OPTO_NODE_HPP

View File

@ -62,10 +62,6 @@ public:
virtual const Type *add_id() const = 0;
static SubNode* make(Node* in1, Node* in2, BasicType bt);
virtual bool operates_on(BasicType bt, bool signed_int) const {
assert(bt == T_INT || bt == T_LONG, "unsupported");
return false;
}
};
@ -81,10 +77,6 @@ public:
const Type *add_id() const { return TypeInt::ZERO; }
const Type *bottom_type() const { return TypeInt::INT; }
virtual uint ideal_reg() const { return Op_RegI; }
virtual bool operates_on(BasicType bt, bool signed_int) const {
assert(bt == T_INT || bt == T_LONG, "unsupported");
return bt == T_INT;
}
};
//------------------------------SubLNode---------------------------------------
@ -98,10 +90,6 @@ public:
const Type *add_id() const { return TypeLong::ZERO; }
const Type *bottom_type() const { return TypeLong::LONG; }
virtual uint ideal_reg() const { return Op_RegL; }
virtual bool operates_on(BasicType bt, bool signed_int) const {
assert(bt == T_INT || bt == T_LONG, "unsupported");
return bt == T_LONG;
}
};
// NOTE: SubFPNode should be taken away and replaced by add and negate
@ -162,10 +150,6 @@ public:
// including eventual control nodes and their projections.
virtual void related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const;
#endif
virtual bool operates_on(BasicType bt, bool signed_int) const {
assert(bt == T_INT || bt == T_LONG, "unsupported");
return false;
}
};
//------------------------------CmpINode---------------------------------------
@ -176,10 +160,6 @@ public:
virtual int Opcode() const;
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
virtual const Type *sub( const Type *, const Type * ) const;
virtual bool operates_on(BasicType bt, bool signed_int) const {
assert(bt == T_INT || bt == T_LONG, "unsupported");
return bt == T_INT && signed_int;
}
};
//------------------------------CmpUNode---------------------------------------
@ -191,10 +171,6 @@ public:
virtual const Type *sub( const Type *, const Type * ) const;
const Type* Value(PhaseGVN* phase) const;
bool is_index_range_check() const;
virtual bool operates_on(BasicType bt, bool signed_int) const {
assert(bt == T_INT || bt == T_LONG, "unsupported");
return bt == T_INT && !signed_int;
}
};
//------------------------------CmpPNode---------------------------------------
@ -225,10 +201,6 @@ public:
virtual int Opcode() const;
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
virtual const Type *sub( const Type *, const Type * ) const;
virtual bool operates_on(BasicType bt, bool signed_int) const {
assert(bt == T_INT || bt == T_LONG, "unsupported");
return bt == T_LONG && signed_int;
}
};
//------------------------------CmpULNode---------------------------------------
@ -238,10 +210,6 @@ public:
CmpULNode(Node* in1, Node* in2) : CmpNode(in1, in2) { }
virtual int Opcode() const;
virtual const Type* sub(const Type*, const Type*) const;
virtual bool operates_on(BasicType bt, bool signed_int) const {
assert(bt == T_INT || bt == T_LONG, "unsupported");
return bt == T_LONG && !signed_int;
}
};
//------------------------------CmpL3Node--------------------------------------

View File

@ -1413,6 +1413,30 @@ const TypeInteger* TypeInteger::bottom(BasicType bt) {
return TypeLong::LONG;
}
const TypeInteger* TypeInteger::zero(BasicType bt) {
if (bt == T_INT) {
return TypeInt::ZERO;
}
assert(bt == T_LONG, "basic type not an int or long");
return TypeLong::ZERO;
}
const TypeInteger* TypeInteger::one(BasicType bt) {
if (bt == T_INT) {
return TypeInt::ONE;
}
assert(bt == T_LONG, "basic type not an int or long");
return TypeLong::ONE;
}
const TypeInteger* TypeInteger::minus_1(BasicType bt) {
if (bt == T_INT) {
return TypeInt::MINUS_1;
}
assert(bt == T_LONG, "basic type not an int or long");
return TypeLong::MINUS_1;
}
//=============================================================================
// Convience common pre-built types.
const TypeInt *TypeInt::MAX; // INT_MAX

View File

@ -558,10 +558,14 @@ public:
virtual jlong hi_as_long() const = 0;
virtual jlong lo_as_long() const = 0;
jlong get_con_as_long(BasicType bt) const;
bool is_con() const { return lo_as_long() == hi_as_long(); }
static const TypeInteger* make(jlong lo, jlong hi, int w, BasicType bt);
static const TypeInteger* bottom(BasicType type);
static const TypeInteger* zero(BasicType type);
static const TypeInteger* one(BasicType type);
static const TypeInteger* minus_1(BasicType type);
};
@ -588,9 +592,9 @@ public:
static const TypeInt *make(jint lo, jint hi, int w);
// Check for single integer
int is_con() const { return _lo==_hi; }
bool is_con() const { return _lo==_hi; }
bool is_con(int i) const { return is_con() && _lo == i; }
jint get_con() const { assert( is_con(), "" ); return _lo; }
jint get_con() const { assert(is_con(), "" ); return _lo; }
virtual bool is_finite() const; // Has a finite value
@ -656,9 +660,9 @@ public:
static const TypeLong *make(jlong lo, jlong hi, int w);
// Check for single integer
int is_con() const { return _lo==_hi; }
bool is_con() const { return _lo==_hi; }
bool is_con(int i) const { return is_con() && _lo == i; }
jlong get_con() const { assert( is_con(), "" ); return _lo; }
jlong get_con() const { assert(is_con(), "" ); return _lo; }
// Check for positive 32-bit value.
int is_positive_int() const { return _lo >= 0 && _hi <= (jlong)max_jint; }