Line data Source code
1 : // Copyright 2015 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #include "src/compiler/graph-assembler.h"
6 :
7 : #include "src/code-factory.h"
8 : #include "src/compiler/linkage.h"
9 : #include "src/objects-inl.h"
10 :
11 : namespace v8 {
12 : namespace internal {
13 : namespace compiler {
14 :
15 790604 : GraphAssembler::GraphAssembler(JSGraph* jsgraph, Node* effect, Node* control,
16 : Zone* zone)
17 : : temp_zone_(zone),
18 : jsgraph_(jsgraph),
19 : current_effect_(effect),
20 790604 : current_control_(control) {}
21 :
22 1759798 : Node* GraphAssembler::IntPtrConstant(intptr_t value) {
23 1759798 : return jsgraph()->IntPtrConstant(value);
24 : }
25 :
26 509800 : Node* GraphAssembler::Int32Constant(int32_t value) {
27 509800 : return jsgraph()->Int32Constant(value);
28 : }
29 :
30 229022 : Node* GraphAssembler::UniqueInt32Constant(int32_t value) {
31 229023 : return graph()->NewNode(common()->Int32Constant(value));
32 : }
33 :
34 5822 : Node* GraphAssembler::SmiConstant(int32_t value) {
35 5822 : return jsgraph()->SmiConstant(value);
36 : }
37 :
38 37392 : Node* GraphAssembler::Uint32Constant(int32_t value) {
39 37392 : return jsgraph()->Uint32Constant(value);
40 : }
41 :
42 79264 : Node* GraphAssembler::Float64Constant(double value) {
43 79264 : return jsgraph()->Float64Constant(value);
44 : }
45 :
46 62056 : Node* GraphAssembler::HeapConstant(Handle<HeapObject> object) {
47 62056 : return jsgraph()->HeapConstant(object);
48 : }
49 :
50 :
51 277092 : Node* GraphAssembler::ExternalConstant(ExternalReference ref) {
52 277092 : return jsgraph()->ExternalConstant(ref);
53 : }
54 :
55 1709 : Node* GraphAssembler::CEntryStubConstant(int result_size) {
56 1709 : return jsgraph()->CEntryStubConstant(result_size);
57 : }
58 :
59 15898 : Node* GraphAssembler::LoadFramePointer() {
60 15898 : return graph()->NewNode(machine()->LoadFramePointer());
61 : }
62 :
63 : #define SINGLETON_CONST_DEF(Name) \
64 : Node* GraphAssembler::Name() { return jsgraph()->Name(); }
65 700911 : JSGRAPH_SINGLETON_CONSTANT_LIST(SINGLETON_CONST_DEF)
66 : #undef SINGLETON_CONST_DEF
67 :
68 : #define PURE_UNOP_DEF(Name) \
69 : Node* GraphAssembler::Name(Node* input) { \
70 : return graph()->NewNode(machine()->Name(), input); \
71 : }
72 2453238 : PURE_ASSEMBLER_MACH_UNOP_LIST(PURE_UNOP_DEF)
73 : #undef PURE_UNOP_DEF
74 :
75 : #define PURE_BINOP_DEF(Name) \
76 : Node* GraphAssembler::Name(Node* left, Node* right) { \
77 : return graph()->NewNode(machine()->Name(), left, right); \
78 : }
79 8296741 : PURE_ASSEMBLER_MACH_BINOP_LIST(PURE_BINOP_DEF)
80 : #undef PURE_BINOP_DEF
81 :
82 : #define CHECKED_BINOP_DEF(Name) \
83 : Node* GraphAssembler::Name(Node* left, Node* right) { \
84 : return graph()->NewNode(machine()->Name(), left, right, current_control_); \
85 : }
86 212562 : CHECKED_ASSEMBLER_MACH_BINOP_LIST(CHECKED_BINOP_DEF)
87 : #undef CHECKED_BINOP_DEF
88 :
89 0 : Node* GraphAssembler::Float64RoundDown(Node* value) {
90 0 : if (machine()->Float64RoundDown().IsSupported()) {
91 0 : return graph()->NewNode(machine()->Float64RoundDown().op(), value);
92 : }
93 : return nullptr;
94 : }
95 :
96 272774 : Node* GraphAssembler::Projection(int index, Node* value) {
97 409162 : return graph()->NewNode(common()->Projection(index), value, current_control_);
98 : }
99 :
100 94919 : Node* GraphAssembler::Allocate(PretenureFlag pretenure, Node* size) {
101 : return current_effect_ =
102 : graph()->NewNode(simplified()->Allocate(Type::Any(), NOT_TENURED),
103 142378 : size, current_effect_, current_control_);
104 : }
105 :
106 1129080 : Node* GraphAssembler::LoadField(FieldAccess const& access, Node* object) {
107 : return current_effect_ =
108 : graph()->NewNode(simplified()->LoadField(access), object,
109 1693619 : current_effect_, current_control_);
110 : }
111 :
112 4261 : Node* GraphAssembler::LoadElement(ElementAccess const& access, Node* object,
113 4261 : Node* index) {
114 : return current_effect_ =
115 : graph()->NewNode(simplified()->LoadElement(access), object, index,
116 12783 : current_effect_, current_control_);
117 : }
118 :
119 97333 : Node* GraphAssembler::StoreField(FieldAccess const& access, Node* object,
120 97333 : Node* value) {
121 : return current_effect_ =
122 : graph()->NewNode(simplified()->StoreField(access), object, value,
123 292000 : current_effect_, current_control_);
124 : }
125 :
126 3119 : Node* GraphAssembler::StoreElement(ElementAccess const& access, Node* object,
127 3119 : Node* index, Node* value) {
128 : return current_effect_ =
129 : graph()->NewNode(simplified()->StoreElement(access), object, index,
130 9357 : value, current_effect_, current_control_);
131 : }
132 :
133 137863 : Node* GraphAssembler::Store(StoreRepresentation rep, Node* object, Node* offset,
134 137863 : Node* value) {
135 : return current_effect_ =
136 : graph()->NewNode(machine()->Store(rep), object, offset, value,
137 413589 : current_effect_, current_control_);
138 : }
139 :
140 481847 : Node* GraphAssembler::Load(MachineType rep, Node* object, Node* offset) {
141 : return current_effect_ =
142 : graph()->NewNode(machine()->Load(rep), object, offset,
143 722770 : current_effect_, current_control_);
144 : }
145 :
146 13028 : Node* GraphAssembler::Retain(Node* buffer) {
147 : return current_effect_ =
148 19542 : graph()->NewNode(common()->Retain(), buffer, current_effect_);
149 : }
150 :
151 7346 : Node* GraphAssembler::UnsafePointerAdd(Node* base, Node* external) {
152 : return current_effect_ =
153 : graph()->NewNode(machine()->UnsafePointerAdd(), base, external,
154 11019 : current_effect_, current_control_);
155 : }
156 :
157 16558 : Node* GraphAssembler::ToNumber(Node* value) {
158 : return current_effect_ =
159 : graph()->NewNode(ToNumberOperator(), ToNumberBuiltinConstant(),
160 24837 : value, NoContextConstant(), current_effect_);
161 : }
162 :
163 102499 : Node* GraphAssembler::DeoptimizeIf(DeoptimizeReason reason, Node* condition,
164 102499 : Node* frame_state) {
165 : return current_control_ = current_effect_ = graph()->NewNode(
166 : common()->DeoptimizeIf(DeoptimizeKind::kEager, reason), condition,
167 307495 : frame_state, current_effect_, current_control_);
168 : }
169 :
170 192077 : Node* GraphAssembler::DeoptimizeUnless(DeoptimizeKind kind,
171 : DeoptimizeReason reason, Node* condition,
172 192077 : Node* frame_state) {
173 : return current_control_ = current_effect_ = graph()->NewNode(
174 : common()->DeoptimizeUnless(kind, reason), condition, frame_state,
175 576232 : current_effect_, current_control_);
176 : }
177 :
178 162554 : Node* GraphAssembler::DeoptimizeUnless(DeoptimizeReason reason, Node* condition,
179 : Node* frame_state) {
180 : return DeoptimizeUnless(DeoptimizeKind::kEager, reason, condition,
181 162554 : frame_state);
182 : }
183 :
184 0 : void GraphAssembler::Branch(Node* condition,
185 0 : GraphAssemblerStaticLabel<1>* if_true,
186 0 : GraphAssemblerStaticLabel<1>* if_false) {
187 : DCHECK_NOT_NULL(current_control_);
188 :
189 : BranchHint hint = BranchHint::kNone;
190 0 : if (if_true->IsDeferred() != if_false->IsDeferred()) {
191 0 : hint = if_false->IsDeferred() ? BranchHint::kTrue : BranchHint::kFalse;
192 : }
193 :
194 : Node* branch =
195 0 : graph()->NewNode(common()->Branch(hint), condition, current_control_);
196 :
197 0 : current_control_ = graph()->NewNode(common()->IfTrue(), branch);
198 : MergeState(if_true);
199 :
200 0 : current_control_ = graph()->NewNode(common()->IfFalse(), branch);
201 : MergeState(if_false);
202 :
203 0 : current_control_ = nullptr;
204 0 : current_effect_ = nullptr;
205 0 : }
206 :
207 : // Extractors (should be only used when destructing the assembler.
208 1012190 : Node* GraphAssembler::ExtractCurrentControl() {
209 1012190 : Node* result = current_control_;
210 1012190 : current_control_ = nullptr;
211 1012190 : return result;
212 : }
213 :
214 1012190 : Node* GraphAssembler::ExtractCurrentEffect() {
215 1012190 : Node* result = current_effect_;
216 1012190 : current_effect_ = nullptr;
217 1012190 : return result;
218 : }
219 :
220 30429961 : void GraphAssembler::Reset(Node* effect, Node* control) {
221 30429961 : current_effect_ = effect;
222 30429961 : current_control_ = control;
223 30429961 : }
224 :
225 12023 : Operator const* GraphAssembler::ToNumberOperator() {
226 8279 : if (!to_number_operator_.is_set()) {
227 1872 : Callable callable = CodeFactory::ToNumber(jsgraph()->isolate());
228 : CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
229 : CallDescriptor* desc = Linkage::GetStubCallDescriptor(
230 : jsgraph()->isolate(), graph()->zone(), callable.descriptor(), 0, flags,
231 3744 : Operator::kEliminatable);
232 1872 : to_number_operator_.set(common()->Call(desc));
233 : }
234 8279 : return to_number_operator_.get();
235 : }
236 :
237 0 : Node* GraphAssemblerLabel::PhiAt(size_t index) {
238 : DCHECK(IsBound());
239 0 : return GetBindingsPtrFor(index)[0];
240 : }
241 :
242 93866 : GraphAssemblerLabel::GraphAssemblerLabel(GraphAssemblerLabelType is_deferred,
243 : size_t merge_count, size_t var_count,
244 : MachineRepresentation* representations,
245 809613 : Zone* zone)
246 93866 : : is_deferred_(is_deferred == GraphAssemblerLabelType::kDeferred),
247 : max_merge_count_(merge_count),
248 187732 : var_count_(var_count) {
249 187733 : effects_ = zone->NewArray<Node*>(MaxMergeCount() + 1);
250 621878 : for (size_t i = 0; i < MaxMergeCount() + 1; i++) {
251 217072 : effects_[i] = nullptr;
252 : }
253 :
254 93867 : controls_ = zone->NewArray<Node*>(MaxMergeCount());
255 434148 : for (size_t i = 0; i < MaxMergeCount(); i++) {
256 123207 : controls_[i] = nullptr;
257 : }
258 :
259 187734 : size_t num_bindings = (MaxMergeCount() + 1) * PhiCount() + 1;
260 93867 : bindings_ = zone->NewArray<Node*>(num_bindings);
261 187733 : for (size_t i = 0; i < num_bindings; i++) {
262 93866 : bindings_[i] = nullptr;
263 : }
264 :
265 187733 : representations_ = zone->NewArray<MachineRepresentation>(PhiCount() + 1);
266 187732 : for (size_t i = 0; i < PhiCount(); i++) {
267 0 : representations_[i] = representations[i];
268 : }
269 93866 : }
270 :
271 93867 : GraphAssemblerLabel::~GraphAssemblerLabel() {
272 : DCHECK(IsBound() || MergedCount() == 0);
273 93867 : }
274 :
275 0 : Node** GraphAssemblerLabel::GetBindingsPtrFor(size_t phi_index) {
276 : DCHECK_LT(phi_index, PhiCount());
277 0 : return &bindings_[phi_index * (MaxMergeCount() + 1)];
278 : }
279 :
280 0 : void GraphAssemblerLabel::SetBinding(size_t phi_index, size_t merge_index,
281 0 : Node* binding) {
282 : DCHECK_LT(phi_index, PhiCount());
283 : DCHECK_LT(merge_index, MaxMergeCount());
284 0 : bindings_[phi_index * (MaxMergeCount() + 1) + merge_index] = binding;
285 0 : }
286 :
287 0 : MachineRepresentation GraphAssemblerLabel::GetRepresentationFor(
288 : size_t phi_index) {
289 : DCHECK_LT(phi_index, PhiCount());
290 0 : return representations_[phi_index];
291 : }
292 :
293 217075 : Node** GraphAssemblerLabel::GetControlsPtr() { return controls_; }
294 :
295 217073 : Node** GraphAssemblerLabel::GetEffectsPtr() { return effects_; }
296 :
297 : } // namespace compiler
298 : } // namespace internal
299 : } // namespace v8
|