Просмотр исходного кода

Give loop's bailout info to bailout instructions in the loop landing pad

Rajat Dua 7 лет назад
Родитель
Сommit
48d117ea65

+ 6 - 6
lib/Backend/GlobOpt.cpp

@@ -514,7 +514,7 @@ GlobOpt::OptBlock(BasicBlock *block)
             if (instr->GetBailOutInfo() == oldBailOutInfo)
             {
                 instr->PromoteAuxBailOut();
-                FillBailOutInfo(block, instr->GetBailOutInfo());
+                FillBailOutInfo(block, instr);
             }
             else
             {
@@ -2425,7 +2425,7 @@ GlobOpt::OptInstr(IR::Instr *&instr, bool* isInstrRemoved)
     // Consider: Do we ever get post-op bailout here, and if so is the FillBailOutInfo call in the right place?
     if (instr->HasBailOutInfo() && !this->IsLoopPrePass())
     {
-        this->FillBailOutInfo(this->currentBlock, instr->GetBailOutInfo());
+        this->FillBailOutInfo(this->currentBlock, instr);
     }
 
     this->instrCountSinceLastCleanUp++;
@@ -2789,7 +2789,7 @@ GlobOpt::OptTagChecks(IR::Instr *instr)
                 bailOutInstr = IR::BailOutInstr::New(Js::OpCode::BailOnNotObject, IR::BailOutOnTaggedValue, instr, instr->m_func);
                 if (!this->IsLoopPrePass())
                 {
-                    FillBailOutInfo(this->currentBlock, bailOutInstr->GetBailOutInfo());
+                    FillBailOutInfo(this->currentBlock, bailOutInstr);
                 }
                 IR::RegOpnd *srcOpnd = regOpnd;
                 if (!srcOpnd)
@@ -11698,7 +11698,7 @@ GlobOpt::ToTypeSpecUse(IR::Instr *instr, IR::Opnd *opnd, BasicBlock *block, Valu
 
                 // Fill in bail out info if the FromVar is a bailout instr, and it wasn't hoisted as invariant.
                 // If it was hoisted, the invariant code will fill out the bailout info with the loop landing pad bailout info.
-                this->FillBailOutInfo(block, newInstr->GetBailOutInfo());
+                this->FillBailOutInfo(block, newInstr);
 
                 if(valueInfo)
                 {
@@ -15579,7 +15579,7 @@ GlobOpt::PreOptPeep(IR::Instr *instr)
                 {
                     if (!this->prePassLoop)
                     {
-                        FillBailOutInfo(this->currentBlock, instr->GetBailOutInfo());
+                        FillBailOutInfo(this->currentBlock, instr);
                     }
                     // Already processed.
                     return instr;
@@ -15598,7 +15598,7 @@ GlobOpt::PreOptPeep(IR::Instr *instr)
 
                 if (!this->currentBlock->loop)
                 {
-                    FillBailOutInfo(this->currentBlock, instr->GetBailOutInfo());
+                    FillBailOutInfo(this->currentBlock, instr);
                 }
                 else
                 {

+ 2 - 1
lib/Backend/GlobOpt.h

@@ -867,7 +867,8 @@ private:
     void                    EndTrackCall(IR::Instr * instr);
     void                    EndTrackingOfArgObjSymsForInlinee();
     void                    FillBailOutInfo(BasicBlock *block, BailOutInfo *bailOutInfo);
-
+    void                    FillBailOutInfo(BasicBlock *block, _In_ IR::Instr * instr);
+    
     static void             MarkNonByteCodeUsed(IR::Instr * instr);
     static void             MarkNonByteCodeUsed(IR::Opnd * opnd);
 

+ 23 - 2
lib/Backend/GlobOptBailOut.cpp

@@ -1022,6 +1022,27 @@ GlobOpt::FillBailOutInfo(BasicBlock *block, BailOutInfo * bailOutInfo)
     this->CaptureValues(block, bailOutInfo);
 }
 
+void
+GlobOpt::FillBailOutInfo(BasicBlock *block, _In_ IR::Instr * instr)
+{
+    AssertMsg(!this->isCallHelper, "Bail out can't be inserted the middle of CallHelper sequence");
+    Assert(instr->HasBailOutInfo());
+
+    if (this->isRecursiveCallOnLandingPad)
+    {
+        Assert(block->IsLandingPad());
+        Loop * loop = block->next->loop;
+        EnsureBailTarget(loop);
+        if (instr->GetBailOutInfo() != loop->bailOutInfo)
+        {
+            instr->ReplaceBailOutInfo(loop->bailOutInfo);
+        }
+        return;
+    }
+
+    FillBailOutInfo(block, instr->GetBailOutInfo());
+}
+
 IR::ByteCodeUsesInstr *
 GlobOpt::InsertByteCodeUses(IR::Instr * instr, bool includeDef)
 {
@@ -1374,7 +1395,7 @@ GlobOpt::GenerateBailAfterOperation(IR::Instr * *const pInstr, IR::BailOutKind k
     {
         this->currentBlock->SetLastInstr(bailOutInstr);
     }
-    FillBailOutInfo(this->currentBlock, bailOutInstr->GetBailOutInfo());
+    FillBailOutInfo(this->currentBlock, bailOutInstr);
     *pInstr = bailOutInstr;
 }
 
@@ -1393,7 +1414,7 @@ GlobOpt::GenerateBailAtOperation(IR::Instr * *const pInstr, const IR::BailOutKin
     {
         this->currentBlock->SetLastInstr(bailOutInstr);
     }
-    FillBailOutInfo(currentBlock, bailOutInstr->GetBailOutInfo());
+    FillBailOutInfo(currentBlock, bailOutInstr);
     *pInstr = bailOutInstr;
 }
 

+ 2 - 1
lib/Backend/IR.cpp

@@ -1216,9 +1216,10 @@ Instr::ReplaceBailOutInfo(BailOutInfo *newBailOutInfo)
         Assert(false);
         __assume(UNREACHED);
     }
-    Assert(!oldBailOutInfo->wasCloned && !oldBailOutInfo->wasCopied);
+    
     if (oldBailOutInfo->bailOutInstr == this)
     {
+        Assert(!oldBailOutInfo->wasCloned && !oldBailOutInfo->wasCopied);
         JitArenaAllocator * alloc = this->m_func->m_alloc;
         oldBailOutInfo->Clear(alloc);
         JitAdelete(alloc, oldBailOutInfo);

+ 5 - 0
test/Optimizer/rlexe.xml

@@ -1483,6 +1483,11 @@
       <compile-flags>-mic:1 -off:simplejit -bgjit- -force:fixdataprops -lic:1</compile-flags>
     </default>
   </test>
+  <test>
+    <default>
+      <files>test150.js</files>
+    </default>
+  </test>
   <test>
     <default>
       <files>IsIn_ArrayNoMissingValues.js</files>

+ 16 - 0
test/Optimizer/test150.js

@@ -0,0 +1,16 @@
+//-------------------------------------------------------------------------------------------------------
+// Copyright (C) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+//-------------------------------------------------------------------------------------------------------
+
+function func2() {
+  for (; Object.prop1;) {}
+}
+var ary = [1];
+var uic8 = new Uint8ClampedArray();
+let i = 0;
+while (ary[uic8[1] >= 0 ? uic8[1] : 0]) {
+  func2();
+  if(i++ > 1000) break;
+}
+print("passed");