Support VecLoad and VecStore in LSA.

Test: test-art-host
Test: test-art-target
Test: load_store_analysis_test

Change-Id: I7d819061ec9ea12f86a926566c3845231fce6e26
diff --git a/compiler/optimizing/load_store_analysis_test.cc b/compiler/optimizing/load_store_analysis_test.cc
index b41e1e4..56361a8 100644
--- a/compiler/optimizing/load_store_analysis_test.cc
+++ b/compiler/optimizing/load_store_analysis_test.cc
@@ -78,11 +78,12 @@
 
   // Test queries on HeapLocationCollector's ref info and index records.
   ReferenceInfo* ref = heap_location_collector.FindReferenceInfoOf(array);
-  size_t field_off = HeapLocation::kInvalidFieldOffset;
+  size_t field = HeapLocation::kInvalidFieldOffset;
+  size_t vec = HeapLocation::kScalar;
   size_t class_def = HeapLocation::kDeclaringClassDefIndexForArrays;
-  size_t loc1 = heap_location_collector.FindHeapLocationIndex(ref, field_off, c1, class_def);
-  size_t loc2 = heap_location_collector.FindHeapLocationIndex(ref, field_off, c2, class_def);
-  size_t loc3 = heap_location_collector.FindHeapLocationIndex(ref, field_off, index, class_def);
+  size_t loc1 = heap_location_collector.FindHeapLocationIndex(ref, field, c1, vec, class_def);
+  size_t loc2 = heap_location_collector.FindHeapLocationIndex(ref, field, c2, vec, class_def);
+  size_t loc3 = heap_location_collector.FindHeapLocationIndex(ref, field, index, vec, class_def);
   // must find this reference info for array in HeapLocationCollector.
   ASSERT_TRUE(ref != nullptr);
   // must find these heap locations;
@@ -167,10 +168,8 @@
 
   // Test queries on HeapLocationCollector's ref info and index records.
   ReferenceInfo* ref = heap_location_collector.FindReferenceInfoOf(object);
-  size_t loc1 = heap_location_collector.FindHeapLocationIndex(
-      ref, 10, nullptr, kUnknownClassDefIndex);
-  size_t loc2 = heap_location_collector.FindHeapLocationIndex(
-      ref, 20, nullptr, kUnknownClassDefIndex);
+  size_t loc1 = heap_location_collector.GetFieldHeapLocation(object, &get_field10->GetFieldInfo());
+  size_t loc2 = heap_location_collector.GetFieldHeapLocation(object, &get_field20->GetFieldInfo());
   // must find references info for object and in HeapLocationCollector.
   ASSERT_TRUE(ref != nullptr);
   // must find these heap locations.
@@ -247,31 +246,236 @@
   size_t loc2 = HeapLocationCollector::kHeapLocationNotFound;
 
   // Test alias: array[0] and array[1]
-  loc1 = heap_location_collector.GetArrayAccessHeapLocation(array, c0);
-  loc2 = heap_location_collector.GetArrayAccessHeapLocation(array, c1);
+  loc1 = heap_location_collector.GetArrayHeapLocation(array, c0);
+  loc2 = heap_location_collector.GetArrayHeapLocation(array, c1);
   ASSERT_FALSE(heap_location_collector.MayAlias(loc1, loc2));
 
   // Test alias: array[i+0] and array[i-0]
-  loc1 = heap_location_collector.GetArrayAccessHeapLocation(array, add0);
-  loc2 = heap_location_collector.GetArrayAccessHeapLocation(array, sub0);
+  loc1 = heap_location_collector.GetArrayHeapLocation(array, add0);
+  loc2 = heap_location_collector.GetArrayHeapLocation(array, sub0);
   ASSERT_TRUE(heap_location_collector.MayAlias(loc1, loc2));
 
   // Test alias: array[i+1] and array[i-1]
-  loc1 = heap_location_collector.GetArrayAccessHeapLocation(array, add1);
-  loc2 = heap_location_collector.GetArrayAccessHeapLocation(array, sub1);
+  loc1 = heap_location_collector.GetArrayHeapLocation(array, add1);
+  loc2 = heap_location_collector.GetArrayHeapLocation(array, sub1);
   ASSERT_FALSE(heap_location_collector.MayAlias(loc1, loc2));
 
   // Test alias: array[i+1] and array[1-i]
-  loc1 = heap_location_collector.GetArrayAccessHeapLocation(array, add1);
-  loc2 = heap_location_collector.GetArrayAccessHeapLocation(array, rev_sub1);
+  loc1 = heap_location_collector.GetArrayHeapLocation(array, add1);
+  loc2 = heap_location_collector.GetArrayHeapLocation(array, rev_sub1);
   ASSERT_TRUE(heap_location_collector.MayAlias(loc1, loc2));
 
   // Test alias: array[i+1] and array[i-(-1)]
-  loc1 = heap_location_collector.GetArrayAccessHeapLocation(array, add1);
-  loc2 = heap_location_collector.GetArrayAccessHeapLocation(array, sub_neg1);
+  loc1 = heap_location_collector.GetArrayHeapLocation(array, add1);
+  loc2 = heap_location_collector.GetArrayHeapLocation(array, sub_neg1);
   ASSERT_TRUE(heap_location_collector.MayAlias(loc1, loc2));
 }
 
+TEST_F(LoadStoreAnalysisTest, ArrayAliasingTest) {
+  HBasicBlock* entry = new (GetAllocator()) HBasicBlock(graph_);
+  graph_->AddBlock(entry);
+  graph_->SetEntryBlock(entry);
+  graph_->BuildDominatorTree();
+
+  HInstruction* array = new (GetAllocator()) HParameterValue(
+      graph_->GetDexFile(), dex::TypeIndex(0), 0, DataType::Type::kReference);
+  HInstruction* index = new (GetAllocator()) HParameterValue(
+      graph_->GetDexFile(), dex::TypeIndex(1), 1, DataType::Type::kInt32);
+  HInstruction* c0 = graph_->GetIntConstant(0);
+  HInstruction* c1 = graph_->GetIntConstant(1);
+  HInstruction* c6 = graph_->GetIntConstant(6);
+  HInstruction* c8 = graph_->GetIntConstant(8);
+
+  HInstruction* arr_set_0 = new (GetAllocator()) HArraySet(array,
+                                                           c0,
+                                                           c0,
+                                                           DataType::Type::kInt32,
+                                                           0);
+  HInstruction* arr_set_1 = new (GetAllocator()) HArraySet(array,
+                                                           c1,
+                                                           c0,
+                                                           DataType::Type::kInt32,
+                                                           0);
+  HInstruction* arr_set_i = new (GetAllocator()) HArraySet(array,
+                                                           index,
+                                                           c0,
+                                                           DataType::Type::kInt32,
+                                                           0);
+
+  HVecOperation* v1 = new (GetAllocator()) HVecReplicateScalar(GetAllocator(),
+                                                               c1,
+                                                               DataType::Type::kInt32,
+                                                               4,
+                                                               kNoDexPc);
+  HVecOperation* v2 = new (GetAllocator()) HVecReplicateScalar(GetAllocator(),
+                                                               c1,
+                                                               DataType::Type::kInt32,
+                                                               2,
+                                                               kNoDexPc);
+  HInstruction* i_add6 = new (GetAllocator()) HAdd(DataType::Type::kInt32, index, c6);
+  HInstruction* i_add8 = new (GetAllocator()) HAdd(DataType::Type::kInt32, index, c8);
+
+  HInstruction* vstore_0 = new (GetAllocator()) HVecStore(
+      GetAllocator(),
+      array,
+      c0,
+      v1,
+      DataType::Type::kInt32,
+      SideEffects::ArrayWriteOfType(DataType::Type::kInt32),
+      4,
+      kNoDexPc);
+  HInstruction* vstore_1 = new (GetAllocator()) HVecStore(
+      GetAllocator(),
+      array,
+      c1,
+      v1,
+      DataType::Type::kInt32,
+      SideEffects::ArrayWriteOfType(DataType::Type::kInt32),
+      4,
+      kNoDexPc);
+  HInstruction* vstore_8 = new (GetAllocator()) HVecStore(
+      GetAllocator(),
+      array,
+      c8,
+      v1,
+      DataType::Type::kInt32,
+      SideEffects::ArrayWriteOfType(DataType::Type::kInt32),
+      4,
+      kNoDexPc);
+  HInstruction* vstore_i = new (GetAllocator()) HVecStore(
+      GetAllocator(),
+      array,
+      index,
+      v1,
+      DataType::Type::kInt32,
+      SideEffects::ArrayWriteOfType(DataType::Type::kInt32),
+      4,
+      kNoDexPc);
+  HInstruction* vstore_i_add6 = new (GetAllocator()) HVecStore(
+      GetAllocator(),
+      array,
+      i_add6,
+      v1,
+      DataType::Type::kInt32,
+      SideEffects::ArrayWriteOfType(DataType::Type::kInt32),
+      4,
+      kNoDexPc);
+  HInstruction* vstore_i_add8 = new (GetAllocator()) HVecStore(
+      GetAllocator(),
+      array,
+      i_add8,
+      v1,
+      DataType::Type::kInt32,
+      SideEffects::ArrayWriteOfType(DataType::Type::kInt32),
+      4,
+      kNoDexPc);
+  HInstruction* vstore_i_add6_vlen2 = new (GetAllocator()) HVecStore(
+      GetAllocator(),
+      array,
+      i_add6,
+      v2,
+      DataType::Type::kInt32,
+      SideEffects::ArrayWriteOfType(DataType::Type::kInt32),
+      2,
+      kNoDexPc);
+
+  entry->AddInstruction(array);
+  entry->AddInstruction(index);
+
+  entry->AddInstruction(arr_set_0);
+  entry->AddInstruction(arr_set_1);
+  entry->AddInstruction(arr_set_i);
+  entry->AddInstruction(v1);
+  entry->AddInstruction(v2);
+  entry->AddInstruction(i_add6);
+  entry->AddInstruction(i_add8);
+  entry->AddInstruction(vstore_0);
+  entry->AddInstruction(vstore_1);
+  entry->AddInstruction(vstore_8);
+  entry->AddInstruction(vstore_i);
+  entry->AddInstruction(vstore_i_add6);
+  entry->AddInstruction(vstore_i_add8);
+  entry->AddInstruction(vstore_i_add6_vlen2);
+
+  LoadStoreAnalysis lsa(graph_);
+  lsa.Run();
+  const HeapLocationCollector& heap_location_collector = lsa.GetHeapLocationCollector();
+
+  // LSA/HeapLocationCollector should see those instructions.
+  ASSERT_EQ(heap_location_collector.GetNumberOfHeapLocations(), 10U);
+  ASSERT_TRUE(heap_location_collector.HasHeapStores());
+
+  // Test queries on HeapLocationCollector's aliasing matrix after load store analysis.
+  size_t loc1, loc2;
+
+  // Test alias: array[0] and array[0,1,2,3]
+  loc1 = heap_location_collector.GetArrayHeapLocation(array, c0);
+  loc2 = heap_location_collector.GetArrayHeapLocation(array, c0, 4);
+  ASSERT_TRUE(heap_location_collector.MayAlias(loc1, loc2));
+
+  // Test alias: array[0] and array[8,9,10,11]
+  loc1 = heap_location_collector.GetArrayHeapLocation(array, c0);
+  loc2 = heap_location_collector.GetArrayHeapLocation(array, c8, 4);
+  ASSERT_FALSE(heap_location_collector.MayAlias(loc1, loc2));
+
+  // Test alias: array[1] and array[8,9,10,11]
+  loc1 = heap_location_collector.GetArrayHeapLocation(array, c1);
+  loc2 = heap_location_collector.GetArrayHeapLocation(array, c8, 4);
+  ASSERT_FALSE(heap_location_collector.MayAlias(loc1, loc2));
+
+  // Test alias: array[1] and array[0,1,2,3]
+  loc1 = heap_location_collector.GetArrayHeapLocation(array, c1);
+  loc2 = heap_location_collector.GetArrayHeapLocation(array, c0, 4);
+  ASSERT_TRUE(heap_location_collector.MayAlias(loc1, loc2));
+
+  // Test alias: array[0,1,2,3] and array[8,9,10,11]
+  loc1 = heap_location_collector.GetArrayHeapLocation(array, c0, 4);
+  loc2 = heap_location_collector.GetArrayHeapLocation(array, c8, 4);
+  ASSERT_FALSE(heap_location_collector.MayAlias(loc1, loc2));
+
+  // Test alias: array[0,1,2,3] and array[1,2,3,4]
+  loc1 = heap_location_collector.GetArrayHeapLocation(array, c1, 4);
+  loc2 = heap_location_collector.GetArrayHeapLocation(array, c0, 4);
+  ASSERT_TRUE(heap_location_collector.MayAlias(loc1, loc2));
+
+  // Test alias: array[0] and array[i,i+1,i+2,i+3]
+  loc1 = heap_location_collector.GetArrayHeapLocation(array, c0);
+  loc2 = heap_location_collector.GetArrayHeapLocation(array, index, 4);
+  ASSERT_TRUE(heap_location_collector.MayAlias(loc1, loc2));
+
+  // Test alias: array[i] and array[0,1,2,3]
+  loc1 = heap_location_collector.GetArrayHeapLocation(array, index);
+  loc2 = heap_location_collector.GetArrayHeapLocation(array, c0, 4);
+  ASSERT_TRUE(heap_location_collector.MayAlias(loc1, loc2));
+
+  // Test alias: array[i] and array[i,i+1,i+2,i+3]
+  loc1 = heap_location_collector.GetArrayHeapLocation(array, index);
+  loc2 = heap_location_collector.GetArrayHeapLocation(array, index, 4);
+  ASSERT_TRUE(heap_location_collector.MayAlias(loc1, loc2));
+
+  // Test alias: array[i] and array[i+8,i+9,i+10,i+11]
+  loc1 = heap_location_collector.GetArrayHeapLocation(array, index);
+  loc2 = heap_location_collector.GetArrayHeapLocation(array, i_add8, 4);
+  ASSERT_FALSE(heap_location_collector.MayAlias(loc1, loc2));
+
+  // Test alias: array[i+6,i+7,i+8,i+9] and array[i+8,i+9,i+10,i+11]
+  // Test partial overlap.
+  loc1 = heap_location_collector.GetArrayHeapLocation(array, i_add6, 4);
+  loc2 = heap_location_collector.GetArrayHeapLocation(array, i_add8, 4);
+  ASSERT_TRUE(heap_location_collector.MayAlias(loc1, loc2));
+
+  // Test alias: array[i+6,i+7] and array[i,i+1,i+2,i+3]
+  // Test different vector lengths.
+  loc1 = heap_location_collector.GetArrayHeapLocation(array, i_add6, 2);
+  loc2 = heap_location_collector.GetArrayHeapLocation(array, index, 4);
+  ASSERT_FALSE(heap_location_collector.MayAlias(loc1, loc2));
+
+  // Test alias: array[i+6,i+7] and array[i+8,i+9,i+10,i+11]
+  loc1 = heap_location_collector.GetArrayHeapLocation(array, i_add6, 2);
+  loc2 = heap_location_collector.GetArrayHeapLocation(array, i_add8, 4);
+  ASSERT_FALSE(heap_location_collector.MayAlias(loc1, loc2));
+}
+
 TEST_F(LoadStoreAnalysisTest, ArrayIndexCalculationOverflowTest) {
   HBasicBlock* entry = new (GetAllocator()) HBasicBlock(graph_);
   graph_->AddBlock(entry);
@@ -359,33 +563,33 @@
   size_t loc2 = HeapLocationCollector::kHeapLocationNotFound;
 
   // Test alias: array[i+0x80000000] and array[i-0x80000000]
-  loc1 = heap_location_collector.GetArrayAccessHeapLocation(array, add_0x80000000);
-  loc2 = heap_location_collector.GetArrayAccessHeapLocation(array, sub_0x80000000);
+  loc1 = heap_location_collector.GetArrayHeapLocation(array, add_0x80000000);
+  loc2 = heap_location_collector.GetArrayHeapLocation(array, sub_0x80000000);
   ASSERT_TRUE(heap_location_collector.MayAlias(loc1, loc2));
 
   // Test alias: array[i+0x10] and array[i-0xFFFFFFF0]
-  loc1 = heap_location_collector.GetArrayAccessHeapLocation(array, add_0x10);
-  loc2 = heap_location_collector.GetArrayAccessHeapLocation(array, sub_0xFFFFFFF0);
+  loc1 = heap_location_collector.GetArrayHeapLocation(array, add_0x10);
+  loc2 = heap_location_collector.GetArrayHeapLocation(array, sub_0xFFFFFFF0);
   ASSERT_TRUE(heap_location_collector.MayAlias(loc1, loc2));
 
   // Test alias: array[i+0x7FFFFFFF] and array[i-0x80000001]
-  loc1 = heap_location_collector.GetArrayAccessHeapLocation(array, add_0x7FFFFFFF);
-  loc2 = heap_location_collector.GetArrayAccessHeapLocation(array, sub_0x80000001);
+  loc1 = heap_location_collector.GetArrayHeapLocation(array, add_0x7FFFFFFF);
+  loc2 = heap_location_collector.GetArrayHeapLocation(array, sub_0x80000001);
   ASSERT_TRUE(heap_location_collector.MayAlias(loc1, loc2));
 
   // Test alias: array[i+0] and array[i-0]
-  loc1 = heap_location_collector.GetArrayAccessHeapLocation(array, add_0);
-  loc2 = heap_location_collector.GetArrayAccessHeapLocation(array, sub_0);
+  loc1 = heap_location_collector.GetArrayHeapLocation(array, add_0);
+  loc2 = heap_location_collector.GetArrayHeapLocation(array, sub_0);
   ASSERT_TRUE(heap_location_collector.MayAlias(loc1, loc2));
 
   // Should not alias:
-  loc1 = heap_location_collector.GetArrayAccessHeapLocation(array, sub_0x80000000);
-  loc2 = heap_location_collector.GetArrayAccessHeapLocation(array, sub_0x80000001);
+  loc1 = heap_location_collector.GetArrayHeapLocation(array, sub_0x80000000);
+  loc2 = heap_location_collector.GetArrayHeapLocation(array, sub_0x80000001);
   ASSERT_FALSE(heap_location_collector.MayAlias(loc1, loc2));
 
   // Should not alias:
-  loc1 = heap_location_collector.GetArrayAccessHeapLocation(array, add_0);
-  loc2 = heap_location_collector.GetArrayAccessHeapLocation(array, sub_0x80000000);
+  loc1 = heap_location_collector.GetArrayHeapLocation(array, add_0);
+  loc2 = heap_location_collector.GetArrayHeapLocation(array, sub_0x80000000);
   ASSERT_FALSE(heap_location_collector.MayAlias(loc1, loc2));
 }
 
@@ -443,10 +647,10 @@
   // times the original reference has been transformed by BoundType,
   // NullCheck, IntermediateAddress, etc.
   ASSERT_EQ(heap_location_collector.GetNumberOfHeapLocations(), 1U);
-  size_t loc1 = heap_location_collector.GetArrayAccessHeapLocation(array, c1);
-  size_t loc2 = heap_location_collector.GetArrayAccessHeapLocation(bound_type, c1);
-  size_t loc3 = heap_location_collector.GetArrayAccessHeapLocation(null_check, c1);
-  size_t loc4 = heap_location_collector.GetArrayAccessHeapLocation(inter_addr, c1);
+  size_t loc1 = heap_location_collector.GetArrayHeapLocation(array, c1);
+  size_t loc2 = heap_location_collector.GetArrayHeapLocation(bound_type, c1);
+  size_t loc3 = heap_location_collector.GetArrayHeapLocation(null_check, c1);
+  size_t loc4 = heap_location_collector.GetArrayHeapLocation(inter_addr, c1);
   ASSERT_TRUE(loc1 != HeapLocationCollector::kHeapLocationNotFound);
   ASSERT_EQ(loc1, loc2);
   ASSERT_EQ(loc1, loc3);