diff options
author | Nicolas Geoffray <ngeoffray@google.com> | 2014-12-02 11:51:19 +0000 |
---|---|---|
committer | Nicolas Geoffray <ngeoffray@google.com> | 2014-12-02 12:24:07 +0000 |
commit | f537012ceb6cba8a78b36a5065beb9588451a250 (patch) | |
tree | 08851014d687b0e08accfdc2f1553a89789b4fd4 /compiler | |
parent | 10a573a1f8708dbe2bcb7835341cbd8e9606af63 (diff) | |
download | art-f537012ceb6cba8a78b36a5065beb9588451a250.zip art-f537012ceb6cba8a78b36a5065beb9588451a250.tar.gz art-f537012ceb6cba8a78b36a5065beb9588451a250.tar.bz2 |
Treat SSA transformation special, as we may have to bailout.
We forgot to bailout when we found a non-natural loop (on which
our optimizations don't work).
Change-Id: I11976b5af4c98f4f29267a74c74d34b5ad81e20c
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/optimizing/find_loops_test.cc | 2 | ||||
-rw-r--r-- | compiler/optimizing/gvn_test.cc | 4 | ||||
-rw-r--r-- | compiler/optimizing/linearize_test.cc | 2 | ||||
-rw-r--r-- | compiler/optimizing/live_ranges_test.cc | 2 | ||||
-rw-r--r-- | compiler/optimizing/liveness_test.cc | 2 | ||||
-rw-r--r-- | compiler/optimizing/nodes.cc | 2 | ||||
-rw-r--r-- | compiler/optimizing/nodes.h | 8 | ||||
-rw-r--r-- | compiler/optimizing/optimizing_compiler.cc | 23 | ||||
-rw-r--r-- | compiler/optimizing/register_allocator_test.cc | 6 | ||||
-rw-r--r-- | compiler/optimizing/ssa_builder.h | 14 |
10 files changed, 35 insertions, 30 deletions
diff --git a/compiler/optimizing/find_loops_test.cc b/compiler/optimizing/find_loops_test.cc index c36b143..82fe03c 100644 --- a/compiler/optimizing/find_loops_test.cc +++ b/compiler/optimizing/find_loops_test.cc @@ -32,7 +32,7 @@ static HGraph* TestCode(const uint16_t* data, ArenaAllocator* allocator) { const DexFile::CodeItem* item = reinterpret_cast<const DexFile::CodeItem*>(data); HGraph* graph = builder.BuildGraph(*item); graph->BuildDominatorTree(); - graph->FindNaturalLoops(); + graph->AnalyzeNaturalLoops(); return graph; } diff --git a/compiler/optimizing/gvn_test.cc b/compiler/optimizing/gvn_test.cc index ad6e338..a6a68ca 100644 --- a/compiler/optimizing/gvn_test.cc +++ b/compiler/optimizing/gvn_test.cc @@ -175,7 +175,7 @@ TEST(GVNTest, LoopFieldElimination) { graph->BuildDominatorTree(); graph->TransformToSSA(); - graph->FindNaturalLoops(); + graph->AnalyzeNaturalLoops(); GlobalValueNumberer(&allocator, graph).Run(); // Check that all field get instructions are still there. @@ -239,7 +239,7 @@ TEST(GVNTest, LoopSideEffects) { graph->BuildDominatorTree(); graph->TransformToSSA(); - graph->FindNaturalLoops(); + graph->AnalyzeNaturalLoops(); ASSERT_TRUE(inner_loop_header->GetLoopInformation()->IsIn( *outer_loop_header->GetLoopInformation())); diff --git a/compiler/optimizing/linearize_test.cc b/compiler/optimizing/linearize_test.cc index c49cf7e..28ca5e8 100644 --- a/compiler/optimizing/linearize_test.cc +++ b/compiler/optimizing/linearize_test.cc @@ -44,7 +44,7 @@ static void TestCode(const uint16_t* data, const int* expected_order, size_t num graph->BuildDominatorTree(); graph->TransformToSSA(); - graph->FindNaturalLoops(); + graph->AnalyzeNaturalLoops(); x86::CodeGeneratorX86 codegen(graph); SsaLivenessAnalysis liveness(*graph, &codegen); diff --git a/compiler/optimizing/live_ranges_test.cc b/compiler/optimizing/live_ranges_test.cc index e3c6fec..5c7e6f0 100644 --- a/compiler/optimizing/live_ranges_test.cc +++ b/compiler/optimizing/live_ranges_test.cc @@ -38,7 +38,7 @@ static HGraph* BuildGraph(const uint16_t* data, ArenaAllocator* allocator) { RemoveSuspendChecks(graph); graph->BuildDominatorTree(); graph->TransformToSSA(); - graph->FindNaturalLoops(); + graph->AnalyzeNaturalLoops(); // `Inline` conditions into ifs. PrepareForRegisterAllocation(graph).Run(); return graph; diff --git a/compiler/optimizing/liveness_test.cc b/compiler/optimizing/liveness_test.cc index 246e7ef..4b69e57 100644 --- a/compiler/optimizing/liveness_test.cc +++ b/compiler/optimizing/liveness_test.cc @@ -50,7 +50,7 @@ static void TestCode(const uint16_t* data, const char* expected) { ASSERT_NE(graph, nullptr); graph->BuildDominatorTree(); graph->TransformToSSA(); - graph->FindNaturalLoops(); + graph->AnalyzeNaturalLoops(); // `Inline` conditions into ifs. PrepareForRegisterAllocation(graph).Run(); x86::CodeGeneratorX86 codegen(graph); diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc index 8cb2ef6..7584f1b 100644 --- a/compiler/optimizing/nodes.cc +++ b/compiler/optimizing/nodes.cc @@ -237,7 +237,7 @@ void HGraph::SimplifyCFG() { } } -bool HGraph::FindNaturalLoops() const { +bool HGraph::AnalyzeNaturalLoops() const { for (size_t i = 0; i < blocks_.Size(); ++i) { HBasicBlock* block = blocks_.Get(i); if (block->IsLoopHeader()) { diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 28496e4..9d0b4a9 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -112,10 +112,10 @@ class HGraph : public ArenaObject<kArenaAllocMisc> { void TransformToSSA(); void SimplifyCFG(); - // Find all natural loops in this graph. Aborts computation and returns false - // if one loop is not natural, that is the header does not dominate the back - // edge. - bool FindNaturalLoops() const; + // Analyze all natural loops in this graph. Returns false if one + // loop is not natural, that is the header does not dominate the + // back edge. + bool AnalyzeNaturalLoops() const; void SplitCriticalEdge(HBasicBlock* block, HBasicBlock* successor); void SimplifyLoop(HBasicBlock* header); diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc index 34485a3..6c9f3fc 100644 --- a/compiler/optimizing/optimizing_compiler.cc +++ b/compiler/optimizing/optimizing_compiler.cc @@ -192,7 +192,6 @@ static bool CanOptimize(const DexFile::CodeItem& code_item) { } static void RunOptimizations(HGraph* graph, const HGraphVisualizer& visualizer) { - TransformToSsa ssa(graph); HDeadCodeElimination opt1(graph); HConstantFolding opt2(graph); SsaRedundantPhiElimination opt3(graph); @@ -202,7 +201,6 @@ static void RunOptimizations(HGraph* graph, const HGraphVisualizer& visualizer) InstructionSimplifier opt7(graph); HOptimization* optimizations[] = { - &ssa, &opt1, &opt2, &opt3, @@ -220,6 +218,23 @@ static void RunOptimizations(HGraph* graph, const HGraphVisualizer& visualizer) } } +static bool TryBuildingSsa(HGraph* graph, + const DexCompilationUnit& dex_compilation_unit, + const HGraphVisualizer& visualizer) { + graph->BuildDominatorTree(); + graph->TransformToSSA(); + + if (!graph->AnalyzeNaturalLoops()) { + LOG(INFO) << "Skipping compilation of " + << PrettyMethod(dex_compilation_unit.GetDexMethodIndex(), + *dex_compilation_unit.GetDexFile()) + << ": it contains a non natural loop"; + return false; + } + visualizer.DumpGraph("ssa transform"); + return true; +} + CompiledMethod* OptimizingCompiler::Compile(const DexFile::CodeItem* code_item, uint32_t access_flags, InvokeType invoke_type, @@ -282,6 +297,10 @@ CompiledMethod* OptimizingCompiler::Compile(const DexFile::CodeItem* code_item, && CanOptimize(*code_item) && RegisterAllocator::CanAllocateRegistersFor(*graph, instruction_set)) { optimized_compiled_methods_++; + if (!TryBuildingSsa(graph, dex_compilation_unit, visualizer)) { + // We could not transform the graph to SSA, bailout. + return nullptr; + } RunOptimizations(graph, visualizer); PrepareForRegisterAllocation(graph).Run(); diff --git a/compiler/optimizing/register_allocator_test.cc b/compiler/optimizing/register_allocator_test.cc index ba4be34..8d75db9 100644 --- a/compiler/optimizing/register_allocator_test.cc +++ b/compiler/optimizing/register_allocator_test.cc @@ -41,7 +41,7 @@ static bool Check(const uint16_t* data) { HGraph* graph = builder.BuildGraph(*item); graph->BuildDominatorTree(); graph->TransformToSSA(); - graph->FindNaturalLoops(); + graph->AnalyzeNaturalLoops(); x86::CodeGeneratorX86 codegen(graph); SsaLivenessAnalysis liveness(*graph, &codegen); liveness.Analyze(); @@ -255,7 +255,7 @@ static HGraph* BuildSSAGraph(const uint16_t* data, ArenaAllocator* allocator) { HGraph* graph = builder.BuildGraph(*item); graph->BuildDominatorTree(); graph->TransformToSSA(); - graph->FindNaturalLoops(); + graph->AnalyzeNaturalLoops(); return graph; } @@ -494,7 +494,7 @@ static HGraph* BuildIfElseWithPhi(ArenaAllocator* allocator, (*phi)->AddInput(*input2); graph->BuildDominatorTree(); - graph->FindNaturalLoops(); + graph->AnalyzeNaturalLoops(); return graph; } diff --git a/compiler/optimizing/ssa_builder.h b/compiler/optimizing/ssa_builder.h index 5ab328f..2cbd51a 100644 --- a/compiler/optimizing/ssa_builder.h +++ b/compiler/optimizing/ssa_builder.h @@ -22,20 +22,6 @@ namespace art { -class TransformToSsa : public HOptimization { - public: - explicit TransformToSsa(HGraph* graph) : HOptimization(graph, true, "ssa transform") {} - - void Run() OVERRIDE { - graph_->BuildDominatorTree(); - graph_->TransformToSSA(); - graph_->FindNaturalLoops(); - } - - private: - DISALLOW_COPY_AND_ASSIGN(TransformToSsa); -}; - static constexpr int kDefaultNumberOfLoops = 2; class SsaBuilder : public HGraphVisitor { |