Allow nested inlining.
Also run optimizations before iterating over
the instructions to get rid of, e.g., null checks.
Change-Id: I6e52e61ce4d0ccb63d687afea09bb4722453bb6a
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc
index 532167c..513be7d 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -36,23 +36,26 @@
static constexpr int kMaxInlineCodeUnits = 100;
static constexpr int kMaxInlineNumberOfBlocks = 3;
+static constexpr int kDepthLimit = 5;
void HInliner::Run() {
- for (HReversePostOrderIterator it(*graph_); !it.Done(); it.Advance()) {
- for (HInstructionIterator instr_it(it.Current()->GetInstructions());
- !instr_it.Done();
- instr_it.Advance()) {
- HInvokeStaticOrDirect* current = instr_it.Current()->AsInvokeStaticOrDirect();
- if (current != nullptr) {
- if (!TryInline(current, current->GetDexMethodIndex(), current->GetInvokeType())) {
+ const GrowableArray<HBasicBlock*>& blocks = graph_->GetReversePostOrder();
+ for (size_t i = 0; i < blocks.Size(); ++i) {
+ HBasicBlock* block = blocks.Get(i);
+ for (HInstruction* instruction = block->GetFirstInstruction(); instruction != nullptr;) {
+ HInstruction* next = instruction->GetNext();
+ HInvokeStaticOrDirect* call = instruction->AsInvokeStaticOrDirect();
+ if (call != nullptr) {
+ if (!TryInline(call, call->GetDexMethodIndex(), call->GetInvokeType())) {
if (kIsDebugBuild) {
std::string callee_name =
- PrettyMethod(current->GetDexMethodIndex(), *outer_compilation_unit_.GetDexFile());
+ PrettyMethod(call->GetDexMethodIndex(), *outer_compilation_unit_.GetDexFile());
bool should_inline = callee_name.find("$inline$") != std::string::npos;
CHECK(!should_inline) << "Could not inline " << callee_name;
}
}
}
+ instruction = next;
}
}
}
@@ -157,8 +160,34 @@
return false;
}
+ // Run simple optimizations on the graph.
+ SsaRedundantPhiElimination redundant_phi(callee_graph);
+ SsaDeadPhiElimination dead_phi(callee_graph);
+ HDeadCodeElimination dce(callee_graph);
+ HConstantFolding fold(callee_graph);
+ InstructionSimplifier simplify(callee_graph);
+
+ HOptimization* optimizations[] = {
+ &redundant_phi,
+ &dead_phi,
+ &dce,
+ &fold,
+ &simplify,
+ };
+
+ for (size_t i = 0; i < arraysize(optimizations); ++i) {
+ HOptimization* optimization = optimizations[i];
+ optimization->Run();
+ }
+
+ if (depth_ + 1 < kDepthLimit) {
+ HInliner inliner(
+ callee_graph, outer_compilation_unit_, compiler_driver_, outer_stats_, depth_ + 1);
+ inliner.Run();
+ }
+
HReversePostOrderIterator it(*callee_graph);
- it.Advance(); // Past the entry block to avoid seeing the suspend check.
+ it.Advance(); // Past the entry block, it does not contain instructions that prevent inlining.
for (; !it.Done(); it.Advance()) {
HBasicBlock* block = it.Current();
if (block->IsLoopHeader()) {
@@ -187,26 +216,6 @@
}
}
- // Run simple optimizations on the graph.
- SsaRedundantPhiElimination redundant_phi(callee_graph);
- SsaDeadPhiElimination dead_phi(callee_graph);
- HDeadCodeElimination dce(callee_graph);
- HConstantFolding fold(callee_graph);
- InstructionSimplifier simplify(callee_graph);
-
- HOptimization* optimizations[] = {
- &redundant_phi,
- &dead_phi,
- &dce,
- &fold,
- &simplify,
- };
-
- for (size_t i = 0; i < arraysize(optimizations); ++i) {
- HOptimization* optimization = optimizations[i];
- optimization->Run();
- }
-
callee_graph->InlineInto(graph_, invoke_instruction);
// Now that we have inlined the callee, we need to update the next