Bug 1574415 - Part 4: Move emitGuardToInt32ModUint32 and emitGuardToUint8Clamped into CacheIRCompiler. r=jandem
authorAndré Bargull <andre.bargull@gmail.com>
Mon, 07 Oct 2019 11:57:10 +0000
changeset 496545 ef1f7213e654816da44e0963a27adf1510e1ea03
parent 496544 3f73e398ca61d24ddb9f8de379e1c077452ff9b1
child 496546 f3b48a00be455786162394ad78a8d044349af958
push id36661
push userccoroiu@mozilla.com
push dateMon, 07 Oct 2019 21:50:01 +0000
treeherdermozilla-central@2b4c8b7a255c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1574415
milestone71.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1574415 - Part 4: Move emitGuardToInt32ModUint32 and emitGuardToUint8Clamped into CacheIRCompiler. r=jandem IonCacheIRCompiler used `MacroAssembler::truncateConstantOrRegisterToInt32` resp. `clampConstantOrRegisterToUint8`, which allowed to handle more types than just int32 and double, but since `SetPropIRGenerator::tryAttachSetTypedElement` only allows number inputs, this code was probably never taken in practice. Therefore the CacheIRCompiler implementation for both methods only handles int32 and double inputs. As an optimisation to generate better assembly and to reduce register pressure, both methods have special-cases for known int32 inputs and are using `ScratchTagScope` to avoid splitting the tag two times. Part 7 will move the duplicated code into a shared helper function. Differential Revision: https://phabricator.services.mozilla.com/D47752
js/src/jit/BaselineCacheIRCompiler.cpp
js/src/jit/CacheIRCompiler.cpp
js/src/jit/CacheIRCompiler.h
js/src/jit/IonCacheIRCompiler.cpp
--- a/js/src/jit/BaselineCacheIRCompiler.cpp
+++ b/js/src/jit/BaselineCacheIRCompiler.cpp
@@ -414,71 +414,16 @@ bool BaselineCacheIRCompiler::emitGuardS
     return false;
   }
 
   Address addr(stubAddress(reader.stubOffset()));
   masm.branchPtr(Assembler::NotEqual, addr, sym, failure->label());
   return true;
 }
 
-bool BaselineCacheIRCompiler::emitGuardToInt32ModUint32() {
-  JitSpew(JitSpew_Codegen, __FUNCTION__);
-  ValueOperand value = allocator.useValueRegister(masm, reader.valOperandId());
-  Register output = allocator.defineRegister(masm, reader.int32OperandId());
-
-  FailurePath* failure;
-  if (!addFailurePath(&failure)) {
-    return false;
-  }
-
-  Label notInt32;
-  masm.branchTestInt32(Assembler::NotEqual, value, &notInt32);
-  masm.unboxInt32(value, output);
-
-  Label done;
-  masm.jump(&done);
-
-  // If the value is a double, truncate; else, jump to failure.
-  masm.bind(&notInt32);
-  masm.branchTestDouble(Assembler::NotEqual, value, failure->label());
-  masm.unboxDouble(value, FloatReg0);
-  masm.branchTruncateDoubleMaybeModUint32(FloatReg0, output, failure->label());
-
-  masm.bind(&done);
-  return true;
-}
-
-bool BaselineCacheIRCompiler::emitGuardToUint8Clamped() {
-  JitSpew(JitSpew_Codegen, __FUNCTION__);
-  ValueOperand value = allocator.useValueRegister(masm, reader.valOperandId());
-  Register output = allocator.defineRegister(masm, reader.int32OperandId());
-
-  FailurePath* failure;
-  if (!addFailurePath(&failure)) {
-    return false;
-  }
-
-  Label notInt32;
-  masm.branchTestInt32(Assembler::NotEqual, value, &notInt32);
-  masm.unboxInt32(value, output);
-  masm.clampIntToUint8(output);
-
-  Label done;
-  masm.jump(&done);
-
-  // If the value is a double, clamp to uint8; else, jump to failure.
-  masm.bind(&notInt32);
-  masm.branchTestDouble(Assembler::NotEqual, value, failure->label());
-  masm.unboxDouble(value, FloatReg0);
-  masm.clampDoubleToUint8(FloatReg0, output);
-
-  masm.bind(&done);
-  return true;
-}
-
 bool BaselineCacheIRCompiler::emitLoadValueResult() {
   JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   masm.loadValue(stubAddress(reader.stubOffset()), output.valueReg());
   return true;
 }
 
 bool BaselineCacheIRCompiler::emitLoadFixedSlotResult() {
--- a/js/src/jit/CacheIRCompiler.cpp
+++ b/js/src/jit/CacheIRCompiler.cpp
@@ -13,16 +13,17 @@
 
 #include "jslibmath.h"
 #include "jit/BaselineCacheIRCompiler.h"
 #include "jit/IonCacheIRCompiler.h"
 #include "jit/IonIC.h"
 #include "jit/SharedICHelpers.h"
 #include "jit/SharedICRegisters.h"
 #include "proxy/Proxy.h"
+#include "vm/ArrayBufferObject.h"
 #include "vm/GeneratorObject.h"
 
 #include "builtin/Boolean-inl.h"
 
 #include "jit/MacroAssembler-inl.h"
 #include "jit/SharedICHelpers-inl.h"
 #include "jit/VMFunctionList-inl.h"
 #include "vm/Realm-inl.h"
@@ -1561,16 +1562,127 @@ bool CacheIRCompiler::emitGuardToInt32In
     // ToPropertyKey(-0.0) is "0", so we can truncate -0.0 to 0 here.
     masm.convertDoubleToInt32(floatReg, output, floatReg.failure(), false);
   }
 
   masm.bind(&done);
   return true;
 }
 
+bool CacheIRCompiler::emitGuardToInt32ModUint32() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
+  ValOperandId inputId = reader.valOperandId();
+  Register output = allocator.defineRegister(masm, reader.int32OperandId());
+
+  if (allocator.knownType(inputId) == JSVAL_TYPE_INT32) {
+    ConstantOrRegister input = allocator.useConstantOrRegister(masm, inputId);
+    if (input.constant()) {
+      masm.move32(Imm32(input.value().toInt32()), output);
+    } else {
+      MOZ_ASSERT(input.reg().type() == MIRType::Int32);
+      masm.move32(input.reg().typedReg().gpr(), output);
+    }
+    return true;
+  }
+
+  ValueOperand input = allocator.useValueRegister(masm, inputId);
+
+  FailurePath* failure;
+  if (!addFailurePath(&failure)) {
+    return false;
+  }
+
+  Label done;
+
+  {
+    ScratchTagScope tag(masm, input);
+    masm.splitTagForTest(input, tag);
+
+    Label notInt32;
+    masm.branchTestInt32(Assembler::NotEqual, tag, &notInt32);
+    {
+      ScratchTagScopeRelease _(&tag);
+
+      masm.unboxInt32(input, output);
+      masm.jump(&done);
+    }
+    masm.bind(&notInt32);
+
+    // If the value is a double, truncate; else, jump to failure.
+    masm.branchTestDouble(Assembler::NotEqual, tag, failure->label());
+    {
+      ScratchTagScopeRelease _(&tag);
+      AutoScratchFloatRegister floatReg(this, failure);
+
+      masm.unboxDouble(input, floatReg);
+      masm.branchTruncateDoubleMaybeModUint32(floatReg, output,
+                                              floatReg.failure());
+    }
+  }
+
+  masm.bind(&done);
+  return true;
+}
+
+bool CacheIRCompiler::emitGuardToUint8Clamped() {
+  JitSpew(JitSpew_Codegen, __FUNCTION__);
+  ValOperandId inputId = reader.valOperandId();
+  Register output = allocator.defineRegister(masm, reader.int32OperandId());
+
+  if (allocator.knownType(inputId) == JSVAL_TYPE_INT32) {
+    ConstantOrRegister input = allocator.useConstantOrRegister(masm, inputId);
+    if (input.constant()) {
+      masm.move32(Imm32(ClampDoubleToUint8(input.value().toInt32())), output);
+    } else {
+      MOZ_ASSERT(input.reg().type() == MIRType::Int32);
+      masm.move32(input.reg().typedReg().gpr(), output);
+      masm.clampIntToUint8(output);
+    }
+    return true;
+  }
+
+  ValueOperand input = allocator.useValueRegister(masm, inputId);
+
+  FailurePath* failure;
+  if (!addFailurePath(&failure)) {
+    return false;
+  }
+
+  Label done;
+
+  {
+    ScratchTagScope tag(masm, input);
+    masm.splitTagForTest(input, tag);
+
+    Label notInt32;
+    masm.branchTestInt32(Assembler::NotEqual, tag, &notInt32);
+    {
+      ScratchTagScopeRelease _(&tag);
+
+      masm.unboxInt32(input, output);
+      masm.clampIntToUint8(output);
+      masm.jump(&done);
+    }
+    masm.bind(&notInt32);
+
+    // If the value is a double, clamp to uint8; else, jump to failure.
+    masm.branchTestDouble(Assembler::NotEqual, tag, failure->label());
+    {
+      ScratchTagScopeRelease _(&tag);
+      AutoScratchFloatRegister floatReg(this);
+
+      masm.unboxDouble(input, floatReg);
+      masm.clampDoubleToUint8(floatReg, output);
+    }
+  }
+
+  masm.bind(&done);
+  return true;
+}
+
 bool CacheIRCompiler::emitGuardType() {
   JitSpew(JitSpew_Codegen, __FUNCTION__);
   ValOperandId inputId = reader.valOperandId();
   ValueType type = reader.valueType();
 
   if (allocator.knownType(inputId) == JSValueType(type)) {
     return true;
   }
--- a/js/src/jit/CacheIRCompiler.h
+++ b/js/src/jit/CacheIRCompiler.h
@@ -29,16 +29,18 @@ class IonCacheIRCompiler;
   _(GuardIsObjectOrNull)                  \
   _(GuardToBoolean)                       \
   _(GuardToString)                        \
   _(GuardToSymbol)                        \
   _(GuardToBigInt)                        \
   _(GuardIsNumber)                        \
   _(GuardToInt32)                         \
   _(GuardToInt32Index)                    \
+  _(GuardToInt32ModUint32)                \
+  _(GuardToUint8Clamped)                  \
   _(GuardType)                            \
   _(GuardClass)                           \
   _(GuardGroupHasUnanalyzedNewScript)     \
   _(GuardIsExtensible)                    \
   _(GuardFunctionIsNative)                \
   _(GuardFunctionIsConstructor)           \
   _(GuardSpecificNativeFunction)          \
   _(GuardFunctionPrototype)               \
--- a/js/src/jit/IonCacheIRCompiler.cpp
+++ b/js/src/jit/IonCacheIRCompiler.cpp
@@ -783,52 +783,16 @@ bool IonCacheIRCompiler::emitGuardSpecif
     return false;
   }
 
   masm.branchPtr(Assembler::NotEqual, sym, ImmGCPtr(expected),
                  failure->label());
   return true;
 }
 
-bool IonCacheIRCompiler::emitGuardToInt32ModUint32() {
-  JitSpew(JitSpew_Codegen, __FUNCTION__);
-  ConstantOrRegister val =
-      allocator.useConstantOrRegister(masm, reader.valOperandId());
-  Register output = allocator.defineRegister(masm, reader.int32OperandId());
-
-  FailurePath* failure;
-  if (!addFailurePath(&failure)) {
-    return false;
-  }
-
-  FloatRegister maybeTempDouble = ic_->asSetPropertyIC()->maybeTempDouble();
-  MOZ_ASSERT(maybeTempDouble != InvalidFloatReg);
-
-  return masm.truncateConstantOrRegisterToInt32(cx_, val, maybeTempDouble,
-                                                output, failure->label());
-}
-
-bool IonCacheIRCompiler::emitGuardToUint8Clamped() {
-  JitSpew(JitSpew_Codegen, __FUNCTION__);
-  ConstantOrRegister val =
-      allocator.useConstantOrRegister(masm, reader.valOperandId());
-  Register output = allocator.defineRegister(masm, reader.int32OperandId());
-
-  FailurePath* failure;
-  if (!addFailurePath(&failure)) {
-    return false;
-  }
-
-  FloatRegister maybeTempDouble = ic_->asSetPropertyIC()->maybeTempDouble();
-  MOZ_ASSERT(maybeTempDouble != InvalidFloatReg);
-
-  return masm.clampConstantOrRegisterToUint8(cx_, val, maybeTempDouble, output,
-                                             failure->label());
-}
-
 bool IonCacheIRCompiler::emitLoadValueResult() {
   MOZ_CRASH("Baseline-specific op");
 }
 
 bool IonCacheIRCompiler::emitLoadFixedSlotResult() {
   JitSpew(JitSpew_Codegen, __FUNCTION__);
   AutoOutputRegister output(*this);
   Register obj = allocator.useRegister(masm, reader.objOperandId());