diff options
author | xueliang.zhong <xueliang.zhong@linaro.org> | 2017-09-19 17:43:29 +0100 |
---|---|---|
committer | Mingyao Yang <mingyao@google.com> | 2017-11-09 15:48:04 -0800 |
commit | b50b16a68ababbc9acab6102bf0bb63bd5083763 (patch) | |
tree | f440f12f8ab3b14b8c4b02c978561f43356e61b0 /compiler/optimizing/load_store_analysis_test.cc | |
parent | 2202d56061941b4fecbdb018d84bcefb05b6c683 (diff) |
Support VecLoad and VecStore in LSA.
Test: test-art-host
Test: test-art-target
Test: load_store_analysis_test
Change-Id: I7d819061ec9ea12f86a926566c3845231fce6e26
Diffstat (limited to 'compiler/optimizing/load_store_analysis_test.cc')
-rw-r--r-- | compiler/optimizing/load_store_analysis_test.cc | 272 |
1 files changed, 238 insertions, 34 deletions
diff --git a/compiler/optimizing/load_store_analysis_test.cc b/compiler/optimizing/load_store_analysis_test.cc index b41e1e4d00..56361a8c90 100644 --- a/compiler/optimizing/load_store_analysis_test.cc +++ b/compiler/optimizing/load_store_analysis_test.cc @@ -78,11 +78,12 @@ TEST_F(LoadStoreAnalysisTest, ArrayHeapLocations) { // 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_F(LoadStoreAnalysisTest, FieldHeapLocations) { // 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 @@ TEST_F(LoadStoreAnalysisTest, ArrayIndexAliasingTest) { 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 @@ TEST_F(LoadStoreAnalysisTest, ArrayIndexCalculationOverflowTest) { 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 @@ TEST_F(LoadStoreAnalysisTest, TestHuntOriginalRef) { // 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); |