// Return all combinations of ISA and code generator that are executable on // hardware, or on simulator, and that we'd like to test. static ::std::vector<CodegenTargetConfig> GetTargetConfigs() {
::std::vector<CodegenTargetConfig> v;
::std::vector<CodegenTargetConfig> test_config_candidates = { #ifdef ART_ENABLE_CODEGEN_arm // TODO: Should't this be `kThumb2` instead of `kArm` here?
CodegenTargetConfig(InstructionSet::kArm, create_codegen_arm_vixl32), #endif #ifdef ART_ENABLE_CODEGEN_arm64
CodegenTargetConfig(InstructionSet::kArm64, create_codegen_arm64), #endif #ifdef ART_ENABLE_CODEGEN_x86
CodegenTargetConfig(InstructionSet::kX86, create_codegen_x86), #endif #ifdef ART_ENABLE_CODEGEN_x86_64
CodegenTargetConfig(InstructionSet::kX86_64, create_codegen_x86_64), #endif
};
for (const CodegenTargetConfig& test_config : test_config_candidates) { if (CanExecuteISA(test_config.GetInstructionSet())) {
v.push_back(test_config);
}
}
return v;
}
class SchedulerTest : public CommonCompilerTest, public OptimizingUnitTestHelper { public:
SchedulerTest() : graph_(CreateGraph()) { }
// Build scheduling graph, and run target specific scheduling on it. void TestBuildDependencyGraphAndSchedule(HScheduler* scheduler) {
HBasicBlock* entry = AddNewBlock();
HBasicBlock* block1 = AddNewBlock();
graph_->SetEntryBlock(entry);
TestSchedulingGraph scheduling_graph(GetScopedAllocator()); // Instructions must be inserted in reverse order into the scheduling graph. for (HBackwardInstructionIteratorPrefetchNext it(block1->GetInstructions()); !it.Done();
it.Advance()) {
scheduling_graph.AddNode(it.Current());
}
// Should not have dependencies cross basic blocks.
ASSERT_FALSE(scheduling_graph.HasImmediateDataDependency(add1, c1));
ASSERT_FALSE(scheduling_graph.HasImmediateDataDependency(add2, c2));
// Read and write dependencies
ASSERT_TRUE(scheduling_graph.HasImmediateOtherDependency(array_set1, array_get1));
ASSERT_TRUE(scheduling_graph.HasImmediateOtherDependency(array_set2, array_get2));
ASSERT_TRUE(scheduling_graph.HasImmediateOtherDependency(array_get2, array_set1)); // Unnecessary dependency is not stored, we rely on transitive dependencies. // The array_set2 -> array_get2 -> array_set1 dependencies are tested above.
ASSERT_FALSE(scheduling_graph.HasImmediateOtherDependency(array_set2, array_set1));
for (HBackwardInstructionIteratorPrefetchNext it(block1->GetInstructions()); !it.Done();
it.Advance()) { // Build scheduling graph with memory access aliasing information // from LSA/heap_location_collector.
scheduling_graph.AddNode(it.Current());
}
// LSA/HeapLocationCollector should see those ArraySet instructions.
ASSERT_EQ(heap_location_collector.GetNumberOfHeapLocations(), 9U);
ASSERT_TRUE(heap_location_collector.HasHeapStores());
// Test queries on HeapLocationCollector's aliasing matrix after load store analysis. // HeapLocationCollector and SchedulingGraph should report consistent relationships.
size_t loc1 = HeapLocationCollector::kHeapLocationNotFound;
size_t loc2 = HeapLocationCollector::kHeapLocationNotFound;
// Test side effect dependency: array[0] and array[1]
loc1 = heap_location_collector.GetArrayHeapLocation(arr_set_0);
loc2 = heap_location_collector.GetArrayHeapLocation(arr_set_1);
ASSERT_FALSE(heap_location_collector.MayAlias(loc1, loc2));
ASSERT_FALSE(scheduling_graph.HasImmediateOtherDependency(arr_set_1, arr_set_0));
// Test side effect dependency based on LSA analysis: array[i] and array[j]
loc1 = heap_location_collector.GetArrayHeapLocation(arr_set_i);
loc2 = heap_location_collector.GetArrayHeapLocation(arr_set_j);
ASSERT_TRUE(heap_location_collector.MayAlias(loc1, loc2)); // Unnecessary dependency is not stored, we rely on transitive dependencies. // The arr_set_j -> arr_set_sub0 -> arr_set_add0 -> arr_set_i dependencies are tested below.
ASSERT_FALSE(scheduling_graph.HasImmediateOtherDependency(arr_set_j, arr_set_i));
// Test side effect dependency based on LSA analysis: array[i] and array[i+0]
loc1 = heap_location_collector.GetArrayHeapLocation(arr_set_i);
loc2 = heap_location_collector.GetArrayHeapLocation(arr_set_add0);
ASSERT_TRUE(heap_location_collector.MayAlias(loc1, loc2));
ASSERT_TRUE(scheduling_graph.HasImmediateOtherDependency(arr_set_add0, arr_set_i));
// Test side effect dependency based on LSA analysis: array[i] and array[i-0]
loc1 = heap_location_collector.GetArrayHeapLocation(arr_set_i);
loc2 = heap_location_collector.GetArrayHeapLocation(arr_set_sub0);
ASSERT_TRUE(heap_location_collector.MayAlias(loc1, loc2)); // Unnecessary dependency is not stored, we rely on transitive dependencies.
ASSERT_FALSE(scheduling_graph.HasImmediateOtherDependency(arr_set_sub0, arr_set_i)); // Instead, we rely on arr_set_sub0 -> arr_set_add0 -> arr_set_i, the latter is tested above.
ASSERT_TRUE(scheduling_graph.HasImmediateOtherDependency(arr_set_sub0, arr_set_add0));
// Test side effect dependency based on LSA analysis: array[i] and array[i+1]
loc1 = heap_location_collector.GetArrayHeapLocation(arr_set_i);
loc2 = heap_location_collector.GetArrayHeapLocation(arr_set_add1);
ASSERT_FALSE(heap_location_collector.MayAlias(loc1, loc2));
ASSERT_FALSE(scheduling_graph.HasImmediateOtherDependency(arr_set_add1, arr_set_i));
// Test side effect dependency based on LSA analysis: array[i+1] and array[i-1]
loc1 = heap_location_collector.GetArrayHeapLocation(arr_set_add1);
loc2 = heap_location_collector.GetArrayHeapLocation(arr_set_sub1);
ASSERT_FALSE(heap_location_collector.MayAlias(loc1, loc2));
ASSERT_FALSE(scheduling_graph.HasImmediateOtherDependency(arr_set_sub1, arr_set_add1));
// Test side effect dependency based on LSA analysis: array[j] and all others array accesses
ASSERT_TRUE(scheduling_graph.HasImmediateOtherDependency(arr_set_j, arr_set_sub0));
ASSERT_TRUE(scheduling_graph.HasImmediateOtherDependency(arr_set_j, arr_set_add1));
ASSERT_TRUE(scheduling_graph.HasImmediateOtherDependency(arr_set_j, arr_set_sub1)); // Unnecessary dependencies are not stored, we rely on transitive dependencies.
ASSERT_FALSE(scheduling_graph.HasImmediateOtherDependency(arr_set_j, arr_set_i));
ASSERT_FALSE(scheduling_graph.HasImmediateOtherDependency(arr_set_j, arr_set_add0));
// Test that ArraySet and FieldSet should not have side effect dependency
ASSERT_FALSE(scheduling_graph.HasImmediateOtherDependency(arr_set_i, set_field10));
ASSERT_FALSE(scheduling_graph.HasImmediateOtherDependency(arr_set_j, set_field10));
// Exercise target specific scheduler and SchedulingLatencyVisitor.
scheduler->Schedule(graph_);
}
class TestSchedulingGraph : public SchedulingGraph { public: explicit TestSchedulingGraph(ScopedArenaAllocator* allocator, const HeapLocationCollector *heap_location_collector = nullptr)
: SchedulingGraph(allocator, heap_location_collector) {}
bool HasImmediateDataDependency(const HInstruction* instruction, const HInstruction* other_instruction) const { const SchedulingNode* node = GetNode(instruction); const SchedulingNode* other = GetNode(other_instruction); if (node == nullptr || other == nullptr) { // Both instructions must be in current basic block, i.e. the SchedulingGraph can see their // corresponding SchedulingNode in the graph, and tell whether there is a dependency. // Otherwise there is no dependency from SchedulingGraph's perspective, for example, // instruction and other_instruction are in different basic blocks. returnfalse;
} return node->HasDataDependency(other);
}
bool HasImmediateOtherDependency(const HInstruction* instruction, const HInstruction* other_instruction) const { const SchedulingNode* node = GetNode(instruction); const SchedulingNode* other = GetNode(other_instruction); if (node == nullptr || other == nullptr) { // Both instructions must be in current basic block, i.e. the SchedulingGraph can see their // corresponding SchedulingNode in the graph, and tell whether there is a dependency. // Otherwise there is no dependency from SchedulingGraph's perspective, for example, // instruction and other_instruction are in different basic blocks. returnfalse;
} return node->HasOtherDependency(other);
}
};
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.