haikuwebkit/Source/WTF/wtf/UnionFind.h

110 lines
3.2 KiB
C
Raw Permalink Normal View History

DFG JIT should infer which uses of a variable are not aliased https://bugs.webkit.org/show_bug.cgi?id=68593 Reviewed by Oliver Hunt. This separates how a variable is stored (i.e. its virtual register) from how it's predicted. Each variable now takes a VariableAccessData as its operand, instead of the virtual register. The VariableAccessData stores the operand and the prediction. If multiple uses of a variable are aliased, their VariableAccessDatas are unified. This also adds tracking of which argument values are used. It correctly observes that an argument value is not used, if the argument is assigned to inside the function before being used. This also adds tracking of which variables are live at the head of a basic block, and separates that from a variable being live at the tail. Finally, this communicates to both OSR entry and OSR exit code how a variable is predicted at a particular point in the code, rather than just communicating how it was predicted in the entire code block (since with this patch there is no longer the notion of a variable having just one prediction for a code block). * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: * JavaScriptCore.vcproj/WTF/WTF.vcproj: * JavaScriptCore.xcodeproj/project.pbxproj: * bytecode/ActionablePrediction.h: Added. (JSC::actionablePredictionFromPredictedType): (JSC::valueObeysPrediction): (JSC::actionablePredictionToString): (JSC::ActionablePredictions::ActionablePredictions): (JSC::ActionablePredictions::setArgument): (JSC::ActionablePredictions::argument): (JSC::ActionablePredictions::setVariable): (JSC::ActionablePredictions::variable): (JSC::ActionablePredictions::argumentUpperBound): (JSC::ActionablePredictions::variableUpperBound): (JSC::ActionablePredictions::pack): (JSC::ActionablePredictions::packVector): * bytecode/CodeBlock.h: * bytecode/PredictionTracker.h: * dfg/DFGByteCodeParser.cpp: (JSC::DFG::ByteCodeParser::newVariableAccessData): (JSC::DFG::ByteCodeParser::getLocal): (JSC::DFG::ByteCodeParser::setLocal): (JSC::DFG::ByteCodeParser::getArgument): (JSC::DFG::ByteCodeParser::setArgument): (JSC::DFG::ByteCodeParser::parseBlock): (JSC::DFG::ByteCodeParser::processPhiStack): (JSC::DFG::ByteCodeParser::parse): * dfg/DFGDriver.cpp: (JSC::DFG::compile): * dfg/DFGGraph.cpp: (JSC::DFG::Graph::nameOfVariableAccessData): (JSC::DFG::Graph::dump): (JSC::DFG::Graph::predictArgumentTypes): * dfg/DFGGraph.h: (JSC::DFG::operandIsArgument): (JSC::DFG::VariableRecord::setFirstTime): (JSC::DFG::BasicBlock::BasicBlock): (JSC::DFG::Graph::predict): (JSC::DFG::Graph::getPrediction): * dfg/DFGJITCompiler.h: (JSC::DFG::JITCompiler::noticeOSREntry): * dfg/DFGNode.h: (JSC::DFG::Node::hasVariableAccessData): (JSC::DFG::Node::hasLocal): (JSC::DFG::Node::variableAccessData): (JSC::DFG::Node::local): * dfg/DFGOSREntry.cpp: (JSC::DFG::prepareOSREntry): * dfg/DFGOSREntry.h: * dfg/DFGPropagator.cpp: (JSC::DFG::Propagator::propagateNodePredictions): * dfg/DFGSpeculativeJIT.cpp: (JSC::DFG::ValueSource::dump): (JSC::DFG::OSRExit::OSRExit): (JSC::DFG::SpeculativeJIT::compile): (JSC::DFG::SpeculativeJIT::checkArgumentTypes): (JSC::DFG::SpeculativeJIT::computeValueRecoveryFor): * dfg/DFGSpeculativeJIT.h: (JSC::DFG::ValueSource::ValueSource): (JSC::DFG::ValueSource::forPrediction): (JSC::DFG::ValueSource::isSet): (JSC::DFG::ValueSource::kind): (JSC::DFG::ValueSource::nodeIndex): (JSC::DFG::ValueSource::nodeIndexFromKind): (JSC::DFG::ValueSource::kindFromNodeIndex): (JSC::DFG::SpeculativeJIT::isKnownArray): (JSC::DFG::SpeculativeJIT::computeValueRecoveryFor): (JSC::DFG::SpeculativeJIT::SpeculativeJIT): * dfg/DFGSpeculativeJIT32_64.cpp: (JSC::DFG::OSRExit::OSRExit): (JSC::DFG::SpeculativeJIT::compile): (JSC::DFG::SpeculativeJIT::checkArgumentTypes): (JSC::DFG::SpeculativeJIT::computeValueRecoveryFor): * wtf/PackedIntVector.h: Added. (WTF::PackedIntVector::PackedIntVector): (WTF::PackedIntVector::operator=): (WTF::PackedIntVector::size): (WTF::PackedIntVector::ensureSize): (WTF::PackedIntVector::resize): (WTF::PackedIntVector::clearAll): (WTF::PackedIntVector::get): (WTF::PackedIntVector::set): (WTF::PackedIntVector::mask): * wtf/Platform.h: * wtf/UnionFind.h: Added. (WTF::UnionFind::UnionFind): (WTF::UnionFind::find): (WTF::UnionFind::unify): Canonical link: https://commits.webkit.org/85138@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@96375 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2011-09-29 23:17:19 +00:00
/*
* Copyright (C) 2011 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.
*/
Use pragma once in WTF https://bugs.webkit.org/show_bug.cgi?id=190527 Reviewed by Chris Dumez. Source/WTF: We also need to consistently include wtf headers from within wtf so we can build wtf without symbol redefinition errors from including the copy in Source and the copy in the build directory. * wtf/ASCIICType.h: * wtf/Assertions.cpp: * wtf/Assertions.h: * wtf/Atomics.h: * wtf/AutomaticThread.cpp: * wtf/AutomaticThread.h: * wtf/BackwardsGraph.h: * wtf/Bag.h: * wtf/BagToHashMap.h: * wtf/BitVector.cpp: * wtf/BitVector.h: * wtf/Bitmap.h: * wtf/BloomFilter.h: * wtf/Box.h: * wtf/BubbleSort.h: * wtf/BumpPointerAllocator.h: * wtf/ByteOrder.h: * wtf/CPUTime.cpp: * wtf/CallbackAggregator.h: * wtf/CheckedArithmetic.h: * wtf/CheckedBoolean.h: * wtf/ClockType.cpp: * wtf/ClockType.h: * wtf/CommaPrinter.h: * wtf/CompilationThread.cpp: * wtf/CompilationThread.h: * wtf/Compiler.h: * wtf/ConcurrentPtrHashSet.cpp: * wtf/ConcurrentVector.h: * wtf/Condition.h: * wtf/CountingLock.cpp: * wtf/CrossThreadTaskHandler.cpp: * wtf/CryptographicUtilities.cpp: * wtf/CryptographicUtilities.h: * wtf/CryptographicallyRandomNumber.cpp: * wtf/CryptographicallyRandomNumber.h: * wtf/CurrentTime.cpp: * wtf/DataLog.cpp: * wtf/DataLog.h: * wtf/DateMath.cpp: * wtf/DateMath.h: * wtf/DecimalNumber.cpp: * wtf/DecimalNumber.h: * wtf/Deque.h: * wtf/DisallowCType.h: * wtf/Dominators.h: * wtf/DoublyLinkedList.h: * wtf/FastBitVector.cpp: * wtf/FastMalloc.cpp: * wtf/FastMalloc.h: * wtf/FeatureDefines.h: * wtf/FilePrintStream.cpp: * wtf/FilePrintStream.h: * wtf/FlipBytes.h: * wtf/FunctionDispatcher.cpp: * wtf/FunctionDispatcher.h: * wtf/GetPtr.h: * wtf/Gigacage.cpp: * wtf/GlobalVersion.cpp: * wtf/GraphNodeWorklist.h: * wtf/GregorianDateTime.cpp: * wtf/GregorianDateTime.h: * wtf/HashFunctions.h: * wtf/HashMap.h: * wtf/HashMethod.h: * wtf/HashSet.h: * wtf/HashTable.cpp: * wtf/HashTraits.h: * wtf/Indenter.h: * wtf/IndexSparseSet.h: * wtf/InlineASM.h: * wtf/Insertion.h: * wtf/IteratorAdaptors.h: * wtf/IteratorRange.h: * wtf/JSONValues.cpp: * wtf/JSValueMalloc.cpp: * wtf/LEBDecoder.h: * wtf/Language.cpp: * wtf/ListDump.h: * wtf/Lock.cpp: * wtf/Lock.h: * wtf/LockAlgorithm.h: * wtf/LockedPrintStream.cpp: * wtf/Locker.h: * wtf/MD5.cpp: * wtf/MD5.h: * wtf/MainThread.cpp: * wtf/MainThread.h: * wtf/MallocPtr.h: * wtf/MathExtras.h: * wtf/MediaTime.cpp: * wtf/MediaTime.h: * wtf/MemoryPressureHandler.cpp: * wtf/MessageQueue.h: * wtf/MetaAllocator.cpp: * wtf/MetaAllocator.h: * wtf/MetaAllocatorHandle.h: * wtf/MonotonicTime.cpp: * wtf/MonotonicTime.h: * wtf/NakedPtr.h: * wtf/NoLock.h: * wtf/NoTailCalls.h: * wtf/Noncopyable.h: * wtf/NumberOfCores.cpp: * wtf/NumberOfCores.h: * wtf/OSAllocator.h: * wtf/OSAllocatorPosix.cpp: * wtf/OSRandomSource.cpp: * wtf/OSRandomSource.h: * wtf/ObjcRuntimeExtras.h: * wtf/OrderMaker.h: * wtf/PackedIntVector.h: * wtf/PageAllocation.h: * wtf/PageBlock.cpp: * wtf/PageBlock.h: * wtf/PageReservation.h: * wtf/ParallelHelperPool.cpp: * wtf/ParallelHelperPool.h: * wtf/ParallelJobs.h: * wtf/ParallelJobsLibdispatch.h: * wtf/ParallelVectorIterator.h: * wtf/ParkingLot.cpp: * wtf/ParkingLot.h: * wtf/Platform.h: * wtf/PointerComparison.h: * wtf/Poisoned.cpp: * wtf/PrintStream.cpp: * wtf/PrintStream.h: * wtf/ProcessID.h: * wtf/ProcessPrivilege.cpp: * wtf/RAMSize.cpp: * wtf/RAMSize.h: * wtf/RandomDevice.cpp: * wtf/RandomNumber.cpp: * wtf/RandomNumber.h: * wtf/RandomNumberSeed.h: * wtf/RangeSet.h: * wtf/RawPointer.h: * wtf/ReadWriteLock.cpp: * wtf/RedBlackTree.h: * wtf/Ref.h: * wtf/RefCountedArray.h: * wtf/RefCountedLeakCounter.cpp: * wtf/RefCountedLeakCounter.h: * wtf/RefCounter.h: * wtf/RefPtr.h: * wtf/RetainPtr.h: * wtf/RunLoop.cpp: * wtf/RunLoop.h: * wtf/RunLoopTimer.h: * wtf/RunLoopTimerCF.cpp: * wtf/SHA1.cpp: * wtf/SHA1.h: * wtf/SaturatedArithmetic.h: (saturatedSubtraction): * wtf/SchedulePair.h: * wtf/SchedulePairCF.cpp: * wtf/SchedulePairMac.mm: * wtf/ScopedLambda.h: * wtf/Seconds.cpp: * wtf/Seconds.h: * wtf/SegmentedVector.h: * wtf/SentinelLinkedList.h: * wtf/SharedTask.h: * wtf/SimpleStats.h: * wtf/SingleRootGraph.h: * wtf/SinglyLinkedList.h: * wtf/SixCharacterHash.cpp: * wtf/SixCharacterHash.h: * wtf/SmallPtrSet.h: * wtf/Spectrum.h: * wtf/StackBounds.cpp: * wtf/StackBounds.h: * wtf/StackStats.cpp: * wtf/StackStats.h: * wtf/StackTrace.cpp: * wtf/StdLibExtras.h: * wtf/StreamBuffer.h: * wtf/StringHashDumpContext.h: * wtf/StringPrintStream.cpp: * wtf/StringPrintStream.h: * wtf/ThreadGroup.cpp: * wtf/ThreadMessage.cpp: * wtf/ThreadSpecific.h: * wtf/Threading.cpp: * wtf/Threading.h: * wtf/ThreadingPrimitives.h: * wtf/ThreadingPthreads.cpp: * wtf/TimeWithDynamicClockType.cpp: * wtf/TimeWithDynamicClockType.h: * wtf/TimingScope.cpp: * wtf/TinyLRUCache.h: * wtf/TinyPtrSet.h: * wtf/TriState.h: * wtf/TypeCasts.h: * wtf/UUID.cpp: * wtf/UnionFind.h: * wtf/VMTags.h: * wtf/ValueCheck.h: * wtf/Vector.h: * wtf/VectorTraits.h: * wtf/WallTime.cpp: * wtf/WallTime.h: * wtf/WeakPtr.h: * wtf/WeakRandom.h: * wtf/WordLock.cpp: * wtf/WordLock.h: * wtf/WorkQueue.cpp: * wtf/WorkQueue.h: * wtf/WorkerPool.cpp: * wtf/cf/LanguageCF.cpp: * wtf/cf/RunLoopCF.cpp: * wtf/cocoa/Entitlements.mm: * wtf/cocoa/MachSendRight.cpp: * wtf/cocoa/MainThreadCocoa.mm: * wtf/cocoa/MemoryFootprintCocoa.cpp: * wtf/cocoa/WorkQueueCocoa.cpp: * wtf/dtoa.cpp: * wtf/dtoa.h: * wtf/ios/WebCoreThread.cpp: * wtf/ios/WebCoreThread.h: * wtf/mac/AppKitCompatibilityDeclarations.h: * wtf/mac/DeprecatedSymbolsUsedBySafari.mm: * wtf/mbmalloc.cpp: * wtf/persistence/PersistentCoders.cpp: * wtf/persistence/PersistentDecoder.cpp: * wtf/persistence/PersistentEncoder.cpp: * wtf/spi/cf/CFBundleSPI.h: * wtf/spi/darwin/CommonCryptoSPI.h: * wtf/text/ASCIIFastPath.h: * wtf/text/ASCIILiteral.cpp: * wtf/text/AtomicString.cpp: * wtf/text/AtomicString.h: * wtf/text/AtomicStringHash.h: * wtf/text/AtomicStringImpl.cpp: * wtf/text/AtomicStringImpl.h: * wtf/text/AtomicStringTable.cpp: * wtf/text/AtomicStringTable.h: * wtf/text/Base64.cpp: * wtf/text/CString.cpp: * wtf/text/CString.h: * wtf/text/ConversionMode.h: * wtf/text/ExternalStringImpl.cpp: * wtf/text/IntegerToStringConversion.h: * wtf/text/LChar.h: * wtf/text/LineEnding.cpp: * wtf/text/StringBuffer.h: * wtf/text/StringBuilder.cpp: * wtf/text/StringBuilder.h: * wtf/text/StringBuilderJSON.cpp: * wtf/text/StringCommon.h: * wtf/text/StringConcatenate.h: * wtf/text/StringHash.h: * wtf/text/StringImpl.cpp: * wtf/text/StringImpl.h: * wtf/text/StringOperators.h: * wtf/text/StringView.cpp: * wtf/text/StringView.h: * wtf/text/SymbolImpl.cpp: * wtf/text/SymbolRegistry.cpp: * wtf/text/SymbolRegistry.h: * wtf/text/TextBreakIterator.cpp: * wtf/text/TextBreakIterator.h: * wtf/text/TextBreakIteratorInternalICU.h: * wtf/text/TextPosition.h: * wtf/text/TextStream.cpp: * wtf/text/UniquedStringImpl.h: * wtf/text/WTFString.cpp: * wtf/text/WTFString.h: * wtf/text/cocoa/StringCocoa.mm: * wtf/text/cocoa/StringViewCocoa.mm: * wtf/text/cocoa/TextBreakIteratorInternalICUCocoa.cpp: * wtf/text/icu/UTextProvider.cpp: * wtf/text/icu/UTextProvider.h: * wtf/text/icu/UTextProviderLatin1.cpp: * wtf/text/icu/UTextProviderLatin1.h: * wtf/text/icu/UTextProviderUTF16.cpp: * wtf/text/icu/UTextProviderUTF16.h: * wtf/threads/BinarySemaphore.cpp: * wtf/threads/BinarySemaphore.h: * wtf/threads/Signals.cpp: * wtf/unicode/CharacterNames.h: * wtf/unicode/Collator.h: * wtf/unicode/CollatorDefault.cpp: * wtf/unicode/UTF8.cpp: * wtf/unicode/UTF8.h: Tools: Put WorkQueue in namespace DRT so it does not conflict with WTF::WorkQueue. * DumpRenderTree/TestRunner.cpp: (TestRunner::queueLoadHTMLString): (TestRunner::queueLoadAlternateHTMLString): (TestRunner::queueBackNavigation): (TestRunner::queueForwardNavigation): (TestRunner::queueLoadingScript): (TestRunner::queueNonLoadingScript): (TestRunner::queueReload): * DumpRenderTree/WorkQueue.cpp: (WorkQueue::singleton): Deleted. (WorkQueue::WorkQueue): Deleted. (WorkQueue::queue): Deleted. (WorkQueue::dequeue): Deleted. (WorkQueue::count): Deleted. (WorkQueue::clear): Deleted. (WorkQueue::processWork): Deleted. * DumpRenderTree/WorkQueue.h: (WorkQueue::setFrozen): Deleted. * DumpRenderTree/WorkQueueItem.h: * DumpRenderTree/mac/DumpRenderTree.mm: (runTest): * DumpRenderTree/mac/FrameLoadDelegate.mm: (-[FrameLoadDelegate processWork:]): (-[FrameLoadDelegate webView:locationChangeDone:forDataSource:]): * DumpRenderTree/mac/TestRunnerMac.mm: (TestRunner::notifyDone): (TestRunner::forceImmediateCompletion): (TestRunner::queueLoad): * DumpRenderTree/win/DumpRenderTree.cpp: (runTest): * DumpRenderTree/win/FrameLoadDelegate.cpp: (FrameLoadDelegate::processWork): (FrameLoadDelegate::locationChangeDone): * DumpRenderTree/win/TestRunnerWin.cpp: (TestRunner::notifyDone): (TestRunner::forceImmediateCompletion): (TestRunner::queueLoad): Canonical link: https://commits.webkit.org/205473@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@237099 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-10-15 14:24:49 +00:00
#pragma once
DFG JIT should infer which uses of a variable are not aliased https://bugs.webkit.org/show_bug.cgi?id=68593 Reviewed by Oliver Hunt. This separates how a variable is stored (i.e. its virtual register) from how it's predicted. Each variable now takes a VariableAccessData as its operand, instead of the virtual register. The VariableAccessData stores the operand and the prediction. If multiple uses of a variable are aliased, their VariableAccessDatas are unified. This also adds tracking of which argument values are used. It correctly observes that an argument value is not used, if the argument is assigned to inside the function before being used. This also adds tracking of which variables are live at the head of a basic block, and separates that from a variable being live at the tail. Finally, this communicates to both OSR entry and OSR exit code how a variable is predicted at a particular point in the code, rather than just communicating how it was predicted in the entire code block (since with this patch there is no longer the notion of a variable having just one prediction for a code block). * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: * JavaScriptCore.vcproj/WTF/WTF.vcproj: * JavaScriptCore.xcodeproj/project.pbxproj: * bytecode/ActionablePrediction.h: Added. (JSC::actionablePredictionFromPredictedType): (JSC::valueObeysPrediction): (JSC::actionablePredictionToString): (JSC::ActionablePredictions::ActionablePredictions): (JSC::ActionablePredictions::setArgument): (JSC::ActionablePredictions::argument): (JSC::ActionablePredictions::setVariable): (JSC::ActionablePredictions::variable): (JSC::ActionablePredictions::argumentUpperBound): (JSC::ActionablePredictions::variableUpperBound): (JSC::ActionablePredictions::pack): (JSC::ActionablePredictions::packVector): * bytecode/CodeBlock.h: * bytecode/PredictionTracker.h: * dfg/DFGByteCodeParser.cpp: (JSC::DFG::ByteCodeParser::newVariableAccessData): (JSC::DFG::ByteCodeParser::getLocal): (JSC::DFG::ByteCodeParser::setLocal): (JSC::DFG::ByteCodeParser::getArgument): (JSC::DFG::ByteCodeParser::setArgument): (JSC::DFG::ByteCodeParser::parseBlock): (JSC::DFG::ByteCodeParser::processPhiStack): (JSC::DFG::ByteCodeParser::parse): * dfg/DFGDriver.cpp: (JSC::DFG::compile): * dfg/DFGGraph.cpp: (JSC::DFG::Graph::nameOfVariableAccessData): (JSC::DFG::Graph::dump): (JSC::DFG::Graph::predictArgumentTypes): * dfg/DFGGraph.h: (JSC::DFG::operandIsArgument): (JSC::DFG::VariableRecord::setFirstTime): (JSC::DFG::BasicBlock::BasicBlock): (JSC::DFG::Graph::predict): (JSC::DFG::Graph::getPrediction): * dfg/DFGJITCompiler.h: (JSC::DFG::JITCompiler::noticeOSREntry): * dfg/DFGNode.h: (JSC::DFG::Node::hasVariableAccessData): (JSC::DFG::Node::hasLocal): (JSC::DFG::Node::variableAccessData): (JSC::DFG::Node::local): * dfg/DFGOSREntry.cpp: (JSC::DFG::prepareOSREntry): * dfg/DFGOSREntry.h: * dfg/DFGPropagator.cpp: (JSC::DFG::Propagator::propagateNodePredictions): * dfg/DFGSpeculativeJIT.cpp: (JSC::DFG::ValueSource::dump): (JSC::DFG::OSRExit::OSRExit): (JSC::DFG::SpeculativeJIT::compile): (JSC::DFG::SpeculativeJIT::checkArgumentTypes): (JSC::DFG::SpeculativeJIT::computeValueRecoveryFor): * dfg/DFGSpeculativeJIT.h: (JSC::DFG::ValueSource::ValueSource): (JSC::DFG::ValueSource::forPrediction): (JSC::DFG::ValueSource::isSet): (JSC::DFG::ValueSource::kind): (JSC::DFG::ValueSource::nodeIndex): (JSC::DFG::ValueSource::nodeIndexFromKind): (JSC::DFG::ValueSource::kindFromNodeIndex): (JSC::DFG::SpeculativeJIT::isKnownArray): (JSC::DFG::SpeculativeJIT::computeValueRecoveryFor): (JSC::DFG::SpeculativeJIT::SpeculativeJIT): * dfg/DFGSpeculativeJIT32_64.cpp: (JSC::DFG::OSRExit::OSRExit): (JSC::DFG::SpeculativeJIT::compile): (JSC::DFG::SpeculativeJIT::checkArgumentTypes): (JSC::DFG::SpeculativeJIT::computeValueRecoveryFor): * wtf/PackedIntVector.h: Added. (WTF::PackedIntVector::PackedIntVector): (WTF::PackedIntVector::operator=): (WTF::PackedIntVector::size): (WTF::PackedIntVector::ensureSize): (WTF::PackedIntVector::resize): (WTF::PackedIntVector::clearAll): (WTF::PackedIntVector::get): (WTF::PackedIntVector::set): (WTF::PackedIntVector::mask): * wtf/Platform.h: * wtf/UnionFind.h: Added. (WTF::UnionFind::UnionFind): (WTF::UnionFind::find): (WTF::UnionFind::unify): Canonical link: https://commits.webkit.org/85138@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@96375 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2011-09-29 23:17:19 +00:00
#include <wtf/Assertions.h>
namespace WTF {
// A UnionFind class can be used to compute disjoint sets using the
// disjoint-set forest data structure. Each UnionFind instance is a
// node in the forest. Typically you use it by using UnionFind as a
// superclass:
//
// class MemberOfSet : public UnionFind<MemberOfSet> { ... }
DFG JIT should infer which uses of a variable are not aliased https://bugs.webkit.org/show_bug.cgi?id=68593 Reviewed by Oliver Hunt. This separates how a variable is stored (i.e. its virtual register) from how it's predicted. Each variable now takes a VariableAccessData as its operand, instead of the virtual register. The VariableAccessData stores the operand and the prediction. If multiple uses of a variable are aliased, their VariableAccessDatas are unified. This also adds tracking of which argument values are used. It correctly observes that an argument value is not used, if the argument is assigned to inside the function before being used. This also adds tracking of which variables are live at the head of a basic block, and separates that from a variable being live at the tail. Finally, this communicates to both OSR entry and OSR exit code how a variable is predicted at a particular point in the code, rather than just communicating how it was predicted in the entire code block (since with this patch there is no longer the notion of a variable having just one prediction for a code block). * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: * JavaScriptCore.vcproj/WTF/WTF.vcproj: * JavaScriptCore.xcodeproj/project.pbxproj: * bytecode/ActionablePrediction.h: Added. (JSC::actionablePredictionFromPredictedType): (JSC::valueObeysPrediction): (JSC::actionablePredictionToString): (JSC::ActionablePredictions::ActionablePredictions): (JSC::ActionablePredictions::setArgument): (JSC::ActionablePredictions::argument): (JSC::ActionablePredictions::setVariable): (JSC::ActionablePredictions::variable): (JSC::ActionablePredictions::argumentUpperBound): (JSC::ActionablePredictions::variableUpperBound): (JSC::ActionablePredictions::pack): (JSC::ActionablePredictions::packVector): * bytecode/CodeBlock.h: * bytecode/PredictionTracker.h: * dfg/DFGByteCodeParser.cpp: (JSC::DFG::ByteCodeParser::newVariableAccessData): (JSC::DFG::ByteCodeParser::getLocal): (JSC::DFG::ByteCodeParser::setLocal): (JSC::DFG::ByteCodeParser::getArgument): (JSC::DFG::ByteCodeParser::setArgument): (JSC::DFG::ByteCodeParser::parseBlock): (JSC::DFG::ByteCodeParser::processPhiStack): (JSC::DFG::ByteCodeParser::parse): * dfg/DFGDriver.cpp: (JSC::DFG::compile): * dfg/DFGGraph.cpp: (JSC::DFG::Graph::nameOfVariableAccessData): (JSC::DFG::Graph::dump): (JSC::DFG::Graph::predictArgumentTypes): * dfg/DFGGraph.h: (JSC::DFG::operandIsArgument): (JSC::DFG::VariableRecord::setFirstTime): (JSC::DFG::BasicBlock::BasicBlock): (JSC::DFG::Graph::predict): (JSC::DFG::Graph::getPrediction): * dfg/DFGJITCompiler.h: (JSC::DFG::JITCompiler::noticeOSREntry): * dfg/DFGNode.h: (JSC::DFG::Node::hasVariableAccessData): (JSC::DFG::Node::hasLocal): (JSC::DFG::Node::variableAccessData): (JSC::DFG::Node::local): * dfg/DFGOSREntry.cpp: (JSC::DFG::prepareOSREntry): * dfg/DFGOSREntry.h: * dfg/DFGPropagator.cpp: (JSC::DFG::Propagator::propagateNodePredictions): * dfg/DFGSpeculativeJIT.cpp: (JSC::DFG::ValueSource::dump): (JSC::DFG::OSRExit::OSRExit): (JSC::DFG::SpeculativeJIT::compile): (JSC::DFG::SpeculativeJIT::checkArgumentTypes): (JSC::DFG::SpeculativeJIT::computeValueRecoveryFor): * dfg/DFGSpeculativeJIT.h: (JSC::DFG::ValueSource::ValueSource): (JSC::DFG::ValueSource::forPrediction): (JSC::DFG::ValueSource::isSet): (JSC::DFG::ValueSource::kind): (JSC::DFG::ValueSource::nodeIndex): (JSC::DFG::ValueSource::nodeIndexFromKind): (JSC::DFG::ValueSource::kindFromNodeIndex): (JSC::DFG::SpeculativeJIT::isKnownArray): (JSC::DFG::SpeculativeJIT::computeValueRecoveryFor): (JSC::DFG::SpeculativeJIT::SpeculativeJIT): * dfg/DFGSpeculativeJIT32_64.cpp: (JSC::DFG::OSRExit::OSRExit): (JSC::DFG::SpeculativeJIT::compile): (JSC::DFG::SpeculativeJIT::checkArgumentTypes): (JSC::DFG::SpeculativeJIT::computeValueRecoveryFor): * wtf/PackedIntVector.h: Added. (WTF::PackedIntVector::PackedIntVector): (WTF::PackedIntVector::operator=): (WTF::PackedIntVector::size): (WTF::PackedIntVector::ensureSize): (WTF::PackedIntVector::resize): (WTF::PackedIntVector::clearAll): (WTF::PackedIntVector::get): (WTF::PackedIntVector::set): (WTF::PackedIntVector::mask): * wtf/Platform.h: * wtf/UnionFind.h: Added. (WTF::UnionFind::UnionFind): (WTF::UnionFind::find): (WTF::UnionFind::unify): Canonical link: https://commits.webkit.org/85138@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@96375 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2011-09-29 23:17:19 +00:00
//
// Calling x->find() gives you a MemberOfSet* that represents the
// disjoint set that x belongs to. Calling x->unify(y) unifies x's
// set with y's set, and ensures that:
//
// x->find() == y->find()
//
// and that:
//
// a->find() == b->find()
//
// for any a, b if prior to the call to x->unify(y), we would have
// had:
//
// a->find() == x
// b->find() == y
//
// This implementation is almost amortized O(1), but could be worse
// in unlikely pathological cases. It favors having a non-recursive
// single pass implementation of unify() and find() over ensuring the
// theoretical O(InverseAckermann[n]) amortized bound, which is much
// closer to amortized O(1).
template<typename T>
class UnionFind {
public:
UnionFind()
: m_parent(0)
{
}
DFG should flush SetLocals to arguments https://bugs.webkit.org/show_bug.cgi?id=83554 Source/JavaScriptCore: Reviewed by Gavin Barraclough. This is necessary to match baseline JIT argument capture behavior. But to make this work right we need to have a story for arguments into which we store values of different formats. This patch introduces the notion of an ArgumentPosition - i.e. an argument in a particular inline call frame - and forces unification of all data pertinent to selecting the argument's data format. Also fixed an amusing bug in the handling of OSR on SetLocals if there was any insertion/deletion of nodes in the basic block. This is benign for now but won't be eventually since the DFG is getting smarter. So better fix it now. Also fixed an amusing bug in the handling of OSR on SetLocals if they are immediately followed by a Flush. I think this bug might have always been there but now it'll happen more commonly, and it's covered by the run-javascriptcore-tests. * JavaScriptCore.xcodeproj/project.pbxproj: * dfg/DFGAbstractState.cpp: (JSC::DFG::AbstractState::execute): * dfg/DFGArgumentPosition.h: Added. (DFG): (ArgumentPosition): (JSC::DFG::ArgumentPosition::ArgumentPosition): (JSC::DFG::ArgumentPosition::addVariable): (JSC::DFG::ArgumentPosition::mergeArgumentAwareness): * dfg/DFGByteCodeParser.cpp: (JSC::DFG::ByteCodeParser::setLocal): (JSC::DFG::ByteCodeParser::setArgument): (InlineStackEntry): (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry): * dfg/DFGDoubleFormatState.h: Added. (DFG): (JSC::DFG::mergeDoubleFormatStates): (JSC::DFG::mergeDoubleFormatState): (JSC::DFG::doubleFormatStateToString): * dfg/DFGGraph.h: (Graph): * dfg/DFGPredictionPropagationPhase.cpp: (JSC::DFG::PredictionPropagationPhase::doRoundOfDoubleVoting): * dfg/DFGSpeculativeJIT32_64.cpp: (JSC::DFG::SpeculativeJIT::compile): * dfg/DFGSpeculativeJIT64.cpp: (JSC::DFG::SpeculativeJIT::compile): * dfg/DFGVariableAccessData.h: (JSC::DFG::VariableAccessData::VariableAccessData): (JSC::DFG::VariableAccessData::predict): (JSC::DFG::VariableAccessData::argumentAwarePrediction): (VariableAccessData): (JSC::DFG::VariableAccessData::mergeArgumentAwarePrediction): (JSC::DFG::VariableAccessData::doubleFormatState): (JSC::DFG::VariableAccessData::shouldUseDoubleFormat): (JSC::DFG::VariableAccessData::tallyVotesForShouldUseDoubleFormat): (JSC::DFG::VariableAccessData::mergeDoubleFormatState): (JSC::DFG::VariableAccessData::makePredictionForDoubleFormat): Source/WTF: Reviewed by Gavin Barraclough. Added an isRoot() method that is a faster shorthand for saying find() == this. * wtf/UnionFind.h: (WTF::UnionFind::isRoot): (UnionFind): LayoutTests: Rubber stamped by Gavin Barraclough. Added a variety of tests for reassigning arguments prior to function.arguments retrieval. * fast/js/dfg-inline-arguments-become-double-expected.txt: Added. * fast/js/dfg-inline-arguments-become-double.html: Added. * fast/js/dfg-inline-arguments-become-int32-expected.txt: Added. * fast/js/dfg-inline-arguments-become-int32.html: Added. * fast/js/dfg-inline-arguments-reset-changetype-expected.txt: Added. * fast/js/dfg-inline-arguments-reset-changetype.html: Added. * fast/js/dfg-inline-arguments-reset-expected.txt: Added. * fast/js/dfg-inline-arguments-reset.html: Added. * fast/js/script-tests/dfg-inline-arguments-become-double.js: Added. (foo): (bar): (baz): (argsToStr): * fast/js/script-tests/dfg-inline-arguments-become-int32.js: Added. (foo): (bar): (baz): (argsToStr): * fast/js/script-tests/dfg-inline-arguments-reset-changetype.js: Added. (foo): (bar): (baz): (argsToStr): * fast/js/script-tests/dfg-inline-arguments-reset.js: Added. (foo): (bar): (baz): (argsToStr): Canonical link: https://commits.webkit.org/101095@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@113796 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2012-04-11 00:37:04 +00:00
bool isRoot() const
{
bool result = !m_parent;
ASSERT(result == (const_cast<UnionFind<T>*>(this)->find() == this));
return result;
}
DFG JIT should infer which uses of a variable are not aliased https://bugs.webkit.org/show_bug.cgi?id=68593 Reviewed by Oliver Hunt. This separates how a variable is stored (i.e. its virtual register) from how it's predicted. Each variable now takes a VariableAccessData as its operand, instead of the virtual register. The VariableAccessData stores the operand and the prediction. If multiple uses of a variable are aliased, their VariableAccessDatas are unified. This also adds tracking of which argument values are used. It correctly observes that an argument value is not used, if the argument is assigned to inside the function before being used. This also adds tracking of which variables are live at the head of a basic block, and separates that from a variable being live at the tail. Finally, this communicates to both OSR entry and OSR exit code how a variable is predicted at a particular point in the code, rather than just communicating how it was predicted in the entire code block (since with this patch there is no longer the notion of a variable having just one prediction for a code block). * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: * JavaScriptCore.vcproj/WTF/WTF.vcproj: * JavaScriptCore.xcodeproj/project.pbxproj: * bytecode/ActionablePrediction.h: Added. (JSC::actionablePredictionFromPredictedType): (JSC::valueObeysPrediction): (JSC::actionablePredictionToString): (JSC::ActionablePredictions::ActionablePredictions): (JSC::ActionablePredictions::setArgument): (JSC::ActionablePredictions::argument): (JSC::ActionablePredictions::setVariable): (JSC::ActionablePredictions::variable): (JSC::ActionablePredictions::argumentUpperBound): (JSC::ActionablePredictions::variableUpperBound): (JSC::ActionablePredictions::pack): (JSC::ActionablePredictions::packVector): * bytecode/CodeBlock.h: * bytecode/PredictionTracker.h: * dfg/DFGByteCodeParser.cpp: (JSC::DFG::ByteCodeParser::newVariableAccessData): (JSC::DFG::ByteCodeParser::getLocal): (JSC::DFG::ByteCodeParser::setLocal): (JSC::DFG::ByteCodeParser::getArgument): (JSC::DFG::ByteCodeParser::setArgument): (JSC::DFG::ByteCodeParser::parseBlock): (JSC::DFG::ByteCodeParser::processPhiStack): (JSC::DFG::ByteCodeParser::parse): * dfg/DFGDriver.cpp: (JSC::DFG::compile): * dfg/DFGGraph.cpp: (JSC::DFG::Graph::nameOfVariableAccessData): (JSC::DFG::Graph::dump): (JSC::DFG::Graph::predictArgumentTypes): * dfg/DFGGraph.h: (JSC::DFG::operandIsArgument): (JSC::DFG::VariableRecord::setFirstTime): (JSC::DFG::BasicBlock::BasicBlock): (JSC::DFG::Graph::predict): (JSC::DFG::Graph::getPrediction): * dfg/DFGJITCompiler.h: (JSC::DFG::JITCompiler::noticeOSREntry): * dfg/DFGNode.h: (JSC::DFG::Node::hasVariableAccessData): (JSC::DFG::Node::hasLocal): (JSC::DFG::Node::variableAccessData): (JSC::DFG::Node::local): * dfg/DFGOSREntry.cpp: (JSC::DFG::prepareOSREntry): * dfg/DFGOSREntry.h: * dfg/DFGPropagator.cpp: (JSC::DFG::Propagator::propagateNodePredictions): * dfg/DFGSpeculativeJIT.cpp: (JSC::DFG::ValueSource::dump): (JSC::DFG::OSRExit::OSRExit): (JSC::DFG::SpeculativeJIT::compile): (JSC::DFG::SpeculativeJIT::checkArgumentTypes): (JSC::DFG::SpeculativeJIT::computeValueRecoveryFor): * dfg/DFGSpeculativeJIT.h: (JSC::DFG::ValueSource::ValueSource): (JSC::DFG::ValueSource::forPrediction): (JSC::DFG::ValueSource::isSet): (JSC::DFG::ValueSource::kind): (JSC::DFG::ValueSource::nodeIndex): (JSC::DFG::ValueSource::nodeIndexFromKind): (JSC::DFG::ValueSource::kindFromNodeIndex): (JSC::DFG::SpeculativeJIT::isKnownArray): (JSC::DFG::SpeculativeJIT::computeValueRecoveryFor): (JSC::DFG::SpeculativeJIT::SpeculativeJIT): * dfg/DFGSpeculativeJIT32_64.cpp: (JSC::DFG::OSRExit::OSRExit): (JSC::DFG::SpeculativeJIT::compile): (JSC::DFG::SpeculativeJIT::checkArgumentTypes): (JSC::DFG::SpeculativeJIT::computeValueRecoveryFor): * wtf/PackedIntVector.h: Added. (WTF::PackedIntVector::PackedIntVector): (WTF::PackedIntVector::operator=): (WTF::PackedIntVector::size): (WTF::PackedIntVector::ensureSize): (WTF::PackedIntVector::resize): (WTF::PackedIntVector::clearAll): (WTF::PackedIntVector::get): (WTF::PackedIntVector::set): (WTF::PackedIntVector::mask): * wtf/Platform.h: * wtf/UnionFind.h: Added. (WTF::UnionFind::UnionFind): (WTF::UnionFind::find): (WTF::UnionFind::unify): Canonical link: https://commits.webkit.org/85138@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@96375 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2011-09-29 23:17:19 +00:00
T* find()
{
T* result = static_cast<T*>(this);
T* next = result->m_parent;
while (next) {
result = next;
next = result->m_parent;
}
ASSERT(result);
if (result != this)
m_parent = result;
return result;
}
void unify(T* other)
{
T* a = static_cast<T*>(this)->find();
T* b = other->find();
ASSERT(!a->m_parent);
ASSERT(!b->m_parent);
if (a == b)
return;
a->m_parent = b;
}
private:
T* m_parent;
};
} // namespace WTF
using WTF::UnionFind;