blob: 75494100d94e3fb75134b9885bb0a6bf886e335b [file] [log] [blame]
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001/*
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +00002 * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00003 *
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 DFGBasicBlock_h
27#define DFGBasicBlock_h
28
29#if ENABLE(DFG_JIT)
30
31#include "DFGAbstractValue.h"
fpizlo@apple.com367a1102012-11-10 23:33:29 +000032#include "DFGBranchDirection.h"
fpizlo@apple.coma62d4822013-10-06 04:22:43 +000033#include "DFGFlushedAt.h"
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +000034#include "DFGNode.h"
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +000035#include "DFGVariadicFunction.h"
fpizlo@apple.com9cf19812012-03-25 23:35:07 +000036#include "Operands.h"
oliver@apple.com827d2cf2013-07-25 04:04:45 +000037#include <wtf/HashMap.h>
38#include <wtf/HashSet.h>
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +000039#include <wtf/OwnPtr.h>
40#include <wtf/Vector.h>
41
42namespace JSC { namespace DFG {
43
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +000044class Graph;
oliver@apple.com426f5b02013-07-25 04:04:27 +000045class InsertionSet;
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +000046
oliver@apple.com426f5b02013-07-25 04:04:27 +000047typedef Vector<BasicBlock*, 2> PredecessorList;
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +000048
oliver@apple.com426f5b02013-07-25 04:04:27 +000049struct BasicBlock : RefCounted<BasicBlock> {
oliver@apple.com827d2cf2013-07-25 04:04:45 +000050 BasicBlock(unsigned bytecodeBegin, unsigned numArguments, unsigned numLocals);
51 ~BasicBlock();
fpizlo@apple.comd9ded3b2011-10-22 01:22:46 +000052
oliver@apple.com827d2cf2013-07-25 04:04:45 +000053 void ensureLocals(unsigned newNumLocals);
fpizlo@apple.com79c51ee2012-05-18 22:30:24 +000054
oliver@apple.com426f5b02013-07-25 04:04:27 +000055 size_t size() const { return m_nodes.size(); }
56 bool isEmpty() const { return !size(); }
57 Node*& at(size_t i) { return m_nodes[i]; }
58 Node* at(size_t i) const { return m_nodes[i]; }
oliver@apple.com827d2cf2013-07-25 04:04:45 +000059 Node*& operator[](size_t i) { return at(i); }
oliver@apple.com426f5b02013-07-25 04:04:27 +000060 Node* operator[](size_t i) const { return at(i); }
61 Node* last() const { return at(size() - 1); }
62 void resize(size_t size) { m_nodes.resize(size); }
63 void grow(size_t size) { m_nodes.grow(size); }
64
65 void append(Node* node) { m_nodes.append(node); }
oliver@apple.come17632e2013-07-25 04:05:31 +000066 void insertBeforeLast(Node* node)
67 {
68 append(last());
69 at(size() - 2) = node;
70 }
oliver@apple.com426f5b02013-07-25 04:04:27 +000071
fpizlo@apple.com79c51ee2012-05-18 22:30:24 +000072 size_t numNodes() const { return phis.size() + size(); }
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +000073 Node* node(size_t i) const
fpizlo@apple.com79c51ee2012-05-18 22:30:24 +000074 {
75 if (i < phis.size())
76 return phis[i];
77 return at(i - phis.size());
78 }
79 bool isPhiIndex(size_t i) const { return i < phis.size(); }
80
oliver@apple.com827d2cf2013-07-25 04:04:45 +000081 bool isInPhis(Node* node) const;
82 bool isInBlock(Node* myNode) const;
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +000083
oliver@apple.com426f5b02013-07-25 04:04:27 +000084 unsigned numSuccessors() { return last()->numSuccessors(); }
85
oliver@apple.com827d2cf2013-07-25 04:04:45 +000086 BasicBlock*& successor(unsigned index)
oliver@apple.com426f5b02013-07-25 04:04:27 +000087 {
88 return last()->successor(index);
89 }
oliver@apple.com827d2cf2013-07-25 04:04:45 +000090 BasicBlock*& successorForCondition(bool condition)
oliver@apple.com426f5b02013-07-25 04:04:27 +000091 {
92 return last()->successorForCondition(condition);
93 }
oliver@apple.com827d2cf2013-07-25 04:04:45 +000094
95 void removePredecessor(BasicBlock* block);
96 void replacePredecessor(BasicBlock* from, BasicBlock* to);
oliver@apple.com426f5b02013-07-25 04:04:27 +000097
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +000098#define DFG_DEFINE_APPEND_NODE(templatePre, templatePost, typeParams, valueParamsComma, valueParams, valueArgs) \
fpizlo@apple.com06f82b52013-03-06 02:27:16 +000099 templatePre typeParams templatePost Node* appendNode(Graph&, SpeculatedType valueParamsComma valueParams);
fpizlo@apple.comf45e88b2013-01-20 19:29:50 +0000100 DFG_VARIADIC_TEMPLATE_FUNCTION(DFG_DEFINE_APPEND_NODE)
101#undef DFG_DEFINE_APPEND_NODE
102
oliver@apple.com827d2cf2013-07-25 04:04:45 +0000103#define DFG_DEFINE_APPEND_NODE(templatePre, templatePost, typeParams, valueParamsComma, valueParams, valueArgs) \
104 templatePre typeParams templatePost Node* appendNonTerminal(Graph&, SpeculatedType valueParamsComma valueParams);
105 DFG_VARIADIC_TEMPLATE_FUNCTION(DFG_DEFINE_APPEND_NODE)
106#undef DFG_DEFINE_APPEND_NODE
107
108 void dump(PrintStream& out) const;
oliver@apple.com426f5b02013-07-25 04:04:27 +0000109
fpizlo@apple.com41f5c952011-10-17 23:54:41 +0000110 // This value is used internally for block linking and OSR entry. It is mostly meaningless
111 // for other purposes due to inlining.
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000112 unsigned bytecodeBegin;
fpizlo@apple.com41f5c952011-10-17 23:54:41 +0000113
oliver@apple.com426f5b02013-07-25 04:04:27 +0000114 BlockIndex index;
115
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000116 bool isOSRTarget;
117 bool cfaHasVisited;
118 bool cfaShouldRevisit;
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000119 bool cfaFoundConstants;
fpizlo@apple.comedcb7a92012-07-13 05:31:05 +0000120 bool cfaDidFinish;
fpizlo@apple.com367a1102012-11-10 23:33:29 +0000121 BranchDirection cfaBranchDirection;
fpizlo@apple.comd9ded3b2011-10-22 01:22:46 +0000122#if !ASSERT_DISABLED
123 bool isLinked;
124#endif
125 bool isReachable;
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000126
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000127 Vector<Node*> phis;
oliver@apple.com426f5b02013-07-25 04:04:27 +0000128 PredecessorList predecessors;
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000129
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000130 Operands<Node*, NodePointerTraits> variablesAtHead;
131 Operands<Node*, NodePointerTraits> variablesAtTail;
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000132
133 Operands<AbstractValue> valuesAtHead;
134 Operands<AbstractValue> valuesAtTail;
oliver@apple.com827d2cf2013-07-25 04:04:45 +0000135
oliver@apple.com4fe26de2013-07-25 04:04:51 +0000136 // These fields are reserved for NaturalLoops.
137 static const unsigned numberOfInnerMostLoopIndices = 2;
138 unsigned innerMostLoopIndices[numberOfInnerMostLoopIndices];
139
oliver@apple.com827d2cf2013-07-25 04:04:45 +0000140 struct SSAData {
fpizlo@apple.coma62d4822013-10-06 04:22:43 +0000141 Operands<FlushedAt> flushAtHead;
142 Operands<FlushedAt> flushAtTail;
oliver@apple.com827d2cf2013-07-25 04:04:45 +0000143 Operands<Node*> availabilityAtHead;
144 Operands<Node*> availabilityAtTail;
145 HashSet<Node*> liveAtHead;
146 HashSet<Node*> liveAtTail;
147 HashMap<Node*, AbstractValue> valuesAtHead;
148 HashMap<Node*, AbstractValue> valuesAtTail;
149
150 SSAData(BasicBlock*);
151 ~SSAData();
152 };
153 OwnPtr<SSAData> ssa;
oliver@apple.com426f5b02013-07-25 04:04:27 +0000154
155private:
156 friend class InsertionSet;
157 Vector<Node*, 8> m_nodes;
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000158};
159
fpizlo@apple.comd9ded3b2011-10-22 01:22:46 +0000160struct UnlinkedBlock {
oliver@apple.com426f5b02013-07-25 04:04:27 +0000161 BasicBlock* m_block;
fpizlo@apple.comd9ded3b2011-10-22 01:22:46 +0000162 bool m_needsNormalLinking;
163 bool m_needsEarlyReturnLinking;
164
165 UnlinkedBlock() { }
166
oliver@apple.com426f5b02013-07-25 04:04:27 +0000167 explicit UnlinkedBlock(BasicBlock* block)
168 : m_block(block)
fpizlo@apple.comd9ded3b2011-10-22 01:22:46 +0000169 , m_needsNormalLinking(true)
170 , m_needsEarlyReturnLinking(false)
171 {
172 }
173};
174
oliver@apple.com426f5b02013-07-25 04:04:27 +0000175static inline unsigned getBytecodeBeginForBlock(BasicBlock** basicBlock)
176{
177 return (*basicBlock)->bytecodeBegin;
178}
179
180static inline BasicBlock* blockForBytecodeOffset(Vector<BasicBlock*>& linkingTargets, unsigned bytecodeBegin)
181{
182 return *binarySearch<BasicBlock*, unsigned>(linkingTargets, linkingTargets.size(), bytecodeBegin, getBytecodeBeginForBlock);
183}
184
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000185} } // namespace JSC::DFG
186
187#endif // ENABLE(DFG_JIT)
188
189#endif // DFGBasicBlock_h
190