Skip to content
Permalink
Browse files
Snippefy op_add for the baseline JIT.
https://bugs.webkit.org/show_bug.cgi?id=150129

Reviewed by Geoffrey Garen and Saam Barati.

Performance is neutral for both 32-bit and 64-bit on X86_64.

* CMakeLists.txt:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
* JavaScriptCore.xcodeproj/project.pbxproj:
* jit/JIT.h:
(JSC::JIT::getOperandConstantInt):
- Move getOperandConstantInt() from the JSVALUE64 section to the common section
  because the snippet needs it.

* jit/JITAddGenerator.cpp: Added.
(JSC::JITAddGenerator::generateFastPath):
* jit/JITAddGenerator.h: Added.
(JSC::JITAddGenerator::JITAddGenerator):
(JSC::JITAddGenerator::endJumpList):
(JSC::JITAddGenerator::slowPathJumpList):
- JITAddGenerator implements an optimization for the case where 1 of the 2 operands
  is a constant int32_t.  It does not implement an optimization for the case where
  both operands are constant int32_t.  This is because:
  1. For the baseline JIT, the ASTBuilder will fold the 2 constants together.
  2. For the DFG, the AbstractInterpreter will also fold the 2 constants.

  Hence, such an optimization path (for 2 constant int32_t operands) would never
  be taken, and is why we won't implement it.

* jit/JITArithmetic.cpp:
(JSC::JIT::compileBinaryArithOp):
(JSC::JIT::compileBinaryArithOpSlowCase):
- Removed op_add cases.  These are no longer used by the op_add emitters.

(JSC::JIT::emit_op_add):
(JSC::JIT::emitSlow_op_add):
- Moved out from the JSVALUE64 section to the common section, and reimplemented
  using the snippet.

* jit/JITArithmetic32_64.cpp:
(JSC::JIT::emitBinaryDoubleOp):
(JSC::JIT::emit_op_add): Deleted.
(JSC::JIT::emitAdd32Constant): Deleted.
(JSC::JIT::emitSlow_op_add): Deleted.
- Remove 32-bit specific version of op_add.  The snippet serves both 32-bit
  and 64-bit implementations.

* jit/JITInlines.h:
(JSC::JIT::getOperandConstantInt):
- Move getOperandConstantInt() from the JSVALUE64 section to the common section
  because the snippet needs it.



Canonical link: https://commits.webkit.org/168997@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@191905 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
Mark Lam committed Nov 2, 2015
1 parent 0960136 commit a442c92f0d452f0b01e088e618453d9efb173cf0
@@ -430,6 +430,7 @@ set(JavaScriptCore_SOURCES
jit/HostCallReturnValue.cpp
jit/IntrinsicEmitter.cpp
jit/JIT.cpp
jit/JITAddGenerator.cpp
jit/JITArithmetic.cpp
jit/JITArithmetic32_64.cpp
jit/JITCall.cpp
@@ -1,3 +1,59 @@
2015-11-02 Mark Lam <mark.lam@apple.com>

Snippefy op_add for the baseline JIT.
https://bugs.webkit.org/show_bug.cgi?id=150129

Reviewed by Geoffrey Garen and Saam Barati.

Performance is neutral for both 32-bit and 64-bit on X86_64.

* CMakeLists.txt:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
* JavaScriptCore.xcodeproj/project.pbxproj:
* jit/JIT.h:
(JSC::JIT::getOperandConstantInt):
- Move getOperandConstantInt() from the JSVALUE64 section to the common section
because the snippet needs it.

* jit/JITAddGenerator.cpp: Added.
(JSC::JITAddGenerator::generateFastPath):
* jit/JITAddGenerator.h: Added.
(JSC::JITAddGenerator::JITAddGenerator):
(JSC::JITAddGenerator::endJumpList):
(JSC::JITAddGenerator::slowPathJumpList):
- JITAddGenerator implements an optimization for the case where 1 of the 2 operands
is a constant int32_t. It does not implement an optimization for the case where
both operands are constant int32_t. This is because:
1. For the baseline JIT, the ASTBuilder will fold the 2 constants together.
2. For the DFG, the AbstractInterpreter will also fold the 2 constants.

Hence, such an optimization path (for 2 constant int32_t operands) would never
be taken, and is why we won't implement it.

* jit/JITArithmetic.cpp:
(JSC::JIT::compileBinaryArithOp):
(JSC::JIT::compileBinaryArithOpSlowCase):
- Removed op_add cases. These are no longer used by the op_add emitters.

(JSC::JIT::emit_op_add):
(JSC::JIT::emitSlow_op_add):
- Moved out from the JSVALUE64 section to the common section, and reimplemented
using the snippet.

* jit/JITArithmetic32_64.cpp:
(JSC::JIT::emitBinaryDoubleOp):
(JSC::JIT::emit_op_add): Deleted.
(JSC::JIT::emitAdd32Constant): Deleted.
(JSC::JIT::emitSlow_op_add): Deleted.
- Remove 32-bit specific version of op_add. The snippet serves both 32-bit
and 64-bit implementations.

* jit/JITInlines.h:
(JSC::JIT::getOperandConstantInt):
- Move getOperandConstantInt() from the JSVALUE64 section to the common section
because the snippet needs it.

2015-11-02 Brian Burg <bburg@apple.com>

Run sort-Xcode-project-file for the JavaScriptCore project.
@@ -3518,7 +3574,6 @@
(JSC::GCAwareJITStubRoutineWithExceptionHandler::~GCAwareJITStubRoutineWithExceptionHandler): Deleted.
* jit/GCAwareJITStubRoutine.h:

>>>>>>> .r191351
2015-10-20 Tim Horton <timothy_horton@apple.com>

Try to fix the build by disabling MAC_GESTURE_EVENTS on 10.9 and 10.10
@@ -638,6 +638,7 @@
<ClCompile Include="..\jit\HostCallReturnValue.cpp" />
<ClCompile Include="..\jit\IntrinsicEmitter.cpp" />
<ClCompile Include="..\jit\JIT.cpp" />
<ClCompile Include="..\jit\JITAddGenerator.cpp" />
<ClCompile Include="..\jit\JITArithmetic.cpp" />
<ClCompile Include="..\jit\JITArithmetic32_64.cpp" />
<ClCompile Include="..\jit\JITCall.cpp" />
@@ -1455,6 +1456,7 @@
<ClInclude Include="..\jit\GPRInfo.h" />
<ClInclude Include="..\jit\HostCallReturnValue.h" />
<ClInclude Include="..\jit\JIT.h" />
<ClInclude Include="..\jit\JITAddGenerator.h" />
<ClInclude Include="..\jit\JITCode.h" />
<ClInclude Include="..\jit\JITCompilationEffort.h" />
<ClInclude Include="..\jit\JITDisassembler.h" />
@@ -420,6 +420,9 @@
<ClCompile Include="..\jit\JIT.cpp">
<Filter>jit</Filter>
</ClCompile>
<ClCompile Include="..\jit\JITAddGenerator.cpp">
<Filter>jit</Filter>
</ClCompile>
<ClCompile Include="..\jit\JITArithmetic.cpp">
<Filter>jit</Filter>
</ClCompile>
@@ -2492,6 +2495,9 @@
<ClInclude Include="..\jit\JIT.h">
<Filter>jit</Filter>
</ClInclude>
<ClInclude Include="..\jit\JITAddGenerator.h">
<Filter>jit</Filter>
</ClInclude>
<ClInclude Include="..\jit\JITCode.h">
<Filter>jit</Filter>
</ClInclude>
@@ -1924,6 +1924,8 @@
E49DC16D12EF295300184A1F /* SourceProviderCacheItem.h in Headers */ = {isa = PBXBuildFile; fileRef = E49DC14912EF261A00184A1F /* SourceProviderCacheItem.h */; settings = {ATTRIBUTES = (Private, ); }; };
FE0D4A061AB8DD0A002F54BF /* ExecutionTimeLimitTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE0D4A041AB8DD0A002F54BF /* ExecutionTimeLimitTest.cpp */; };
FE0D4A091ABA2437002F54BF /* GlobalContextWithFinalizerTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE0D4A071ABA2437002F54BF /* GlobalContextWithFinalizerTest.cpp */; };
FE1220271BE7F58C0039E6F2 /* JITAddGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1220261BE7F5640039E6F2 /* JITAddGenerator.h */; settings = {ASSET_TAGS = (); }; };
FE1220281BE7F5910039E6F2 /* JITAddGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE1220251BE7F5640039E6F2 /* JITAddGenerator.cpp */; settings = {ASSET_TAGS = (); }; };
FE1C0FFD1B193E9800B53FCA /* Exception.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1C0FFC1B193E9800B53FCA /* Exception.h */; settings = {ATTRIBUTES = (Private, ); }; };
FE1C0FFF1B194FD100B53FCA /* Exception.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE1C0FFE1B194FD100B53FCA /* Exception.cpp */; };
FE20CE9D15F04A9500DF3430 /* LLIntCLoop.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE20CE9B15F04A9500DF3430 /* LLIntCLoop.cpp */; };
@@ -4016,6 +4018,8 @@
FE0D4A051AB8DD0A002F54BF /* ExecutionTimeLimitTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ExecutionTimeLimitTest.h; path = API/tests/ExecutionTimeLimitTest.h; sourceTree = "<group>"; };
FE0D4A071ABA2437002F54BF /* GlobalContextWithFinalizerTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GlobalContextWithFinalizerTest.cpp; path = API/tests/GlobalContextWithFinalizerTest.cpp; sourceTree = "<group>"; };
FE0D4A081ABA2437002F54BF /* GlobalContextWithFinalizerTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GlobalContextWithFinalizerTest.h; path = API/tests/GlobalContextWithFinalizerTest.h; sourceTree = "<group>"; };
FE1220251BE7F5640039E6F2 /* JITAddGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITAddGenerator.cpp; sourceTree = "<group>"; };
FE1220261BE7F5640039E6F2 /* JITAddGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITAddGenerator.h; sourceTree = "<group>"; };
FE1C0FFC1B193E9800B53FCA /* Exception.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Exception.h; sourceTree = "<group>"; };
FE1C0FFE1B194FD100B53FCA /* Exception.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Exception.cpp; sourceTree = "<group>"; };
FE20CE9B15F04A9500DF3430 /* LLIntCLoop.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntCLoop.cpp; path = llint/LLIntCLoop.cpp; sourceTree = "<group>"; };
@@ -4651,6 +4655,8 @@
DE5A09FF1BA3AC3E003D4424 /* IntrinsicEmitter.cpp */,
1429D92D0ED22D7000B89619 /* JIT.cpp */,
1429D92E0ED22D7000B89619 /* JIT.h */,
FE1220251BE7F5640039E6F2 /* JITAddGenerator.cpp */,
FE1220261BE7F5640039E6F2 /* JITAddGenerator.h */,
86A90ECF0EE7D51F00AB350D /* JITArithmetic.cpp */,
A75706DD118A2BCF0057F88F /* JITArithmetic32_64.cpp */,
86CC85A20EE79B7400288682 /* JITCall.cpp */,
@@ -7242,6 +7248,7 @@
BC18C4260E16F5CD00B34460 /* JSRetainPtr.h in Headers */,
14874AE615EBDE4A002E3587 /* JSScope.h in Headers */,
A7C0C4AC168103020017011D /* JSScriptRefPrivate.h in Headers */,
FE1220271BE7F58C0039E6F2 /* JITAddGenerator.h in Headers */,
0F919D11157F332C004A4E7D /* JSSegmentedVariableObject.h in Headers */,
A7299D9E17D12837005F5FF9 /* JSSet.h in Headers */,
A790DD70182F499700588807 /* JSSetIterator.h in Headers */,
@@ -8296,6 +8303,7 @@
0F300B7B18AB1B1400A6D72E /* DFGIntegerCheckCombiningPhase.cpp in Sources */,
0F898F311B27689F0083A33C /* DFGIntegerRangeOptimizationPhase.cpp in Sources */,
0FC97F3D18202119002C9B26 /* DFGInvalidationPointInjectionPhase.cpp in Sources */,
FE1220281BE7F5910039E6F2 /* JITAddGenerator.cpp in Sources */,
0FEA0A33170D40BF00BB722C /* DFGJITCode.cpp in Sources */,
86EC9DCB1328DF82002B2AD7 /* DFGJITCompiler.cpp in Sources */,
A78A9778179738B8009DF744 /* DFGJITFinalizer.cpp in Sources */,
@@ -403,6 +403,8 @@ namespace JSC {
void emitGetVirtualRegister(int src, JSValueRegs dst);
void emitPutVirtualRegister(int dst, JSValueRegs src);

int32_t getOperandConstantInt(int src);

#if USE(JSVALUE32_64)
bool getOperandConstantInt(int op1, int op2, int& op, int32_t& constant);

@@ -427,7 +429,6 @@ namespace JSC {
void compileGetByIdHotPath(const Identifier*);

// Arithmetic opcode helpers
void emitAdd32Constant(int dst, int op, int32_t constant, ResultType opType);
void emitSub32Constant(int dst, int op, int32_t constant, ResultType opType);
void emitBinaryDoubleOp(OpcodeID, int dst, int op1, int op2, OperandTypes, JumpList& notInt32Op1, JumpList& notInt32Op2, bool op1IsInRegisters = true, bool op2IsInRegisters = true);

@@ -447,8 +448,6 @@ namespace JSC {
emitPutVirtualRegister(dst, payload);
}

int32_t getOperandConstantInt(int src);

Jump emitJumpIfJSCell(RegisterID);
Jump emitJumpIfBothJSCells(RegisterID, RegisterID, RegisterID);
void emitJumpSlowCaseIfJSCell(RegisterID);
@@ -0,0 +1,130 @@
/*
* Copyright (C) 2015 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "config.h"

#if ENABLE(JIT)
#include "JITAddGenerator.h"

namespace JSC {

void JITAddGenerator::generateFastPath(CCallHelpers& jit)
{
ASSERT(m_scratchGPR != InvalidGPRReg);
ASSERT(m_scratchGPR != m_left.payloadGPR());
ASSERT(m_scratchGPR != m_right.payloadGPR());
#if ENABLE(JSVALUE32_64)
ASSERT(m_scratchGPR != m_left.tagGPR());x
ASSERT(m_scratchGPR != m_right.tagGPR());
ASSERT(m_scratchFPR != InvalidFPRReg);
#endif

if (!m_leftType.mightBeNumber() || !m_rightType.mightBeNumber()) {
m_slowPathJumpList.append(jit.jump());
return;
}

if (m_operandsConstness == RightIsConstInt32) {
// Try to do intVar + intConstant.
CCallHelpers::Jump notInt32 = jit.branchIfNotInt32(m_left);

m_slowPathJumpList.append(jit.branchAdd32(CCallHelpers::Overflow, m_left.payloadGPR(), CCallHelpers::Imm32(m_rightConstInt32), m_scratchGPR));

jit.boxInt32(m_scratchGPR, m_result);
m_endJumpList.append(jit.jump());

if (!jit.supportsFloatingPoint()) {
m_slowPathJumpList.append(notInt32);
return;
}

// Try to do doubleVar + double(intConstant).
notInt32.link(&jit);
if (!m_leftType.definitelyIsNumber())
m_slowPathJumpList.append(jit.branchIfNotNumber(m_left, m_scratchGPR));

jit.unboxDoubleNonDestructive(m_left, m_leftFPR, m_scratchGPR, m_scratchFPR);

jit.move(CCallHelpers::Imm32(m_rightConstInt32), m_scratchGPR);
jit.convertInt32ToDouble(m_scratchGPR, m_rightFPR);

// Fall thru to doubleVar + doubleVar.

} else {
ASSERT(m_operandsConstness == NeitherAreConstInt32);
CCallHelpers::Jump leftNotInt;
CCallHelpers::Jump rightNotInt;

// Try to do intVar + intVar.
leftNotInt = jit.branchIfNotInt32(m_left);
rightNotInt = jit.branchIfNotInt32(m_right);

m_slowPathJumpList.append(jit.branchAdd32(CCallHelpers::Overflow, m_right.payloadGPR(), m_left.payloadGPR(), m_scratchGPR));

jit.boxInt32(m_scratchGPR, m_result);
m_endJumpList.append(jit.jump());

if (!jit.supportsFloatingPoint()) {
m_slowPathJumpList.append(leftNotInt);
m_slowPathJumpList.append(rightNotInt);
return;
}

leftNotInt.link(&jit);
if (!m_leftType.definitelyIsNumber())
m_slowPathJumpList.append(jit.branchIfNotNumber(m_left, m_scratchGPR));
if (!m_rightType.definitelyIsNumber())
m_slowPathJumpList.append(jit.branchIfNotNumber(m_right, m_scratchGPR));

jit.unboxDoubleNonDestructive(m_left, m_leftFPR, m_scratchGPR, m_scratchFPR);
CCallHelpers::Jump rightIsDouble = jit.branchIfNotInt32(m_right);

jit.convertInt32ToDouble(m_right.payloadGPR(), m_rightFPR);
CCallHelpers::Jump rightWasInteger = jit.jump();

rightNotInt.link(&jit);
if (!m_rightType.definitelyIsNumber())
m_slowPathJumpList.append(jit.branchIfNotNumber(m_right, m_scratchGPR));

jit.convertInt32ToDouble(m_left.payloadGPR(), m_leftFPR);

rightIsDouble.link(&jit);
jit.unboxDoubleNonDestructive(m_right, m_rightFPR, m_scratchGPR, m_scratchFPR);

rightWasInteger.link(&jit);

// Fall thru to doubleVar + doubleVar.
}

// Do doubleVar + doubleVar.
jit.addDouble(m_rightFPR, m_leftFPR);
jit.boxDouble(m_leftFPR, m_result);

m_endJumpList.append(jit.jump());
}

} // namespace JSC

#endif // ENABLE(JIT)

0 comments on commit a442c92

Please sign in to comment.