Jelajahi Sumber

Do int64 const prop

Michael Ferris 8 tahun lalu
induk
melakukan
2622c05ac1

+ 8 - 8
lib/Backend/BackwardPass.cpp

@@ -5585,13 +5585,13 @@ BackwardPass::TrackIntUsage(IR::Instr *const instr)
             {
                 Assert(dstSym);
                 Assert(instr->GetSrc1());
-                Assert(instr->GetSrc1()->IsRegOpnd() || instr->GetSrc1()->IsIntConstOpnd());
+                Assert(instr->GetSrc1()->IsRegOpnd() || instr->GetSrc1()->IsImmediateOpnd());
                 Assert(instr->GetSrc2());
-                Assert(instr->GetSrc2()->IsRegOpnd() || instr->GetSrc2()->IsIntConstOpnd());
+                Assert(instr->GetSrc2()->IsRegOpnd() || instr->GetSrc2()->IsImmediateOpnd());
 
                 if (instr->ignoreNegativeZero ||
-                    (instr->GetSrc1()->IsIntConstOpnd() && instr->GetSrc1()->AsIntConstOpnd()->GetValue() != 0) ||
-                    (instr->GetSrc2()->IsIntConstOpnd() && instr->GetSrc2()->AsIntConstOpnd()->GetValue() != 0))
+                    (instr->GetSrc1()->IsImmediateOpnd() && instr->GetSrc1()->GetImmediateValue(func) != 0) ||
+                    (instr->GetSrc2()->IsImmediateOpnd() && instr->GetSrc2()->GetImmediateValue(func) != 0))
                 {
                     SetNegativeZeroDoesNotMatterIfLastUse(instr->GetSrc1());
                     SetNegativeZeroDoesNotMatterIfLastUse(instr->GetSrc2());
@@ -5641,13 +5641,13 @@ BackwardPass::TrackIntUsage(IR::Instr *const instr)
             {
                 Assert(dstSym);
                 Assert(instr->GetSrc1());
-                Assert(instr->GetSrc1()->IsRegOpnd() || instr->GetSrc1()->IsIntConstOpnd());
+                Assert(instr->GetSrc1()->IsRegOpnd() || instr->GetSrc1()->IsImmediateOpnd());
                 Assert(instr->GetSrc2());
-                Assert(instr->GetSrc2()->IsRegOpnd() || instr->GetSrc2()->IsIntConstOpnd());
+                Assert(instr->GetSrc2()->IsRegOpnd() || instr->GetSrc2()->IsImmediateOpnd());
 
                 if (instr->ignoreNegativeZero ||
-                    (instr->GetSrc1()->IsIntConstOpnd() && instr->GetSrc1()->AsIntConstOpnd()->GetValue() != 0) ||
-                    (instr->GetSrc2()->IsIntConstOpnd() && instr->GetSrc2()->AsIntConstOpnd()->GetValue() != 0))
+                    (instr->GetSrc1()->IsImmediateOpnd() && instr->GetSrc1()->GetImmediateValue(func) != 0) ||
+                    (instr->GetSrc2()->IsImmediateOpnd() && instr->GetSrc2()->GetImmediateValue(func) != 0))
                 {
                     SetNegativeZeroDoesNotMatterIfLastUse(instr->GetSrc1());
                     SetNegativeZeroDoesNotMatterIfLastUse(instr->GetSrc2());

+ 17 - 0
lib/Backend/GlobOpt.cpp

@@ -6430,6 +6430,7 @@ GlobOpt::CopyProp(IR::Opnd *opnd, IR::Instr *instr, Value *val, IR::IndirOpnd *p
 
     // Constant prop?
     int32 intConstantValue;
+    int64 int64ConstantValue;
     if (valueInfo->TryGetIntConstantValue(&intConstantValue))
     {
         if (PHASE_OFF(Js::ConstPropPhase, this->func))
@@ -6590,6 +6591,22 @@ GlobOpt::CopyProp(IR::Opnd *opnd, IR::Instr *instr, Value *val, IR::IndirOpnd *p
         }
         return opnd;
     }
+    else if (valueInfo->TryGetIntConstantValue(&int64ConstantValue, false))
+    {
+        if (PHASE_OFF(Js::ConstPropPhase, this->func))
+        {
+            return opnd;
+        }
+
+        if (this->func->GetJITFunctionBody()->IsWasmFunction() && opnd->IsInt64())
+        {
+            IR::Int64ConstOpnd *intOpnd = IR::Int64ConstOpnd::New(int64ConstantValue, TyInt64, instr->m_func);
+            GOPT_TRACE_OPND(opnd, _u("Constant prop %lld (value:%lld)\n"), intOpnd->GetImmediateValue(instr->m_func), int64ConstantValue);
+            this->CaptureByteCodeSymUses(instr);
+            opnd = instr->ReplaceSrc(opnd, intOpnd);
+        }
+        return opnd;
+    }
 
     Sym *opndSym = nullptr;
     if (opnd->IsRegOpnd())

+ 27 - 10
lib/Backend/LowerMDShared.cpp

@@ -841,15 +841,32 @@ LowererMD::LowerRet(IR::Instr * retInstr)
             regType = TyInt64;
 #ifdef _M_IX86
             regType = TyInt32;
-            Int64RegPair srcPair = m_lowerer->FindOrCreateInt64Pair(retInstr->GetSrc1()->AsRegOpnd());
-
-            retInstr->UnlinkSrc1();
-            retInstr->SetSrc1(srcPair.low);
+            {
+                IR::Opnd* lowOpnd = nullptr;
+                IR::Opnd* highOpnd = nullptr;
+                if (retInstr->GetSrc1()->IsRegOpnd())
+                {
+                    Int64RegPair srcPair = m_lowerer->FindOrCreateInt64Pair(retInstr->GetSrc1()->AsRegOpnd());
+                    lowOpnd = srcPair.low;
+                    highOpnd = srcPair.high;
+                }
+                else if (retInstr->GetSrc1()->IsImmediateOpnd())
+                {
+                    int64 value = retInstr->GetSrc1()->GetImmediateValue(m_func);
+                    lowOpnd = IR::IntConstOpnd::New(value & UINT_MAX, regType, m_func);
+                    highOpnd = IR::IntConstOpnd::New(value >> 32, regType, m_func);
+                }
+                else
+                {
+                    Assert(UNREACHED);
+                }
+                retInstr->UnlinkSrc1();
+                retInstr->SetSrc1(lowOpnd);
 
-            // Mov high bits to edx
-            IR::RegOpnd* regEdx = IR::RegOpnd::New(nullptr, RegEDX, TyInt32, this->m_func);
-            IR::Instr* movHighInstr = IR::Instr::New(Js::OpCode::Ld_I4, regEdx, srcPair.high, this->m_func);
-            retInstr->InsertBefore(ChangeToAssign(movHighInstr));
+                // Mov high bits to edx
+                IR::RegOpnd* regEdx = IR::RegOpnd::New(nullptr, RegEDX, regType, this->m_func);
+                Lowerer::InsertMove(regEdx, highOpnd, retInstr);
+            }
 #endif
             break;
         }
@@ -2808,8 +2825,7 @@ void LowererMD::GenerateFastCmXx(IR::Instr *instr)
         {
             opnd = IR::IntConstOpnd::New(0, TyInt32, this->m_func);
         }
-        newInstr = IR::Instr::New(Js::OpCode::MOV, tmp, opnd, this->m_func);
-        done->InsertBefore(newInstr);
+        m_lowerer->InsertMove(tmp, opnd, done);
     }
 
     Js::OpCode cmpOp;
@@ -2833,6 +2849,7 @@ void LowererMD::GenerateFastCmXx(IR::Instr *instr)
     newInstr->SetSrc1(src1);
     newInstr->SetSrc2(src2);
     done->InsertBefore(newInstr);
+    LowererMD::Legalize(newInstr);
 
     if (isFloatSrc)
     {

+ 2 - 0
test/wasm/baselines/cse.baseline

@@ -0,0 +1,2 @@
+ --- CSE (foo_i32[0]): Add_I4
+PASSED

+ 38 - 0
test/wasm/cse.js

@@ -0,0 +1,38 @@
+//-------------------------------------------------------------------------------------------------------
+// Copyright (C) Microsoft Corporation and contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+//-------------------------------------------------------------------------------------------------------
+WScript.Flag("-wasmI64");
+
+function makeModule(type) {
+  const funcName = `foo_${type}`;
+  const mod = new WebAssembly.Module(WebAssembly.wabt.convertWast2Wasm(`
+  (module
+    (func (export "${funcName}") (param ${type}) (result ${type})
+      (${type}.sub
+        (${type}.add (get_local 0) (${type}.const 3))
+        (${type}.add (get_local 0) (${type}.const 3))
+      )
+    )
+  )`));
+  const {exports} = new WebAssembly.Instance(mod);
+  return exports[funcName];
+}
+const modules = {i32: makeModule("i32"), i64: makeModule("i64")};
+function test(type, value) {
+  const foo = modules[type];
+  let res = foo(value);
+  if (type === "i64") {
+    res = res.low + res.high;
+  }
+  if (res !== 0) {
+    print(`Error: ${type} (${value} + 3) - (${value} + 3) == ${res} !== 0`);
+  }
+}
+test("i32", 0);
+test("i32", 1);
+test("i64", 0);
+test("i64", 1);
+test("i64", 2 * 4294967296);
+
+print("PASSED");

+ 8 - 0
test/wasm/rlexe.xml

@@ -214,4 +214,12 @@
     <tags>exclude_amd64</tags>
   </default>
 </test>
+<test>
+  <default>
+    <files>cse.js</files>
+    <baseline>baselines/cse.baseline</baseline>
+    <compile-flags>-wasm -maic:0 -testtrace:cse:2.0-99.999</compile-flags>
+    <tags>exclude_jshost,exclude_win7,exclude_nonative</tags>
+  </default>
+</test>
 </regress-exe>