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); }