diff options
author | Nicolas Geoffray <ngeoffray@google.com> | 2014-12-17 10:13:46 +0000 |
---|---|---|
committer | Nicolas Geoffray <ngeoffray@google.com> | 2014-12-17 14:11:29 +0000 |
commit | 7c5367badfe61b96c5836d495d286cee64861579 (patch) | |
tree | 0468316d467302abc1f9feae3af8e64c2877610b /compiler/optimizing | |
parent | 240016da1d6615b26c8342bdeb4bae381570ac47 (diff) | |
download | art-7c5367badfe61b96c5836d495d286cee64861579.tar.gz art-7c5367badfe61b96c5836d495d286cee64861579.tar.bz2 art-7c5367badfe61b96c5836d495d286cee64861579.zip |
Fix ids and remove invoke when inlining.
Bugs found by Razvan Lupusoru.
Change-Id: I3a5a9af280d8700d18f52abb4a2cff0e3a9aac74
Diffstat (limited to 'compiler/optimizing')
-rw-r--r-- | compiler/optimizing/graph_checker.cc | 10 | ||||
-rw-r--r-- | compiler/optimizing/graph_checker.h | 4 | ||||
-rw-r--r-- | compiler/optimizing/inliner.cc | 5 | ||||
-rw-r--r-- | compiler/optimizing/nodes.cc | 5 |
4 files changed, 21 insertions, 3 deletions
diff --git a/compiler/optimizing/graph_checker.cc b/compiler/optimizing/graph_checker.cc index 5d712feb2b..e55175faec 100644 --- a/compiler/optimizing/graph_checker.cc +++ b/compiler/optimizing/graph_checker.cc @@ -16,9 +16,9 @@ #include "graph_checker.h" -#include <string> #include <map> #include <sstream> +#include <string> #include "base/bit_vector-inl.h" @@ -123,6 +123,14 @@ void GraphChecker::VisitBasicBlock(HBasicBlock* block) { } void GraphChecker::VisitInstruction(HInstruction* instruction) { + if (seen_ids_.IsBitSet(instruction->GetId())) { + std::stringstream error; + error << "Duplicate id in graph " << instruction->GetId() << "."; + errors_.push_back(error.str()); + } else { + seen_ids_.SetBit(instruction->GetId()); + } + // Ensure `instruction` is associated with `current_block_`. if (instruction->GetBlock() != current_block_) { std::stringstream error; diff --git a/compiler/optimizing/graph_checker.h b/compiler/optimizing/graph_checker.h index b6c9f1720c..ba60cb99c6 100644 --- a/compiler/optimizing/graph_checker.h +++ b/compiler/optimizing/graph_checker.h @@ -30,7 +30,8 @@ class GraphChecker : public HGraphDelegateVisitor { const char* dump_prefix = "art::GraphChecker: ") : HGraphDelegateVisitor(graph), allocator_(allocator), - dump_prefix_(dump_prefix) {} + dump_prefix_(dump_prefix), + seen_ids_(allocator, graph->GetCurrentInstructionId(), false) {} // Check the whole graph (in insertion order). virtual void Run() { VisitInsertionOrder(); } @@ -68,6 +69,7 @@ class GraphChecker : public HGraphDelegateVisitor { private: // String displayed before dumped errors. const char* const dump_prefix_; + ArenaBitVector seen_ids_; DISALLOW_COPY_AND_ASSIGN(GraphChecker); }; diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc index 1de5b78121..73eb521ea6 100644 --- a/compiler/optimizing/inliner.cc +++ b/compiler/optimizing/inliner.cc @@ -200,6 +200,11 @@ bool HInliner::TryInline(HInvoke* invoke_instruction, } callee_graph->InlineInto(graph_, invoke_instruction); + + // Now that we have inlined the callee, we need to update the next + // instruction id of the caller, so that new instructions added + // after optimizations get a unique id. + graph_->SetCurrentInstructionId(callee_graph->GetNextInstructionId()); VLOG(compiler) << "Successfully inlined " << PrettyMethod(method_index, outer_dex_file); outer_stats_->RecordStat(kInlinedInvoke); return true; diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc index fb941b542f..4133cf676f 100644 --- a/compiler/optimizing/nodes.cc +++ b/compiler/optimizing/nodes.cc @@ -750,13 +750,16 @@ void HGraph::InlineInto(HGraph* outer_graph, HInvoke* invoke) { } } - // Finally, replace the invoke with the return value of the inlined graph. + // Replace the invoke with the return value of the inlined graph. if (last->IsReturn()) { invoke->ReplaceWith(last->InputAt(0)); body->RemoveInstruction(last); } else { DCHECK(last->IsReturnVoid()); } + + // Finally remove the invoke from the caller. + invoke->GetBlock()->RemoveInstruction(invoke); } } // namespace art |