@@ -280,8 +280,26 @@ Node* AddNode::IdealIL(PhaseGVN* phase, bool can_reshape, BasicType bt) {
280280 assert ( in1->in (2 ) != this && in2->in (2 ) != this ,
281281 " dead loop in AddINode::Ideal" );
282282 Node* sub = SubNode::make (nullptr , nullptr , bt);
283- sub->init_req (1 , phase->transform (AddNode::make (in1->in (1 ), in2->in (1 ), bt)));
284- sub->init_req (2 , phase->transform (AddNode::make (in1->in (2 ), in2->in (2 ), bt)));
283+ Node* sub_in1;
284+ PhaseIterGVN* igvn = phase->is_IterGVN ();
285+ // During IGVN, if both inputs of the new AddNode are a tree of SubNodes, this same transformation will be applied
286+ // to every node of the tree. Calling transform() causes the transformation to be applied recursively, once per
287+ // tree node whether some subtrees are identical or not. Pushing to the IGVN worklist instead, causes the transform
288+ // to be applied once per unique subtrees (because all uses of a subtree are updated with the result of the
289+ // transformation). In case of a large tree, this can make a difference in compilation time.
290+ if (igvn != nullptr ) {
291+ sub_in1 = igvn->register_new_node_with_optimizer (AddNode::make (in1->in (1 ), in2->in (1 ), bt));
292+ } else {
293+ sub_in1 = phase->transform (AddNode::make (in1->in (1 ), in2->in (1 ), bt));
294+ }
295+ Node* sub_in2;
296+ if (igvn != nullptr ) {
297+ sub_in2 = igvn->register_new_node_with_optimizer (AddNode::make (in1->in (2 ), in2->in (2 ), bt));
298+ } else {
299+ sub_in2 = phase->transform (AddNode::make (in1->in (2 ), in2->in (2 ), bt));
300+ }
301+ sub->init_req (1 , sub_in1);
302+ sub->init_req (2 , sub_in2);
285303 return sub;
286304 }
287305 // Convert "(a-b)+(b+c)" into "(a+c)"
0 commit comments