< prev index next >

src/hotspot/share/opto/addnode.cpp

Print this page

        

@@ -234,10 +234,44 @@
   return NULL;
 }
 
 
 //=============================================================================
+
+static Node* convert_add_to_muladd(PhaseGVN *phase, Node* in1, Node* in2) {
+  // Only convert to this type of node if backend supports and if vectorizer supports it as well.
+  // The reason vectorizer is also checked is because this transformation is explicitly done
+  // to make vectorizer analysis easier for forms where type transition happens during operation.
+  if (Matcher::match_rule_supported(Op_MulAddS2I) &&
+    Matcher::match_rule_supported(Op_MulAddVS2VI)) {
+    if (in1->Opcode() == Op_MulI && in2->Opcode() == Op_MulI) {
+      Node* mul_in1 = in1->in(1);
+      Node* mul_in2 = in1->in(2);
+      Node* mul_in3 = in2->in(1);
+      Node* mul_in4 = in2->in(2);
+
+      if (mul_in1->Opcode() == Op_LoadS &&
+        mul_in2->Opcode() == Op_LoadS &&
+        mul_in3->Opcode() == Op_LoadS &&
+        mul_in4->Opcode() == Op_LoadS) {
+        Node* adr1 = mul_in1->in(MemNode::Address);
+        Node* adr2 = mul_in2->in(MemNode::Address);
+        Node* adr3 = mul_in3->in(MemNode::Address);
+        Node* adr4 = mul_in4->in(MemNode::Address);
+
+        if (adr1->is_AddP() && adr2->is_AddP() && adr3->is_AddP() && adr4->is_AddP()) {
+          if ((adr1->in(AddPNode::Base) == adr3->in(AddPNode::Base)) &&
+            (adr2->in(AddPNode::Base) == adr4->in(AddPNode::Base))) {
+            return new MulAddS2INode(mul_in1, mul_in2, mul_in3, mul_in4);
+          }
+        }
+      }
+    }
+  }
+  return NULL;
+}
+
 //------------------------------Idealize---------------------------------------
 Node *AddINode::Ideal(PhaseGVN *phase, bool can_reshape) {
   Node* in1 = in(1);
   Node* in2 = in(2);
   int op1 = in1->Opcode();

@@ -318,10 +352,15 @@
         return new URShiftINode( a, in1->in(2) );
       }
     }
   }
 
+  Node* muladd = convert_add_to_muladd(phase, in1, in2);
+  if (muladd != NULL) {
+    return muladd;
+  }
+
   return AddNode::Ideal(phase, can_reshape);
 }
 
 
 //------------------------------Identity---------------------------------------
< prev index next >