Title: [193989] trunk/Source/_javascript_Core
Revision
193989
Author
benja...@webkit.org
Date
2015-12-11 15:45:04 -0800 (Fri, 11 Dec 2015)

Log Message

[JSC] Add an implementation of pow() taking an integer exponent to B3
https://bugs.webkit.org/show_bug.cgi?id=152165

Reviewed by Mark Lam.

LLVM has this really neat optimized opcode for
raising the power of something by an integer exponent.

There is no such native instruction so we need to extend
the existing FTLOutput API to something efficient.

DFG has a pretty competitive implementation. In this patch,
I added a version of it to B3.
I created powDoubleInt32() instead of putting the code directly
in FTL for easier testing and optimization.

* CMakeLists.txt:
* _javascript_Core.xcodeproj/project.pbxproj:
* b3/B3MathExtras.cpp: Added.
(JSC::B3::powDoubleInt32):
* b3/B3MathExtras.h: Added.
* b3/B3MemoryValue.h:
* b3/testb3.cpp:
(JSC::B3::testPowDoubleByIntegerLoop):
(JSC::B3::run):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::compileArithPowIntegerFastPath):
* ftl/FTLB3Output.cpp:
(JSC::FTL::Output::doublePowi):
* ftl/FTLB3Output.h:
(JSC::FTL::Output::doublePowi): Deleted.

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/CMakeLists.txt (193988 => 193989)


--- trunk/Source/_javascript_Core/CMakeLists.txt	2015-12-11 23:30:34 UTC (rev 193988)
+++ trunk/Source/_javascript_Core/CMakeLists.txt	2015-12-11 23:45:04 UTC (rev 193989)
@@ -115,6 +115,7 @@
     b3/B3InsertionSet.cpp
     b3/B3LowerMacros.cpp
     b3/B3LowerToAir.cpp
+    b3/B3MathExtras.cpp
     b3/B3MemoryValue.cpp
     b3/B3MoveConstants.cpp
     b3/B3OpaqueByproducts.cpp

Modified: trunk/Source/_javascript_Core/ChangeLog (193988 => 193989)


--- trunk/Source/_javascript_Core/ChangeLog	2015-12-11 23:30:34 UTC (rev 193988)
+++ trunk/Source/_javascript_Core/ChangeLog	2015-12-11 23:45:04 UTC (rev 193989)
@@ -1,3 +1,37 @@
+2015-12-11  Benjamin Poulain  <benja...@webkit.org>
+
+        [JSC] Add an implementation of pow() taking an integer exponent to B3
+        https://bugs.webkit.org/show_bug.cgi?id=152165
+
+        Reviewed by Mark Lam.
+
+        LLVM has this really neat optimized opcode for
+        raising the power of something by an integer exponent.
+
+        There is no such native instruction so we need to extend
+        the existing FTLOutput API to something efficient.
+
+        DFG has a pretty competitive implementation. In this patch,
+        I added a version of it to B3.
+        I created powDoubleInt32() instead of putting the code directly
+        in FTL for easier testing and optimization.
+
+        * CMakeLists.txt:
+        * _javascript_Core.xcodeproj/project.pbxproj:
+        * b3/B3MathExtras.cpp: Added.
+        (JSC::B3::powDoubleInt32):
+        * b3/B3MathExtras.h: Added.
+        * b3/B3MemoryValue.h:
+        * b3/testb3.cpp:
+        (JSC::B3::testPowDoubleByIntegerLoop):
+        (JSC::B3::run):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::compileArithPowIntegerFastPath):
+        * ftl/FTLB3Output.cpp:
+        (JSC::FTL::Output::doublePowi):
+        * ftl/FTLB3Output.h:
+        (JSC::FTL::Output::doublePowi): Deleted.
+
 2015-12-11  Filip Pizlo  <fpi...@apple.com>
 
         B3 should have CSE

Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (193988 => 193989)


--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2015-12-11 23:30:34 UTC (rev 193988)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2015-12-11 23:45:04 UTC (rev 193989)
@@ -1135,6 +1135,8 @@
 		43422A631C158E6D00E2EB98 /* B3ConstFloatValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 43422A611C15871B00E2EB98 /* B3ConstFloatValue.h */; };
 		43422A661C16267500E2EB98 /* B3ReduceDoubleToFloat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43422A641C16221E00E2EB98 /* B3ReduceDoubleToFloat.cpp */; };
 		43422A671C16267800E2EB98 /* B3ReduceDoubleToFloat.h in Headers */ = {isa = PBXBuildFile; fileRef = 43422A651C16221E00E2EB98 /* B3ReduceDoubleToFloat.h */; };
+		43AB26C61C1A535900D82AE6 /* B3MathExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = 43AB26C51C1A52F700D82AE6 /* B3MathExtras.h */; };
+		43AB26C71C1A535C00D82AE6 /* B3MathExtras.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43AB26C41C1A52F700D82AE6 /* B3MathExtras.cpp */; };
 		4443AE3316E188D90076F110 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 51F0EB6105C86C6B00E6DF1B /* Foundation.framework */; };
 		451539B912DC994500EF7AC4 /* Yarr.h in Headers */ = {isa = PBXBuildFile; fileRef = 451539B812DC994500EF7AC4 /* Yarr.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		52678F8E1A031009006A306D /* BasicBlockLocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52678F8C1A031009006A306D /* BasicBlockLocation.cpp */; };
@@ -2015,17 +2017,17 @@
 		FE3913541B794F6E00EDAF71 /* LiveObjectList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE3913521B794AC900EDAF71 /* LiveObjectList.cpp */; };
 		FE3913551B794F8A00EDAF71 /* LiveObjectData.h in Headers */ = {isa = PBXBuildFile; fileRef = FE3913511B794AC900EDAF71 /* LiveObjectData.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		FE3913561B794F8F00EDAF71 /* LiveObjectList.h in Headers */ = {isa = PBXBuildFile; fileRef = FE3913531B794AC900EDAF71 /* LiveObjectList.h */; settings = {ATTRIBUTES = (Private, ); }; };
-		FE3A06A61C10B72D00390FDD /* JITBitOrGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = FE3A06A41C10B70800390FDD /* JITBitOrGenerator.h */; settings = {ASSET_TAGS = (); }; };
-		FE3A06A81C10BC8100390FDD /* JITBitBinaryOpGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = FE3A06A71C10BC7400390FDD /* JITBitBinaryOpGenerator.h */; settings = {ASSET_TAGS = (); }; };
-		FE3A06AC1C10C39E00390FDD /* JITBitOrGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE3A06A31C10B70800390FDD /* JITBitOrGenerator.cpp */; settings = {ASSET_TAGS = (); }; };
-		FE3A06B11C10CB8400390FDD /* JITBitAndGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE3A06AD1C10CB6F00390FDD /* JITBitAndGenerator.cpp */; settings = {ASSET_TAGS = (); }; };
-		FE3A06B21C10CB8900390FDD /* JITBitAndGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = FE3A06AE1C10CB6F00390FDD /* JITBitAndGenerator.h */; settings = {ASSET_TAGS = (); }; };
-		FE3A06B31C10CB8E00390FDD /* JITBitXorGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE3A06AF1C10CB6F00390FDD /* JITBitXorGenerator.cpp */; settings = {ASSET_TAGS = (); }; };
-		FE3A06B41C10CB9300390FDD /* JITBitXorGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = FE3A06B01C10CB6F00390FDD /* JITBitXorGenerator.h */; settings = {ASSET_TAGS = (); }; };
-		FE3A06BD1C11040D00390FDD /* JITLeftShiftGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE3A06B61C1103D900390FDD /* JITLeftShiftGenerator.cpp */; settings = {ASSET_TAGS = (); }; };
-		FE3A06BE1C11041200390FDD /* JITLeftShiftGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = FE3A06B71C1103D900390FDD /* JITLeftShiftGenerator.h */; settings = {ASSET_TAGS = (); }; };
-		FE3A06BF1C11041600390FDD /* JITRightShiftGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE3A06B81C1103D900390FDD /* JITRightShiftGenerator.cpp */; settings = {ASSET_TAGS = (); }; };
-		FE3A06C01C11041A00390FDD /* JITRightShiftGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = FE3A06B91C1103D900390FDD /* JITRightShiftGenerator.h */; settings = {ASSET_TAGS = (); }; };
+		FE3A06A61C10B72D00390FDD /* JITBitOrGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = FE3A06A41C10B70800390FDD /* JITBitOrGenerator.h */; };
+		FE3A06A81C10BC8100390FDD /* JITBitBinaryOpGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = FE3A06A71C10BC7400390FDD /* JITBitBinaryOpGenerator.h */; };
+		FE3A06AC1C10C39E00390FDD /* JITBitOrGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE3A06A31C10B70800390FDD /* JITBitOrGenerator.cpp */; };
+		FE3A06B11C10CB8400390FDD /* JITBitAndGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE3A06AD1C10CB6F00390FDD /* JITBitAndGenerator.cpp */; };
+		FE3A06B21C10CB8900390FDD /* JITBitAndGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = FE3A06AE1C10CB6F00390FDD /* JITBitAndGenerator.h */; };
+		FE3A06B31C10CB8E00390FDD /* JITBitXorGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE3A06AF1C10CB6F00390FDD /* JITBitXorGenerator.cpp */; };
+		FE3A06B41C10CB9300390FDD /* JITBitXorGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = FE3A06B01C10CB6F00390FDD /* JITBitXorGenerator.h */; };
+		FE3A06BD1C11040D00390FDD /* JITLeftShiftGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE3A06B61C1103D900390FDD /* JITLeftShiftGenerator.cpp */; };
+		FE3A06BE1C11041200390FDD /* JITLeftShiftGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = FE3A06B71C1103D900390FDD /* JITLeftShiftGenerator.h */; };
+		FE3A06BF1C11041600390FDD /* JITRightShiftGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE3A06B81C1103D900390FDD /* JITRightShiftGenerator.cpp */; };
+		FE3A06C01C11041A00390FDD /* JITRightShiftGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = FE3A06B91C1103D900390FDD /* JITRightShiftGenerator.h */; };
 		FE4238901BE18C3C00514737 /* JITSubGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE42388F1BE18C1200514737 /* JITSubGenerator.cpp */; };
 		FE4BFF2B1AD476E700088F87 /* FunctionOverrides.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE4BFF291AD476E700088F87 /* FunctionOverrides.cpp */; };
 		FE4BFF2C1AD476E700088F87 /* FunctionOverrides.h in Headers */ = {isa = PBXBuildFile; fileRef = FE4BFF2A1AD476E700088F87 /* FunctionOverrides.h */; };
@@ -3211,6 +3213,8 @@
 		43422A611C15871B00E2EB98 /* B3ConstFloatValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3ConstFloatValue.h; path = b3/B3ConstFloatValue.h; sourceTree = "<group>"; };
 		43422A641C16221E00E2EB98 /* B3ReduceDoubleToFloat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3ReduceDoubleToFloat.cpp; path = b3/B3ReduceDoubleToFloat.cpp; sourceTree = "<group>"; };
 		43422A651C16221E00E2EB98 /* B3ReduceDoubleToFloat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3ReduceDoubleToFloat.h; path = b3/B3ReduceDoubleToFloat.h; sourceTree = "<group>"; };
+		43AB26C41C1A52F700D82AE6 /* B3MathExtras.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3MathExtras.cpp; path = b3/B3MathExtras.cpp; sourceTree = "<group>"; };
+		43AB26C51C1A52F700D82AE6 /* B3MathExtras.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3MathExtras.h; path = b3/B3MathExtras.h; sourceTree = "<group>"; };
 		449097EE0F8F81B50076A327 /* FeatureDefines.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = FeatureDefines.xcconfig; sourceTree = "<group>"; };
 		451539B812DC994500EF7AC4 /* Yarr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Yarr.h; path = yarr/Yarr.h; sourceTree = "<group>"; };
 		45E12D8806A49B0F00E9DF84 /* jsc.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = jsc.cpp; sourceTree = "<group>"; tabWidth = 4; };
@@ -4636,6 +4640,8 @@
 				0F338E1A1BF286EA0013C88F /* B3LowerMacros.h */,
 				0FEC84D31BDACDAC0080FF74 /* B3LowerToAir.cpp */,
 				0FEC84D41BDACDAC0080FF74 /* B3LowerToAir.h */,
+				43AB26C41C1A52F700D82AE6 /* B3MathExtras.cpp */,
+				43AB26C51C1A52F700D82AE6 /* B3MathExtras.h */,
 				0FEC84D51BDACDAC0080FF74 /* B3MemoryValue.cpp */,
 				0FEC84D61BDACDAC0080FF74 /* B3MemoryValue.h */,
 				0F338E031BF0276C0013C88F /* B3MoveConstants.cpp */,
@@ -7564,6 +7570,7 @@
 				70EC0EC31AA0D7DA00B6AAFA /* JSStringIterator.h in Headers */,
 				2600B5A7152BAAA70091EE5F /* JSStringJoiner.h in Headers */,
 				BC18C4280E16F5CD00B34460 /* JSStringRef.h in Headers */,
+				43AB26C61C1A535900D82AE6 /* B3MathExtras.h in Headers */,
 				BC18C4290E16F5CD00B34460 /* JSStringRefCF.h in Headers */,
 				1A28D4A8177B71C80007FA3C /* JSStringRefPrivate.h in Headers */,
 				0F919D0D157EE0A2004A4E7D /* JSSymbolTableObject.h in Headers */,
@@ -8437,6 +8444,7 @@
 				0FEC85731BDACDC70080FF74 /* AirCCallSpecial.cpp in Sources */,
 				0FEC85751BDACDC70080FF74 /* AirCode.cpp in Sources */,
 				0F4570381BE44C910062A629 /* AirEliminateDeadCode.cpp in Sources */,
+				43AB26C71C1A535C00D82AE6 /* B3MathExtras.cpp in Sources */,
 				0FEC85781BDACDC70080FF74 /* AirGenerate.cpp in Sources */,
 				0FEC85931BDB1E100080FF74 /* AirGenerated.cpp in Sources */,
 				0FEC857B1BDACDC70080FF74 /* AirHandleCalleeSaves.cpp in Sources */,

Added: trunk/Source/_javascript_Core/b3/B3MathExtras.cpp (0 => 193989)


--- trunk/Source/_javascript_Core/b3/B3MathExtras.cpp	                        (rev 0)
+++ trunk/Source/_javascript_Core/b3/B3MathExtras.cpp	2015-12-11 23:45:04 UTC (rev 193989)
@@ -0,0 +1,126 @@
+/*
+ * 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"
+#include "B3MathExtras.h"
+
+#if ENABLE(B3_JIT)
+
+#include "B3BasicBlockInlines.h"
+#include "B3CCallValue.h"
+#include "B3Const32Value.h"
+#include "B3ConstDoubleValue.h"
+#include "B3ConstPtrValue.h"
+#include "B3ControlValue.h"
+#include "B3UpsilonValue.h"
+#include "B3ValueInlines.h"
+
+namespace JSC { namespace B3 {
+
+std::pair<BasicBlock*, Value*> powDoubleInt32(Procedure& procedure, BasicBlock* start, Origin origin, Value* x, Value* y)
+{
+    BasicBlock* functionCallCase = procedure.addBlock();
+    BasicBlock* loopPreHeaderCase = procedure.addBlock();
+    BasicBlock* loopTestForEvenCase = procedure.addBlock();
+    BasicBlock* loopOdd = procedure.addBlock();
+    BasicBlock* loopEvenOdd = procedure.addBlock();
+    BasicBlock* continuation = procedure.addBlock();
+
+    Value* shouldGoSlowPath = start->appendNew<Value>(procedure, Above, origin,
+        y,
+        start->appendNew<Const32Value>(procedure, origin, 1000));
+    start->appendNew<ControlValue>(
+        procedure, Branch, origin,
+        shouldGoSlowPath,
+        FrequentedBlock(functionCallCase), FrequentedBlock(loopPreHeaderCase));
+
+    // Function call.
+    Value* yAsDouble = functionCallCase->appendNew<Value>(procedure, IToD, origin, y);
+    Value* powResult = functionCallCase->appendNew<CCallValue>(
+        procedure, Double, origin,
+        functionCallCase->appendNew<ConstPtrValue>(procedure, origin, bitwise_cast<void*>(pow)),
+        x, yAsDouble);
+    UpsilonValue* powResultUpsilon = functionCallCase->appendNew<UpsilonValue>(procedure, origin, powResult);
+    functionCallCase->appendNew<ControlValue>(procedure, Jump, origin, FrequentedBlock(continuation));
+
+    // Loop pre-header.
+    Value* initialResult = loopPreHeaderCase->appendNew<ConstDoubleValue>(procedure, origin, 1.);
+    UpsilonValue* initialLoopValue = loopPreHeaderCase->appendNew<UpsilonValue>(procedure, origin, initialResult);
+    UpsilonValue* initialResultValue = loopPreHeaderCase->appendNew<UpsilonValue>(procedure, origin, initialResult);
+    UpsilonValue* initialSquaredInput = loopPreHeaderCase->appendNew<UpsilonValue>(procedure, origin, x);
+    UpsilonValue* initialLoopCounter = loopPreHeaderCase->appendNew<UpsilonValue>(procedure, origin, y);
+    loopPreHeaderCase->appendNew<ControlValue>(procedure, Jump, origin, FrequentedBlock(loopTestForEvenCase));
+
+    // Test if what is left of the counter is even.
+    Value* inLoopCounter = loopTestForEvenCase->appendNew<Value>(procedure, Phi, Int32, origin);
+    Value* inLoopSquaredInput = loopTestForEvenCase->appendNew<Value>(procedure, Phi, Double, origin);
+    Value* lastCounterBit = loopTestForEvenCase->appendNew<Value>(procedure, BitAnd, origin,
+        inLoopCounter,
+        loopTestForEvenCase->appendNew<Const32Value>(procedure, origin, 1));
+    loopTestForEvenCase->appendNew<ControlValue>(
+        procedure, Branch, origin,
+        lastCounterBit,
+        FrequentedBlock(loopOdd), FrequentedBlock(loopEvenOdd));
+
+    // Counter is odd.
+    Value* inLoopResult = loopOdd->appendNew<Value>(procedure, Phi, Double, origin);
+    Value* updatedResult = loopOdd->appendNew<Value>(procedure, Mul, origin, inLoopResult, inLoopSquaredInput);
+    UpsilonValue* updatedLoopResultUpsilon = loopOdd->appendNew<UpsilonValue>(procedure, origin, updatedResult);
+    initialLoopValue->setPhi(inLoopResult);
+    updatedLoopResultUpsilon->setPhi(inLoopResult);
+    UpsilonValue* updatedLoopResult = loopOdd->appendNew<UpsilonValue>(procedure, origin, updatedResult);
+
+    loopOdd->appendNew<ControlValue>(procedure, Jump, origin, FrequentedBlock(loopEvenOdd));
+
+    // Even value and following the Odd.
+    Value* squaredInput = loopEvenOdd->appendNew<Value>(procedure, Mul, origin, inLoopSquaredInput, inLoopSquaredInput);
+    UpsilonValue* squaredInputUpsilon = loopEvenOdd->appendNew<UpsilonValue>(procedure, origin, squaredInput);
+    initialSquaredInput->setPhi(inLoopSquaredInput);
+    squaredInputUpsilon->setPhi(inLoopSquaredInput);
+
+    Value* updatedCounter = loopEvenOdd->appendNew<Value>(procedure, ZShr, origin,
+        inLoopCounter,
+        loopEvenOdd->appendNew<Const32Value>(procedure, origin, 1));
+    UpsilonValue* updatedCounterUpsilon = loopEvenOdd->appendNew<UpsilonValue>(procedure, origin, updatedCounter);
+    initialLoopCounter->setPhi(inLoopCounter);
+    updatedCounterUpsilon->setPhi(inLoopCounter);
+
+    loopEvenOdd->appendNew<ControlValue>(
+        procedure, Branch, origin,
+        updatedCounter,
+        FrequentedBlock(loopTestForEvenCase), FrequentedBlock(continuation));
+
+    // Inline loop.
+    Value* finalResultPhi = continuation->appendNew<Value>(procedure, Phi, Double, origin);
+    powResultUpsilon->setPhi(finalResultPhi);
+    initialResultValue->setPhi(finalResultPhi);
+    updatedLoopResult->setPhi(finalResultPhi);
+    return std::make_pair(continuation, finalResultPhi);
+}
+
+} } // namespace JSC::B3
+
+#endif // ENABLE(B3_JIT)
+

Added: trunk/Source/_javascript_Core/b3/B3MathExtras.h (0 => 193989)


--- trunk/Source/_javascript_Core/b3/B3MathExtras.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/b3/B3MathExtras.h	2015-12-11 23:45:04 UTC (rev 193989)
@@ -0,0 +1,48 @@
+/*
+ * 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. 
+ */
+
+#ifndef B3MathExtras_h
+#define B3MathExtras_h
+
+#if ENABLE(B3_JIT)
+
+#include "B3Origin.h"
+
+namespace JSC { namespace B3 {
+
+class BasicBlock;
+class Procedure;
+class Value;
+
+// Raise "x" to "y" power.
+// Return a new block continuing the flow and the value representing the result.
+JS_EXPORT_PRIVATE std::pair<BasicBlock*, Value*> powDoubleInt32(Procedure&, BasicBlock*, Origin, Value* x, Value* y);
+
+} } // namespace JSC::B3
+
+#endif // ENABLE(B3_JIT)
+
+#endif // B3MathExtras_h
+

Modified: trunk/Source/_javascript_Core/b3/B3MemoryValue.h (193988 => 193989)


--- trunk/Source/_javascript_Core/b3/B3MemoryValue.h	2015-12-11 23:30:34 UTC (rev 193988)
+++ trunk/Source/_javascript_Core/b3/B3MemoryValue.h	2015-12-11 23:45:04 UTC (rev 193989)
@@ -20,7 +20,7 @@
  * 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. 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #ifndef B3MemoryValue_h

Modified: trunk/Source/_javascript_Core/b3/testb3.cpp (193988 => 193989)


--- trunk/Source/_javascript_Core/b3/testb3.cpp	2015-12-11 23:30:34 UTC (rev 193988)
+++ trunk/Source/_javascript_Core/b3/testb3.cpp	2015-12-11 23:45:04 UTC (rev 193989)
@@ -34,6 +34,7 @@
 #include "B3ConstPtrValue.h"
 #include "B3ControlValue.h"
 #include "B3Effects.h"
+#include "B3MathExtras.h"
 #include "B3MemoryValue.h"
 #include "B3Procedure.h"
 #include "B3StackSlotValue.h"
@@ -7111,6 +7112,21 @@
     CHECK(invoke<intptr_t>(*code, 43, 642462, 32533) == 32533);
 }
 
+void testPowDoubleByIntegerLoop(double xOperand, int32_t yOperand)
+{
+    Procedure proc;
+    BasicBlock* root = proc.addBlock();
+
+    Value* x = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
+    Value* y = root->appendNew<Value>(proc, Trunc, Origin(),
+        root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
+    auto result = powDoubleInt32(proc, root, Origin(), x, y);
+    BasicBlock* continuation = result.first;
+    continuation->appendNew<ControlValue>(proc, Return, Origin(), result.second);
+
+    CHECK(isIdentical(compileAndRun<double>(proc, xOperand, yOperand), pow(xOperand, yOperand)));
+}
+
 // Make sure the compiler does not try to optimize anything out.
 NEVER_INLINE double zero()
 {
@@ -8056,6 +8072,7 @@
     RUN(testSelectFold(42));
     RUN(testSelectFold(43));
     RUN(testSelectInvert());
+    RUN_BINARY(testPowDoubleByIntegerLoop, floatingPointOperands<double>(), int64Operands());
 
     if (tasks.isEmpty())
         usage();

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (193988 => 193989)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2015-12-11 23:30:34 UTC (rev 193988)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2015-12-11 23:45:04 UTC (rev 193989)
@@ -4223,8 +4223,7 @@
 static MacroAssembler::Jump compileArithPowIntegerFastPath(JITCompiler& assembler, FPRReg xOperand, GPRReg yOperand, FPRReg result)
 {
     MacroAssembler::JumpList skipFastPath;
-    skipFastPath.append(assembler.branch32(MacroAssembler::LessThan, yOperand, MacroAssembler::TrustedImm32(0)));
-    skipFastPath.append(assembler.branch32(MacroAssembler::GreaterThan, yOperand, MacroAssembler::TrustedImm32(1000)));
+    skipFastPath.append(assembler.branch32(MacroAssembler::Above, yOperand, MacroAssembler::TrustedImm32(1000)));
 
     static const double _oneConstant_ = 1.0;
     assembler.loadDouble(MacroAssembler::TrustedImmPtr(&oneConstant), result);

Modified: trunk/Source/_javascript_Core/ftl/FTLB3Output.cpp (193988 => 193989)


--- trunk/Source/_javascript_Core/ftl/FTLB3Output.cpp	2015-12-11 23:30:34 UTC (rev 193988)
+++ trunk/Source/_javascript_Core/ftl/FTLB3Output.cpp	2015-12-11 23:45:04 UTC (rev 193989)
@@ -29,6 +29,8 @@
 #if ENABLE(FTL_JIT)
 #if FTL_USES_B3
 
+#include "B3MathExtras.h"
+
 namespace JSC { namespace FTL {
 
 Output::Output(State& state)
@@ -69,6 +71,13 @@
     return load;
 }
 
+LValue Output::doublePowi(LValue x, LValue y)
+{
+    auto result = powDoubleInt32(m_proc, m_block, origin(), x, y);
+    m_block = result.first;
+    return result.second;
+}
+
 LValue Output::load8SignExt32(TypedPointer pointer)
 {
     LValue load = m_block->appendNew<B3::MemoryValue>(m_proc, B3::Load8S, B3::Int32, origin(), pointer.value());

Modified: trunk/Source/_javascript_Core/ftl/FTLB3Output.h (193988 => 193989)


--- trunk/Source/_javascript_Core/ftl/FTLB3Output.h	2015-12-11 23:30:34 UTC (rev 193988)
+++ trunk/Source/_javascript_Core/ftl/FTLB3Output.h	2015-12-11 23:45:04 UTC (rev 193989)
@@ -169,7 +169,7 @@
 
     LValue doublePow(LValue xOperand, LValue yOperand) { return callWithoutSideEffects(B3::Double, pow, xOperand, yOperand); }
 
-    LValue doublePowi(LValue xOperand, LValue yOperand) { CRASH(); }
+    LValue doublePowi(LValue xOperand, LValue yOperand);
 
     LValue doubleSqrt(LValue value) { return m_block->appendNew<B3::Value>(m_proc, B3::Sqrt, origin(), value); }
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to