Selaa lähdekoodia

A couple of fixes with inline args opt and stack args opt

Rajat Dua 7 vuotta sitten
vanhempi
sitoutus
ea11fc00ef

+ 7 - 1
lib/Backend/BackwardPass.cpp

@@ -8033,11 +8033,12 @@ BackwardPass::ProcessInlineeStart(IR::Instr* inlineeStart)
 
     if (!inlineeStart->m_func->m_hasInlineArgsOpt)
     {
-        PHASE_PRINT_TESTTRACE(Js::InlineArgsOptPhase, func, _u("%s[%d]: Skipping inline args optimization: %s[%d] HasCalls: %s 'arguments' access: %s Can do inlinee args opt: %s\n"),
+        PHASE_PRINT_TESTTRACE(Js::InlineArgsOptPhase, func, _u("%s[%d]: Skipping inline args optimization: %s[%d] HasCalls: %s, 'arguments' access: %s, stackArgs enabled: %s, Can do inlinee args opt: %s\n"),
                 func->GetJITFunctionBody()->GetDisplayName(), func->GetJITFunctionBody()->GetFunctionNumber(),
                 inlineeStart->m_func->GetJITFunctionBody()->GetDisplayName(), inlineeStart->m_func->GetJITFunctionBody()->GetFunctionNumber(),
                 IsTrueOrFalse(inlineeStart->m_func->GetHasCalls()),
                 IsTrueOrFalse(inlineeStart->m_func->GetHasUnoptimizedArgumentsAccess()),
+                IsTrueOrFalse(inlineeStart->m_func->IsStackArgsEnabled()),
                 IsTrueOrFalse(inlineeStart->m_func->m_canDoInlineArgsOpt));
         return false;
     }
@@ -8115,6 +8116,11 @@ BackwardPass::ProcessInlineeEnd(IR::Instr* instr)
     }
     else if (this->tag == Js::DeadStorePhase)
     {
+        if (instr->m_func->GetJITFunctionBody()->UsesArgumentsObject() && !instr->m_func->IsStackArgsEnabled())
+        {
+            instr->m_func->DisableCanDoInlineArgOpt();
+        }
+
         if (instr->m_func->m_hasInlineArgsOpt)
         {
             Assert(instr->m_func->frameInfo);

+ 1 - 0
lib/Backend/Func.cpp

@@ -67,6 +67,7 @@ Func::Func(JitArenaAllocator *alloc, JITTimeWorkItem * workItem,
     m_hasInlineArgsOpt(false),
     m_canDoInlineArgsOpt(true),
     unoptimizableArgumentsObjReference(0),
+    unoptimizableArgumentsObjReferenceInInlinees(0),
     m_doFastPaths(false),
     hasBailout(false),
     firstIRTemp(0),

+ 2 - 0
lib/Backend/Func.h

@@ -726,6 +726,7 @@ public:
     StackSym *          tempSymBool;
     uint32              loopCount;
     uint32              unoptimizableArgumentsObjReference;
+    uint32              unoptimizableArgumentsObjReferenceInInlinees;
     Js::ProfileId       callSiteIdInParentFunc;
     InlineeFrameInfo*   cachedInlineeFrameInfo;
     bool                m_hasCalls: 1; // This is more accurate compared to m_isLeaf
@@ -855,6 +856,7 @@ public:
                         {
                             curFunc->m_canDoInlineArgsOpt = false;
                             curFunc->m_hasInlineArgsOpt = false;
+                            curFunc->frameInfo = nullptr;
                             curFunc = curFunc->GetParentFunc();
                         }
     }

+ 6 - 3
lib/Backend/GlobOptBailOut.cpp

@@ -482,11 +482,12 @@ GlobOpt::CaptureByteCodeSymUses(IR::Instr * instr)
 void
 GlobOpt::ProcessInlineeEnd(IR::Instr* instr)
 {
-    if (!PHASE_OFF(Js::StackArgLenConstOptPhase, instr->m_func) && instr->m_func->IsStackArgsEnabled()
-        && instr->m_func->hasArgLenAndConstOpt && instr->m_func->unoptimizableArgumentsObjReference == 0)
+    if (!PHASE_OFF(Js::StackArgLenConstOptPhase, instr->m_func) && 
+        (!instr->m_func->GetJITFunctionBody()->UsesArgumentsObject() || instr->m_func->IsStackArgsEnabled())
+        && instr->m_func->unoptimizableArgumentsObjReference == 0 && instr->m_func->unoptimizableArgumentsObjReferenceInInlinees == 0)
     {
         instr->m_func->hasUnoptimizedArgumentsAccess = false;
-        if (DoInlineArgsOpt(instr->m_func))
+        if (!instr->m_func->m_hasInlineArgsOpt && DoInlineArgsOpt(instr->m_func))
         {
             instr->m_func->m_hasInlineArgsOpt = true;
             Assert(instr->m_func->cachedInlineeFrameInfo);
@@ -502,6 +503,8 @@ GlobOpt::ProcessInlineeEnd(IR::Instr* instr)
 
     Assert(this->currentBlock->globOptData.inlinedArgOutSize >= instr->GetArgOutSize(/*getInterpreterArgOutCount*/ false));
     this->currentBlock->globOptData.inlinedArgOutSize -= instr->GetArgOutSize(/*getInterpreterArgOutCount*/ false);
+
+    instr->m_func->GetParentFunc()->unoptimizableArgumentsObjReferenceInInlinees += instr->m_func->unoptimizableArgumentsObjReference;
 }
 
 void

+ 5 - 0
test/Optimizer/rlexe.xml

@@ -1500,6 +1500,11 @@
       <compile-flags>-off:usefixeddataprops -off:objtypespec</compile-flags>
     </default>
   </test>
+  <test>
+    <default>
+      <files>test152.js</files>
+    </default>
+  </test>
   <test>
     <default>
       <files>IsIn_ArrayNoMissingValues.js</files>

+ 44 - 0
test/Optimizer/test152.js

@@ -0,0 +1,44 @@
+//-------------------------------------------------------------------------------------------------------
+// Copyright (C) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+//-------------------------------------------------------------------------------------------------------
+
+function bar()
+{
+    return arguments.length + arguments[0];
+}
+
+function foo(a)
+{
+    return bar(a) + arguments;
+}
+
+foo(1)
+foo(1)
+foo(1)
+
+
+function test4(a)
+{
+    return arguments.length + arguments[0];
+}
+
+function test3(a)
+{
+    return test4(a);
+}
+
+function test2(a)
+{
+    return test3(a) + arguments.length;
+}
+
+function test1(a)
+{
+    return test2(a)
+}
+test1(1)
+test1(1)
+test1(1)
+
+print("passed")