Index: runtime/vm/flow_graph_inliner.cc |
=================================================================== |
--- runtime/vm/flow_graph_inliner.cc (revision 41687) |
+++ runtime/vm/flow_graph_inliner.cc (working copy) |
@@ -51,6 +51,8 @@ |
DEFINE_FLAG(int, max_inlined_per_depth, 500, |
"Max. number of inlined calls per depth"); |
DEFINE_FLAG(bool, print_inlining_tree, false, "Print inlining tree"); |
+DEFINE_FLAG(bool, enable_inlining_annotations, false, |
+ "Enable inlining annotations"); |
DECLARE_FLAG(bool, compiler_stats); |
DECLARE_FLAG(bool, enable_type_checks); |
@@ -448,6 +450,25 @@ |
}; |
+static bool HasAnnotation(const Function& function, const char* annotation) { |
+ const Class& owner = Class::Handle(function.Owner()); |
+ const Library& library = Library::Handle(owner.library()); |
+ const Array& metadata = |
+ Array::Cast(Object::Handle(library.GetMetadata(function))); |
+ |
+ if (metadata.Length() > 0) { |
+ Object& val = Object::Handle(); |
+ for (intptr_t i = 0; i < metadata.Length(); i++) { |
+ val = metadata.At(i); |
+ if (val.IsString() && String::Cast(val).Equals(annotation)) { |
+ return true; |
+ } |
+ } |
+ } |
+ return false; |
+} |
+ |
+ |
class CallSiteInliner : public ValueObject { |
public: |
explicit CallSiteInliner(FlowGraph* flow_graph) |
@@ -593,6 +614,12 @@ |
return false; |
} |
+ if (FLAG_enable_inlining_annotations && |
+ HasAnnotation(function, "NeverInline")) { |
Vyacheslav Egorov (Google)
2014/11/13 13:01:42
Maybe make a Symbol for this?
Florian Schneider
2014/11/13 13:38:53
I'll make it a constant variable. Symbol is not ne
|
+ TRACE_INLINING(OS::Print(" Bailout: NeverInline annotation\n")); |
+ return false; |
+ } |
+ |
GrowableArray<Value*>* arguments = call_data->arguments; |
const intptr_t constant_arguments = CountConstants(*arguments); |
if (!ShouldWeInline(function, |
@@ -614,7 +641,6 @@ |
// Abort if this is a recursive occurrence. |
Definition* call = call_data->call; |
if (!FLAG_inline_recursive && IsCallRecursive(unoptimized_code, call)) { |
- function.set_is_inlinable(false); |
TRACE_INLINING(OS::Print(" Bailout: recursive function\n")); |
PRINT_INLINING_TREE("Recursive function", |
&call_data->caller, &function, call_data->call); |
@@ -763,6 +789,7 @@ |
&call_data->caller, &function, call_data->call); |
return false; |
} |
+ |
if (function.IsInvokeFieldDispatcher() || |
function.IsNoSuchMethodDispatcher()) { |
// Append call sites to the currently processed list so that dispatcher |
@@ -1685,6 +1712,13 @@ |
bool FlowGraphInliner::AlwaysInline(const Function& function) { |
+ if (FLAG_enable_inlining_annotations && |
+ HasAnnotation(function, "AlwaysInline")) { |
Vyacheslav Egorov (Google)
2014/11/13 13:01:42
Maybe make a symbol for this?
Florian Schneider
2014/11/13 13:38:53
Done. Same as above.
|
+ TRACE_INLINING(OS::Print("AlwaysInline annotation for %s\n", |
+ function.ToCString())); |
+ return true; |
+ } |
+ |
if (function.IsImplicitGetterFunction() || function.IsGetterFunction() || |
function.IsImplicitSetterFunction() || function.IsSetterFunction()) { |
const intptr_t count = function.optimized_instruction_count(); |