From d72c97e20b96880ceb525a42b4a158e1a764e807 Mon Sep 17 00:00:00 2001 From: Mythri Date: Wed, 9 Aug 2017 16:23:13 +0100 Subject: [PATCH] [Turbofan] Allow recursive inlining Currently, we do not inline recursive functions. This is in general a good idea but could be useful in some cases. For example, in rayTrace there is a class.create function to create new classes, which basically calls the initialize function on the object. When there are classes which instantiate other classes this leads to recursion. These are really small functions (within the small function budget) and it is good to inline them. Allowing such functions to inline improves the score on rayTrace by 12-16% and box2d by 24-30%. There is also an absolute limit on the maximum levels of inlining to avoid any corner cases and to ensure inlining always terminates. Bug: v8:6682 Change-Id: I6784f68d6395097d126c0850b1a1336b6583d958 Reviewed-on: https://chromium-review.googlesource.com/608235 Reviewed-by: Michael Starzinger Commit-Queue: Mythri Alle Cr-Commit-Position: refs/heads/master@{#47255} --- src/compiler/js-inlining.cc | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/compiler/js-inlining.cc b/src/compiler/js-inlining.cc index b858ac674d..6b0623eb66 100644 --- a/src/compiler/js-inlining.cc +++ b/src/compiler/js-inlining.cc @@ -24,6 +24,12 @@ namespace v8 { namespace internal { namespace compiler { +namespace { +// This is just to avoid some corner cases, especially since we allow recursive +// inlining. +static const int kMaxDepthForInlining = 50; +} // namespace + #define TRACE(...) \ do { \ if (FLAG_trace_turbo_inlining) PrintF(__VA_ARGS__); \ @@ -475,19 +481,19 @@ Reduction JSInliner::ReduceJSCall(Node* node) { return NoChange(); } - // TODO(turbofan): TranslatedState::GetAdaptedArguments() currently relies on - // not inlining recursive functions. We might want to relax that at some - // point. + // To ensure inlining always terminates, we have an upper limit on inlining + // the nested calls. + int nesting_level = 0; for (Node* frame_state = call.frame_state(); frame_state->opcode() == IrOpcode::kFrameState; frame_state = frame_state->InputAt(kFrameStateOuterStateInput)) { - FrameStateInfo const& frame_info = OpParameter(frame_state); - Handle frame_shared_info; - if (frame_info.shared_info().ToHandle(&frame_shared_info) && - *frame_shared_info == *shared_info) { - TRACE("Not inlining %s into %s because call is recursive\n", - shared_info->DebugName()->ToCString().get(), - info_->shared_info()->DebugName()->ToCString().get()); + nesting_level++; + if (nesting_level > kMaxDepthForInlining) { + TRACE( + "Not inlining %s into %s because call has exceeded the maximum depth " + "for function inlining\n", + shared_info->DebugName()->ToCString().get(), + info_->shared_info()->DebugName()->ToCString().get()); return NoChange(); } }