Allow for fine tuning the inliner.

Bug: 21868508

(cherry picked and squashed from commits
ec74835a7e4f2660250a2f3f9508cbbe5269e49a and
0941b9d48a9a8c6d80a1af7a0d0fc9f80fe2b9a1)

Change-Id: I1750e6bea20321d04680132281a6c2924531c5ae
diff --git a/compiler/dex/quick/quick_cfi_test.cc b/compiler/dex/quick/quick_cfi_test.cc
index dd68dd4..8318b52 100644
--- a/compiler/dex/quick/quick_cfi_test.cc
+++ b/compiler/dex/quick/quick_cfi_test.cc
@@ -56,6 +56,8 @@
       CompilerOptions::kDefaultSmallMethodThreshold,
       CompilerOptions::kDefaultTinyMethodThreshold,
       CompilerOptions::kDefaultNumDexMethodsThreshold,
+      CompilerOptions::kDefaultInlineDepthLimit,
+      CompilerOptions::kDefaultInlineMaxCodeUnits,
       false,
       CompilerOptions::kDefaultTopKProfileThreshold,
       false,
diff --git a/compiler/dex/quick/x86/quick_assemble_x86_test.cc b/compiler/dex/quick/x86/quick_assemble_x86_test.cc
index 798e23f..98e9f38 100644
--- a/compiler/dex/quick/x86/quick_assemble_x86_test.cc
+++ b/compiler/dex/quick/x86/quick_assemble_x86_test.cc
@@ -39,6 +39,8 @@
         CompilerOptions::kDefaultSmallMethodThreshold,
         CompilerOptions::kDefaultTinyMethodThreshold,
         CompilerOptions::kDefaultNumDexMethodsThreshold,
+        CompilerOptions::kDefaultInlineDepthLimit,
+        CompilerOptions::kDefaultInlineMaxCodeUnits,
         false,
         CompilerOptions::kDefaultTopKProfileThreshold,
         false,
diff --git a/compiler/driver/compiler_options.cc b/compiler/driver/compiler_options.cc
index 226e6b7..3f5a1ea 100644
--- a/compiler/driver/compiler_options.cc
+++ b/compiler/driver/compiler_options.cc
@@ -27,6 +27,8 @@
       small_method_threshold_(kDefaultSmallMethodThreshold),
       tiny_method_threshold_(kDefaultTinyMethodThreshold),
       num_dex_methods_threshold_(kDefaultNumDexMethodsThreshold),
+      inline_depth_limit_(kDefaultInlineDepthLimit),
+      inline_max_code_units_(kDefaultInlineMaxCodeUnits),
       include_patch_information_(kDefaultIncludePatchInformation),
       top_k_profile_threshold_(kDefaultTopKProfileThreshold),
       debuggable_(false),
@@ -52,6 +54,8 @@
                                  size_t small_method_threshold,
                                  size_t tiny_method_threshold,
                                  size_t num_dex_methods_threshold,
+                                 size_t inline_depth_limit,
+                                 size_t inline_max_code_units,
                                  bool include_patch_information,
                                  double top_k_profile_threshold,
                                  bool debuggable,
@@ -71,6 +75,8 @@
     small_method_threshold_(small_method_threshold),
     tiny_method_threshold_(tiny_method_threshold),
     num_dex_methods_threshold_(num_dex_methods_threshold),
+    inline_depth_limit_(inline_depth_limit),
+    inline_max_code_units_(inline_max_code_units),
     include_patch_information_(include_patch_information),
     top_k_profile_threshold_(top_k_profile_threshold),
     debuggable_(debuggable),
diff --git a/compiler/driver/compiler_options.h b/compiler/driver/compiler_options.h
index fe681e2..a34116d 100644
--- a/compiler/driver/compiler_options.h
+++ b/compiler/driver/compiler_options.h
@@ -51,6 +51,8 @@
   static constexpr double kDefaultTopKProfileThreshold = 90.0;
   static const bool kDefaultGenerateDebugInfo = kIsDebugBuild;
   static const bool kDefaultIncludePatchInformation = false;
+  static const size_t kDefaultInlineDepthLimit = 5;
+  static const size_t kDefaultInlineMaxCodeUnits = 100;
 
   CompilerOptions();
   ~CompilerOptions();
@@ -61,6 +63,8 @@
                   size_t small_method_threshold,
                   size_t tiny_method_threshold,
                   size_t num_dex_methods_threshold,
+                  size_t inline_depth_limit,
+                  size_t inline_max_code_units,
                   bool include_patch_information,
                   double top_k_profile_threshold,
                   bool debuggable,
@@ -137,6 +141,14 @@
     return num_dex_methods_threshold_;
   }
 
+  size_t GetInlineDepthLimit() const {
+    return inline_depth_limit_;
+  }
+
+  size_t GetInlineMaxCodeUnits() const {
+    return inline_max_code_units_;
+  }
+
   double GetTopKProfileThreshold() const {
     return top_k_profile_threshold_;
   }
@@ -202,6 +214,8 @@
   const size_t small_method_threshold_;
   const size_t tiny_method_threshold_;
   const size_t num_dex_methods_threshold_;
+  const size_t inline_depth_limit_;
+  const size_t inline_max_code_units_;
   const bool include_patch_information_;
   // When using a profile file only the top K% of the profiled samples will be compiled.
   const double top_k_profile_threshold_;
diff --git a/compiler/jit/jit_compiler.cc b/compiler/jit/jit_compiler.cc
index a1d8226..5ef744c 100644
--- a/compiler/jit/jit_compiler.cc
+++ b/compiler/jit/jit_compiler.cc
@@ -71,6 +71,8 @@
       CompilerOptions::kDefaultSmallMethodThreshold,
       CompilerOptions::kDefaultTinyMethodThreshold,
       CompilerOptions::kDefaultNumDexMethodsThreshold,
+      CompilerOptions::kDefaultInlineDepthLimit,
+      CompilerOptions::kDefaultInlineMaxCodeUnits,
       false,
       CompilerOptions::kDefaultTopKProfileThreshold,
       false,  // TODO: Think about debuggability of JIT-compiled code.
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc
index eeb1636..8490730 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -22,6 +22,7 @@
 #include "constant_folding.h"
 #include "dead_code_elimination.h"
 #include "driver/compiler_driver-inl.h"
+#include "driver/compiler_options.h"
 #include "driver/dex_compilation_unit.h"
 #include "instruction_simplifier.h"
 #include "mirror/class_loader.h"
@@ -37,10 +38,12 @@
 
 namespace art {
 
-static constexpr int kMaxInlineCodeUnits = 100;
-static constexpr int kDepthLimit = 5;
-
 void HInliner::Run() {
+  const CompilerOptions& compiler_options = compiler_driver_->GetCompilerOptions();
+  if ((compiler_options.GetInlineDepthLimit() == 0)
+      || (compiler_options.GetInlineMaxCodeUnits() == 0)) {
+    return;
+  }
   if (graph_->IsDebuggable()) {
     // For simplicity, we currently never inline when the graph is debuggable. This avoids
     // doing some logic in the runtime to discover if a method could have been inlined.
@@ -100,7 +103,8 @@
     return false;
   }
 
-  if (code_item->insns_size_in_code_units_ > kMaxInlineCodeUnits) {
+  size_t inline_max_code_units = compiler_driver_->GetCompilerOptions().GetInlineMaxCodeUnits();
+  if (code_item->insns_size_in_code_units_ > inline_max_code_units) {
     VLOG(compiler) << "Method " << PrettyMethod(method_index, caller_dex_file)
                    << " is too big to inline";
     return false;
@@ -220,7 +224,7 @@
     optimization->Run();
   }
 
-  if (depth_ + 1 < kDepthLimit) {
+  if (depth_ + 1 < compiler_driver_->GetCompilerOptions().GetInlineDepthLimit()) {
     HInliner inliner(callee_graph,
                      outer_compilation_unit_,
                      dex_compilation_unit,
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index d21f5cb..d1fe039 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -280,6 +280,18 @@
   UsageError("      Example: --num-dex-method=%d", CompilerOptions::kDefaultNumDexMethodsThreshold);
   UsageError("      Default: %d", CompilerOptions::kDefaultNumDexMethodsThreshold);
   UsageError("");
+  UsageError("  --inline-depth-limit=<depth-limit>: the depth limit of inlining for fine tuning");
+  UsageError("      the compiler. A zero value will disable inlining. Honored only by Optimizing.");
+  UsageError("      Example: --inline-depth-limit=%d", CompilerOptions::kDefaultInlineDepthLimit);
+  UsageError("      Default: %d", CompilerOptions::kDefaultInlineDepthLimit);
+  UsageError("");
+  UsageError("  --inline-max-code-units=<code-units-count>: the maximum code units that a method");
+  UsageError("      can have to be considered for inlining. A zero value will disable inlining.");
+  UsageError("      Honored only by Optimizing.");
+  UsageError("      Example: --inline-max-code-units=%d",
+             CompilerOptions::kDefaultInlineMaxCodeUnits);
+  UsageError("      Default: %d", CompilerOptions::kDefaultInlineMaxCodeUnits);
+  UsageError("");
   UsageError("  --dump-timing: display a breakdown of where time was spent");
   UsageError("");
   UsageError("  --include-patch-information: Include patching information so the generated code");
@@ -550,6 +562,8 @@
     int small_method_threshold = CompilerOptions::kDefaultSmallMethodThreshold;
     int tiny_method_threshold = CompilerOptions::kDefaultTinyMethodThreshold;
     int num_dex_methods_threshold = CompilerOptions::kDefaultNumDexMethodsThreshold;
+    int inline_depth_limit = CompilerOptions::kDefaultInlineDepthLimit;
+    int inline_max_code_units = CompilerOptions::kDefaultInlineMaxCodeUnits;
 
     // Profile file to use
     double top_k_profile_threshold = CompilerOptions::kDefaultTopKProfileThreshold;
@@ -720,6 +734,22 @@
         if (num_dex_methods_threshold < 0) {
           Usage("--num-dex-methods passed a negative value %s", num_dex_methods_threshold);
         }
+      } else if (option.starts_with("--inline-depth-limit=")) {
+        const char* limit = option.substr(strlen("--inline-depth-limit=")).data();
+        if (!ParseInt(limit, &inline_depth_limit)) {
+          Usage("Failed to parse --inline-depth-limit '%s' as an integer", limit);
+        }
+        if (inline_depth_limit < 0) {
+          Usage("--inline-depth-limit passed a negative value %s", inline_depth_limit);
+        }
+      } else if (option.starts_with("--inline-max-code-units=")) {
+        const char* code_units = option.substr(strlen("--inline-max-code-units=")).data();
+        if (!ParseInt(code_units, &inline_max_code_units)) {
+          Usage("Failed to parse --inline-max-code-units '%s' as an integer", code_units);
+        }
+        if (inline_max_code_units < 0) {
+          Usage("--inline-max-code-units passed a negative value %s", inline_max_code_units);
+        }
       } else if (option == "--host") {
         is_host_ = true;
       } else if (option == "--runtime-arg") {
@@ -992,6 +1022,8 @@
                                                 small_method_threshold,
                                                 tiny_method_threshold,
                                                 num_dex_methods_threshold,
+                                                inline_depth_limit,
+                                                inline_max_code_units,
                                                 include_patch_information,
                                                 top_k_profile_threshold,
                                                 debuggable,