--- old/src/share/vm/opto/subnode.cpp 2016-02-12 16:44:37.437399394 +0100 +++ new/src/share/vm/opto/subnode.cpp 2016-02-12 16:44:36.426820278 +0100 @@ -111,6 +111,17 @@ } +SubNode* SubNode::make(BasicType bt, Node *in1, Node *in2) { + switch(bt) { + case T_INT: return new SubINode(in1, in2); + case T_LONG: return new SubLNode(in1, in2); + case T_FLOAT: return new SubFNode(in1, in2); + case T_DOUBLE: return new SubDNode(in1, in2); + } + fatal("Bad basic type %s", type2name(bt)); + return NULL; +} + //============================================================================= //------------------------------Helper function-------------------------------- --- old/src/share/vm/opto/subnode.hpp 2016-02-12 16:44:37.521875164 +0100 +++ new/src/share/vm/opto/subnode.hpp 2016-02-12 16:44:36.475369147 +0100 @@ -39,7 +39,7 @@ // are compressed into -1, and all positive answers compressed to 1. class SubNode : public Node { public: - SubNode( Node *in1, Node *in2 ) : Node(0,in1,in2) { + SubNode(Node *in1, Node *in2) : Node(0,in1,in2) { init_class_id(Class_Sub); } @@ -50,16 +50,18 @@ // Compute a new Type for this node. Basically we just do the pre-check, // then call the virtual add() to set the type. virtual const Type* Value(PhaseGVN* phase) const; - const Type* Value_common( PhaseTransform *phase ) const; + const Type* Value_common(PhaseTransform *phase) const; // Supplied function returns the subtractend of the inputs. // This also type-checks the inputs for sanity. Guaranteed never to // be passed a TOP or BOTTOM type, these are filtered out by a pre-check. - virtual const Type *sub( const Type *, const Type * ) const = 0; + virtual const Type *sub(const Type*, const Type*) const = 0; // Supplied function to return the additive identity type. // This is returned whenever the subtracts inputs are the same. virtual const Type *add_id() const = 0; + + static SubNode* make(BasicType bt, Node *in1, Node *in2); }; --- old/src/share/vm/opto/loopnode.cpp 2016-02-12 16:44:37.547139465 +0100 +++ new/src/share/vm/opto/loopnode.cpp 2016-02-12 16:44:36.570487679 +0100 @@ -1743,11 +1743,13 @@ void PhaseIdealLoop::replace_parallel_iv(IdealLoopTree *loop) { assert(loop->_head->is_CountedLoop(), ""); CountedLoopNode *cl = loop->_head->as_CountedLoop(); - if (!cl->is_valid_counted_loop()) + if (!cl->is_valid_counted_loop()) { return; // skip malformed counted loop + } Node *incr = cl->incr(); - if (incr == NULL) + if (incr == NULL) { return; // Dead loop? + } Node *init = cl->init_trip(); Node *phi = cl->phi(); int stride_con = cl->stride_con(); @@ -1756,26 +1758,30 @@ for (DUIterator i = cl->outs(); cl->has_out(i); i++) { Node *out = cl->out(i); // Look for other phis (secondary IVs). Skip dead ones - if (!out->is_Phi() || out == phi || !has_node(out)) + if (!out->is_Phi() || out == phi || !has_node(out)) { continue; + } PhiNode* phi2 = out->as_Phi(); - Node *incr2 = phi2->in( LoopNode::LoopBackControl ); + Node *incr2 = phi2->in(LoopNode::LoopBackControl); // Look for induction variables of the form: X += constant if (phi2->region() != loop->_head || incr2->req() != 3 || incr2->in(1) != phi2 || incr2 == incr || - incr2->Opcode() != Op_AddI || - !incr2->in(2)->is_Con()) + (incr2->Opcode() != Op_AddI && incr2->Opcode() != Op_AddL) || + !incr2->in(2)->is_Con()) { continue; + } + BasicType bt = incr2->Opcode() == Op_AddI ? T_INT : T_LONG; // Check for parallel induction variable (parallel to trip counter) // via an affine function. In particular, count-down loops with // count-up array indices are common. We only RCE references off // the trip-counter, so we need to convert all these to trip-counter // expressions. - Node *init2 = phi2->in( LoopNode::EntryControl ); - int stride_con2 = incr2->in(2)->get_int(); + Node *init2 = phi2->in(LoopNode::EntryControl); + Node* stride2 = incr2->in(2); + jlong stride_con2 = (bt == T_INT) ? stride2->get_int() : stride2->get_long(); // The general case here gets a little tricky. We want to find the // GCD of all possible parallel IV's and make a new IV using this @@ -1784,7 +1790,7 @@ // Instead we require 'stride_con2' to be a multiple of 'stride_con', // where +/-1 is the common case, but other integer multiples are // also easy to handle. - int ratio_con = stride_con2/stride_con; + jlong ratio_con = stride_con2/stride_con; if ((ratio_con * stride_con) == stride_con2) { // Check for exact #ifndef PRODUCT @@ -1797,21 +1803,33 @@ // variable differs from the trip counter by a loop-invariant // amount, the difference between their respective initial values. // It is scaled by the 'ratio_con'. - Node* ratio = _igvn.intcon(ratio_con); + Node* ratio = (bt == T_INT) ? (Node*)_igvn.intcon((int)ratio_con) : (Node*)_igvn.longcon(ratio_con); set_ctrl(ratio, C->root()); - Node* ratio_init = new MulINode(init, ratio); - _igvn.register_new_node_with_optimizer(ratio_init, init); + Node* conv_init = init; + if (bt == T_LONG) { + conv_init = new ConvI2LNode(init); + _igvn.register_new_node_with_optimizer(conv_init, init); + set_early_ctrl(conv_init); + } + Node* ratio_init = MulNode::make(bt, conv_init, ratio); + _igvn.register_new_node_with_optimizer(ratio_init, conv_init); set_early_ctrl(ratio_init); - Node* diff = new SubINode(init2, ratio_init); + Node* diff = SubNode::make(bt, init2, ratio_init); _igvn.register_new_node_with_optimizer(diff, init2); set_early_ctrl(diff); - Node* ratio_idx = new MulINode(phi, ratio); - _igvn.register_new_node_with_optimizer(ratio_idx, phi); + Node* conv_phi = phi; + if (bt == T_LONG) { + conv_phi = new ConvI2LNode(phi); + _igvn.register_new_node_with_optimizer(conv_phi, phi); + set_ctrl(conv_phi, cl); + } + Node* ratio_idx = MulINode::make(bt, conv_phi, ratio); + _igvn.register_new_node_with_optimizer(ratio_idx, conv_phi); set_ctrl(ratio_idx, cl); - Node* add = new AddINode(ratio_idx, diff); + Node* add = AddNode::make(bt, ratio_idx, diff); _igvn.register_new_node_with_optimizer(add); set_ctrl(add, cl); - _igvn.replace_node( phi2, add ); + _igvn.replace_node(phi2, add); // Sometimes an induction variable is unused if (add->outcnt() == 0) { _igvn.remove_dead_node(add); --- old/src/share/vm/opto/mulnode.hpp 2016-02-12 16:44:37.581829325 +0100 +++ new/src/share/vm/opto/mulnode.hpp 2016-02-12 16:44:36.545503504 +0100 @@ -41,7 +41,7 @@ class MulNode : public Node { virtual uint hash() const; public: - MulNode( Node *in1, Node *in2 ): Node(0,in1,in2) { + MulNode(Node *in1, Node *in2): Node(0,in1,in2) { init_class_id(Class_Mul); } @@ -61,7 +61,7 @@ // This also type-checks the inputs for sanity. Guaranteed never to // be passed a TOP or BOTTOM type, these are filtered out by a pre-check. // This call recognizes the multiplicative zero type. - virtual const Type *mul_ring( const Type *, const Type * ) const = 0; + virtual const Type *mul_ring(const Type*, const Type*) const = 0; // Supplied function to return the multiplicative identity type virtual const Type *mul_id() const = 0; @@ -75,6 +75,7 @@ // Supplied function to return the multiplicative opcode virtual int mul_opcode() const = 0; + static MulNode* make(BasicType bt, Node *in1, Node *in2); }; //------------------------------MulINode--------------------------------------- --- old/src/share/vm/opto/mulnode.cpp 2016-02-12 16:44:37.724653038 +0100 +++ new/src/share/vm/opto/mulnode.cpp 2016-02-12 16:44:36.455821352 +0100 @@ -170,6 +170,16 @@ return mul_ring(t1,t2); // Local flavor of type multiplication } +MulNode* MulNode::make(BasicType bt, Node *in1, Node *in2) { + switch(bt) { + case T_INT: return new MulINode(in1, in2); + case T_LONG: return new MulLNode(in1, in2); + case T_FLOAT: return new MulFNode(in1, in2); + case T_DOUBLE: return new MulDNode(in1, in2); + } + fatal("Bad basic type %s", type2name(bt)); + return NULL; +} //============================================================================= //------------------------------Ideal------------------------------------------ --- old/src/share/vm/opto/addnode.cpp 2016-02-12 16:44:37.751123646 +0100 +++ new/src/share/vm/opto/addnode.cpp 2016-02-12 16:44:36.596496291 +0100 @@ -234,6 +234,16 @@ return NULL; } +AddNode* AddNode::make(BasicType bt, Node *in1, Node *in2) { + switch(bt) { + case T_INT: return new AddINode(in1, in2); + case T_LONG: return new AddLNode(in1, in2); + case T_FLOAT: return new AddFNode(in1, in2); + case T_DOUBLE: return new AddDNode(in1, in2); + } + fatal("Bad basic type %s", type2name(bt)); + return NULL; +} //============================================================================= //------------------------------Idealize--------------------------------------- --- old/src/share/vm/opto/addnode.hpp 2016-02-12 16:44:37.872895203 +0100 +++ new/src/share/vm/opto/addnode.hpp 2016-02-12 16:44:36.516162052 +0100 @@ -41,7 +41,7 @@ class AddNode : public Node { virtual uint hash() const; public: - AddNode( Node *in1, Node *in2 ) : Node(0,in1,in2) { + AddNode(Node *in1, Node *in2) : Node(0,in1,in2) { init_class_id(Class_Add); } @@ -58,16 +58,17 @@ virtual const Type* Value(PhaseGVN* phase) const; // Check if this addition involves the additive identity - virtual const Type *add_of_identity( const Type *t1, const Type *t2 ) const; + virtual const Type *add_of_identity(const Type *t1, const Type *t2) const; // Supplied function returns the sum of the inputs. // This also type-checks the inputs for sanity. Guaranteed never to // be passed a TOP or BOTTOM type, these are filtered out by a pre-check. - virtual const Type *add_ring( const Type *, const Type * ) const = 0; + virtual const Type *add_ring(const Type*, const Type*) const = 0; // Supplied function to return the additive identity type virtual const Type *add_id() const = 0; + static AddNode* make(BasicType bt, Node *in1, Node *in2); }; //------------------------------AddINode---------------------------------------