]> git.saurik.com Git - apple/javascriptcore.git/blame - dfg/DFGVirtualRegisterAllocationPhase.cpp
JavaScriptCore-1097.3.3.tar.gz
[apple/javascriptcore.git] / dfg / DFGVirtualRegisterAllocationPhase.cpp
CommitLineData
6fe7ccc8
A
1/*
2 * Copyright (C) 2011 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 "DFGVirtualRegisterAllocationPhase.h"
28
29#if ENABLE(DFG_JIT)
30
31#include "DFGGraph.h"
32#include "DFGScoreBoard.h"
33
34namespace JSC { namespace DFG {
35
36class VirtualRegisterAllocationPhase : public Phase {
37public:
38 VirtualRegisterAllocationPhase(Graph& graph)
39 : Phase(graph, "virtual register allocation")
40 {
41 }
42
43 void run()
44 {
45#if DFG_ENABLE(DEBUG_VERBOSE)
46 dataLog("Preserved vars: ");
47 m_graph.m_preservedVars.dump(WTF::dataFile());
48 dataLog("\n");
49#endif
50 ScoreBoard scoreBoard(m_graph, m_graph.m_preservedVars);
51 scoreBoard.assertClear();
52#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
53 bool needsNewLine = false;
54#endif
55 for (size_t blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
56 BasicBlock* block = m_graph.m_blocks[blockIndex].get();
57 for (size_t indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
58 NodeIndex nodeIndex = block->at(indexInBlock);
59#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
60 if (needsNewLine)
61 dataLog("\n");
62 dataLog(" @%u:", nodeIndex);
63 needsNewLine = true;
64#endif
65 Node& node = m_graph[nodeIndex];
66
67 if (!node.shouldGenerate() || node.op() == Phi || node.op() == Flush)
68 continue;
69
70 // GetLocal nodes are effectively phi nodes in the graph, referencing
71 // results from prior blocks.
72 if (node.op() != GetLocal) {
73 // First, call use on all of the current node's children, then
74 // allocate a VirtualRegister for this node. We do so in this
75 // order so that if a child is on its last use, and a
76 // VirtualRegister is freed, then it may be reused for node.
77 if (node.flags() & NodeHasVarArgs) {
78 for (unsigned childIdx = node.firstChild(); childIdx < node.firstChild() + node.numChildren(); childIdx++)
79 scoreBoard.use(m_graph.m_varArgChildren[childIdx]);
80 } else {
81 scoreBoard.use(node.child1());
82 scoreBoard.use(node.child2());
83 scoreBoard.use(node.child3());
84 }
85 }
86
87 if (!node.hasResult())
88 continue;
89
90 VirtualRegister virtualRegister = scoreBoard.allocate();
91#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
92 dataLog(" Assigning virtual register %u to node %u.",
93 virtualRegister, nodeIndex);
94#endif
95 node.setVirtualRegister(virtualRegister);
96 // 'mustGenerate' nodes have their useCount artificially elevated,
97 // call use now to account for this.
98 if (node.mustGenerate())
99 scoreBoard.use(nodeIndex);
100 }
101 scoreBoard.assertClear();
102 }
103#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
104 if (needsNewLine)
105 dataLog("\n");
106#endif
107
108 // 'm_numCalleeRegisters' is the number of locals and temporaries allocated
109 // for the function (and checked for on entry). Since we perform a new and
110 // different allocation of temporaries, more registers may now be required.
111 unsigned calleeRegisters = scoreBoard.highWatermark() + m_graph.m_parameterSlots;
112 size_t inlineCallFrameCount = codeBlock()->inlineCallFrames().size();
113 for (size_t i = 0; i < inlineCallFrameCount; i++) {
114 InlineCallFrame& inlineCallFrame = codeBlock()->inlineCallFrames()[i];
115 CodeBlock* codeBlock = baselineCodeBlockForInlineCallFrame(&inlineCallFrame);
116 unsigned requiredCalleeRegisters = inlineCallFrame.stackOffset + codeBlock->m_numCalleeRegisters;
117 if (requiredCalleeRegisters > calleeRegisters)
118 calleeRegisters = requiredCalleeRegisters;
119 }
120 if ((unsigned)codeBlock()->m_numCalleeRegisters < calleeRegisters)
121 codeBlock()->m_numCalleeRegisters = calleeRegisters;
122#if DFG_ENABLE(DEBUG_VERBOSE)
123 dataLog("Num callee registers: %u\n", calleeRegisters);
124#endif
125 }
126};
127
128void performVirtualRegisterAllocation(Graph& graph)
129{
130 runPhase<VirtualRegisterAllocationPhase>(graph);
131}
132
133} } // namespace JSC::DFG
134
135#endif // ENABLE(DFG_JIT)