WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
the patch
blah.patch (text/plain), 19.31 KB, created by
Filip Pizlo
on 2013-12-08 13:05:21 PST
(
hide
)
Description:
the patch
Filename:
MIME Type:
Creator:
Filip Pizlo
Created:
2013-12-08 13:05:21 PST
Size:
19.31 KB
patch
obsolete
>Index: Source/JavaScriptCore/ChangeLog >=================================================================== >--- Source/JavaScriptCore/ChangeLog (revision 160293) >+++ Source/JavaScriptCore/ChangeLog (working copy) >@@ -1,3 +1,59 @@ >+2013-12-08 Filip Pizlo <fpizlo@apple.com> >+ >+ FTL should support UntypedUse versions of Compare nodes >+ https://bugs.webkit.org/show_bug.cgi?id=125426 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ This adds UntypedUse versions of all comparisons except CompareStrictEq, which is >+ sufficiently different that I thought I'd do it in another patch. >+ >+ This also extends our ability to abstract over comparison kind and removes a bunch of >+ copy-paste code. >+ >+ * dfg/DFGSpeculativeJIT64.cpp: >+ (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompare): >+ * ftl/FTLCapabilities.cpp: >+ (JSC::FTL::canCompile): >+ * ftl/FTLIntrinsicRepository.h: >+ * ftl/FTLLowerDFGToLLVM.cpp: >+ (JSC::FTL::LowerDFGToLLVM::compileCompareEq): >+ (JSC::FTL::LowerDFGToLLVM::compileCompareLess): >+ (JSC::FTL::LowerDFGToLLVM::compileCompareLessEq): >+ (JSC::FTL::LowerDFGToLLVM::compileCompareGreater): >+ (JSC::FTL::LowerDFGToLLVM::compileCompareGreaterEq): >+ (JSC::FTL::LowerDFGToLLVM::compare): >+ (JSC::FTL::LowerDFGToLLVM::nonSpeculativeCompare): >+ * ftl/FTLOutput.h: >+ (JSC::FTL::Output::icmp): >+ (JSC::FTL::Output::equal): >+ (JSC::FTL::Output::notEqual): >+ (JSC::FTL::Output::above): >+ (JSC::FTL::Output::aboveOrEqual): >+ (JSC::FTL::Output::below): >+ (JSC::FTL::Output::belowOrEqual): >+ (JSC::FTL::Output::greaterThan): >+ (JSC::FTL::Output::greaterThanOrEqual): >+ (JSC::FTL::Output::lessThan): >+ (JSC::FTL::Output::lessThanOrEqual): >+ (JSC::FTL::Output::fcmp): >+ (JSC::FTL::Output::doubleEqual): >+ (JSC::FTL::Output::doubleNotEqualOrUnordered): >+ (JSC::FTL::Output::doubleLessThan): >+ (JSC::FTL::Output::doubleLessThanOrEqual): >+ (JSC::FTL::Output::doubleGreaterThan): >+ (JSC::FTL::Output::doubleGreaterThanOrEqual): >+ (JSC::FTL::Output::doubleEqualOrUnordered): >+ (JSC::FTL::Output::doubleNotEqual): >+ (JSC::FTL::Output::doubleLessThanOrUnordered): >+ (JSC::FTL::Output::doubleLessThanOrEqualOrUnordered): >+ (JSC::FTL::Output::doubleGreaterThanOrUnordered): >+ (JSC::FTL::Output::doubleGreaterThanOrEqualOrUnordered): >+ * tests/stress/untyped-equality.js: Added. >+ (foo): >+ * tests/stress/untyped-less-than.js: Added. >+ (foo): >+ > 2013-12-07 Filip Pizlo <fpizlo@apple.com> > > Fold typedArray.length if typedArray is constant >Index: Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (revision 160293) >+++ Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (working copy) >@@ -486,6 +486,7 @@ private: > > void SpeculativeJIT::nonSpeculativeNonPeepholeCompare(Node* node, MacroAssembler::RelationalCondition cond, S_JITOperation_EJJ helperFunction) > { >+ ASSERT(node->isBinaryUseKind(UntypedUse)); > JSValueOperand arg1(this, node->child1()); > JSValueOperand arg2(this, node->child2()); > GPRReg arg1GPR = arg1.gpr(); >Index: Source/JavaScriptCore/ftl/FTLCapabilities.cpp >=================================================================== >--- Source/JavaScriptCore/ftl/FTLCapabilities.cpp (revision 160293) >+++ Source/JavaScriptCore/ftl/FTLCapabilities.cpp (working copy) >@@ -179,6 +179,17 @@ inline CapabilityLevel canCompile(Node* > } > break; > case CompareEq: >+ if (node->isBinaryUseKind(Int32Use)) >+ break; >+ if (node->isBinaryUseKind(MachineIntUse)) >+ break; >+ if (node->isBinaryUseKind(NumberUse)) >+ break; >+ if (node->isBinaryUseKind(ObjectUse)) >+ break; >+ if (node->isBinaryUseKind(UntypedUse)) >+ break; >+ return CannotCompile; > case CompareStrictEq: > if (node->isBinaryUseKind(Int32Use)) > break; >@@ -199,6 +210,8 @@ inline CapabilityLevel canCompile(Node* > break; > if (node->isBinaryUseKind(NumberUse)) > break; >+ if (node->isBinaryUseKind(UntypedUse)) >+ break; > return CannotCompile; > case Switch: > switch (node->switchData()->kind) { >Index: Source/JavaScriptCore/ftl/FTLIntrinsicRepository.h >=================================================================== >--- Source/JavaScriptCore/ftl/FTLIntrinsicRepository.h (revision 160293) >+++ Source/JavaScriptCore/ftl/FTLIntrinsicRepository.h (working copy) >@@ -67,6 +67,7 @@ namespace JSC { namespace FTL { > macro(P_JITOperation_EStSS, functionType(intPtr, intPtr, intPtr, intPtr, intPtr)) \ > macro(P_JITOperation_EStZ, functionType(intPtr, intPtr, intPtr, int32)) \ > macro(S_JITOperation_EJ, functionType(intPtr, intPtr, int64)) \ >+ macro(S_JITOperation_EJJ, functionType(intPtr, intPtr, int64, int64)) \ > macro(V_JITOperation_EJJJ, functionType(voidType, intPtr, int64, int64, int64)) \ > macro(V_JITOperation_EOZD, functionType(voidType, intPtr, intPtr, int32, doubleType)) \ > macro(V_JITOperation_EOZJ, functionType(voidType, intPtr, intPtr, int32, int64)) \ >Index: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp >=================================================================== >--- Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (revision 160293) >+++ Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (working copy) >@@ -2396,6 +2396,11 @@ private: > return; > } > >+ if (m_node->isBinaryUseKind(UntypedUse)) { >+ nonSpeculativeCompare(LLVMIntEQ, operationCompareEq); >+ return; >+ } >+ > RELEASE_ASSERT_NOT_REACHED(); > } > >@@ -2464,106 +2469,22 @@ private: > > void compileCompareLess() > { >- if (m_node->isBinaryUseKind(Int32Use)) { >- setBoolean( >- m_out.lessThan(lowInt32(m_node->child1()), lowInt32(m_node->child2()))); >- return; >- } >- >- if (m_node->isBinaryUseKind(MachineIntUse)) { >- Int52Kind kind; >- LValue left = lowWhicheverInt52(m_node->child1(), kind); >- LValue right = lowInt52(m_node->child2(), kind); >- setBoolean(m_out.lessThan(left, right)); >- return; >- } >- >- if (m_node->isBinaryUseKind(NumberUse)) { >- setBoolean( >- m_out.doubleLessThan(lowDouble(m_node->child1()), lowDouble(m_node->child2()))); >- return; >- } >- >- RELEASE_ASSERT_NOT_REACHED(); >+ compare(LLVMIntSLT, LLVMRealOLT, operationCompareLess); > } > > void compileCompareLessEq() > { >- if (m_node->isBinaryUseKind(Int32Use)) { >- setBoolean( >- m_out.lessThanOrEqual(lowInt32(m_node->child1()), lowInt32(m_node->child2()))); >- return; >- } >- >- if (m_node->isBinaryUseKind(MachineIntUse)) { >- Int52Kind kind; >- LValue left = lowWhicheverInt52(m_node->child1(), kind); >- LValue right = lowInt52(m_node->child2(), kind); >- setBoolean(m_out.lessThanOrEqual(left, right)); >- return; >- } >- >- if (m_node->isBinaryUseKind(NumberUse)) { >- setBoolean( >- m_out.doubleLessThanOrEqual( >- lowDouble(m_node->child1()), lowDouble(m_node->child2()))); >- return; >- } >- >- RELEASE_ASSERT_NOT_REACHED(); >+ compare(LLVMIntSLE, LLVMRealOLE, operationCompareLessEq); > } > > void compileCompareGreater() > { >- if (m_node->isBinaryUseKind(Int32Use)) { >- setBoolean( >- m_out.greaterThan(lowInt32(m_node->child1()), lowInt32(m_node->child2()))); >- return; >- } >- >- if (m_node->isBinaryUseKind(MachineIntUse)) { >- Int52Kind kind; >- LValue left = lowWhicheverInt52(m_node->child1(), kind); >- LValue right = lowInt52(m_node->child2(), kind); >- setBoolean(m_out.greaterThan(left, right)); >- return; >- } >- >- if (m_node->isBinaryUseKind(NumberUse)) { >- setBoolean( >- m_out.doubleGreaterThan( >- lowDouble(m_node->child1()), lowDouble(m_node->child2()))); >- return; >- } >- >- RELEASE_ASSERT_NOT_REACHED(); >+ compare(LLVMIntSGT, LLVMRealOGT, operationCompareGreater); > } > > void compileCompareGreaterEq() > { >- if (m_node->isBinaryUseKind(Int32Use)) { >- setBoolean( >- m_out.greaterThanOrEqual( >- lowInt32(m_node->child1()), lowInt32(m_node->child2()))); >- return; >- } >- >- if (m_node->isBinaryUseKind(MachineIntUse)) { >- Int52Kind kind; >- LValue left = lowWhicheverInt52(m_node->child1(), kind); >- LValue right = lowInt52(m_node->child2(), kind); >- setBoolean(m_out.greaterThanOrEqual(left, right)); >- return; >- } >- >- if (m_node->isBinaryUseKind(NumberUse)) { >- setBoolean( >- m_out.doubleGreaterThanOrEqual( >- lowDouble(m_node->child1()), lowDouble(m_node->child2()))); >- return; >- } >- >- RELEASE_ASSERT_NOT_REACHED(); >+ compare(LLVMIntSGE, LLVMRealOGE, operationCompareGreaterEq); > } > > void compileLogicalNot() >@@ -2800,6 +2721,69 @@ private: > m_state.forNode(edge).m_value); > } > >+ void compare( >+ LIntPredicate intCondition, LRealPredicate realCondition, >+ S_JITOperation_EJJ helperFunction) >+ { >+ if (m_node->isBinaryUseKind(Int32Use)) { >+ LValue left = lowInt32(m_node->child1()); >+ LValue right = lowInt32(m_node->child2()); >+ setBoolean(m_out.icmp(intCondition, left, right)); >+ return; >+ } >+ >+ if (m_node->isBinaryUseKind(MachineIntUse)) { >+ Int52Kind kind; >+ LValue left = lowWhicheverInt52(m_node->child1(), kind); >+ LValue right = lowInt52(m_node->child2(), kind); >+ setBoolean(m_out.icmp(intCondition, left, right)); >+ return; >+ } >+ >+ if (m_node->isBinaryUseKind(NumberUse)) { >+ LValue left = lowDouble(m_node->child1()); >+ LValue right = lowDouble(m_node->child2()); >+ setBoolean(m_out.fcmp(realCondition, left, right)); >+ return; >+ } >+ >+ if (m_node->isBinaryUseKind(UntypedUse)) { >+ nonSpeculativeCompare(intCondition, helperFunction); >+ return; >+ } >+ >+ RELEASE_ASSERT_NOT_REACHED(); >+ } >+ >+ void nonSpeculativeCompare(LIntPredicate intCondition, S_JITOperation_EJJ helperFunction) >+ { >+ LValue left = lowJSValue(m_node->child1()); >+ LValue right = lowJSValue(m_node->child2()); >+ >+ LBasicBlock leftIsInt = FTL_NEW_BLOCK(m_out, ("CompareEq untyped left is int")); >+ LBasicBlock fastPath = FTL_NEW_BLOCK(m_out, ("CompareEq untyped fast path")); >+ LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, ("CompareEq untyped slow path")); >+ LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("CompareEq untyped continuation")); >+ >+ m_out.branch(isNotInt32(left), slowPath, leftIsInt); >+ >+ LBasicBlock lastNext = m_out.appendTo(leftIsInt, fastPath); >+ m_out.branch(isNotInt32(right), slowPath, fastPath); >+ >+ m_out.appendTo(fastPath, slowPath); >+ ValueFromBlock fastResult = m_out.anchor( >+ m_out.icmp(intCondition, unboxInt32(left), unboxInt32(right))); >+ m_out.jump(continuation); >+ >+ m_out.appendTo(slowPath, continuation); >+ ValueFromBlock slowResult = m_out.anchor(m_out.notNull(vmCall( >+ m_out.operation(helperFunction), m_callFrame, left, right))); >+ m_out.jump(continuation); >+ >+ m_out.appendTo(continuation, lastNext); >+ setBoolean(m_out.phi(m_out.boolean, fastResult, slowResult)); >+ } >+ > LValue allocateCell(LValue allocator, LValue structure, LBasicBlock slowPath) > { > LBasicBlock success = FTL_NEW_BLOCK(m_out, ("object allocation success")); >Index: Source/JavaScriptCore/ftl/FTLOutput.h >=================================================================== >--- Source/JavaScriptCore/ftl/FTLOutput.h (revision 160293) >+++ Source/JavaScriptCore/ftl/FTLOutput.h (working copy) >@@ -314,29 +314,31 @@ public: > void storePtr(LValue value, LValue base, const AbstractField& field) { storePtr(value, address(base, field)); } > void storeDouble(LValue value, LValue base, const AbstractField& field) { storeDouble(value, address(base, field)); } > >- LValue equal(LValue left, LValue right) { return buildICmp(m_builder, LLVMIntEQ, left, right); } >- LValue notEqual(LValue left, LValue right) { return buildICmp(m_builder, LLVMIntNE, left, right); } >- LValue above(LValue left, LValue right) { return buildICmp(m_builder, LLVMIntUGT, left, right); } >- LValue aboveOrEqual(LValue left, LValue right) { return buildICmp(m_builder, LLVMIntUGE, left, right); } >- LValue below(LValue left, LValue right) { return buildICmp(m_builder, LLVMIntULT, left, right); } >- LValue belowOrEqual(LValue left, LValue right) { return buildICmp(m_builder, LLVMIntULE, left, right); } >- LValue greaterThan(LValue left, LValue right) { return buildICmp(m_builder, LLVMIntSGT, left, right); } >- LValue greaterThanOrEqual(LValue left, LValue right) { return buildICmp(m_builder, LLVMIntSGE, left, right); } >- LValue lessThan(LValue left, LValue right) { return buildICmp(m_builder, LLVMIntSLT, left, right); } >- LValue lessThanOrEqual(LValue left, LValue right) { return buildICmp(m_builder, LLVMIntSLE, left, right); } >- >- LValue doubleEqual(LValue left, LValue right) { return buildFCmp(m_builder, LLVMRealOEQ, left, right); } >- LValue doubleNotEqualOrUnordered(LValue left, LValue right) { return buildFCmp(m_builder, LLVMRealUNE, left, right); } >- LValue doubleLessThan(LValue left, LValue right) { return buildFCmp(m_builder, LLVMRealOLT, left, right); } >- LValue doubleLessThanOrEqual(LValue left, LValue right) { return buildFCmp(m_builder, LLVMRealOLE, left, right); } >- LValue doubleGreaterThan(LValue left, LValue right) { return buildFCmp(m_builder, LLVMRealOGT, left, right); } >- LValue doubleGreaterThanOrEqual(LValue left, LValue right) { return buildFCmp(m_builder, LLVMRealOGE, left, right); } >- LValue doubleEqualOrUnordered(LValue left, LValue right) { return buildFCmp(m_builder, LLVMRealUEQ, left, right); } >- LValue doubleNotEqual(LValue left, LValue right) { return buildFCmp(m_builder, LLVMRealONE, left, right); } >- LValue doubleLessThanOrUnordered(LValue left, LValue right) { return buildFCmp(m_builder, LLVMRealULT, left, right); } >- LValue doubleLessThanOrEqualOrUnordered(LValue left, LValue right) { return buildFCmp(m_builder, LLVMRealULE, left, right); } >- LValue doubleGreaterThanOrUnordered(LValue left, LValue right) { return buildFCmp(m_builder, LLVMRealUGT, left, right); } >- LValue doubleGreaterThanOrEqualOrUnordered(LValue left, LValue right) { return buildFCmp(m_builder, LLVMRealUGE, left, right); } >+ LValue icmp(LIntPredicate cond, LValue left, LValue right) { return buildICmp(m_builder, cond, left, right); } >+ LValue equal(LValue left, LValue right) { return icmp(LLVMIntEQ, left, right); } >+ LValue notEqual(LValue left, LValue right) { return icmp(LLVMIntNE, left, right); } >+ LValue above(LValue left, LValue right) { return icmp(LLVMIntUGT, left, right); } >+ LValue aboveOrEqual(LValue left, LValue right) { return icmp(LLVMIntUGE, left, right); } >+ LValue below(LValue left, LValue right) { return icmp(LLVMIntULT, left, right); } >+ LValue belowOrEqual(LValue left, LValue right) { return icmp(LLVMIntULE, left, right); } >+ LValue greaterThan(LValue left, LValue right) { return icmp(LLVMIntSGT, left, right); } >+ LValue greaterThanOrEqual(LValue left, LValue right) { return icmp(LLVMIntSGE, left, right); } >+ LValue lessThan(LValue left, LValue right) { return icmp(LLVMIntSLT, left, right); } >+ LValue lessThanOrEqual(LValue left, LValue right) { return icmp(LLVMIntSLE, left, right); } >+ >+ LValue fcmp(LRealPredicate cond, LValue left, LValue right) { return buildFCmp(m_builder, cond, left, right); } >+ LValue doubleEqual(LValue left, LValue right) { return fcmp(LLVMRealOEQ, left, right); } >+ LValue doubleNotEqualOrUnordered(LValue left, LValue right) { return fcmp(LLVMRealUNE, left, right); } >+ LValue doubleLessThan(LValue left, LValue right) { return fcmp(LLVMRealOLT, left, right); } >+ LValue doubleLessThanOrEqual(LValue left, LValue right) { return fcmp(LLVMRealOLE, left, right); } >+ LValue doubleGreaterThan(LValue left, LValue right) { return fcmp(LLVMRealOGT, left, right); } >+ LValue doubleGreaterThanOrEqual(LValue left, LValue right) { return fcmp(LLVMRealOGE, left, right); } >+ LValue doubleEqualOrUnordered(LValue left, LValue right) { return fcmp(LLVMRealUEQ, left, right); } >+ LValue doubleNotEqual(LValue left, LValue right) { return fcmp(LLVMRealONE, left, right); } >+ LValue doubleLessThanOrUnordered(LValue left, LValue right) { return fcmp(LLVMRealULT, left, right); } >+ LValue doubleLessThanOrEqualOrUnordered(LValue left, LValue right) { return fcmp(LLVMRealULE, left, right); } >+ LValue doubleGreaterThanOrUnordered(LValue left, LValue right) { return fcmp(LLVMRealUGT, left, right); } >+ LValue doubleGreaterThanOrEqualOrUnordered(LValue left, LValue right) { return fcmp(LLVMRealUGE, left, right); } > > LValue isZero8(LValue value) { return equal(value, int8Zero); } > LValue notZero8(LValue value) { return notEqual(value, int8Zero); } >Index: Source/JavaScriptCore/tests/stress/untyped-equality.js >=================================================================== >--- Source/JavaScriptCore/tests/stress/untyped-equality.js (revision 0) >+++ Source/JavaScriptCore/tests/stress/untyped-equality.js (working copy) >@@ -0,0 +1,20 @@ >+function foo(a, b) { >+ return a == b; >+} >+ >+noInline(foo); >+ >+var data = [ >+ [5, 6.5, false], >+ ["foo", "bar", false], >+ [true, false, false], >+ ["42", 42, true], >+ [1.2, 1.2, true] >+]; >+ >+for (var i = 0; i < 100000; ++i) { >+ var test = data[i % data.length]; >+ var result = foo(test[0], test[1]); >+ if (result != test[2]) >+ throw "Error: bad result for " + test + ": " + result; >+} >Index: Source/JavaScriptCore/tests/stress/untyped-less-than.js >=================================================================== >--- Source/JavaScriptCore/tests/stress/untyped-less-than.js (revision 0) >+++ Source/JavaScriptCore/tests/stress/untyped-less-than.js (working copy) >@@ -0,0 +1,23 @@ >+function foo(a, b) { >+ return a < b; >+} >+ >+noInline(foo); >+ >+var data = [ >+ [5, 6.5, true], >+ ["foo", "bar", false], >+ [true, false, false], >+ [false, true, true], >+ ["42", 42, false], >+ [1.2, 1.2, false], >+ ["-1", 1, true], >+ [-1, "1", true] >+]; >+ >+for (var i = 0; i < 100000; ++i) { >+ var test = data[i % data.length]; >+ var result = foo(test[0], test[1]); >+ if (result != test[2]) >+ throw "Error: bad result for " + test + ": " + result; >+}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
oliver
:
review+
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 125426
: 218709