2 * Copyright (C) 2011, 2013 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 "DFGVirtualRegisterAllocationPhase.h"
32 #include "DFGScoreBoard.h"
33 #include "JSCInlines.h"
34 #include "StackAlignment.h"
35 #include <wtf/StdLibExtras.h>
37 namespace JSC
{ namespace DFG
{
39 class VirtualRegisterAllocationPhase
: public Phase
{
41 VirtualRegisterAllocationPhase(Graph
& graph
)
42 : Phase(graph
, "virtual register allocation")
48 DFG_ASSERT(m_graph
, nullptr, m_graph
.m_form
== ThreadedCPS
);
50 ScoreBoard
scoreBoard(m_graph
.m_nextMachineLocal
);
51 scoreBoard
.assertClear();
52 for (size_t blockIndex
= 0; blockIndex
< m_graph
.numBlocks(); ++blockIndex
) {
53 BasicBlock
* block
= m_graph
.block(blockIndex
);
56 if (!block
->isReachable
)
58 if (!ASSERT_DISABLED
) {
59 // Force usage of highest-numbered virtual registers.
60 scoreBoard
.sortFree();
62 for (size_t indexInBlock
= 0; indexInBlock
< block
->size(); ++indexInBlock
) {
63 Node
* node
= block
->at(indexInBlock
);
65 if (!node
->shouldGenerate())
74 ASSERT(!node
->child1()->hasResult());
80 // First, call use on all of the current node's children, then
81 // allocate a VirtualRegister for this node. We do so in this
82 // order so that if a child is on its last use, and a
83 // VirtualRegister is freed, then it may be reused for node.
84 if (node
->flags() & NodeHasVarArgs
) {
85 for (unsigned childIdx
= node
->firstChild(); childIdx
< node
->firstChild() + node
->numChildren(); childIdx
++)
86 scoreBoard
.useIfHasResult(m_graph
.m_varArgChildren
[childIdx
]);
88 scoreBoard
.useIfHasResult(node
->child1());
89 scoreBoard
.useIfHasResult(node
->child2());
90 scoreBoard
.useIfHasResult(node
->child3());
93 if (!node
->hasResult())
96 VirtualRegister virtualRegister
= scoreBoard
.allocate();
97 node
->setVirtualRegister(virtualRegister
);
98 // 'mustGenerate' nodes have their useCount artificially elevated,
99 // call use now to account for this.
100 if (node
->mustGenerate())
101 scoreBoard
.use(node
);
103 scoreBoard
.assertClear();
106 // Record the number of virtual registers we're using. This is used by calls
107 // to figure out where to put the parameters.
108 m_graph
.m_nextMachineLocal
= scoreBoard
.highWatermark();
114 bool performVirtualRegisterAllocation(Graph
& graph
)
116 SamplingRegion
samplingRegion("DFG Virtual Register Allocation Phase");
117 return runPhase
<VirtualRegisterAllocationPhase
>(graph
);
120 } } // namespace JSC::DFG
122 #endif // ENABLE(DFG_JIT)