Source/JavaScriptCore/CMakeLists.txt

@@set(JavaScriptCore_SOURCES
126126 dfg/DFGBasicBlock.cpp
127127 dfg/DFGBinarySwitch.cpp
128128 dfg/DFGBlockInsertionSet.cpp
 129 dfg/DFGBlockWorklist.cpp
129130 dfg/DFGByteCodeParser.cpp
130131 dfg/DFGCFAPhase.cpp
131132 dfg/DFGCFGSimplificationPhase.cpp

@@set(JavaScriptCore_SOURCES
175176 dfg/DFGLoopPreHeaderCreationPhase.cpp
176177 dfg/DFGMayExit.cpp
177178 dfg/DFGMinifiedNode.cpp
 179 dfg/DFGNaiveDominators.cpp
178180 dfg/DFGNaturalLoops.cpp
179181 dfg/DFGNode.cpp
180182 dfg/DFGNodeFlags.cpp
172947

Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj

372372 <ClCompile Include="..\dfg\DFGBasicBlock.cpp" />
373373 <ClCompile Include="..\dfg\DFGBinarySwitch.cpp" />
374374 <ClCompile Include="..\dfg\DFGBlockInsertionSet.cpp" />
 375 <ClCompile Include="..\dfg\DFGBlockWorklist.cpp" />
375376 <ClCompile Include="..\dfg\DFGByteCodeParser.cpp" />
376377 <ClCompile Include="..\dfg\DFGCapabilities.cpp" />
377378 <ClCompile Include="..\dfg\DFGCFAPhase.cpp" />

421422 <ClCompile Include="..\dfg\DFGLoopPreHeaderCreationPhase.cpp" />
422423 <ClCompile Include="..\dfg\DFGMayExit.cpp" />
423424 <ClCompile Include="..\dfg\DFGMinifiedNode.cpp" />
 425 <ClCompile Include="..\dfg\DFGNaiveDominators.cpp" />
424426 <ClCompile Include="..\dfg\DFGNaturalLoops.cpp" />
425427 <ClCompile Include="..\dfg\DFGNode.cpp" />
426428 <ClCompile Include="..\dfg\DFGNodeFlags.cpp" />

993995 <ClInclude Include="..\dfg\DFGBasicBlockInlines.h" />
994996 <ClInclude Include="..\dfg\DFGBinarySwitch.h" />
995997 <ClInclude Include="..\dfg\DFGBlockInsertionSet.h" />
 998 <ClInclude Include="..\dfg\DFGBlockMap.h" />
 999 <ClInclude Include="..\dfg\DFGBlockMapInlines.h" />
 1000 <ClInclude Include="..\dfg\DFGBlockWorklist.h" />
 1001 <ClInclude Include="..\dfg\DFGBlockSet.h" />
9961002 <ClInclude Include="..\dfg\DFGBranchDirection.h" />
9971003 <ClInclude Include="..\dfg\DFGByteCodeParser.h" />
9981004 <ClInclude Include="..\dfg\DFGCallArrayAllocatorSlowPathGenerator.h" />

10561062 <ClInclude Include="..\dfg\DFGMinifiedGraph.h" />
10571063 <ClInclude Include="..\dfg\DFGMinifiedID.h" />
10581064 <ClInclude Include="..\dfg\DFGMinifiedNode.h" />
 1065 <ClInclude Include="..\dfg\DFGNaiveDominators.h" />
10591066 <ClInclude Include="..\dfg\DFGNaturalLoops.h" />
10601067 <ClInclude Include="..\dfg\DFGNode.h" />
10611068 <ClInclude Include="..\dfg\DFGNodeAllocator.h" />
172947

Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

498498 0FC314121814559100033232 /* RegisterSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC314101814559100033232 /* RegisterSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
499499 0FC314131814559100033232 /* TempRegisterSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC314111814559100033232 /* TempRegisterSet.cpp */; };
500500 0FC3141518146D7000033232 /* RegisterSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC3141418146D7000033232 /* RegisterSet.cpp */; };
 501 0FC3CCFC19ADA410006AC72A /* DFGBlockMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC3CCF519ADA410006AC72A /* DFGBlockMap.h */; settings = {ATTRIBUTES = (Private, ); }; };
 502 0FC3CCFD19ADA410006AC72A /* DFGBlockMapInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC3CCF619ADA410006AC72A /* DFGBlockMapInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
 503 0FC3CCFE19ADA410006AC72A /* DFGBlockSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC3CCF719ADA410006AC72A /* DFGBlockSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
 504 0FC3CCFF19ADA410006AC72A /* DFGBlockWorklist.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC3CCF819ADA410006AC72A /* DFGBlockWorklist.cpp */; };
 505 0FC3CD0019ADA410006AC72A /* DFGBlockWorklist.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC3CCF919ADA410006AC72A /* DFGBlockWorklist.h */; settings = {ATTRIBUTES = (Private, ); }; };
 506 0FC3CD0119ADA411006AC72A /* DFGNaiveDominators.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC3CCFA19ADA410006AC72A /* DFGNaiveDominators.cpp */; };
 507 0FC3CD0219ADA411006AC72A /* DFGNaiveDominators.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC3CCFB19ADA410006AC72A /* DFGNaiveDominators.h */; settings = {ATTRIBUTES = (Private, ); }; };
501508 0FC712DE17CD8779008CC93C /* DeferredCompilationCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC712DC17CD8778008CC93C /* DeferredCompilationCallback.cpp */; };
502509 0FC712DF17CD877C008CC93C /* DeferredCompilationCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC712DD17CD8778008CC93C /* DeferredCompilationCallback.h */; settings = {ATTRIBUTES = (Private, ); }; };
503510 0FC712E217CD8791008CC93C /* JITToDFGDeferredCompilationCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC712E017CD878F008CC93C /* JITToDFGDeferredCompilationCallback.cpp */; };

24212428 0FC314101814559100033232 /* RegisterSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegisterSet.h; sourceTree = "<group>"; };
24222429 0FC314111814559100033232 /* TempRegisterSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TempRegisterSet.cpp; sourceTree = "<group>"; };
24232430 0FC3141418146D7000033232 /* RegisterSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegisterSet.cpp; sourceTree = "<group>"; };
 2431 0FC3CCF519ADA410006AC72A /* DFGBlockMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGBlockMap.h; path = dfg/DFGBlockMap.h; sourceTree = "<group>"; };
 2432 0FC3CCF619ADA410006AC72A /* DFGBlockMapInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGBlockMapInlines.h; path = dfg/DFGBlockMapInlines.h; sourceTree = "<group>"; };
 2433 0FC3CCF719ADA410006AC72A /* DFGBlockSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGBlockSet.h; path = dfg/DFGBlockSet.h; sourceTree = "<group>"; };
 2434 0FC3CCF819ADA410006AC72A /* DFGBlockWorklist.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGBlockWorklist.cpp; path = dfg/DFGBlockWorklist.cpp; sourceTree = "<group>"; };
 2435 0FC3CCF919ADA410006AC72A /* DFGBlockWorklist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGBlockWorklist.h; path = dfg/DFGBlockWorklist.h; sourceTree = "<group>"; };
 2436 0FC3CCFA19ADA410006AC72A /* DFGNaiveDominators.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGNaiveDominators.cpp; path = dfg/DFGNaiveDominators.cpp; sourceTree = "<group>"; };
 2437 0FC3CCFB19ADA410006AC72A /* DFGNaiveDominators.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGNaiveDominators.h; path = dfg/DFGNaiveDominators.h; sourceTree = "<group>"; };
24242438 0FC712DC17CD8778008CC93C /* DeferredCompilationCallback.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DeferredCompilationCallback.cpp; sourceTree = "<group>"; };
24252439 0FC712DD17CD8778008CC93C /* DeferredCompilationCallback.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DeferredCompilationCallback.h; sourceTree = "<group>"; };
24262440 0FC712E017CD878F008CC93C /* JITToDFGDeferredCompilationCallback.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = JITToDFGDeferredCompilationCallback.cpp; sourceTree = "<group>"; };

48194833 A70B083117A0B79B00DAF14B /* DFGBinarySwitch.h */,
48204834 A7D89CE417A0B8CC00773AD8 /* DFGBlockInsertionSet.cpp */,
48214835 A7D89CE517A0B8CC00773AD8 /* DFGBlockInsertionSet.h */,
 4836 0FC3CCF519ADA410006AC72A /* DFGBlockMap.h */,
 4837 0FC3CCF619ADA410006AC72A /* DFGBlockMapInlines.h */,
 4838 0FC3CCF719ADA410006AC72A /* DFGBlockSet.h */,
 4839 0FC3CCF819ADA410006AC72A /* DFGBlockWorklist.cpp */,
 4840 0FC3CCF919ADA410006AC72A /* DFGBlockWorklist.h */,
48224841 0F8364B5164B0C0E0053329A /* DFGBranchDirection.h */,
48234842 86EC9DB41328DF82002B2AD7 /* DFGByteCodeParser.cpp */,
48244843 86EC9DB51328DF82002B2AD7 /* DFGByteCodeParser.h */,

49304949 0FB4B51016B3A964003F696B /* DFGMinifiedID.h */,
49314950 0F2BDC4C1522818300CD8910 /* DFGMinifiedNode.cpp */,
49324951 0F2BDC3E1522801700CD8910 /* DFGMinifiedNode.h */,
 4952 0FC3CCFA19ADA410006AC72A /* DFGNaiveDominators.cpp */,
 4953 0FC3CCFB19ADA410006AC72A /* DFGNaiveDominators.h */,
49334954 A737810A1799EA2E00817533 /* DFGNaturalLoops.cpp */,
49344955 A737810B1799EA2E00817533 /* DFGNaturalLoops.h */,
49354956 0FB4B51E16B62772003F696B /* DFGNode.cpp */,

58425863 C2FC9BD316644DFB00810D33 /* CopiedBlockInlines.h in Headers */,
58435864 C2EAA3FA149A835E00FCE112 /* CopiedSpace.h in Headers */,
58445865 C2C8D02D14A3C6E000578E65 /* CopiedSpaceInlines.h in Headers */,
 5866 0FC3CCFD19ADA410006AC72A /* DFGBlockMapInlines.h in Headers */,
58455867 0F5A52D017ADD717008ECB2D /* CopyToken.h in Headers */,
58465868 C2239D1816262BDD005AC5FD /* CopyVisitor.h in Headers */,
58475869 C2239D1916262BDD005AC5FD /* CopyVisitorInlines.h in Headers */,

59175939 A7BFF3C0179868940002F462 /* DFGFiltrationResult.h in Headers */,
59185940 A78A9777179738B8009DF744 /* DFGFinalizer.h in Headers */,
59195941 0F2BDC16151C5D4F00CD8910 /* DFGFixupPhase.h in Headers */,
 5942 0FC3CCFC19ADA410006AC72A /* DFGBlockMap.h in Headers */,
59205943 0F9D339717FFC4E60073C2BC /* DFGFlushedAt.h in Headers */,
59215944 A7D89CF817A0B8CC00773AD8 /* DFGFlushFormat.h in Headers */,
59225945 86EC9DC61328DF82002B2AD7 /* DFGGenerationInfo.h in Headers */,

63176340 0F431738146BAC69007E3890 /* ListableHandler.h in Headers */,
63186341 A7E2EA6B0FB460CF00601F06 /* LiteralParser.h in Headers */,
63196342 0F0FC45A14BD15F500B81154 /* LLIntCallLinkInfo.h in Headers */,
 6343 0FC3CD0019ADA410006AC72A /* DFGBlockWorklist.h in Headers */,
63206344 FE20CE9E15F04A9500DF3430 /* LLIntCLoop.h in Headers */,
63216345 0F4680CA14BBB16C00BFE272 /* LLIntCommon.h in Headers */,
63226346 0F4680D314BBD16700BFE272 /* LLIntData.h in Headers */,

63296353 0F0123331944EA1B00843A0C /* DFGValueStrength.h in Headers */,
63306354 0FCEFACE1805E75500472CE4 /* LLVMAPI.h in Headers */,
63316355 0FCEFACF1805E75500472CE4 /* LLVMAPIFunctions.h in Headers */,
 6356 0FC3CCFE19ADA410006AC72A /* DFGBlockSet.h in Headers */,
63326357 A7E5AB381799E4B200D2833D /* LLVMDisassembler.h in Headers */,
63336358 0FCEFAD31805EDCC00472CE4 /* LLVMHeaders.h in Headers */,
63346359 142E3139134FF0A600AFADB5 /* Local.h in Headers */,

63746399 7EFF00640EC05A9A00AA7C93 /* NodeInfo.h in Headers */,
63756400 BC18C43F0E16F5CD00B34460 /* Nodes.h in Headers */,
63766401 99E45A2818A1B2590026D88F /* NondeterministicInput.h in Headers */,
 6402 0FC3CD0219ADA411006AC72A /* DFGNaiveDominators.h in Headers */,
63776403 BC18C4410E16F5CD00B34460 /* NumberConstructor.h in Headers */,
63786404 0F5780A218FE1E98001E72D9 /* PureNaN.h in Headers */,
63796405 BC18C4420E16F5CD00B34460 /* NumberConstructor.lut.h in Headers */,

72977323 A7D89CFF17A0B8CC00773AD8 /* DFGSSAConversionPhase.cpp in Sources */,
72987324 2A05ABD51961DF2400341750 /* JSPropertyNameEnumerator.cpp in Sources */,
72997325 0FC20CB918556A3500C9E954 /* DFGSSALoweringPhase.cpp in Sources */,
 7326 0FC3CD0119ADA411006AC72A /* DFGNaiveDominators.cpp in Sources */,
73007327 0F9FB4F417FCB91700CB67F8 /* DFGStackLayoutPhase.cpp in Sources */,
73017328 0F4F29DF18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.cpp in Sources */,
73027329 0FE7211D193B9C590031F6ED /* DFGTransition.cpp in Sources */,

73577384 0FD8A31917D51F2200CA2C40 /* FTLForOSREntryJITCode.cpp in Sources */,
73587385 0F25F1AF181635F300522F39 /* FTLInlineCacheSize.cpp in Sources */,
73597386 0FEA0A281709623B00BB722C /* FTLIntrinsicRepository.cpp in Sources */,
 7387 0FC3CCFF19ADA410006AC72A /* DFGBlockWorklist.cpp in Sources */,
73607388 0FEA0A0D170513DB00BB722C /* FTLJITCode.cpp in Sources */,
73617389 A78A9780179738D5009DF744 /* FTLJITFinalizer.cpp in Sources */,
73627390 0F6B1CB5185FC9E900845D97 /* FTLJSCall.cpp in Sources */,
172947

Source/JavaScriptCore/dfg/DFGBlockMap.h

 1/*
 2 * Copyright (C) 2014 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#ifndef DFGBlockMap_h
 27#define DFGBlockMap_h
 28
 29#if ENABLE(DFG_JIT)
 30
 31#include "DFGBasicBlock.h"
 32
 33namespace JSC { namespace DFG {
 34
 35class Graph;
 36
 37template<typename T>
 38class BlockMap {
 39public:
 40 BlockMap()
 41 {
 42 }
 43
 44 BlockMap(Graph&);
 45
 46 BlockIndex size() const
 47 {
 48 return m_vector.size();
 49 }
 50
 51 T& operator[](BlockIndex blockIndex)
 52 {
 53 return m_vector[blockIndex];
 54 }
 55
 56 const T& operator[](BlockIndex blockIndex)
 57 {
 58 return m_vector[blockIndex];
 59 }
 60
 61 T& operator[](BasicBlock* block)
 62 {
 63 return m_vector[block->index];
 64 }
 65
 66 const T& operator[](BasicBlock* block) const
 67 {
 68 return m_vector[block->index];
 69 }
 70
 71private:
 72 Vector<T> m_vector;
 73};
 74
 75} } // namespace JSC::DFG
 76
 77#endif // ENABLE(DFG_JIT)
 78
 79#endif // DFGBlockMap_h
 80
0

Source/JavaScriptCore/dfg/DFGBlockMapInlines.h

 1/*
 2 * Copyright (C) 2014 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#ifndef DFGBlockMapInlines_h
 27#define DFGBlockMapInlines_h
 28
 29#if ENABLE(DFG_JIT)
 30
 31#include "DFGBlockMap.h"
 32#include "DFGGraph.h"
 33
 34namespace JSC { namespace DFG {
 35
 36template<typename T>
 37BlockMap<T>::BlockMap(Graph& graph)
 38{
 39 m_vector.resize(graph.numBlocks());
 40}
 41
 42} } // namespace JSC::DFG
 43
 44#endif // ENABLE(DFG_JIT)
 45
 46#endif // DFGBlockMapInlines_h
0

Source/JavaScriptCore/dfg/DFGBlockSet.h

 1/*
 2 * Copyright (C) 2014 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#ifndef DFGBlockSet_h
 27#define DFGBlockSet_h
 28
 29#if ENABLE(DFG_JIT)
 30
 31#include "DFGBasicBlock.h"
 32
 33namespace JSC { namespace DFG {
 34
 35class BlockSet {
 36public:
 37 BlockSet() { }
 38
 39 bool add(BasicBlock* block)
 40 {
 41 return m_set.set(block->index);
 42 }
 43
 44 bool contains(BasicBlock* block) const
 45 {
 46 if (!block)
 47 return false;
 48 return m_set.get(block->index);
 49 }
 50
 51private:
 52 BitVector m_set;
 53};
 54
 55} } // namespace JSC::DFG
 56
 57#endif // ENABLE(DFG_JIT)
 58
 59#endif // DFGBlockSet_h
 60
0

Source/JavaScriptCore/dfg/DFGBlockWorklist.cpp

 1/*
 2 * Copyright (C) 2014 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#include "config.h"
 27#include "DFGBlockWorklist.h"
 28
 29#if ENABLE(DFG_JIT)
 30
 31#include "DFGBasicBlock.h"
 32
 33namespace JSC { namespace DFG {
 34
 35BlockWorklist::BlockWorklist()
 36{
 37}
 38
 39BlockWorklist::~BlockWorklist()
 40{
 41}
 42
 43bool BlockWorklist::push(BasicBlock* block)
 44{
 45 if (!m_seen.set(block))
 46 return false;
 47
 48 m_stack.append(block);
 49 return true;
 50}
 51
 52BasicBlock* BlockWorklist::pop()
 53{
 54 if (m_stack.isEmpty())
 55 return nullptr;
 56
 57 return m_stack.takeLast();
 58}
 59
 60PostOrderBlockWorklist::PostOrderBlockWorklist()
 61{
 62}
 63
 64PostOrderBlockWorklist::~PostOrderBlockWorlist()
 65{
 66}
 67
 68void PostOrderBlockWorklist::pushPre(BasicBlock* block)
 69{
 70 m_worklist.push(block, PreOrder);
 71}
 72
 73void PostOrderBlockWorklist.pushPost(BasicBlock* block)
 74{
 75 m_worklist.forcePush(block, PostOrder);
 76}
 77
 78BlockWithOrder PostOrderBlockWorklist::pop()
 79{
 80 BlockWith<VisitOrder> result = m_worklist.pop();
 81 return BlockWithOrder(result.block, result.data);
 82}
 83
 84} } // namespace JSC::DFG
 85
 86#endif // ENABLE(DFG_JIT)
0

Source/JavaScriptCore/dfg/DFGBlockWorklist.h

 1/*
 2 * Copyright (C) 2014 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#ifndef DFGBlockWorklist_h
 27#define DFGBlockWorklist_h
 28
 29#if ENABLE(DFG_JIT)
 30
 31#include "DFGBasicBlock.h"
 32#include "DFGBlockSet.h"
 33#include <wtf/Vector.h>
 34
 35namespace JSC { namespace DFG {
 36
 37struct BasicBlock;
 38
 39class BlockWorklist {
 40public:
 41 BlockWorklist();
 42 ~BlockWorklist();
 43
 44 bool push(BasicBlock*); // Returns true if we didn't know about the block before.
 45
 46 bool notEmpty() const { return !m_stack.isEmpty(); }
 47 BasicBlock* pop();
 48
 49private:
 50 BlockSet m_seen;
 51 Vector<BasicBlock*, 16> m_stack;
 52};
 53
 54// When you say BlockWith<int> you should read it as "block with an int".
 55template<typename T>
 56struct BlockWith {
 57 BlockWith()
 58 : block(nullptr)
 59 {
 60 }
 61
 62 BlockWith(BasicBlock* block, const T& data)
 63 : block(block)
 64 , data(data)
 65 {
 66 }
 67
 68 typedef void* (BlockWith<T>::*UnspecifiedBoolType);
 69 operator UnspecifiedBoolType*() const
 70 {
 71 return block ? reinterpret_cast<UnspecifiedBoolType*>(1) : nullptr;
 72 }
 73
 74 BasicBlock* block;
 75 T data;
 76};
 77
 78// Extended block worklist is useful for enqueueing some meta-data along with the block. It also
 79// permits forcibly enqueueing things even if the block has already been seen.
 80template<typename T>
 81class ExtendedBlockWorklist {
 82public:
 83 ExtendedBlockWorklist() { }
 84
 85 bool forcePush(const BlockWith<T>& entry)
 86 {
 87 m_stack.append(entry);
 88 }
 89
 90 bool forcePush(BasicBlock* block, const T& data)
 91 {
 92 forcePush(BlockWith<T>(block, data));
 93 }
 94
 95 bool push(const BlockWith<T>& entry)
 96 {
 97 if (!m_seen.add(entry.block))
 98 return;
 99
 100 forcePush(entry);
 101 }
 102
 103 bool push(BasicBlock* block, const T& data)
 104 {
 105 push(BlockWith<T>(block, data));
 106 }
 107
 108 bool notEmpty() const { return !m_stack.isEmpty(); }
 109
 110 BlockWith<T> pop()
 111 {
 112 if (m_stack.isEmpty())
 113 return BlockWith<T>();
 114
 115 return m_stack.takeLast();
 116 }
 117
 118private:
 119 BlockSet m_seen;
 120 Vector<BlockWith<T>> m_stack;
 121};
 122
 123enum VisitOrder {
 124 PreOrder,
 125 PostOrder
 126};
 127
 128struct BlockWithOrder {
 129 BlockWithOrder()
 130 : block(nullptr)
 131 , order(PreOrder)
 132 {
 133 }
 134
 135 BlockWithOrder(BasicBlock* block, VisitOrder order)
 136 : block(block)
 137 , order(order)
 138 {
 139 }
 140
 141 typedef void* (BlockWithOrder::*UnspecifiedBoolType);
 142 operator UnspecifiedBoolType*() const
 143 {
 144 return block ? reinterpret_cast<UnspecifiedBoolType*>(1) : nullptr;
 145 }
 146
 147 BasicBlock* block;
 148 VisitOrder order;
 149};
 150
 151// Block worklist suitable for post-order traversal.
 152class PostOrderBlockWorklist {
 153public:
 154 PostOrderBlockWorklist();
 155 ~PostOrderBlockWorklist();
 156
 157 void pushPre(BasicBlock*);
 158 void pushPost(BasicBlock*);
 159
 160 void push(BasicBlock* block, VisitOrder order = PreOrder)
 161 {
 162 switch (order) {
 163 case PreOrder:
 164 pushPre(block);
 165 return;
 166 case PostOrder:
 167 pushPost(block);
 168 return;
 169 }
 170 }
 171 void push(const BlockWithOrder& data)
 172 {
 173 push(data.block, data.order);
 174 }
 175
 176 bool nonEmpty() const { return !m_worklist.isEmpty(); }
 177 BlockWithOrder pop();
 178
 179private:
 180 ExtendedBlockWorklist<VisitOrder> m_worklist;
 181};
 182
 183} } // namespace JSC::DFG
 184
 185#endif // ENABLE(DFG_JIT)
 186
 187#endif // DFGBlockWorklist_h
 188
0

Source/JavaScriptCore/dfg/DFGCSEPhase.cpp

2929#if ENABLE(DFG_JIT)
3030
3131#include "DFGAbstractHeap.h"
 32#include "DFGBlockMapInlines.h"
3233#include "DFGClobberSet.h"
3334#include "DFGClobberize.h"
3435#include "DFGEdgeUsesStructure.h"

@@class GlobalCSEPhase : public Phase {
364365public:
365366 GlobalCSEPhase(Graph& graph)
366367 : Phase(graph, "global common subexpression elimination")
 368 , m_impureDataMap(graph)
367369 {
368370 }
369371

@@public:
377379
378380 m_graph.getBlocksInPreOrder(m_preOrder);
379381
380  m_impureDataMap.resize(m_graph.numBlocks());
381 
382382 // First figure out what gets clobbered by blocks. Node that this uses the preOrder list
383383 // for convenience only.
384384 for (unsigned i = m_preOrder.size(); i--;) {
385385 m_block = m_preOrder[i];
386  m_impureData = &m_impureDataMap[m_block->index];
 386 m_impureData = &m_impureDataMap[m_block];
387387 for (unsigned nodeIndex = m_block->size(); nodeIndex--;)
388388 addWrites(m_graph, m_block->at(nodeIndex), m_impureData->writes);
389389 }

@@public:
407407 {
408408 m_pureValues.clear();
409409
410  for (unsigned i = m_impureDataMap.size(); i--;) {
 410 for (BlockIndex i = m_impureDataMap.size(); i--;) {
411411 m_impureDataMap[i].availableAtTail.clear();
412412 m_impureDataMap[i].didVisit = false;
413413 }

@@public:
423423
424424 for (unsigned i = 0; i < m_preOrder.size(); ++i) {
425425 m_block = m_preOrder[i];
426  m_impureData = &m_impureDataMap[m_block->index];
 426 m_impureData = &m_impureDataMap[m_block];
427427 m_writesSoFar.clear();
428428
429429 if (verbose)

@@public:
562562
563563 if (verbose)
564564 dataLog(" Searching in block ", *block, "\n");
565  ImpureBlockData& data = m_impureDataMap[block->index];
 565 ImpureBlockData& data = m_impureDataMap[block];
566566
567567 // We require strict domination because this would only see things in our own block if
568568 // they came *after* our position in the block. Clearly, while our block dominates

@@public:
612612 // the reduction in compile time would warrant the increase in complexity, though.
613613 // https://bugs.webkit.org/show_bug.cgi?id=134876
614614 for (BasicBlock* block : seenList)
615  m_impureDataMap[block->index].availableAtTail.add(location, match);
 615 m_impureDataMap[block].availableAtTail.add(location, match);
616616 m_impureData->availableAtTail.add(location, match);
617617
618618 return match;

@@public:
654654 Vector<BasicBlock*> m_preOrder;
655655
656656 PureMultiMap m_pureValues;
657  Vector<ImpureBlockData> m_impureDataMap;
 657 BlockMap<ImpureBlockData> m_impureDataMap;
658658
659659 BasicBlock* m_block;
660660 Node* m_node;
172947

Source/JavaScriptCore/dfg/DFGDominators.cpp

11/*
2  * Copyright (C) 2011 Apple Inc. All rights reserved.
 2 * Copyright (C) 2011, 2014 Apple Inc. All rights reserved.
33 *
44 * Redistribution and use in source and binary forms, with or without
55 * modification, are permitted provided that the following conditions

2828
2929#if ENABLE(DFG_JIT)
3030
 31#include "DFGBlockMapInlines.h"
3132#include "DFGGraph.h"
3233#include "JSCInlines.h"
3334

@@Dominators::~Dominators()
4142{
4243}
4344
44 void Dominators::compute(Graph& graph)
45 {
46  // This implements a naive dominator solver.
 45namespace {
 46
 47// This implements Lengauer and Tarjan's "A Fast Algorithm for Finding Dominators in a Flowgraph"
 48// (TOPLAS 1979). It uses the "simple" implementation of LINK and EVAL. The full paper is linked
 49// below; this code attempts to closely follow the algorithm as it is presented in the paper; in
 50// particular sections 3 and 4.
 51// https://www.cs.princeton.edu/courses/archive/fall03/cs528/handouts/a%20fast%20algorithm%20for%20finding.pdf
 52
 53struct LengauerTarjan {
 54 LengauerTarjan(Graph& graph)
 55 : m_graph(graph)
 56 , m_data(graph)
 57 {
 58 for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
 59 BasicBlock* block = m_graph.block(blockIndex);
 60 if (!block)
 61 continue;
 62 m_data[block].label = block;
 63 }
 64 }
 65
 66 void compute()
 67 {
 68 computeDepthFirstPreNumbering(); // Step 1.
 69 computeSemiDominatorsAndImplicitImmediateDominators(); // Steps 2 and 3.
 70 computeExplicitImmediateDominators(); // Step 4.
 71 }
 72
 73 void computeDepthFirstPreNumbering()
 74 {
 75 BlockWorklist worklist;
 76 worklist.push(m_graph.block(0));
 77
 78 while (BasicBlock* block = worklist.pop()) {
 79 m_data[block].semiNumber = blockByPreNumber.size();
 80 blockByPreNumber.append(block);
 81 for (unsigned i = block->numSuccessors(); i--;) {
 82 BasicBlock* successorBlock = block->successor(i);
 83 if (!worklist.push(successorBlock))
 84 continue;
 85 m_data[successorBlock].parent = block;
 86 }
 87 }
 88 }
 89
 90 void computeSemiDominatorsAndImplicitImmediateDominators()
 91 {
 92 for (unsigned currentPreNumber = m_blockByPreNumber.size(); currentPreNumber-- > 1;) {
 93 BasicBlock* block = m_blockByPreNumber[currentPreNumber];
 94 BlockData& blockData = m_data[block];
 95
 96 // Step 2:
 97 for (BasicBlock* predecessorBlock : block->predecessors) {
 98 BasicBlock* intermediateBlock = eval(predecessorBlock);
 99 blockData.semiNumber = std::min(
 100 m_data[intermediateBlock].semiNumber, blockData.semiNumber);
 101 }
 102 m_data[m_blockByPreNumber[blockData.semiNumber]].bucket.append(block);
 103 link(blockData.parent, block);
 104
 105 // Step 3:
 106 for (BasicBlock* semiDominee = m_data[blockData.parent].bucket) {
 107 BasicBlock* possibleDominator = eval(semiDominee);
 108 BlockData& semiDomineeData = m_data[semiDominee];
 109 BlockData& possibleDominatorData = m_data[possibleDominator];
 110 if (possibleDominatorData.semiNumber < semiDomineeData.semiNumer)
 111 semiDomineeData.dom = possibleDominator;
 112 else
 113 semiDomineeData.dom = blockData.parent;
 114 }
 115 }
 116 }
47117
48  ASSERT(graph.block(0)->predecessors.isEmpty());
 118 void computeExplicitImmediateDominators()
 119 {
 120 for (unsigned currentPreNumber = 1; currentPreNumber < m_blockByPreNumber.size(); ++currentPreNumber) {
 121 BasicBlock* block = m_blockByPreNumber[currentPreNumber];
 122 BlockData& blockData = m_data[block];
 123
 124 if (blockData.dom != m_blockByPreNumber[blockData.semiNumber])
 125 blockData.dom = m_data[blockData.dom].dom;
 126 }
 127 }
49128
50  unsigned numBlocks = graph.numBlocks();
 129 void link(BasicBlock* from, BasicBlock* to)
 130 {
 131 m_data[from].ancestor = to;
 132 }
51133
52  // Allocate storage for the dense dominance matrix.
53  if (numBlocks > m_results.size()) {
54  m_results.grow(numBlocks);
55  for (unsigned i = numBlocks; i--;)
56  m_results[i].resize(numBlocks);
57  m_scratch.resize(numBlocks);
 134 BasicBlock* eval(BasicBlock* block)
 135 {
 136 if (!m_data[block].ancestor)
 137 return block;
 138
 139 compress(block);
 140 return m_data[block].label;
 141 }
 142
 143 void compress(BasicBlock* initialBlock)
 144 {
 145 // This was meant to be a recursive function, but we don't like recursion because we don't
 146 // want to blow the stack. The original function will call compress() recursively on the
 147 // ancestor of anything that has an ancestor. So, we populate our worklist with the
 148 // recursive ancestors of initialBlock. Then we process the list starting from the block
 149 // that is furthest up the ancestor chain.
 150
 151 BasicBlock* ancestor = m_data[initialBlock].ancestor;
 152 ASSERT(ancestor);
 153 if (!m_data[ancestor].ancestor)
 154 return;
 155
 156 Vector<BasicBlock*, 16> stack;
 157 for (BasicBlock* block = initialBlock; block; block = m_data[block].ancestor)
 158 stack.append(block);
 159
 160 // We only care about blocks that have an ancestor that has an ancestor. The last two
 161 // elements in the stack won't satisfy this property.
 162 ASSERT(stack.size() >= 2);
 163 ASSERT(!m_data[stack[stack.size() - 1]].ancestor);
 164 ASSERT(!m_data[m_data[stack[stack.size() - 2]].ancestor].ancestor);
 165
 166 for (unsigned i = stack.size() - 2; i--;) {
 167 BasicBlock* block = stack[i];
 168 BasicBlock*& labelOfBlock = m_data[block].label;
 169 BasicBlock*& ancestorOfBlock = m_data[block].ancestor;
 170 ASSERT(ancestorOfBlock);
 171 ASSERT(m_data[ancestorOfBlock].ancestor);
 172
 173 BasicBlock* labelOfAncestorOfBlock = m_data[ancestorOfBlock].label;
 174
 175 if (m_data[labelOfAncesorOfBlock].semiNumber <
 176 m_data[labelOfBlock].semiNumber)
 177 labelOfBlock = labelOfAncestorOfBlock;
 178 ancestorOfBlock = m_data[ancestorOfBlock].ancestor;
 179 }
58180 }
59181
60  // We know that the entry block is only dominated by itself.
61  m_results[0].clearAll();
62  m_results[0].set(0);
 182 BasicBlock* immediateDominator(BasicBlock* block)
 183 {
 184 return m_data[block].dom;
 185 }
 186
 187 struct BlockData {
 188 BlockData()
 189 : parent(nullptr)
 190 , preNumber(UINT_MAX)
 191 , semiNumber(UINT_MAX)
 192 , ancestor(nullptr)
 193 , label(nullptr)
 194 , dom(nullptr)
 195 {
 196 }
 197
 198 BasicBlock* parent;
 199 unsigned preNumber;
 200 unsigned semiNumber;
 201 BasicBlock* ancestor;
 202 BasicBlock* label;
 203 Vector<BasicBlock*> bucket;
 204 BasicBlock* dom;
 205 };
 206
 207 Graph& m_graph;
 208 BlockMap<BlockData> m_data;
 209 Vector<BasicBlock*> m_blockByPreNumber;
 210};
 211
 212} // anonymous namespace
63213
64  // Find all of the valid blocks.
65  m_scratch.clearAll();
66  for (unsigned i = numBlocks; i--;) {
67  if (!graph.block(i))
 214void Dominators::compute(Graph& graph)
 215{
 216 LengauerTarjan lengauerTarjan(graph);
 217 lengauerTarjan.compute();
 218
 219 m_data = BlockMap<BlockData>(graph);
 220
 221 // From here we want to build a spanning tree with both upward and downward links and we want
 222 // to do a search over this tree to compute pre and post numbers that can be used for dominance
 223 // tests.
 224
 225 for (BlockIndex blockIndex = graph.numBlocks(); blockIndex--;) {
 226 BasicBlock* block = graph.block(blockIndex);
 227 if (!block)
68228 continue;
69  m_scratch.set(i);
 229
 230 BasicBlock* idomBlock = lengauerTarjan.m_data[block].dom;
 231 m_data[block].idomParent = idomBlock;
 232 m_data[idomBlock].idomKids.append(block);
70233 }
71234
72  // Mark all nodes as dominated by everything.
73  for (unsigned i = numBlocks; i-- > 1;) {
74  if (!graph.block(i) || graph.block(i)->predecessors.isEmpty())
75  m_results[i].clearAll();
76  else
77  m_results[i].set(m_scratch);
78  }
79 
80  // Iteratively eliminate nodes that are not dominator.
81  bool changed;
82  do {
83  changed = false;
84  // Prune dominators in all non entry blocks: forward scan.
85  for (unsigned i = 1; i < numBlocks; ++i)
86  changed |= pruneDominators(graph, i);
87 
88  if (!changed)
 235 unsigned nextPreNumber = 0;
 236 unsigned nextPostNumber = 0;
 237
 238 PostOrderBlockWorklist worklist;
 239 worklist.push(m_graph.block(0));
 240 while (BlockWithOrder item = worklist.pop()) {
 241 m_data[0].preNumber = nextPreNumber++;
 242 switch (item.order) {
 243 case PreOrder:
 244 worklist.pushPost(item.block);
 245 for (unsigned i = item.block->numSuccessors(); i--;)
 246 worklish.push(item.block->successor(i));
 247 break;
 248 case PostOrder:
 249 m_data[item.block].postNumber = nextPostNumber++;
89250 break;
 251 }
 252 }
90253
91  // Prune dominators in all non entry blocks: backward scan.
92  changed = false;
93  for (unsigned i = numBlocks; i-- > 1;)
94  changed |= pruneDominators(graph, i);
95  } while (changed);
 254 if (validationEnabled()) {
 255 // Check our dominator calculation:
 256 // 1) Check that our range-based ancestry test is the same as a naive ancestry test.
 257 // 2) Check that our notion of who dominates whom is identical to a naive (not
 258 // Lengauer-Tarjan) dominator calculation.
 259
 260 NaiveDominators naiveDominators;
 261 naiveDominators.compute(graph);
 262
 263 for (BlockIndex fromBlockIndex = graph.numBlocks(); fromBlockIndex--;) {
 264 BasicBlock* fromBlock = graph.block(fromBlockIndex);
 265 if (!fromBlock)
 266 continue;
 267 for (BlockIndex toBlockIndex = graph.numBlocks(); toBlockIndex--;) {
 268 BasicBlock* toBlock = graph.block(toBlockIndex);
 269 if (!toBlock)
 270 continue;
 271
 272 DFG_ASSERT(graph, nullptr, dominates(from, to) == naiveDominates(from, to));
 273 DFG_ASSERT(graph, nullptr, dominates(from, to) == naiveDominators.dominates(from, to));
 274 }
 275 }
 276 }
96277}
97278
98 bool Dominators::pruneDominators(Graph& graph, BlockIndex idx)
 279bool Dominators::naiveDominates(BasicBlock* from, BasicBlock* to) const
99280{
100  BasicBlock* block = graph.block(idx);
101 
102  if (!block || block->predecessors.isEmpty())
103  return false;
104 
105  // Find the intersection of dom(preds).
106  m_scratch.set(m_results[block->predecessors[0]->index]);
107  for (unsigned j = block->predecessors.size(); j-- > 1;)
108  m_scratch.filter(m_results[block->predecessors[j]->index]);
109 
110  // The block is also dominated by itself.
111  m_scratch.set(idx);
112 
113  return m_results[idx].setAndCheck(m_scratch);
 281 for (BasicBlock* block = to; block; block = m_data[block].idomParent) {
 282 if (block == from)
 283 return true;
 284 }
 285 return false;
114286}
115287
116 void Dominators::dump(Graph& graph, PrintStream& out) const
 288void Dominators::dump(PrintStream& out) const
117289{
118  for (BlockIndex blockIndex = 0; blockIndex < graph.numBlocks(); ++blockIndex) {
119  BasicBlock* block = graph.block(blockIndex);
120  if (!block)
 290 if (!isValid()) {
 291 out.print("Not Valid.\n");
 292 return;
 293 }
 294
 295 for (BlockIndex blockIndex = 0; blockIndex < m_data.size(); ++blockIndex) {
 296 if (m_data[blockIndex].preNumber == UINT_MAX)
121297 continue;
122  out.print(" Block ", *block, ":");
123  for (BlockIndex otherIndex = 0; otherIndex < graph.numBlocks(); ++otherIndex) {
124  if (!dominates(block->index, otherIndex))
125  continue;
126  out.print(" #", otherIndex);
127  }
128  out.print("\n");
 298
 299 out.print("Block #", blockIndex, ": idom = ", *m_data[blockIndex].idomParent, ", idomKids = [");
 300 CommaPrinter comma;
 301 for (unsigned i = 0; i < m_data[blockIndex].idomKids.size(); ++i)
 302 out.print(comma, *m_data[blockIndex].idomKids[i]);
 303 out.print("], pre/post = ", m_data[blockIndex].preNumber, "/", m_data[blockIndex].postNumber, "\n");
129304 }
130305}
131306
172947

Source/JavaScriptCore/dfg/DFGDominators.h

11/*
2  * Copyright (C) 2011 Apple Inc. All rights reserved.
 2 * Copyright (C) 2011, 2014 Apple Inc. All rights reserved.
33 *
44 * Redistribution and use in source and binary forms, with or without
55 * modification, are permitted provided that the following conditions

@@public:
4444
4545 void compute(Graph&);
4646
47  bool dominates(BlockIndex from, BlockIndex to) const
 47 bool dominates(BlockIndex fromIndex, BlockIndex toIndex) const
4848 {
4949 ASSERT(isValid());
50  return m_results[to].get(from);
 50 BlockData& from = m_data[fromIndex];
 51 BlockData& to = m_data[toIndex];
 52 return to.preNumber >= from.preNumber && to.postNumber <= from.postNumber;
5153 }
5254
5355 bool dominates(BasicBlock* from, BasicBlock* to) const

@@public:
5557 return dominates(from->index, to->index);
5658 }
5759
58  void dump(Graph&, PrintStream&) const;
 60 void dump(PrintStream&) const;
5961
6062private:
61  bool pruneDominators(Graph&, BlockIndex);
 63 bool naiveDominates(BasicBlock* from, BasicBlock* to) const;
6264
63  Vector<FastBitVector> m_results; // For each block, the bitvector of blocks that dominate it.
64  FastBitVector m_scratch; // A temporary bitvector with bit for each block. We recycle this to save new/deletes.
 65 struct BlockData {
 66 BlockData()
 67 : idomParent(nullptr)
 68 , preNumber(UINT_MAX)
 69 , postNumber(UINT_MAX)
 70 {
 71 }
 72
 73 Vector<BasicBlock*> idomKids;
 74 BasicBlock* idomParent;
 75
 76 unsigned preNumber;
 77 unsigned postNumber;
 78 };
 79
 80 BlockMap<BlockData> m_data;
6581};
6682
6783} } // namespace JSC::DFG
172947

Source/JavaScriptCore/dfg/DFGGraph.cpp

3232#include "CodeBlock.h"
3333#include "CodeBlockWithJITType.h"
3434#include "DFGClobberSet.h"
 35#include "DFGBlockWorklist.h"
3536#include "DFGJITCode.h"
3637#include "DFGVariableAccessDataDump.h"
3738#include "FullBytecodeLiveness.h"

@@void Graph::substituteGetLocal(BasicBloc
635636 }
636637}
637638
638 // Utilities for pre- and post-order traversals.
639 namespace {
640 
641 inline void addForPreOrder(Vector<BasicBlock*>& result, Vector<BasicBlock*, 16>& worklist, BitVector& seen, BasicBlock* block)
642 {
643  if (seen.get(block->index))
644  return;
645 
646  result.append(block);
647  worklist.append(block);
648  seen.set(block->index);
649 }
650 
651 enum PostOrderTaskKind {
652  PostOrderFirstVisit,
653  PostOrderAddToResult
654 };
655 
656 struct PostOrderTask {
657  PostOrderTask(BasicBlock* block = nullptr, PostOrderTaskKind kind = PostOrderFirstVisit)
658  : m_block(block)
659  , m_kind(kind)
660  {
661  }
662 
663  BasicBlock* m_block;
664  PostOrderTaskKind m_kind;
665 };
666 
667 inline void addForPostOrder(Vector<PostOrderTask, 16>& worklist, BitVector& seen, BasicBlock* block)
668 {
669  if (seen.get(block->index))
670  return;
671 
672  worklist.append(PostOrderTask(block, PostOrderFirstVisit));
673  seen.set(block->index);
674 }
675 
676 } // anonymous namespace
677 
678639void Graph::getBlocksInPreOrder(Vector<BasicBlock*>& result)
679640{
680  Vector<BasicBlock*, 16> worklist;
681  BitVector seen;
682  addForPreOrder(result, worklist, seen, block(0));
683  while (!worklist.isEmpty()) {
684  BasicBlock* block = worklist.takeLast();
 641 BlockWorklist worklist;
 642 worklist.push(block(0));
 643 while (BasicBlock* block = worklist.pop()) {
 644 result.append(block);
685645 for (unsigned i = block->numSuccessors(); i--;)
686  addForPreOrder(result, worklist, seen, block->successor(i));
 646 worklist.push(block->successor(i));
687647 }
688648}
689649
690650void Graph::getBlocksInPostOrder(Vector<BasicBlock*>& result)
691651{
692  Vector<PostOrderTask, 16> worklist;
693  BitVector seen;
694  addForPostOrder(worklist, seen, block(0));
695  while (!worklist.isEmpty()) {
696  PostOrderTask task = worklist.takeLast();
697  switch (task.m_kind) {
698  case PostOrderFirstVisit:
699  worklist.append(PostOrderTask(task.m_block, PostOrderAddToResult));
700  for (unsigned i = task.m_block->numSuccessors(); i--;)
701  addForPostOrder(worklist, seen, task.m_block->successor(i));
 652 PostOrderBlockWorklist worklist;
 653 worklist.push(block(0));
 654 while (BlockWithOrder item = worklist.pop()) {
 655 switch (item.order) {
 656 case PreOrder:
 657 worklist.pushPost(item.block);
 658 for (unsigned i = item.block->numSuccessors(); i--;)
 659 worklist.push(item.block->successor(i));
702660 break;
703  case PostOrderAddToResult:
704  result.append(task.m_block);
 661 case PostOrder:
 662 result.append(item.block);
705663 break;
706664 }
707665 }
172947

Source/JavaScriptCore/dfg/DFGInvalidationPointInjectionPhase.cpp

2828
2929#if ENABLE(DFG_JIT)
3030
 31#include "DFGBlockSet.h"
3132#include "DFGClobberize.h"
3233#include "DFGGraph.h"
3334#include "DFGInsertionSet.h"

@@public:
5051 {
5152 ASSERT(m_graph.m_form != SSA);
5253
53  BitVector blocksThatNeedInvalidationPoints;
 54 BlockSet blocksThatNeedInvalidationPoints;
5455
5556 for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
5657 BasicBlock* block = m_graph.block(blockIndex);

@@public:
6364 // Note: this assumes that control flow occurs at bytecode instruction boundaries.
6465 if (m_originThatHadFire.isSet()) {
6566 for (unsigned i = block->numSuccessors(); i--;)
66  blocksThatNeedInvalidationPoints.set(block->successor(i)->index);
 67 blocksThatNeedInvalidationPoints.add(block->successor(i));
6768 }
6869
6970 m_insertionSet.execute(block);
7071 }
7172
7273 for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
73  if (!blocksThatNeedInvalidationPoints.get(blockIndex))
 74 BasicBlock* block = m_graph.block(blockIndex);
 75
 76 if (!blocksThatNeedInvalidationPoints.contains(block))
7477 continue;
7578
76  BasicBlock* block = m_graph.block(blockIndex);
7779 insertInvalidationCheck(0, block->at(0));
7880 m_insertionSet.execute(block);
7981 }
172947

Source/JavaScriptCore/dfg/DFGNaiveDominators.cpp

 1/*
 2 * Copyright (C) 2011, 2014 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#include "config.h"
 27#include "DFGNaiveDominators.h"
 28
 29#if ENABLE(DFG_JIT)
 30
 31#include "DFGGraph.h"
 32#include "JSCInlines.h"
 33
 34namespace JSC { namespace DFG {
 35
 36NaiveDominators::NaiveDominators()
 37{
 38}
 39
 40NaiveDominators::~NaiveDominators()
 41{
 42}
 43
 44void NaiveDominators::compute(Graph& graph)
 45{
 46 // This implements a naive dominator solver.
 47
 48 ASSERT(graph.block(0)->predecessors.isEmpty());
 49
 50 unsigned numBlocks = graph.numBlocks();
 51
 52 // Allocate storage for the dense dominance matrix.
 53 if (numBlocks > m_results.size()) {
 54 m_results.grow(numBlocks);
 55 for (unsigned i = numBlocks; i--;)
 56 m_results[i].resize(numBlocks);
 57 m_scratch.resize(numBlocks);
 58 }
 59
 60 // We know that the entry block is only dominated by itself.
 61 m_results[0].clearAll();
 62 m_results[0].set(0);
 63
 64 // Find all of the valid blocks.
 65 m_scratch.clearAll();
 66 for (unsigned i = numBlocks; i--;) {
 67 if (!graph.block(i))
 68 continue;
 69 m_scratch.set(i);
 70 }
 71
 72 // Mark all nodes as dominated by everything.
 73 for (unsigned i = numBlocks; i-- > 1;) {
 74 if (!graph.block(i) || graph.block(i)->predecessors.isEmpty())
 75 m_results[i].clearAll();
 76 else
 77 m_results[i].set(m_scratch);
 78 }
 79
 80 // Iteratively eliminate nodes that are not dominator.
 81 bool changed;
 82 do {
 83 changed = false;
 84 // Prune dominators in all non entry blocks: forward scan.
 85 for (unsigned i = 1; i < numBlocks; ++i)
 86 changed |= pruneDominators(graph, i);
 87
 88 if (!changed)
 89 break;
 90
 91 // Prune dominators in all non entry blocks: backward scan.
 92 changed = false;
 93 for (unsigned i = numBlocks; i-- > 1;)
 94 changed |= pruneDominators(graph, i);
 95 } while (changed);
 96}
 97
 98bool NaiveDominators::pruneDominators(Graph& graph, BlockIndex idx)
 99{
 100 BasicBlock* block = graph.block(idx);
 101
 102 if (!block || block->predecessors.isEmpty())
 103 return false;
 104
 105 // Find the intersection of dom(preds).
 106 m_scratch.set(m_results[block->predecessors[0]->index]);
 107 for (unsigned j = block->predecessors.size(); j-- > 1;)
 108 m_scratch.filter(m_results[block->predecessors[j]->index]);
 109
 110 // The block is also dominated by itself.
 111 m_scratch.set(idx);
 112
 113 return m_results[idx].setAndCheck(m_scratch);
 114}
 115
 116void NaiveDominators::dump(Graph& graph, PrintStream& out) const
 117{
 118 for (BlockIndex blockIndex = 0; blockIndex < graph.numBlocks(); ++blockIndex) {
 119 BasicBlock* block = graph.block(blockIndex);
 120 if (!block)
 121 continue;
 122 out.print(" Block ", *block, ":");
 123 for (BlockIndex otherIndex = 0; otherIndex < graph.numBlocks(); ++otherIndex) {
 124 if (!dominates(block->index, otherIndex))
 125 continue;
 126 out.print(" #", otherIndex);
 127 }
 128 out.print("\n");
 129 }
 130}
 131
 132} } // namespace JSC::DFG
 133
 134#endif // ENABLE(DFG_JIT)
 135
0

Source/JavaScriptCore/dfg/DFGNaiveDominators.h

 1/*
 2 * Copyright (C) 2011, 2014 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#ifndef DFGNaiveDominators_h
 27#define DFGNaiveDominators_h
 28
 29#if ENABLE(DFG_JIT)
 30
 31#include "DFGBasicBlock.h"
 32#include "DFGCommon.h"
 33#include <wtf/FastBitVector.h>
 34
 35namespace JSC { namespace DFG {
 36
 37class Graph;
 38
 39// This class is only used for validating the real dominators implementation.
 40
 41class NaiveDominators {
 42public:
 43 NaiveDominators();
 44 ~NaiveDominators();
 45
 46 void compute(Graph&);
 47
 48 bool dominates(BlockIndex from, BlockIndex to) const
 49 {
 50 ASSERT(isValid());
 51 return m_results[to].get(from);
 52 }
 53
 54 bool dominates(BasicBlock* from, BasicBlock* to) const
 55 {
 56 return dominates(from->index, to->index);
 57 }
 58
 59 void dump(Graph&, PrintStream&) const;
 60
 61private:
 62 bool pruneDominators(Graph&, BlockIndex);
 63
 64 Vector<FastBitVector> m_results; // For each block, the bitvector of blocks that dominate it.
 65 FastBitVector m_scratch; // A temporary bitvector with bit for each block. We recycle this to save new/deletes.
 66};
 67
 68} } // namespace JSC::DFG
 69
 70#endif // ENABLE(DFG_JIT)
 71
 72#endif // DFGNaiveDominators_h
0