summaryrefslogtreecommitdiffstats
path: root/compiler/optimizing
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/optimizing')
-rw-r--r--compiler/optimizing/graph_checker.cc10
-rw-r--r--compiler/optimizing/graph_checker.h4
-rw-r--r--compiler/optimizing/inliner.cc5
-rw-r--r--compiler/optimizing/nodes.cc5
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