Selaa lähdekoodia

Mult optimization in MemOp bug fix

wyrichte 7 vuotta sitten
vanhempi
sitoutus
f0da7b6bf3
5 muutettua tiedostoa jossa 135 lisäystä ja 9 poistoa
  1. 6 3
      lib/Backend/BackwardPass.cpp
  2. 12 6
      lib/Backend/GlobOpt.cpp
  3. 18 0
      test/loop/MemOp.baseline
  4. 85 0
      test/loop/MemOp.js
  5. 14 0
      test/loop/rlexe.xml

+ 6 - 3
lib/Backend/BackwardPass.cpp

@@ -8848,19 +8848,22 @@ BackwardPass::RestoreInductionVariableValuesAfterMemOp(Loop *loop)
         
         IR::Opnd *inductionVariableOpnd = IR::RegOpnd::New(sym, IRType::TyInt32, localFunc);
         IR::Opnd *tempInductionVariableOpnd = IR::RegOpnd::New(IRType::TyInt32, localFunc);
-        IR::Opnd *sizeOpnd = globOpt->GenerateInductionVariableChangeForMemOp(loop, inductionVariableChangeInfo.unroll);
 
         // The induction variable is restored to a temp register before the MemOp occurs. Once the MemOp is
         // complete, the induction variable's register is set to the value of the temp register. This is done
         // in order to avoid overwriting the induction variable's value after a bailout on the MemOp.
-        IR::Instr* restoreInductionVarToTemp = IR::Instr::New(opCode, tempInductionVariableOpnd, inductionVariableOpnd, sizeOpnd, loop->GetFunc());
-        IR::Instr* restoreInductionVar = IR::Instr::New(Js::OpCode::Ld_A, inductionVariableOpnd, tempInductionVariableOpnd, loop->GetFunc());
+        IR::Instr* restoreInductionVarToTemp = IR::Instr::New(opCode, tempInductionVariableOpnd, inductionVariableOpnd, loop->GetFunc());
 
         // The IR that restores the induction variable's value is placed before the MemOp. Since this IR can
         // bailout to the loop's landing pad, placing this IR before the MemOp avoids performing the MemOp,
         // bailing out because of this IR, and then performing the effects of the loop again.
         loop->landingPad->InsertInstrBefore(restoreInductionVarToTemp, loop->memOpInfo->instr);
 
+        // The amount to be added or subtraced (depends on opCode) to the induction vairable after the MemOp.
+        IR::Opnd *sizeOpnd = globOpt->GenerateInductionVariableChangeForMemOp(loop, inductionVariableChangeInfo.unroll, restoreInductionVarToTemp);
+        restoreInductionVarToTemp->SetSrc2(sizeOpnd);
+        IR::Instr* restoreInductionVar = IR::Instr::New(Js::OpCode::Ld_A, inductionVariableOpnd, tempInductionVariableOpnd, loop->GetFunc());
+
         // If restoring an induction variable results in an overflow, bailout to the loop's landing pad.
         restoreInductionVarToTemp->ConvertToBailOutInstr(loop->bailOutInfo, IR::BailOutOnOverflow);
 

+ 12 - 6
lib/Backend/GlobOpt.cpp

@@ -2230,7 +2230,13 @@ MemOpCheckInductionVariable:
                 {
                     Loop::InductionVariableChangeInfo inductionVariableChangeInfo = { 0, 0 };
                     inductionVariableChangeInfo = loop->memOpInfo->inductionVariableChangeInfoMap->Lookup(inductionSymID, inductionVariableChangeInfo);
-                    inductionVariableChangeInfo.unroll++;
+
+                    // If inductionVariableChangeInfo.unroll has been invalidated, do
+                    // not modify the Js::Constants::InvalidLoopUnrollFactor value
+                    if (inductionVariableChangeInfo.unroll != Js::Constants::InvalidLoopUnrollFactor)
+                    {
+                        inductionVariableChangeInfo.unroll++;
+                    }
                     inductionVariableChangeInfo.isIncremental = isIncr;
                     loop->memOpInfo->inductionVariableChangeInfoMap->Item(inductionSymID, inductionVariableChangeInfo);
                 }
@@ -16855,12 +16861,12 @@ GlobOpt::GenerateInductionVariableChangeForMemOp(Loop *loop, byte unroll, IR::In
 
             IR::Opnd *unrollOpnd = IR::IntConstOpnd::New(unroll, type, localFunc);
 
-            InsertInstr(IR::Instr::New(Js::OpCode::Mul_I4,
-                sizeOpnd,
-                loopCountOpnd,
-                unrollOpnd,
-                localFunc));
+            IR::Instr *inductionChangeMultiplier = IR::Instr::New(
+                Js::OpCode::Mul_I4, sizeOpnd, loopCountOpnd, unrollOpnd, localFunc);
+
+            InsertInstr(inductionChangeMultiplier);
 
+            inductionChangeMultiplier->ConvertToBailOutInstr(loop->bailOutInfo, IR::BailOutOnOverflow);
         }
     }
     else

+ 18 - 0
test/loop/MemOp.baseline

@@ -0,0 +1,18 @@
+200
+2147483649
+30
+300
+2147483650
+40
+0
+2147483647
+10
+0
+2147483647
+10
+0
+2147483647
+10
+100
+2147483648
+20

+ 85 - 0
test/loop/MemOp.js

@@ -0,0 +1,85 @@
+//-------------------------------------------------------------------------------------------------------
+// Copyright (C) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+//-------------------------------------------------------------------------------------------------------
+
+function f0(a, start, end) {
+    for (var i = start, j = start; i < end; i++, j++) {
+        j = j + 1
+        a[i] = 1
+    }
+    a[j]
+    print(j)
+
+}
+
+function f1(a, start, end) {
+    for (var i = start, j = start; i < end; i++, j++) {
+        j = j + 2
+        a[i] = 1
+    }
+    a[j]
+    print(j)
+
+}
+
+function f2(a, start, end) {
+    for (var i = start, j = start; i >= end; i--, j--) {
+        j = j - 1
+        a[i] = 1
+    }
+    a[j]
+    print(j)
+}
+
+function f3(a, start, end) {
+    for (var i = start, j = start; i >= end; i--, j--) {
+        j = j - 2
+        a[i] = 1
+    }
+    a[j]
+    print(j)
+}
+
+function f4(a, start, end) {
+    for (var i = start, j = start; i < end; i++, j--) {
+        j = j + 1
+        a[i] = 1
+    }
+    a[j]
+    print(j)
+}
+
+function f5(a, start, end) {
+    for (var i = start, j = start; i < end; i++, j--) {
+        j = j + 2
+        a[i] = 1
+    }
+    a[j]
+    print(j)
+}
+
+var a = new Float64Array(0xfff);
+f0(a, 0, 100)
+f0(a, 0x7fffffff, 0x80000000)
+f0(a, 10, 20)
+
+f1(a, 0, 100)
+f1(a, 0x7fffffff, 0x80000000)
+f1(a, 10, 20)
+
+f2(a, 0, 100)
+f2(a, 0x7fffffff, 0x80000000)
+f2(a, 10, 20)
+
+f3(a, 0, 100)
+f3(a, 0x7fffffff, 0x80000000)
+f3(a, 10, 20)
+
+f4(a, 0, 100)
+f4(a, 0x7fffffff, 0x80000000)
+f4(a, 10, 20)
+
+f5(a, 0, 100)
+f5(a, 0x7fffffff, 0x80000000)
+f5(a, 10, 20)

+ 14 - 0
test/loop/rlexe.xml

@@ -46,4 +46,18 @@
       <files>infinite.js</files>
     </default>
   </test>
+  <test>
+    <default>
+      <files>MemOp.js</files>
+      <compile-flags>-off:simplejit -mic:1 -bgjit-</compile-flags>
+      <baseline>MemOp.baseline</baseline>
+    </default>
+  </test>
+  <test>
+    <default>
+      <files>MemOp.js</files>
+      <compile-flags></compile-flags>
+      <baseline>MemOp.baseline</baseline>
+    </default>
+  </test>
 </regress-exe>