Line data Source code
1 : // Copyright 2014 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 : #ifndef V8_COMPILER_RAW_MACHINE_ASSEMBLER_H_
6 : #define V8_COMPILER_RAW_MACHINE_ASSEMBLER_H_
7 :
8 : #include "src/assembler.h"
9 : #include "src/compiler/access-builder.h"
10 : #include "src/compiler/common-operator.h"
11 : #include "src/compiler/graph.h"
12 : #include "src/compiler/linkage.h"
13 : #include "src/compiler/machine-operator.h"
14 : #include "src/compiler/node.h"
15 : #include "src/compiler/operator.h"
16 : #include "src/compiler/simplified-operator.h"
17 : #include "src/globals.h"
18 : #include "src/heap/factory.h"
19 : #include "src/isolate.h"
20 :
21 : namespace v8 {
22 : namespace internal {
23 : namespace compiler {
24 :
25 : class BasicBlock;
26 : class RawMachineLabel;
27 : class Schedule;
28 : class SourcePositionTable;
29 :
30 : // The RawMachineAssembler produces a low-level IR graph. All nodes are wired
31 : // into a graph and also placed into a schedule immediately, hence subsequent
32 : // code generation can happen without the need for scheduling.
33 : //
34 : // In order to create a schedule on-the-fly, the assembler keeps track of basic
35 : // blocks by having one current basic block being populated and by referencing
36 : // other basic blocks through the use of labels.
37 : //
38 : // Also note that the generated graph is only valid together with the generated
39 : // schedule, using one without the other is invalid as the graph is inherently
40 : // non-schedulable due to missing control and effect dependencies.
41 : class V8_EXPORT_PRIVATE RawMachineAssembler {
42 : public:
43 : RawMachineAssembler(
44 : Isolate* isolate, Graph* graph, CallDescriptor* call_descriptor,
45 : MachineRepresentation word = MachineType::PointerRepresentation(),
46 : MachineOperatorBuilder::Flags flags =
47 : MachineOperatorBuilder::Flag::kNoFlags,
48 : MachineOperatorBuilder::AlignmentRequirements alignment_requirements =
49 : MachineOperatorBuilder::AlignmentRequirements::
50 : FullUnalignedAccessSupport(),
51 : PoisoningMitigationLevel poisoning_level =
52 : PoisoningMitigationLevel::kPoisonCriticalOnly);
53 250814 : ~RawMachineAssembler() = default;
54 :
55 : Isolate* isolate() const { return isolate_; }
56 : Graph* graph() const { return graph_; }
57 : Zone* zone() const { return graph()->zone(); }
58 8237266 : MachineOperatorBuilder* machine() { return &machine_; }
59 15656996 : CommonOperatorBuilder* common() { return &common_; }
60 324564 : SimplifiedOperatorBuilder* simplified() { return &simplified_; }
61 : CallDescriptor* call_descriptor() const { return call_descriptor_; }
62 : PoisoningMitigationLevel poisoning_level() const { return poisoning_level_; }
63 :
64 : // Finalizes the schedule and exports it to be used for code generation. Note
65 : // that this RawMachineAssembler becomes invalid after export.
66 : Schedule* Export();
67 : // Finalizes the schedule and transforms it into a graph that's suitable for
68 : // it to be used for Turbofan optimization and re-scheduling. Note that this
69 : // RawMachineAssembler becomes invalid after export.
70 : Graph* ExportForOptimization();
71 :
72 : // ===========================================================================
73 : // The following utility methods create new nodes with specific operators and
74 : // place them into the current basic block. They don't perform control flow,
75 : // hence will not switch the current basic block.
76 :
77 : Node* NullConstant();
78 : Node* UndefinedConstant();
79 :
80 : // Constants.
81 : Node* PointerConstant(void* value) {
82 151293 : return IntPtrConstant(reinterpret_cast<intptr_t>(value));
83 : }
84 : Node* IntPtrConstant(intptr_t value) {
85 : // TODO(dcarney): mark generated code as unserializable if value != 0.
86 : return kSystemPointerSize == 8 ? Int64Constant(value)
87 4276727 : : Int32Constant(static_cast<int>(value));
88 : }
89 : Node* RelocatableIntPtrConstant(intptr_t value, RelocInfo::Mode rmode);
90 1671502 : Node* Int32Constant(int32_t value) {
91 3343004 : return AddNode(common()->Int32Constant(value));
92 : }
93 16 : Node* StackSlot(MachineRepresentation rep, int alignment = 0) {
94 32 : return AddNode(machine()->StackSlot(rep, alignment));
95 : }
96 4406401 : Node* Int64Constant(int64_t value) {
97 8812802 : return AddNode(common()->Int64Constant(value));
98 : }
99 240 : Node* NumberConstant(double value) {
100 480 : return AddNode(common()->NumberConstant(value));
101 : }
102 8007 : Node* Float32Constant(float value) {
103 16014 : return AddNode(common()->Float32Constant(value));
104 : }
105 22258 : Node* Float64Constant(double value) {
106 44516 : return AddNode(common()->Float64Constant(value));
107 : }
108 764365 : Node* HeapConstant(Handle<HeapObject> object) {
109 1528730 : return AddNode(common()->HeapConstant(object));
110 : }
111 212100 : Node* ExternalConstant(ExternalReference address) {
112 424200 : return AddNode(common()->ExternalConstant(address));
113 : }
114 : Node* RelocatableInt32Constant(int32_t value, RelocInfo::Mode rmode) {
115 : return AddNode(common()->RelocatableInt32Constant(value, rmode));
116 : }
117 0 : Node* RelocatableInt64Constant(int64_t value, RelocInfo::Mode rmode) {
118 0 : return AddNode(common()->RelocatableInt64Constant(value, rmode));
119 : }
120 :
121 231568 : Node* Projection(int index, Node* a) {
122 694704 : return AddNode(common()->Projection(index), a);
123 : }
124 :
125 : // Memory Operations.
126 73666 : Node* Load(MachineType rep, Node* base,
127 : LoadSensitivity needs_poisoning = LoadSensitivity::kSafe) {
128 73666 : return Load(rep, base, IntPtrConstant(0), needs_poisoning);
129 : }
130 1676888 : Node* Load(MachineType rep, Node* base, Node* index,
131 : LoadSensitivity needs_poisoning = LoadSensitivity::kSafe) {
132 1676888 : const Operator* op = machine()->Load(rep);
133 1676888 : CHECK_NE(PoisoningMitigationLevel::kPoisonAll, poisoning_level_);
134 1676888 : if (needs_poisoning == LoadSensitivity::kCritical &&
135 : poisoning_level_ == PoisoningMitigationLevel::kPoisonCriticalOnly) {
136 1269 : op = machine()->PoisonedLoad(rep);
137 : }
138 1676888 : return AddNode(op, base, index);
139 : }
140 130428 : Node* Store(MachineRepresentation rep, Node* base, Node* value,
141 : WriteBarrierKind write_barrier) {
142 260856 : return Store(rep, base, IntPtrConstant(0), value, write_barrier);
143 : }
144 337383 : Node* Store(MachineRepresentation rep, Node* base, Node* index, Node* value,
145 : WriteBarrierKind write_barrier) {
146 674766 : return AddNode(machine()->Store(StoreRepresentation(rep, write_barrier)),
147 337383 : base, index, value);
148 : }
149 249356 : void OptimizedStoreField(MachineRepresentation rep, Node* object, int offset,
150 : Node* value, WriteBarrierKind write_barrier) {
151 748068 : AddNode(simplified()->StoreField(FieldAccess(
152 : BaseTaggedness::kTaggedBase, offset, MaybeHandle<Name>(),
153 : MaybeHandle<Map>(), Type::Any(),
154 : MachineType::TypeForRepresentation(rep), write_barrier)),
155 : object, value);
156 249356 : }
157 10764 : void OptimizedStoreMap(Node* object, Node* value) {
158 32292 : AddNode(simplified()->StoreField(AccessBuilder::ForMap()), object, value);
159 10764 : }
160 0 : Node* Retain(Node* value) { return AddNode(common()->Retain(), value); }
161 :
162 : Node* OptimizedAllocate(Node* size, AllocationType allocation);
163 :
164 : // Unaligned memory operations
165 : Node* UnalignedLoad(MachineType type, Node* base) {
166 : return UnalignedLoad(type, base, IntPtrConstant(0));
167 : }
168 9340 : Node* UnalignedLoad(MachineType type, Node* base, Node* index) {
169 9340 : if (machine()->UnalignedLoadSupported(type.representation())) {
170 18680 : return AddNode(machine()->Load(type), base, index);
171 : } else {
172 0 : return AddNode(machine()->UnalignedLoad(type), base, index);
173 : }
174 : }
175 32 : Node* UnalignedStore(MachineRepresentation rep, Node* base, Node* value) {
176 32 : return UnalignedStore(rep, base, IntPtrConstant(0), value);
177 : }
178 2960 : Node* UnalignedStore(MachineRepresentation rep, Node* base, Node* index,
179 : Node* value) {
180 2960 : if (machine()->UnalignedStoreSupported(rep)) {
181 5920 : return AddNode(machine()->Store(StoreRepresentation(
182 : rep, WriteBarrierKind::kNoWriteBarrier)),
183 : base, index, value);
184 : } else {
185 0 : return AddNode(
186 : machine()->UnalignedStore(UnalignedStoreRepresentation(rep)), base,
187 0 : index, value);
188 : }
189 : }
190 :
191 : // Atomic memory operations.
192 448 : Node* AtomicLoad(MachineType type, Node* base, Node* index) {
193 448 : if (type.representation() == MachineRepresentation::kWord64) {
194 112 : if (machine()->Is64()) {
195 224 : return AddNode(machine()->Word64AtomicLoad(type), base, index);
196 : } else {
197 0 : return AddNode(machine()->Word32AtomicPairLoad(), base, index);
198 : }
199 : }
200 672 : return AddNode(machine()->Word32AtomicLoad(type), base, index);
201 : }
202 :
203 : #if defined(V8_TARGET_BIG_ENDIAN)
204 : #define VALUE_HALVES value_high, value
205 : #else
206 : #define VALUE_HALVES value, value_high
207 : #endif
208 :
209 224 : Node* AtomicStore(MachineRepresentation rep, Node* base, Node* index,
210 : Node* value, Node* value_high) {
211 224 : if (rep == MachineRepresentation::kWord64) {
212 56 : if (machine()->Is64()) {
213 : DCHECK_NULL(value_high);
214 112 : return AddNode(machine()->Word64AtomicStore(rep), base, index, value);
215 : } else {
216 0 : return AddNode(machine()->Word32AtomicPairStore(), base, index,
217 0 : VALUE_HALVES);
218 : }
219 : }
220 : DCHECK_NULL(value_high);
221 336 : return AddNode(machine()->Word32AtomicStore(rep), base, index, value);
222 : }
223 : #define ATOMIC_FUNCTION(name) \
224 : Node* Atomic##name(MachineType rep, Node* base, Node* index, Node* value, \
225 : Node* value_high) { \
226 : if (rep.representation() == MachineRepresentation::kWord64) { \
227 : if (machine()->Is64()) { \
228 : DCHECK_NULL(value_high); \
229 : return AddNode(machine()->Word64Atomic##name(rep), base, index, \
230 : value); \
231 : } else { \
232 : return AddNode(machine()->Word32AtomicPair##name(), base, index, \
233 : VALUE_HALVES); \
234 : } \
235 : } \
236 : DCHECK_NULL(value_high); \
237 : return AddNode(machine()->Word32Atomic##name(rep), base, index, value); \
238 : }
239 1344 : ATOMIC_FUNCTION(Exchange)
240 1344 : ATOMIC_FUNCTION(Add)
241 1344 : ATOMIC_FUNCTION(Sub)
242 1344 : ATOMIC_FUNCTION(And)
243 1344 : ATOMIC_FUNCTION(Or)
244 1344 : ATOMIC_FUNCTION(Xor)
245 : #undef ATOMIC_FUNCTION
246 : #undef VALUE_HALVES
247 :
248 448 : Node* AtomicCompareExchange(MachineType rep, Node* base, Node* index,
249 : Node* old_value, Node* old_value_high,
250 : Node* new_value, Node* new_value_high) {
251 448 : if (rep.representation() == MachineRepresentation::kWord64) {
252 112 : if (machine()->Is64()) {
253 : DCHECK_NULL(old_value_high);
254 : DCHECK_NULL(new_value_high);
255 112 : return AddNode(machine()->Word64AtomicCompareExchange(rep), base, index,
256 112 : old_value, new_value);
257 : } else {
258 0 : return AddNode(machine()->Word32AtomicPairCompareExchange(), base,
259 : index, old_value, old_value_high, new_value,
260 0 : new_value_high);
261 : }
262 : }
263 : DCHECK_NULL(old_value_high);
264 : DCHECK_NULL(new_value_high);
265 336 : return AddNode(machine()->Word32AtomicCompareExchange(rep), base, index,
266 336 : old_value, new_value);
267 : }
268 :
269 : // Arithmetic Operations.
270 307089 : Node* WordAnd(Node* a, Node* b) {
271 614178 : return AddNode(machine()->WordAnd(), a, b);
272 : }
273 12663 : Node* WordOr(Node* a, Node* b) { return AddNode(machine()->WordOr(), a, b); }
274 297 : Node* WordXor(Node* a, Node* b) {
275 594 : return AddNode(machine()->WordXor(), a, b);
276 : }
277 458660 : Node* WordShl(Node* a, Node* b) {
278 917320 : return AddNode(machine()->WordShl(), a, b);
279 : }
280 24345 : Node* WordShr(Node* a, Node* b) {
281 48690 : return AddNode(machine()->WordShr(), a, b);
282 : }
283 230890 : Node* WordSar(Node* a, Node* b) {
284 461780 : return AddNode(machine()->WordSar(), a, b);
285 : }
286 0 : Node* WordRor(Node* a, Node* b) {
287 0 : return AddNode(machine()->WordRor(), a, b);
288 : }
289 668292 : Node* WordEqual(Node* a, Node* b) {
290 1336584 : return AddNode(machine()->WordEqual(), a, b);
291 : }
292 : Node* WordNotEqual(Node* a, Node* b) {
293 95804 : return Word32BinaryNot(WordEqual(a, b));
294 : }
295 0 : Node* WordNot(Node* a) {
296 0 : if (machine()->Is32()) {
297 0 : return Word32BitwiseNot(a);
298 : } else {
299 0 : return Word64Not(a);
300 : }
301 : }
302 :
303 134519 : Node* Word32And(Node* a, Node* b) {
304 269038 : return AddNode(machine()->Word32And(), a, b);
305 : }
306 64003 : Node* Word32Or(Node* a, Node* b) {
307 128006 : return AddNode(machine()->Word32Or(), a, b);
308 : }
309 4323 : Node* Word32Xor(Node* a, Node* b) {
310 8646 : return AddNode(machine()->Word32Xor(), a, b);
311 : }
312 9112 : Node* Word32Shl(Node* a, Node* b) {
313 18224 : return AddNode(machine()->Word32Shl(), a, b);
314 : }
315 37158 : Node* Word32Shr(Node* a, Node* b) {
316 74316 : return AddNode(machine()->Word32Shr(), a, b);
317 : }
318 954 : Node* Word32Sar(Node* a, Node* b) {
319 1908 : return AddNode(machine()->Word32Sar(), a, b);
320 : }
321 398 : Node* Word32Ror(Node* a, Node* b) {
322 796 : return AddNode(machine()->Word32Ror(), a, b);
323 : }
324 183 : Node* Word32Clz(Node* a) { return AddNode(machine()->Word32Clz(), a); }
325 510600 : Node* Word32Equal(Node* a, Node* b) {
326 1021200 : return AddNode(machine()->Word32Equal(), a, b);
327 : }
328 : Node* Word32NotEqual(Node* a, Node* b) {
329 78924 : return Word32BinaryNot(Word32Equal(a, b));
330 : }
331 892 : Node* Word32BitwiseNot(Node* a) { return Word32Xor(a, Int32Constant(-1)); }
332 183832 : Node* Word32BinaryNot(Node* a) { return Word32Equal(a, Int32Constant(0)); }
333 :
334 13 : Node* Word64And(Node* a, Node* b) {
335 26 : return AddNode(machine()->Word64And(), a, b);
336 : }
337 1 : Node* Word64Or(Node* a, Node* b) {
338 2 : return AddNode(machine()->Word64Or(), a, b);
339 : }
340 1 : Node* Word64Xor(Node* a, Node* b) {
341 2 : return AddNode(machine()->Word64Xor(), a, b);
342 : }
343 96 : Node* Word64Shl(Node* a, Node* b) {
344 192 : return AddNode(machine()->Word64Shl(), a, b);
345 : }
346 22 : Node* Word64Shr(Node* a, Node* b) {
347 44 : return AddNode(machine()->Word64Shr(), a, b);
348 : }
349 3 : Node* Word64Sar(Node* a, Node* b) {
350 6 : return AddNode(machine()->Word64Sar(), a, b);
351 : }
352 0 : Node* Word64Ror(Node* a, Node* b) {
353 0 : return AddNode(machine()->Word64Ror(), a, b);
354 : }
355 12 : Node* Word64Clz(Node* a) { return AddNode(machine()->Word64Clz(), a); }
356 12412 : Node* Word64Equal(Node* a, Node* b) {
357 24824 : return AddNode(machine()->Word64Equal(), a, b);
358 : }
359 : Node* Word64NotEqual(Node* a, Node* b) {
360 24 : return Word32BinaryNot(Word64Equal(a, b));
361 : }
362 0 : Node* Word64Not(Node* a) { return Word64Xor(a, Int64Constant(-1)); }
363 :
364 61727 : Node* Int32Add(Node* a, Node* b) {
365 123454 : return AddNode(machine()->Int32Add(), a, b);
366 : }
367 28732 : Node* Int32AddWithOverflow(Node* a, Node* b) {
368 57464 : return AddNode(machine()->Int32AddWithOverflow(), a, b);
369 : }
370 24905 : Node* Int32Sub(Node* a, Node* b) {
371 49810 : return AddNode(machine()->Int32Sub(), a, b);
372 : }
373 16844 : Node* Int32SubWithOverflow(Node* a, Node* b) {
374 33688 : return AddNode(machine()->Int32SubWithOverflow(), a, b);
375 : }
376 32349 : Node* Int32Mul(Node* a, Node* b) {
377 64698 : return AddNode(machine()->Int32Mul(), a, b);
378 : }
379 7 : Node* Int32MulHigh(Node* a, Node* b) {
380 14 : return AddNode(machine()->Int32MulHigh(), a, b);
381 : }
382 14376 : Node* Int32MulWithOverflow(Node* a, Node* b) {
383 28752 : return AddNode(machine()->Int32MulWithOverflow(), a, b);
384 : }
385 535 : Node* Int32Div(Node* a, Node* b) {
386 1070 : return AddNode(machine()->Int32Div(), a, b);
387 : }
388 906 : Node* Int32Mod(Node* a, Node* b) {
389 1812 : return AddNode(machine()->Int32Mod(), a, b);
390 : }
391 50786 : Node* Int32LessThan(Node* a, Node* b) {
392 101572 : return AddNode(machine()->Int32LessThan(), a, b);
393 : }
394 33054 : Node* Int32LessThanOrEqual(Node* a, Node* b) {
395 66108 : return AddNode(machine()->Int32LessThanOrEqual(), a, b);
396 : }
397 10 : Node* Uint32Div(Node* a, Node* b) {
398 20 : return AddNode(machine()->Uint32Div(), a, b);
399 : }
400 22050 : Node* Uint32LessThan(Node* a, Node* b) {
401 44100 : return AddNode(machine()->Uint32LessThan(), a, b);
402 : }
403 12386 : Node* Uint32LessThanOrEqual(Node* a, Node* b) {
404 24772 : return AddNode(machine()->Uint32LessThanOrEqual(), a, b);
405 : }
406 10 : Node* Uint32Mod(Node* a, Node* b) {
407 20 : return AddNode(machine()->Uint32Mod(), a, b);
408 : }
409 5 : Node* Uint32MulHigh(Node* a, Node* b) {
410 10 : return AddNode(machine()->Uint32MulHigh(), a, b);
411 : }
412 9728 : Node* Int32GreaterThan(Node* a, Node* b) { return Int32LessThan(b, a); }
413 : Node* Int32GreaterThanOrEqual(Node* a, Node* b) {
414 19504 : return Int32LessThanOrEqual(b, a);
415 : }
416 3368 : Node* Uint32GreaterThan(Node* a, Node* b) { return Uint32LessThan(b, a); }
417 : Node* Uint32GreaterThanOrEqual(Node* a, Node* b) {
418 4736 : return Uint32LessThanOrEqual(b, a);
419 : }
420 4 : Node* Int32Neg(Node* a) { return Int32Sub(Int32Constant(0), a); }
421 :
422 593885 : Node* Int64Add(Node* a, Node* b) {
423 1187770 : return AddNode(machine()->Int64Add(), a, b);
424 : }
425 27572 : Node* Int64AddWithOverflow(Node* a, Node* b) {
426 55144 : return AddNode(machine()->Int64AddWithOverflow(), a, b);
427 : }
428 94252 : Node* Int64Sub(Node* a, Node* b) {
429 188504 : return AddNode(machine()->Int64Sub(), a, b);
430 : }
431 26900 : Node* Int64SubWithOverflow(Node* a, Node* b) {
432 53800 : return AddNode(machine()->Int64SubWithOverflow(), a, b);
433 : }
434 35293 : Node* Int64Mul(Node* a, Node* b) {
435 70586 : return AddNode(machine()->Int64Mul(), a, b);
436 : }
437 449 : Node* Int64Div(Node* a, Node* b) {
438 898 : return AddNode(machine()->Int64Div(), a, b);
439 : }
440 : Node* Int64Mod(Node* a, Node* b) {
441 : return AddNode(machine()->Int64Mod(), a, b);
442 : }
443 : Node* Int64Neg(Node* a) { return Int64Sub(Int64Constant(0), a); }
444 24576 : Node* Int64LessThan(Node* a, Node* b) {
445 49152 : return AddNode(machine()->Int64LessThan(), a, b);
446 : }
447 7444 : Node* Int64LessThanOrEqual(Node* a, Node* b) {
448 14888 : return AddNode(machine()->Int64LessThanOrEqual(), a, b);
449 : }
450 102214 : Node* Uint64LessThan(Node* a, Node* b) {
451 204428 : return AddNode(machine()->Uint64LessThan(), a, b);
452 : }
453 42540 : Node* Uint64LessThanOrEqual(Node* a, Node* b) {
454 85080 : return AddNode(machine()->Uint64LessThanOrEqual(), a, b);
455 : }
456 17152 : Node* Int64GreaterThan(Node* a, Node* b) { return Int64LessThan(b, a); }
457 : Node* Int64GreaterThanOrEqual(Node* a, Node* b) {
458 2100 : return Int64LessThanOrEqual(b, a);
459 : }
460 1904 : Node* Uint64GreaterThan(Node* a, Node* b) { return Uint64LessThan(b, a); }
461 : Node* Uint64GreaterThanOrEqual(Node* a, Node* b) {
462 29468 : return Uint64LessThanOrEqual(b, a);
463 : }
464 : Node* Uint64Div(Node* a, Node* b) {
465 : return AddNode(machine()->Uint64Div(), a, b);
466 : }
467 : Node* Uint64Mod(Node* a, Node* b) {
468 : return AddNode(machine()->Uint64Mod(), a, b);
469 : }
470 : Node* Int32PairAdd(Node* a_low, Node* a_high, Node* b_low, Node* b_high) {
471 : return AddNode(machine()->Int32PairAdd(), a_low, a_high, b_low, b_high);
472 : }
473 : Node* Int32PairSub(Node* a_low, Node* a_high, Node* b_low, Node* b_high) {
474 : return AddNode(machine()->Int32PairSub(), a_low, a_high, b_low, b_high);
475 : }
476 : Node* Int32PairMul(Node* a_low, Node* a_high, Node* b_low, Node* b_high) {
477 : return AddNode(machine()->Int32PairMul(), a_low, a_high, b_low, b_high);
478 : }
479 : Node* Word32PairShl(Node* low_word, Node* high_word, Node* shift) {
480 : return AddNode(machine()->Word32PairShl(), low_word, high_word, shift);
481 : }
482 : Node* Word32PairShr(Node* low_word, Node* high_word, Node* shift) {
483 : return AddNode(machine()->Word32PairShr(), low_word, high_word, shift);
484 : }
485 : Node* Word32PairSar(Node* low_word, Node* high_word, Node* shift) {
486 : return AddNode(machine()->Word32PairSar(), low_word, high_word, shift);
487 : }
488 :
489 : #define INTPTR_BINOP(prefix, name) \
490 : Node* IntPtr##name(Node* a, Node* b) { \
491 : return kSystemPointerSize == 8 ? prefix##64##name(a, b) \
492 : : prefix##32##name(a, b); \
493 : }
494 :
495 592508 : INTPTR_BINOP(Int, Add)
496 672 : INTPTR_BINOP(Int, AddWithOverflow)
497 92923 : INTPTR_BINOP(Int, Sub)
498 0 : INTPTR_BINOP(Int, SubWithOverflow)
499 34837 : INTPTR_BINOP(Int, Mul)
500 449 : INTPTR_BINOP(Int, Div)
501 7424 : INTPTR_BINOP(Int, LessThan)
502 5344 : INTPTR_BINOP(Int, LessThanOrEqual)
503 7272 : INTPTR_BINOP(Word, Equal)
504 : INTPTR_BINOP(Word, NotEqual)
505 : INTPTR_BINOP(Int, GreaterThanOrEqual)
506 : INTPTR_BINOP(Int, GreaterThan)
507 :
508 : #undef INTPTR_BINOP
509 :
510 : #define UINTPTR_BINOP(prefix, name) \
511 : Node* UintPtr##name(Node* a, Node* b) { \
512 : return kSystemPointerSize == 8 ? prefix##64##name(a, b) \
513 : : prefix##32##name(a, b); \
514 : }
515 :
516 100310 : UINTPTR_BINOP(Uint, LessThan)
517 13072 : UINTPTR_BINOP(Uint, LessThanOrEqual)
518 : UINTPTR_BINOP(Uint, GreaterThanOrEqual)
519 : UINTPTR_BINOP(Uint, GreaterThan)
520 :
521 : #undef UINTPTR_BINOP
522 :
523 0 : Node* Int32AbsWithOverflow(Node* a) {
524 0 : return AddNode(machine()->Int32AbsWithOverflow().op(), a);
525 : }
526 :
527 0 : Node* Int64AbsWithOverflow(Node* a) {
528 0 : return AddNode(machine()->Int64AbsWithOverflow().op(), a);
529 : }
530 :
531 : Node* IntPtrAbsWithOverflow(Node* a) {
532 : return kSystemPointerSize == 8 ? Int64AbsWithOverflow(a)
533 0 : : Int32AbsWithOverflow(a);
534 : }
535 :
536 1268 : Node* Float32Add(Node* a, Node* b) {
537 2536 : return AddNode(machine()->Float32Add(), a, b);
538 : }
539 2256 : Node* Float32Sub(Node* a, Node* b) {
540 4512 : return AddNode(machine()->Float32Sub(), a, b);
541 : }
542 464 : Node* Float32Mul(Node* a, Node* b) {
543 928 : return AddNode(machine()->Float32Mul(), a, b);
544 : }
545 8 : Node* Float32Div(Node* a, Node* b) {
546 16 : return AddNode(machine()->Float32Div(), a, b);
547 : }
548 18 : Node* Float32Abs(Node* a) { return AddNode(machine()->Float32Abs(), a); }
549 : Node* Float32Neg(Node* a) { return AddNode(machine()->Float32Neg(), a); }
550 : Node* Float32Sqrt(Node* a) { return AddNode(machine()->Float32Sqrt(), a); }
551 0 : Node* Float32Equal(Node* a, Node* b) {
552 0 : return AddNode(machine()->Float32Equal(), a, b);
553 : }
554 : Node* Float32NotEqual(Node* a, Node* b) {
555 : return Word32BinaryNot(Float32Equal(a, b));
556 : }
557 4 : Node* Float32LessThan(Node* a, Node* b) {
558 8 : return AddNode(machine()->Float32LessThan(), a, b);
559 : }
560 0 : Node* Float32LessThanOrEqual(Node* a, Node* b) {
561 0 : return AddNode(machine()->Float32LessThanOrEqual(), a, b);
562 : }
563 0 : Node* Float32GreaterThan(Node* a, Node* b) { return Float32LessThan(b, a); }
564 : Node* Float32GreaterThanOrEqual(Node* a, Node* b) {
565 0 : return Float32LessThanOrEqual(b, a);
566 : }
567 4 : Node* Float32Max(Node* a, Node* b) {
568 8 : return AddNode(machine()->Float32Max(), a, b);
569 : }
570 4 : Node* Float32Min(Node* a, Node* b) {
571 8 : return AddNode(machine()->Float32Min(), a, b);
572 : }
573 6889 : Node* Float64Add(Node* a, Node* b) {
574 13778 : return AddNode(machine()->Float64Add(), a, b);
575 : }
576 5111 : Node* Float64Sub(Node* a, Node* b) {
577 10222 : return AddNode(machine()->Float64Sub(), a, b);
578 : }
579 1770 : Node* Float64Mul(Node* a, Node* b) {
580 3540 : return AddNode(machine()->Float64Mul(), a, b);
581 : }
582 738 : Node* Float64Div(Node* a, Node* b) {
583 1476 : return AddNode(machine()->Float64Div(), a, b);
584 : }
585 527 : Node* Float64Mod(Node* a, Node* b) {
586 1054 : return AddNode(machine()->Float64Mod(), a, b);
587 : }
588 64 : Node* Float64Max(Node* a, Node* b) {
589 128 : return AddNode(machine()->Float64Max(), a, b);
590 : }
591 64 : Node* Float64Min(Node* a, Node* b) {
592 128 : return AddNode(machine()->Float64Min(), a, b);
593 : }
594 15642 : Node* Float64Abs(Node* a) { return AddNode(machine()->Float64Abs(), a); }
595 606 : Node* Float64Neg(Node* a) { return AddNode(machine()->Float64Neg(), a); }
596 180 : Node* Float64Acos(Node* a) { return AddNode(machine()->Float64Acos(), a); }
597 180 : Node* Float64Acosh(Node* a) { return AddNode(machine()->Float64Acosh(), a); }
598 180 : Node* Float64Asin(Node* a) { return AddNode(machine()->Float64Asin(), a); }
599 180 : Node* Float64Asinh(Node* a) { return AddNode(machine()->Float64Asinh(), a); }
600 180 : Node* Float64Atan(Node* a) { return AddNode(machine()->Float64Atan(), a); }
601 180 : Node* Float64Atanh(Node* a) { return AddNode(machine()->Float64Atanh(), a); }
602 60 : Node* Float64Atan2(Node* a, Node* b) {
603 120 : return AddNode(machine()->Float64Atan2(), a, b);
604 : }
605 180 : Node* Float64Cbrt(Node* a) { return AddNode(machine()->Float64Cbrt(), a); }
606 180 : Node* Float64Cos(Node* a) { return AddNode(machine()->Float64Cos(), a); }
607 180 : Node* Float64Cosh(Node* a) { return AddNode(machine()->Float64Cosh(), a); }
608 180 : Node* Float64Exp(Node* a) { return AddNode(machine()->Float64Exp(), a); }
609 180 : Node* Float64Expm1(Node* a) { return AddNode(machine()->Float64Expm1(), a); }
610 180 : Node* Float64Log(Node* a) { return AddNode(machine()->Float64Log(), a); }
611 180 : Node* Float64Log1p(Node* a) { return AddNode(machine()->Float64Log1p(), a); }
612 180 : Node* Float64Log10(Node* a) { return AddNode(machine()->Float64Log10(), a); }
613 180 : Node* Float64Log2(Node* a) { return AddNode(machine()->Float64Log2(), a); }
614 112 : Node* Float64Pow(Node* a, Node* b) {
615 224 : return AddNode(machine()->Float64Pow(), a, b);
616 : }
617 180 : Node* Float64Sin(Node* a) { return AddNode(machine()->Float64Sin(), a); }
618 180 : Node* Float64Sinh(Node* a) { return AddNode(machine()->Float64Sinh(), a); }
619 168 : Node* Float64Sqrt(Node* a) { return AddNode(machine()->Float64Sqrt(), a); }
620 180 : Node* Float64Tan(Node* a) { return AddNode(machine()->Float64Tan(), a); }
621 180 : Node* Float64Tanh(Node* a) { return AddNode(machine()->Float64Tanh(), a); }
622 24059 : Node* Float64Equal(Node* a, Node* b) {
623 48118 : return AddNode(machine()->Float64Equal(), a, b);
624 : }
625 : Node* Float64NotEqual(Node* a, Node* b) {
626 400 : return Word32BinaryNot(Float64Equal(a, b));
627 : }
628 13170 : Node* Float64LessThan(Node* a, Node* b) {
629 26340 : return AddNode(machine()->Float64LessThan(), a, b);
630 : }
631 5242 : Node* Float64LessThanOrEqual(Node* a, Node* b) {
632 10484 : return AddNode(machine()->Float64LessThanOrEqual(), a, b);
633 : }
634 3536 : Node* Float64GreaterThan(Node* a, Node* b) { return Float64LessThan(b, a); }
635 : Node* Float64GreaterThanOrEqual(Node* a, Node* b) {
636 3705 : return Float64LessThanOrEqual(b, a);
637 : }
638 :
639 : // Conversions.
640 780552 : Node* BitcastTaggedToWord(Node* a) {
641 1561104 : return AddNode(machine()->BitcastTaggedToWord(), a);
642 : }
643 24868 : Node* BitcastMaybeObjectToWord(Node* a) {
644 49736 : return AddNode(machine()->BitcastMaybeObjectToWord(), a);
645 : }
646 126080 : Node* BitcastWordToTagged(Node* a) {
647 252160 : return AddNode(machine()->BitcastWordToTagged(), a);
648 : }
649 515298 : Node* BitcastWordToTaggedSigned(Node* a) {
650 1030596 : return AddNode(machine()->BitcastWordToTaggedSigned(), a);
651 : }
652 8473 : Node* TruncateFloat64ToWord32(Node* a) {
653 16946 : return AddNode(machine()->TruncateFloat64ToWord32(), a);
654 : }
655 2041 : Node* ChangeFloat32ToFloat64(Node* a) {
656 4082 : return AddNode(machine()->ChangeFloat32ToFloat64(), a);
657 : }
658 67524 : Node* ChangeInt32ToFloat64(Node* a) {
659 135048 : return AddNode(machine()->ChangeInt32ToFloat64(), a);
660 : }
661 4 : Node* ChangeInt64ToFloat64(Node* a) {
662 8 : return AddNode(machine()->ChangeInt64ToFloat64(), a);
663 : }
664 5221 : Node* ChangeUint32ToFloat64(Node* a) {
665 10442 : return AddNode(machine()->ChangeUint32ToFloat64(), a);
666 : }
667 20 : Node* ChangeFloat64ToInt32(Node* a) {
668 40 : return AddNode(machine()->ChangeFloat64ToInt32(), a);
669 : }
670 4 : Node* ChangeFloat64ToInt64(Node* a) {
671 8 : return AddNode(machine()->ChangeFloat64ToInt64(), a);
672 : }
673 120 : Node* ChangeFloat64ToUint32(Node* a) {
674 240 : return AddNode(machine()->ChangeFloat64ToUint32(), a);
675 : }
676 1456 : Node* ChangeFloat64ToUint64(Node* a) {
677 2912 : return AddNode(machine()->ChangeFloat64ToUint64(), a);
678 : }
679 : Node* TruncateFloat64ToUint32(Node* a) {
680 : return AddNode(machine()->TruncateFloat64ToUint32(), a);
681 : }
682 228 : Node* TruncateFloat32ToInt32(Node* a) {
683 456 : return AddNode(machine()->TruncateFloat32ToInt32(), a);
684 : }
685 4 : Node* TruncateFloat32ToUint32(Node* a) {
686 8 : return AddNode(machine()->TruncateFloat32ToUint32(), a);
687 : }
688 8 : Node* TryTruncateFloat32ToInt64(Node* a) {
689 16 : return AddNode(machine()->TryTruncateFloat32ToInt64(), a);
690 : }
691 8 : Node* TryTruncateFloat64ToInt64(Node* a) {
692 16 : return AddNode(machine()->TryTruncateFloat64ToInt64(), a);
693 : }
694 8 : Node* TryTruncateFloat32ToUint64(Node* a) {
695 16 : return AddNode(machine()->TryTruncateFloat32ToUint64(), a);
696 : }
697 8 : Node* TryTruncateFloat64ToUint64(Node* a) {
698 16 : return AddNode(machine()->TryTruncateFloat64ToUint64(), a);
699 : }
700 151798 : Node* ChangeInt32ToInt64(Node* a) {
701 303596 : return AddNode(machine()->ChangeInt32ToInt64(), a);
702 : }
703 115330 : Node* ChangeUint32ToUint64(Node* a) {
704 230660 : return AddNode(machine()->ChangeUint32ToUint64(), a);
705 : }
706 8 : Node* ChangeTaggedToCompressed(Node* a) {
707 16 : return AddNode(machine()->ChangeTaggedToCompressed(), a);
708 : }
709 4 : Node* ChangeTaggedPointerToCompressedPointer(Node* a) {
710 8 : return AddNode(machine()->ChangeTaggedPointerToCompressedPointer(), a);
711 : }
712 4 : Node* ChangeTaggedSignedToCompressedSigned(Node* a) {
713 8 : return AddNode(machine()->ChangeTaggedSignedToCompressedSigned(), a);
714 : }
715 8 : Node* ChangeCompressedToTagged(Node* a) {
716 16 : return AddNode(machine()->ChangeCompressedToTagged(), a);
717 : }
718 4 : Node* ChangeCompressedPointerToTaggedPointer(Node* a) {
719 8 : return AddNode(machine()->ChangeCompressedPointerToTaggedPointer(), a);
720 : }
721 4 : Node* ChangeCompressedSignedToTaggedSigned(Node* a) {
722 8 : return AddNode(machine()->ChangeCompressedSignedToTaggedSigned(), a);
723 : }
724 2149 : Node* TruncateFloat64ToFloat32(Node* a) {
725 4298 : return AddNode(machine()->TruncateFloat64ToFloat32(), a);
726 : }
727 376228 : Node* TruncateInt64ToInt32(Node* a) {
728 752456 : return AddNode(machine()->TruncateInt64ToInt32(), a);
729 : }
730 14636 : Node* RoundFloat64ToInt32(Node* a) {
731 29272 : return AddNode(machine()->RoundFloat64ToInt32(), a);
732 : }
733 396 : Node* RoundInt32ToFloat32(Node* a) {
734 792 : return AddNode(machine()->RoundInt32ToFloat32(), a);
735 : }
736 4 : Node* RoundInt64ToFloat32(Node* a) {
737 8 : return AddNode(machine()->RoundInt64ToFloat32(), a);
738 : }
739 1132 : Node* RoundInt64ToFloat64(Node* a) {
740 2264 : return AddNode(machine()->RoundInt64ToFloat64(), a);
741 : }
742 4 : Node* RoundUint32ToFloat32(Node* a) {
743 8 : return AddNode(machine()->RoundUint32ToFloat32(), a);
744 : }
745 4 : Node* RoundUint64ToFloat32(Node* a) {
746 8 : return AddNode(machine()->RoundUint64ToFloat32(), a);
747 : }
748 1740 : Node* RoundUint64ToFloat64(Node* a) {
749 3480 : return AddNode(machine()->RoundUint64ToFloat64(), a);
750 : }
751 60 : Node* BitcastFloat32ToInt32(Node* a) {
752 120 : return AddNode(machine()->BitcastFloat32ToInt32(), a);
753 : }
754 4 : Node* BitcastFloat64ToInt64(Node* a) {
755 8 : return AddNode(machine()->BitcastFloat64ToInt64(), a);
756 : }
757 60 : Node* BitcastInt32ToFloat32(Node* a) {
758 120 : return AddNode(machine()->BitcastInt32ToFloat32(), a);
759 : }
760 4 : Node* BitcastInt64ToFloat64(Node* a) {
761 8 : return AddNode(machine()->BitcastInt64ToFloat64(), a);
762 : }
763 4 : Node* Float32RoundDown(Node* a) {
764 8 : return AddNode(machine()->Float32RoundDown().op(), a);
765 : }
766 118 : Node* Float64RoundDown(Node* a) {
767 236 : return AddNode(machine()->Float64RoundDown().op(), a);
768 : }
769 4 : Node* Float32RoundUp(Node* a) {
770 8 : return AddNode(machine()->Float32RoundUp().op(), a);
771 : }
772 114 : Node* Float64RoundUp(Node* a) {
773 228 : return AddNode(machine()->Float64RoundUp().op(), a);
774 : }
775 4 : Node* Float32RoundTruncate(Node* a) {
776 8 : return AddNode(machine()->Float32RoundTruncate().op(), a);
777 : }
778 338 : Node* Float64RoundTruncate(Node* a) {
779 676 : return AddNode(machine()->Float64RoundTruncate().op(), a);
780 : }
781 0 : Node* Float64RoundTiesAway(Node* a) {
782 0 : return AddNode(machine()->Float64RoundTiesAway().op(), a);
783 : }
784 4 : Node* Float32RoundTiesEven(Node* a) {
785 8 : return AddNode(machine()->Float32RoundTiesEven().op(), a);
786 : }
787 389 : Node* Float64RoundTiesEven(Node* a) {
788 778 : return AddNode(machine()->Float64RoundTiesEven().op(), a);
789 : }
790 : Node* Word32ReverseBytes(Node* a) {
791 : return AddNode(machine()->Word32ReverseBytes(), a);
792 : }
793 : Node* Word64ReverseBytes(Node* a) {
794 : return AddNode(machine()->Word64ReverseBytes(), a);
795 : }
796 :
797 : // Float64 bit operations.
798 60 : Node* Float64ExtractLowWord32(Node* a) {
799 120 : return AddNode(machine()->Float64ExtractLowWord32(), a);
800 : }
801 6404 : Node* Float64ExtractHighWord32(Node* a) {
802 12808 : return AddNode(machine()->Float64ExtractHighWord32(), a);
803 : }
804 60 : Node* Float64InsertLowWord32(Node* a, Node* b) {
805 120 : return AddNode(machine()->Float64InsertLowWord32(), a, b);
806 : }
807 60 : Node* Float64InsertHighWord32(Node* a, Node* b) {
808 120 : return AddNode(machine()->Float64InsertHighWord32(), a, b);
809 : }
810 2700 : Node* Float64SilenceNaN(Node* a) {
811 5400 : return AddNode(machine()->Float64SilenceNaN(), a);
812 : }
813 :
814 : // Stack operations.
815 57798 : Node* LoadStackPointer() { return AddNode(machine()->LoadStackPointer()); }
816 24024 : Node* LoadFramePointer() { return AddNode(machine()->LoadFramePointer()); }
817 28668 : Node* LoadParentFramePointer() {
818 57336 : return AddNode(machine()->LoadParentFramePointer());
819 : }
820 :
821 : // Parameters.
822 : Node* TargetParameter();
823 : Node* Parameter(size_t index);
824 :
825 : // Pointer utilities.
826 6204 : Node* LoadFromPointer(void* address, MachineType rep, int32_t offset = 0) {
827 12408 : return Load(rep, PointerConstant(address), Int32Constant(offset));
828 : }
829 103940 : Node* StoreToPointer(void* address, MachineRepresentation rep, Node* node) {
830 103940 : return Store(rep, PointerConstant(address), node, kNoWriteBarrier);
831 : }
832 76 : Node* UnalignedLoadFromPointer(void* address, MachineType rep,
833 : int32_t offset = 0) {
834 152 : return UnalignedLoad(rep, PointerConstant(address), Int32Constant(offset));
835 : }
836 32 : Node* UnalignedStoreToPointer(void* address, MachineRepresentation rep,
837 : Node* node) {
838 32 : return UnalignedStore(rep, PointerConstant(address), node);
839 : }
840 44 : Node* StringConstant(const char* string) {
841 88 : return HeapConstant(isolate()->factory()->InternalizeUtf8String(string));
842 : }
843 :
844 19056 : Node* TaggedPoisonOnSpeculation(Node* value) {
845 19056 : if (poisoning_level_ != PoisoningMitigationLevel::kDontPoison) {
846 1712 : return AddNode(machine()->TaggedPoisonOnSpeculation(), value);
847 : }
848 : return value;
849 : }
850 :
851 45864 : Node* WordPoisonOnSpeculation(Node* value) {
852 45864 : if (poisoning_level_ != PoisoningMitigationLevel::kDontPoison) {
853 0 : return AddNode(machine()->WordPoisonOnSpeculation(), value);
854 : }
855 : return value;
856 : }
857 :
858 : // Call a given call descriptor and the given arguments.
859 : // The call target is passed as part of the {inputs} array.
860 : Node* CallN(CallDescriptor* call_descriptor, int input_count,
861 : Node* const* inputs);
862 :
863 : // Call a given call descriptor and the given arguments and frame-state.
864 : // The call target and frame state are passed as part of the {inputs} array.
865 : Node* CallNWithFrameState(CallDescriptor* call_descriptor, int input_count,
866 : Node* const* inputs);
867 :
868 : // Tail call a given call descriptor and the given arguments.
869 : // The call target is passed as part of the {inputs} array.
870 : Node* TailCallN(CallDescriptor* call_descriptor, int input_count,
871 : Node* const* inputs);
872 :
873 : // Call to a C function with zero arguments.
874 : Node* CallCFunction0(MachineType return_type, Node* function);
875 : // Call to a C function with one parameter.
876 : Node* CallCFunction1(MachineType return_type, MachineType arg0_type,
877 : Node* function, Node* arg0);
878 : // Call to a C function with one argument, while saving/restoring caller
879 : // registers.
880 : Node* CallCFunction1WithCallerSavedRegisters(
881 : MachineType return_type, MachineType arg0_type, Node* function,
882 : Node* arg0, SaveFPRegsMode mode = kSaveFPRegs);
883 : // Call to a C function with two arguments.
884 : Node* CallCFunction2(MachineType return_type, MachineType arg0_type,
885 : MachineType arg1_type, Node* function, Node* arg0,
886 : Node* arg1);
887 : // Call to a C function with three arguments.
888 : Node* CallCFunction3(MachineType return_type, MachineType arg0_type,
889 : MachineType arg1_type, MachineType arg2_type,
890 : Node* function, Node* arg0, Node* arg1, Node* arg2);
891 : // Call to a C function with three arguments, while saving/restoring caller
892 : // registers.
893 : Node* CallCFunction3WithCallerSavedRegisters(
894 : MachineType return_type, MachineType arg0_type, MachineType arg1_type,
895 : MachineType arg2_type, Node* function, Node* arg0, Node* arg1, Node* arg2,
896 : SaveFPRegsMode mode = kSaveFPRegs);
897 : // Call to a C function with four arguments.
898 : Node* CallCFunction4(MachineType return_type, MachineType arg0_type,
899 : MachineType arg1_type, MachineType arg2_type,
900 : MachineType arg3_type, Node* function, Node* arg0,
901 : Node* arg1, Node* arg2, Node* arg3);
902 : // Call to a C function with five arguments.
903 : Node* CallCFunction5(MachineType return_type, MachineType arg0_type,
904 : MachineType arg1_type, MachineType arg2_type,
905 : MachineType arg3_type, MachineType arg4_type,
906 : Node* function, Node* arg0, Node* arg1, Node* arg2,
907 : Node* arg3, Node* arg4);
908 : // Call to a C function with six arguments.
909 : Node* CallCFunction6(MachineType return_type, MachineType arg0_type,
910 : MachineType arg1_type, MachineType arg2_type,
911 : MachineType arg3_type, MachineType arg4_type,
912 : MachineType arg5_type, Node* function, Node* arg0,
913 : Node* arg1, Node* arg2, Node* arg3, Node* arg4,
914 : Node* arg5);
915 : // Call to a C function with eight arguments.
916 : Node* CallCFunction8(MachineType return_type, MachineType arg0_type,
917 : MachineType arg1_type, MachineType arg2_type,
918 : MachineType arg3_type, MachineType arg4_type,
919 : MachineType arg5_type, MachineType arg6_type,
920 : MachineType arg7_type, Node* function, Node* arg0,
921 : Node* arg1, Node* arg2, Node* arg3, Node* arg4,
922 : Node* arg5, Node* arg6, Node* arg7);
923 : // Call to a C function with nine arguments.
924 : Node* CallCFunction9(MachineType return_type, MachineType arg0_type,
925 : MachineType arg1_type, MachineType arg2_type,
926 : MachineType arg3_type, MachineType arg4_type,
927 : MachineType arg5_type, MachineType arg6_type,
928 : MachineType arg7_type, MachineType arg8_type,
929 : Node* function, Node* arg0, Node* arg1, Node* arg2,
930 : Node* arg3, Node* arg4, Node* arg5, Node* arg6,
931 : Node* arg7, Node* arg8);
932 :
933 : // ===========================================================================
934 : // The following utility methods deal with control flow, hence might switch
935 : // the current basic block or create new basic blocks for labels.
936 :
937 : // Control flow.
938 : void Goto(RawMachineLabel* label);
939 : void Branch(Node* condition, RawMachineLabel* true_val,
940 : RawMachineLabel* false_val);
941 : void Switch(Node* index, RawMachineLabel* default_label,
942 : const int32_t* case_values, RawMachineLabel** case_labels,
943 : size_t case_count);
944 : void Return(Node* value);
945 : void Return(Node* v1, Node* v2);
946 : void Return(Node* v1, Node* v2, Node* v3);
947 : void Return(Node* v1, Node* v2, Node* v3, Node* v4);
948 : void Return(int count, Node* v[]);
949 : void PopAndReturn(Node* pop, Node* value);
950 : void PopAndReturn(Node* pop, Node* v1, Node* v2);
951 : void PopAndReturn(Node* pop, Node* v1, Node* v2, Node* v3);
952 : void PopAndReturn(Node* pop, Node* v1, Node* v2, Node* v3, Node* v4);
953 : void Bind(RawMachineLabel* label);
954 : void Deoptimize(Node* state);
955 : void DebugAbort(Node* message);
956 : void DebugBreak();
957 : void Unreachable();
958 : void Comment(const std::string& msg);
959 :
960 : #if DEBUG
961 : void Bind(RawMachineLabel* label, AssemblerDebugInfo info);
962 : void SetInitialDebugInformation(AssemblerDebugInfo info);
963 : void PrintCurrentBlock(std::ostream& os);
964 : #endif // DEBUG
965 : bool InsideBlock();
966 :
967 : // Add success / exception successor blocks and ends the current block ending
968 : // in a potentially throwing call node.
969 : void Continuations(Node* call, RawMachineLabel* if_success,
970 : RawMachineLabel* if_exception);
971 :
972 : // Variables.
973 158 : Node* Phi(MachineRepresentation rep, Node* n1, Node* n2) {
974 316 : return AddNode(common()->Phi(rep, 2), n1, n2, graph()->start());
975 : }
976 : Node* Phi(MachineRepresentation rep, Node* n1, Node* n2, Node* n3) {
977 : return AddNode(common()->Phi(rep, 3), n1, n2, n3, graph()->start());
978 : }
979 : Node* Phi(MachineRepresentation rep, Node* n1, Node* n2, Node* n3, Node* n4) {
980 : return AddNode(common()->Phi(rep, 4), n1, n2, n3, n4, graph()->start());
981 : }
982 : Node* Phi(MachineRepresentation rep, int input_count, Node* const* inputs);
983 : void AppendPhiInput(Node* phi, Node* new_input);
984 :
985 : // ===========================================================================
986 : // The following generic node creation methods can be used for operators that
987 : // are not covered by the above utility methods. There should rarely be a need
988 : // to do that outside of testing though.
989 :
990 : Node* AddNode(const Operator* op, int input_count, Node* const* inputs);
991 :
992 : Node* AddNode(const Operator* op) {
993 7282325 : return AddNode(op, 0, static_cast<Node* const*>(nullptr));
994 : }
995 :
996 : template <class... TArgs>
997 : Node* AddNode(const Operator* op, Node* n1, TArgs... args) {
998 9172755 : Node* buffer[] = {n1, args...};
999 9172755 : return AddNode(op, sizeof...(args) + 1, buffer);
1000 : }
1001 :
1002 : void SetSourcePosition(const char* file, int line);
1003 : SourcePositionTable* source_positions() { return source_positions_; }
1004 :
1005 : private:
1006 : Node* MakeNode(const Operator* op, int input_count, Node* const* inputs);
1007 : BasicBlock* Use(RawMachineLabel* label);
1008 : BasicBlock* EnsureBlock(RawMachineLabel* label);
1009 : BasicBlock* CurrentBlock();
1010 :
1011 : // A post-processing pass to add effect and control edges so that the graph
1012 : // can be optimized and re-scheduled.
1013 : // TODO(tebbi): Move this to a separate class.
1014 : void MakeReschedulable();
1015 : Node* CreateNodeFromPredecessors(const std::vector<BasicBlock*>& predecessors,
1016 : const std::vector<Node*>& sidetable,
1017 : const Operator* op,
1018 : const std::vector<Node*>& additional_inputs);
1019 : void MakePhiBinary(Node* phi, int split_point, Node* left_control,
1020 : Node* right_control);
1021 : void MarkControlDeferred(Node* control_input);
1022 :
1023 : Schedule* schedule() { return schedule_; }
1024 : size_t parameter_count() const { return call_descriptor_->ParameterCount(); }
1025 :
1026 : Isolate* isolate_;
1027 : Graph* graph_;
1028 : Schedule* schedule_;
1029 : SourcePositionTable* source_positions_;
1030 : MachineOperatorBuilder machine_;
1031 : CommonOperatorBuilder common_;
1032 : SimplifiedOperatorBuilder simplified_;
1033 : CallDescriptor* call_descriptor_;
1034 : Node* target_parameter_;
1035 : NodeVector parameters_;
1036 : BasicBlock* current_block_;
1037 : PoisoningMitigationLevel poisoning_level_;
1038 :
1039 : DISALLOW_COPY_AND_ASSIGN(RawMachineAssembler);
1040 : };
1041 :
1042 : class V8_EXPORT_PRIVATE RawMachineLabel final {
1043 : public:
1044 : enum Type { kDeferred, kNonDeferred };
1045 :
1046 : explicit RawMachineLabel(Type type = kNonDeferred)
1047 3734108 : : deferred_(type == kDeferred) {}
1048 : ~RawMachineLabel();
1049 :
1050 : BasicBlock* block() const { return block_; }
1051 :
1052 : private:
1053 : BasicBlock* block_ = nullptr;
1054 : bool used_ = false;
1055 : bool bound_ = false;
1056 : bool deferred_;
1057 : friend class RawMachineAssembler;
1058 : DISALLOW_COPY_AND_ASSIGN(RawMachineLabel);
1059 : };
1060 :
1061 : } // namespace compiler
1062 : } // namespace internal
1063 : } // namespace v8
1064 :
1065 : #endif // V8_COMPILER_RAW_MACHINE_ASSEMBLER_H_
|