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 789186 : GraphAssembler::GraphAssembler(JSGraph* jsgraph, Node* effect, Node* control,
16 : Zone* zone)
17 : : temp_zone_(zone),
18 : jsgraph_(jsgraph),
19 : current_effect_(effect),
20 789186 : current_control_(control) {}
21 :
22 1760967 : Node* GraphAssembler::IntPtrConstant(intptr_t value) {
23 1760967 : return jsgraph()->IntPtrConstant(value);
24 : }
25 :
26 509192 : Node* GraphAssembler::Int32Constant(int32_t value) {
27 509192 : return jsgraph()->Int32Constant(value);
28 : }
29 :
30 230061 : Node* GraphAssembler::UniqueInt32Constant(int32_t value) {
31 230062 : return graph()->NewNode(common()->Int32Constant(value));
32 : }
33 :
34 5786 : Node* GraphAssembler::SmiConstant(int32_t value) {
35 5786 : return jsgraph()->SmiConstant(value);
36 : }
37 :
38 37371 : Node* GraphAssembler::Uint32Constant(int32_t value) {
39 37371 : return jsgraph()->Uint32Constant(value);
40 : }
41 :
42 79088 : Node* GraphAssembler::Float64Constant(double value) {
43 79088 : return jsgraph()->Float64Constant(value);
44 : }
45 :
46 61859 : Node* GraphAssembler::HeapConstant(Handle<HeapObject> object) {
47 61859 : return jsgraph()->HeapConstant(object);
48 : }
49 :
50 :
51 278194 : Node* GraphAssembler::ExternalConstant(ExternalReference ref) {
52 278194 : return jsgraph()->ExternalConstant(ref);
53 : }
54 :
55 1606 : Node* GraphAssembler::CEntryStubConstant(int result_size) {
56 1606 : return jsgraph()->CEntryStubConstant(result_size);
57 : }
58 :
59 15850 : Node* GraphAssembler::LoadFramePointer() {
60 15850 : return graph()->NewNode(machine()->LoadFramePointer());
61 : }
62 :
63 : #define SINGLETON_CONST_DEF(Name) \
64 : Node* GraphAssembler::Name() { return jsgraph()->Name(); }
65 701006 : 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 2457656 : 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 8295266 : 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 212874 : 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 273268 : Node* GraphAssembler::Projection(int index, Node* value) {
97 409904 : return graph()->NewNode(common()->Projection(index), value, current_control_);
98 : }
99 :
100 95099 : Node* GraphAssembler::Allocate(PretenureFlag pretenure, Node* size) {
101 : return current_effect_ =
102 : graph()->NewNode(simplified()->Allocate(Type::Any(), NOT_TENURED),
103 142648 : size, current_effect_, current_control_);
104 : }
105 :
106 1127204 : Node* GraphAssembler::LoadField(FieldAccess const& access, Node* object) {
107 : return current_effect_ =
108 : graph()->NewNode(simplified()->LoadField(access), object,
109 1690806 : current_effect_, current_control_);
110 : }
111 :
112 4267 : Node* GraphAssembler::LoadElement(ElementAccess const& access, Node* object,
113 4267 : Node* index) {
114 : return current_effect_ =
115 : graph()->NewNode(simplified()->LoadElement(access), object, index,
116 12801 : current_effect_, current_control_);
117 : }
118 :
119 97542 : Node* GraphAssembler::StoreField(FieldAccess const& access, Node* object,
120 97542 : Node* value) {
121 : return current_effect_ =
122 : graph()->NewNode(simplified()->StoreField(access), object, value,
123 292627 : 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 138466 : Node* GraphAssembler::Store(StoreRepresentation rep, Node* object, Node* offset,
134 138465 : Node* value) {
135 : return current_effect_ =
136 : graph()->NewNode(machine()->Store(rep), object, offset, value,
137 415398 : current_effect_, current_control_);
138 : }
139 :
140 483850 : Node* GraphAssembler::Load(MachineType rep, Node* object, Node* offset) {
141 : return current_effect_ =
142 : graph()->NewNode(machine()->Load(rep), object, offset,
143 725776 : current_effect_, current_control_);
144 : }
145 :
146 13040 : Node* GraphAssembler::Retain(Node* buffer) {
147 : return current_effect_ =
148 19560 : 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 16490 : Node* GraphAssembler::ToNumber(Node* value) {
158 : return current_effect_ =
159 : graph()->NewNode(ToNumberOperator(), ToNumberBuiltinConstant(),
160 24735 : value, NoContextConstant(), current_effect_);
161 : }
162 :
163 102312 : Node* GraphAssembler::DeoptimizeIf(DeoptimizeReason reason, Node* condition,
164 102312 : Node* frame_state) {
165 : return current_control_ = current_effect_ = graph()->NewNode(
166 : common()->DeoptimizeIf(DeoptimizeKind::kEager, reason), condition,
167 306935 : frame_state, current_effect_, current_control_);
168 : }
169 :
170 191503 : Node* GraphAssembler::DeoptimizeUnless(DeoptimizeKind kind,
171 : DeoptimizeReason reason, Node* condition,
172 191503 : Node* frame_state) {
173 : return current_control_ = current_effect_ = graph()->NewNode(
174 : common()->DeoptimizeUnless(kind, reason), condition, frame_state,
175 574511 : current_effect_, current_control_);
176 : }
177 :
178 161931 : Node* GraphAssembler::DeoptimizeUnless(DeoptimizeReason reason, Node* condition,
179 : Node* frame_state) {
180 : return DeoptimizeUnless(DeoptimizeKind::kEager, reason, condition,
181 161931 : 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 1012981 : Node* GraphAssembler::ExtractCurrentControl() {
209 1012981 : Node* result = current_control_;
210 1012981 : current_control_ = nullptr;
211 1012981 : return result;
212 : }
213 :
214 1012981 : Node* GraphAssembler::ExtractCurrentEffect() {
215 1012981 : Node* result = current_effect_;
216 1012981 : current_effect_ = nullptr;
217 1012981 : return result;
218 : }
219 :
220 30415977 : void GraphAssembler::Reset(Node* effect, Node* control) {
221 30415977 : current_effect_ = effect;
222 30415977 : current_control_ = control;
223 30415977 : }
224 :
225 11981 : Operator const* GraphAssembler::ToNumberOperator() {
226 8245 : if (!to_number_operator_.is_set()) {
227 1868 : 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 3736 : Operator::kEliminatable);
232 1868 : to_number_operator_.set(common()->Call(desc));
233 : }
234 8245 : 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 93917 : GraphAssemblerLabel::GraphAssemblerLabel(GraphAssemblerLabelType is_deferred,
243 : size_t merge_count, size_t var_count,
244 : MachineRepresentation* representations,
245 809956 : Zone* zone)
246 93917 : : is_deferred_(is_deferred == GraphAssemblerLabelType::kDeferred),
247 : max_merge_count_(merge_count),
248 187834 : var_count_(var_count) {
249 187834 : effects_ = zone->NewArray<Node*>(MaxMergeCount() + 1);
250 622118 : for (size_t i = 0; i < MaxMergeCount() + 1; i++) {
251 217142 : effects_[i] = nullptr;
252 : }
253 :
254 93917 : controls_ = zone->NewArray<Node*>(MaxMergeCount());
255 434288 : for (size_t i = 0; i < MaxMergeCount(); i++) {
256 123227 : controls_[i] = nullptr;
257 : }
258 :
259 187834 : size_t num_bindings = (MaxMergeCount() + 1) * PhiCount() + 1;
260 93918 : bindings_ = zone->NewArray<Node*>(num_bindings);
261 187835 : for (size_t i = 0; i < num_bindings; i++) {
262 93917 : bindings_[i] = nullptr;
263 : }
264 :
265 187836 : representations_ = zone->NewArray<MachineRepresentation>(PhiCount() + 1);
266 187836 : for (size_t i = 0; i < PhiCount(); i++) {
267 0 : representations_[i] = representations[i];
268 : }
269 93918 : }
270 :
271 93918 : GraphAssemblerLabel::~GraphAssemblerLabel() {
272 : DCHECK(IsBound() || MergedCount() == 0);
273 93918 : }
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 217143 : Node** GraphAssemblerLabel::GetControlsPtr() { return controls_; }
294 :
295 217144 : Node** GraphAssemblerLabel::GetEffectsPtr() { return effects_; }
296 :
297 : } // namespace compiler
298 : } // namespace internal
299 : } // namespace v8
|