]>
git.saurik.com Git - apple/javascriptcore.git/blob - dfg/DFGConstantHoistingPhase.cpp
2 * Copyright (C) 2015 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
27 #include "DFGConstantHoistingPhase.h"
32 #include "DFGInsertionSet.h"
34 #include "DFGPredictionPropagationPhase.h"
35 #include "DFGVariableAccessDataDump.h"
36 #include "JSCInlines.h"
38 namespace JSC
{ namespace DFG
{
42 class ConstantHoistingPhase
: public Phase
{
44 ConstantHoistingPhase(Graph
& graph
)
45 : Phase(graph
, "constant hoisting")
51 DFG_ASSERT(m_graph
, nullptr, m_graph
.m_form
== SSA
);
53 m_graph
.clearReplacements();
55 HashMap
<FrozenValue
*, Node
*> jsValues
;
56 HashMap
<FrozenValue
*, Node
*> doubleValues
;
57 HashMap
<FrozenValue
*, Node
*> int52Values
;
59 auto valuesFor
= [&] (NodeType op
) -> HashMap
<FrozenValue
*, Node
*>& {
60 // Use a roundabout approach because clang thinks that this closure returning a
61 // reference to a stack-allocated value in outer scope is a bug. It's not.
62 HashMap
<FrozenValue
*, Node
*>* result
;
69 result
= &doubleValues
;
72 result
= &int52Values
;
75 DFG_CRASH(m_graph
, nullptr, "Invalid node type in valuesFor()");
85 for (BasicBlock
* block
: m_graph
.blocksInNaturalOrder()) {
86 unsigned sourceIndex
= 0;
87 unsigned targetIndex
= 0;
88 while (sourceIndex
< block
->size()) {
89 Node
* node
= block
->at(sourceIndex
++);
94 HashMap
<FrozenValue
*, Node
*>& values
= valuesFor(node
->op());
95 auto result
= values
.add(node
->constant(), node
);
96 if (result
.isNewEntry
)
97 node
->origin
= NodeOrigin();
99 node
->setReplacement(result
.iterator
->value
);
105 block
->at(targetIndex
++) = node
;
109 block
->resize(targetIndex
);
112 // Insert the constants into the root block.
113 InsertionSet
insertionSet(m_graph
);
114 auto insertConstants
= [&] (const HashMap
<FrozenValue
*, Node
*>& values
) {
115 for (auto& entry
: values
)
116 insertionSet
.insert(0, entry
.value
);
118 insertConstants(jsValues
);
119 insertConstants(doubleValues
);
120 insertConstants(int52Values
);
121 insertionSet
.execute(m_graph
.block(0));
123 // Perform all of the substitutions. We want all instances of the removed constants to
124 // point at their replacements.
125 for (BasicBlock
* block
: m_graph
.blocksInNaturalOrder()) {
126 for (Node
* node
: *block
)
127 m_graph
.performSubstitution(node
);
130 // And finally free the constants that we removed.
131 for (Node
* node
: toFree
)
132 m_graph
.m_allocator
.free(node
);
138 } // anonymous namespace
140 bool performConstantHoisting(Graph
& graph
)
142 SamplingRegion
samplingRegion("DFG Constant Hoisting Phase");
143 return runPhase
<ConstantHoistingPhase
>(graph
);
146 } } // namespace JSC::DFG
148 #endif // ENABLE(DFG_JIT)