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 : #include "src/compiler/common-operator.h"
6 :
7 : #include "src/assembler.h"
8 : #include "src/base/lazy-instance.h"
9 : #include "src/compiler/linkage.h"
10 : #include "src/compiler/node.h"
11 : #include "src/compiler/opcodes.h"
12 : #include "src/compiler/operator.h"
13 : #include "src/handles-inl.h"
14 : #include "src/zone/zone.h"
15 :
16 : namespace v8 {
17 : namespace internal {
18 : namespace compiler {
19 :
20 63 : std::ostream& operator<<(std::ostream& os, BranchHint hint) {
21 63 : switch (hint) {
22 : case BranchHint::kNone:
23 29 : return os << "None";
24 : case BranchHint::kTrue:
25 17 : return os << "True";
26 : case BranchHint::kFalse:
27 17 : return os << "False";
28 : }
29 0 : UNREACHABLE();
30 : }
31 :
32 :
33 5396978 : BranchHint BranchHintOf(const Operator* const op) {
34 : DCHECK_EQ(IrOpcode::kBranch, op->opcode());
35 5396978 : return OpParameter<BranchHint>(op);
36 : }
37 :
38 3496958 : int ValueInputCountOfReturn(Operator const* const op) {
39 : DCHECK_EQ(IrOpcode::kReturn, op->opcode());
40 : // Return nodes have a hidden input at index 0 which we ignore in the value
41 : // input count.
42 3496958 : return op->ValueInputCount() - 1;
43 : }
44 :
45 0 : bool operator==(DeoptimizeParameters lhs, DeoptimizeParameters rhs) {
46 0 : return lhs.kind() == rhs.kind() && lhs.reason() == rhs.reason();
47 : }
48 :
49 0 : bool operator!=(DeoptimizeParameters lhs, DeoptimizeParameters rhs) {
50 0 : return !(lhs == rhs);
51 : }
52 :
53 0 : size_t hash_value(DeoptimizeParameters p) {
54 0 : return base::hash_combine(p.kind(), p.reason());
55 : }
56 :
57 0 : std::ostream& operator<<(std::ostream& os, DeoptimizeParameters p) {
58 0 : return os << p.kind() << ":" << p.reason();
59 : }
60 :
61 1424992 : DeoptimizeParameters const& DeoptimizeParametersOf(Operator const* const op) {
62 : DCHECK(op->opcode() == IrOpcode::kDeoptimize ||
63 : op->opcode() == IrOpcode::kDeoptimizeIf ||
64 : op->opcode() == IrOpcode::kDeoptimizeUnless);
65 1424992 : return OpParameter<DeoptimizeParameters>(op);
66 : }
67 :
68 :
69 770 : bool operator==(SelectParameters const& lhs, SelectParameters const& rhs) {
70 770 : return lhs.representation() == rhs.representation() &&
71 0 : lhs.hint() == rhs.hint();
72 : }
73 :
74 :
75 0 : bool operator!=(SelectParameters const& lhs, SelectParameters const& rhs) {
76 0 : return !(lhs == rhs);
77 : }
78 :
79 :
80 35864 : size_t hash_value(SelectParameters const& p) {
81 35864 : return base::hash_combine(p.representation(), p.hint());
82 : }
83 :
84 :
85 0 : std::ostream& operator<<(std::ostream& os, SelectParameters const& p) {
86 0 : return os << p.representation() << "|" << p.hint();
87 : }
88 :
89 :
90 27894 : SelectParameters const& SelectParametersOf(const Operator* const op) {
91 : DCHECK_EQ(IrOpcode::kSelect, op->opcode());
92 27894 : return OpParameter<SelectParameters>(op);
93 : }
94 :
95 9507717 : CallDescriptor const* CallDescriptorOf(const Operator* const op) {
96 : DCHECK(op->opcode() == IrOpcode::kCall ||
97 : op->opcode() == IrOpcode::kCallWithCallerSavedRegisters ||
98 : op->opcode() == IrOpcode::kTailCall);
99 9507717 : return OpParameter<CallDescriptor const*>(op);
100 : }
101 :
102 887271 : size_t ProjectionIndexOf(const Operator* const op) {
103 : DCHECK_EQ(IrOpcode::kProjection, op->opcode());
104 887271 : return OpParameter<size_t>(op);
105 : }
106 :
107 :
108 1825054 : MachineRepresentation PhiRepresentationOf(const Operator* const op) {
109 : DCHECK_EQ(IrOpcode::kPhi, op->opcode());
110 2124449 : return OpParameter<MachineRepresentation>(op);
111 : }
112 :
113 :
114 9932803 : int ParameterIndexOf(const Operator* const op) {
115 : DCHECK_EQ(IrOpcode::kParameter, op->opcode());
116 9932803 : return OpParameter<ParameterInfo>(op).index();
117 : }
118 :
119 :
120 0 : const ParameterInfo& ParameterInfoOf(const Operator* const op) {
121 : DCHECK_EQ(IrOpcode::kParameter, op->opcode());
122 0 : return OpParameter<ParameterInfo>(op);
123 : }
124 :
125 :
126 7207689 : bool operator==(ParameterInfo const& lhs, ParameterInfo const& rhs) {
127 7207689 : return lhs.index() == rhs.index();
128 : }
129 :
130 :
131 0 : bool operator!=(ParameterInfo const& lhs, ParameterInfo const& rhs) {
132 0 : return !(lhs == rhs);
133 : }
134 :
135 :
136 10130026 : size_t hash_value(ParameterInfo const& p) { return p.index(); }
137 :
138 :
139 24 : std::ostream& operator<<(std::ostream& os, ParameterInfo const& i) {
140 12 : if (i.debug_name()) os << i.debug_name() << '#';
141 12 : os << i.index();
142 12 : return os;
143 : }
144 :
145 0 : std::ostream& operator<<(std::ostream& os, ObjectStateInfo const& i) {
146 0 : return os << "id:" << i.object_id() << "|size:" << i.size();
147 : }
148 :
149 83508 : size_t hash_value(ObjectStateInfo const& p) {
150 83508 : return base::hash_combine(p.object_id(), p.size());
151 : }
152 :
153 0 : std::ostream& operator<<(std::ostream& os, TypedObjectStateInfo const& i) {
154 0 : return os << "id:" << i.object_id() << "|" << i.machine_types();
155 : }
156 :
157 44993 : size_t hash_value(TypedObjectStateInfo const& p) {
158 44993 : return base::hash_combine(p.object_id(), p.machine_types());
159 : }
160 :
161 4 : bool operator==(RelocatablePtrConstantInfo const& lhs,
162 4 : RelocatablePtrConstantInfo const& rhs) {
163 4 : return lhs.rmode() == rhs.rmode() && lhs.value() == rhs.value() &&
164 0 : lhs.type() == rhs.type();
165 : }
166 :
167 0 : bool operator!=(RelocatablePtrConstantInfo const& lhs,
168 : RelocatablePtrConstantInfo const& rhs) {
169 0 : return !(lhs == rhs);
170 : }
171 :
172 1714 : size_t hash_value(RelocatablePtrConstantInfo const& p) {
173 1714 : return base::hash_combine(p.value(), p.rmode(), p.type());
174 : }
175 :
176 0 : std::ostream& operator<<(std::ostream& os,
177 0 : RelocatablePtrConstantInfo const& p) {
178 0 : return os << p.value() << "|" << p.rmode() << "|" << p.type();
179 : }
180 :
181 0 : SparseInputMask::InputIterator::InputIterator(
182 : SparseInputMask::BitMaskType bit_mask, Node* parent)
183 21215902 : : bit_mask_(bit_mask), parent_(parent), real_index_(0) {
184 : #if DEBUG
185 : if (bit_mask_ != SparseInputMask::kDenseBitMask) {
186 : DCHECK_EQ(base::bits::CountPopulation(bit_mask_) -
187 : base::bits::CountPopulation(kEndMarker),
188 : parent->InputCount());
189 : }
190 : #endif
191 0 : }
192 :
193 84222657 : void SparseInputMask::InputIterator::Advance() {
194 : DCHECK(!IsEnd());
195 :
196 84222657 : if (IsReal()) {
197 30225246 : ++real_index_;
198 : }
199 84222657 : bit_mask_ >>= 1;
200 84222657 : }
201 :
202 44834233 : Node* SparseInputMask::InputIterator::GetReal() const {
203 : DCHECK(IsReal());
204 89668466 : return parent_->InputAt(real_index_);
205 : }
206 :
207 177998147 : bool SparseInputMask::InputIterator::IsReal() const {
208 471540932 : return bit_mask_ == SparseInputMask::kDenseBitMask ||
209 387318275 : (bit_mask_ & kEntryMask);
210 : }
211 :
212 78427718 : bool SparseInputMask::InputIterator::IsEnd() const {
213 78427718 : return (bit_mask_ == kEndMarker) ||
214 24323716 : (bit_mask_ == SparseInputMask::kDenseBitMask &&
215 102751434 : real_index_ >= parent_->InputCount());
216 : }
217 :
218 0 : int SparseInputMask::CountReal() const {
219 : DCHECK(!IsDense());
220 0 : return base::bits::CountPopulation(bit_mask_) -
221 0 : base::bits::CountPopulation(kEndMarker);
222 : }
223 :
224 21215902 : SparseInputMask::InputIterator SparseInputMask::IterateOverInputs(Node* node) {
225 : DCHECK(IsDense() || CountReal() == node->InputCount());
226 42431804 : return InputIterator(bit_mask_, node);
227 : }
228 :
229 0 : bool operator==(SparseInputMask const& lhs, SparseInputMask const& rhs) {
230 1239046 : return lhs.mask() == rhs.mask();
231 : }
232 :
233 6016061 : bool operator!=(SparseInputMask const& lhs, SparseInputMask const& rhs) {
234 6016061 : return !(lhs == rhs);
235 : }
236 :
237 26090781 : size_t hash_value(SparseInputMask const& p) {
238 26090781 : return base::hash_value(p.mask());
239 : }
240 :
241 0 : std::ostream& operator<<(std::ostream& os, SparseInputMask const& p) {
242 0 : if (p.IsDense()) {
243 0 : return os << "dense";
244 : } else {
245 : SparseInputMask::BitMaskType mask = p.mask();
246 : DCHECK_NE(mask, SparseInputMask::kDenseBitMask);
247 :
248 0 : os << "sparse:";
249 :
250 0 : while (mask != SparseInputMask::kEndMarker) {
251 0 : if (mask & SparseInputMask::kEntryMask) {
252 0 : os << "^";
253 : } else {
254 0 : os << ".";
255 : }
256 0 : mask >>= 1;
257 : }
258 : return os;
259 : }
260 : }
261 :
262 1945524 : bool operator==(TypedStateValueInfo const& lhs,
263 1945524 : TypedStateValueInfo const& rhs) {
264 1945524 : return lhs.machine_types() == rhs.machine_types() &&
265 0 : lhs.sparse_input_mask() == rhs.sparse_input_mask();
266 : }
267 :
268 0 : bool operator!=(TypedStateValueInfo const& lhs,
269 : TypedStateValueInfo const& rhs) {
270 0 : return !(lhs == rhs);
271 : }
272 :
273 19179670 : size_t hash_value(TypedStateValueInfo const& p) {
274 19179605 : return base::hash_combine(p.machine_types(), p.sparse_input_mask());
275 : }
276 :
277 0 : std::ostream& operator<<(std::ostream& os, TypedStateValueInfo const& p) {
278 0 : return os << p.machine_types() << "|" << p.sparse_input_mask();
279 : }
280 :
281 0 : size_t hash_value(RegionObservability observability) {
282 0 : return static_cast<size_t>(observability);
283 : }
284 :
285 0 : std::ostream& operator<<(std::ostream& os, RegionObservability observability) {
286 0 : switch (observability) {
287 : case RegionObservability::kObservable:
288 0 : return os << "observable";
289 : case RegionObservability::kNotObservable:
290 0 : return os << "not-observable";
291 : }
292 0 : UNREACHABLE();
293 : }
294 :
295 111808 : RegionObservability RegionObservabilityOf(Operator const* op) {
296 : DCHECK_EQ(IrOpcode::kBeginRegion, op->opcode());
297 111808 : return OpParameter<RegionObservability>(op);
298 : }
299 :
300 45233 : Type* TypeGuardTypeOf(Operator const* op) {
301 : DCHECK_EQ(IrOpcode::kTypeGuard, op->opcode());
302 45233 : return OpParameter<Type*>(op);
303 : }
304 :
305 0 : std::ostream& operator<<(std::ostream& os,
306 : const ZoneVector<MachineType>* types) {
307 : // Print all the MachineTypes, separated by commas.
308 : bool first = true;
309 0 : for (MachineType elem : *types) {
310 0 : if (!first) {
311 0 : os << ", ";
312 : }
313 : first = false;
314 0 : os << elem;
315 : }
316 0 : return os;
317 : }
318 :
319 24445 : int OsrValueIndexOf(Operator const* op) {
320 : DCHECK_EQ(IrOpcode::kOsrValue, op->opcode());
321 24445 : return OpParameter<int>(op);
322 : }
323 :
324 30027217 : SparseInputMask SparseInputMaskOf(Operator const* op) {
325 : DCHECK(op->opcode() == IrOpcode::kStateValues ||
326 : op->opcode() == IrOpcode::kTypedStateValues);
327 :
328 30027217 : if (op->opcode() == IrOpcode::kTypedStateValues) {
329 : return OpParameter<TypedStateValueInfo>(op).sparse_input_mask();
330 : }
331 8819084 : return OpParameter<SparseInputMask>(op);
332 : }
333 :
334 14618423 : ZoneVector<MachineType> const* MachineTypesOf(Operator const* op) {
335 : DCHECK(op->opcode() == IrOpcode::kTypedObjectState ||
336 : op->opcode() == IrOpcode::kTypedStateValues);
337 :
338 14618423 : if (op->opcode() == IrOpcode::kTypedStateValues) {
339 14561293 : return OpParameter<TypedStateValueInfo>(op).machine_types();
340 : }
341 57130 : return OpParameter<TypedObjectStateInfo>(op).machine_types();
342 : }
343 :
344 : #define COMMON_CACHED_OP_LIST(V) \
345 : V(Dead, Operator::kFoldable, 0, 0, 0, 1, 1, 1) \
346 : V(IfTrue, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \
347 : V(IfFalse, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \
348 : V(IfSuccess, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \
349 : V(IfException, Operator::kKontrol, 0, 1, 1, 1, 1, 1) \
350 : V(IfDefault, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \
351 : V(Throw, Operator::kKontrol, 0, 1, 1, 0, 0, 1) \
352 : V(Terminate, Operator::kKontrol, 0, 1, 1, 0, 0, 1) \
353 : V(OsrNormalEntry, Operator::kFoldable, 0, 1, 1, 0, 1, 1) \
354 : V(OsrLoopEntry, Operator::kFoldable | Operator::kNoThrow, 0, 1, 1, 0, 1, 1) \
355 : V(LoopExit, Operator::kKontrol, 0, 0, 2, 0, 0, 1) \
356 : V(LoopExitValue, Operator::kPure, 1, 0, 1, 1, 0, 0) \
357 : V(LoopExitEffect, Operator::kNoThrow, 0, 1, 1, 0, 1, 0) \
358 : V(Checkpoint, Operator::kKontrol, 0, 1, 1, 0, 1, 0) \
359 : V(FinishRegion, Operator::kKontrol, 1, 1, 0, 1, 1, 0) \
360 : V(Retain, Operator::kKontrol, 1, 1, 0, 0, 1, 0)
361 :
362 : #define CACHED_RETURN_LIST(V) \
363 : V(1) \
364 : V(2) \
365 : V(3) \
366 : V(4)
367 :
368 : #define CACHED_END_LIST(V) \
369 : V(1) \
370 : V(2) \
371 : V(3) \
372 : V(4) \
373 : V(5) \
374 : V(6) \
375 : V(7) \
376 : V(8)
377 :
378 :
379 : #define CACHED_EFFECT_PHI_LIST(V) \
380 : V(1) \
381 : V(2) \
382 : V(3) \
383 : V(4) \
384 : V(5) \
385 : V(6)
386 :
387 : #define CACHED_INDUCTION_VARIABLE_PHI_LIST(V) \
388 : V(4) \
389 : V(5) \
390 : V(6) \
391 : V(7)
392 :
393 : #define CACHED_LOOP_LIST(V) \
394 : V(1) \
395 : V(2)
396 :
397 :
398 : #define CACHED_MERGE_LIST(V) \
399 : V(1) \
400 : V(2) \
401 : V(3) \
402 : V(4) \
403 : V(5) \
404 : V(6) \
405 : V(7) \
406 : V(8)
407 :
408 : #define CACHED_DEOPTIMIZE_LIST(V) \
409 : V(Eager, MinusZero) \
410 : V(Eager, NoReason) \
411 : V(Eager, WrongMap) \
412 : V(Soft, InsufficientTypeFeedbackForGenericKeyedAccess) \
413 : V(Soft, InsufficientTypeFeedbackForGenericNamedAccess)
414 :
415 : #define CACHED_DEOPTIMIZE_IF_LIST(V) \
416 : V(Eager, DivisionByZero) \
417 : V(Eager, Hole) \
418 : V(Eager, MinusZero) \
419 : V(Eager, Overflow) \
420 : V(Eager, Smi)
421 :
422 : #define CACHED_DEOPTIMIZE_UNLESS_LIST(V) \
423 : V(Eager, LostPrecision) \
424 : V(Eager, LostPrecisionOrNaN) \
425 : V(Eager, NoReason) \
426 : V(Eager, NotAHeapNumber) \
427 : V(Eager, NotANumberOrOddball) \
428 : V(Eager, NotASmi) \
429 : V(Eager, OutOfBounds) \
430 : V(Eager, WrongInstanceType) \
431 : V(Eager, WrongMap)
432 :
433 : #define CACHED_TRAP_IF_LIST(V) \
434 : V(TrapDivUnrepresentable) \
435 : V(TrapFloatUnrepresentable)
436 :
437 : // The reason for a trap.
438 : #define CACHED_TRAP_UNLESS_LIST(V) \
439 : V(TrapUnreachable) \
440 : V(TrapMemOutOfBounds) \
441 : V(TrapDivByZero) \
442 : V(TrapDivUnrepresentable) \
443 : V(TrapRemByZero) \
444 : V(TrapFloatUnrepresentable) \
445 : V(TrapFuncInvalid) \
446 : V(TrapFuncSigMismatch)
447 :
448 : #define CACHED_PARAMETER_LIST(V) \
449 : V(0) \
450 : V(1) \
451 : V(2) \
452 : V(3) \
453 : V(4) \
454 : V(5) \
455 : V(6)
456 :
457 :
458 : #define CACHED_PHI_LIST(V) \
459 : V(kTagged, 1) \
460 : V(kTagged, 2) \
461 : V(kTagged, 3) \
462 : V(kTagged, 4) \
463 : V(kTagged, 5) \
464 : V(kTagged, 6) \
465 : V(kBit, 2) \
466 : V(kFloat64, 2) \
467 : V(kWord32, 2)
468 :
469 :
470 : #define CACHED_PROJECTION_LIST(V) \
471 : V(0) \
472 : V(1)
473 :
474 :
475 : #define CACHED_STATE_VALUES_LIST(V) \
476 : V(0) \
477 : V(1) \
478 : V(2) \
479 : V(3) \
480 : V(4) \
481 : V(5) \
482 : V(6) \
483 : V(7) \
484 : V(8) \
485 : V(10) \
486 : V(11) \
487 : V(12) \
488 : V(13) \
489 : V(14)
490 :
491 :
492 28407 : struct CommonOperatorGlobalCache final {
493 : #define CACHED(Name, properties, value_input_count, effect_input_count, \
494 : control_input_count, value_output_count, effect_output_count, \
495 : control_output_count) \
496 : struct Name##Operator final : public Operator { \
497 : Name##Operator() \
498 : : Operator(IrOpcode::k##Name, properties, #Name, value_input_count, \
499 : effect_input_count, control_input_count, \
500 : value_output_count, effect_output_count, \
501 : control_output_count) {} \
502 : }; \
503 : Name##Operator k##Name##Operator;
504 880617 : COMMON_CACHED_OP_LIST(CACHED)
505 : #undef CACHED
506 :
507 : template <size_t kInputCount>
508 0 : struct EndOperator final : public Operator {
509 227256 : EndOperator()
510 : : Operator( // --
511 : IrOpcode::kEnd, Operator::kKontrol, // opcode
512 : "End", // name
513 227256 : 0, 0, kInputCount, 0, 0, 0) {} // counts
514 : };
515 : #define CACHED_END(input_count) \
516 : EndOperator<input_count> kEnd##input_count##Operator;
517 : CACHED_END_LIST(CACHED_END)
518 : #undef CACHED_END
519 :
520 : template <size_t kValueInputCount>
521 0 : struct ReturnOperator final : public Operator {
522 113628 : ReturnOperator()
523 : : Operator( // --
524 : IrOpcode::kReturn, Operator::kNoThrow, // opcode
525 : "Return", // name
526 113628 : kValueInputCount + 1, 1, 1, 0, 0, 1) {} // counts
527 : };
528 : #define CACHED_RETURN(value_input_count) \
529 : ReturnOperator<value_input_count> kReturn##value_input_count##Operator;
530 : CACHED_RETURN_LIST(CACHED_RETURN)
531 : #undef CACHED_RETURN
532 :
533 : template <BranchHint kBranchHint>
534 0 : struct BranchOperator final : public Operator1<BranchHint> {
535 85221 : BranchOperator()
536 : : Operator1<BranchHint>( // --
537 : IrOpcode::kBranch, Operator::kKontrol, // opcode
538 : "Branch", // name
539 : 1, 0, 1, 0, 0, 2, // counts
540 85221 : kBranchHint) {} // parameter
541 : };
542 : BranchOperator<BranchHint::kNone> kBranchNoneOperator;
543 : BranchOperator<BranchHint::kTrue> kBranchTrueOperator;
544 : BranchOperator<BranchHint::kFalse> kBranchFalseOperator;
545 :
546 : template <int kEffectInputCount>
547 0 : struct EffectPhiOperator final : public Operator {
548 170442 : EffectPhiOperator()
549 : : Operator( // --
550 : IrOpcode::kEffectPhi, Operator::kKontrol, // opcode
551 : "EffectPhi", // name
552 170442 : 0, kEffectInputCount, 1, 0, 1, 0) {} // counts
553 : };
554 : #define CACHED_EFFECT_PHI(input_count) \
555 : EffectPhiOperator<input_count> kEffectPhi##input_count##Operator;
556 : CACHED_EFFECT_PHI_LIST(CACHED_EFFECT_PHI)
557 : #undef CACHED_EFFECT_PHI
558 :
559 : template <RegionObservability kRegionObservability>
560 0 : struct BeginRegionOperator final : public Operator1<RegionObservability> {
561 56814 : BeginRegionOperator()
562 : : Operator1<RegionObservability>( // --
563 : IrOpcode::kBeginRegion, Operator::kKontrol, // opcode
564 : "BeginRegion", // name
565 : 0, 1, 0, 0, 1, 0, // counts
566 56814 : kRegionObservability) {} // parameter
567 : };
568 : BeginRegionOperator<RegionObservability::kObservable>
569 : kBeginRegionObservableOperator;
570 : BeginRegionOperator<RegionObservability::kNotObservable>
571 : kBeginRegionNotObservableOperator;
572 :
573 : template <size_t kInputCount>
574 0 : struct LoopOperator final : public Operator {
575 56814 : LoopOperator()
576 : : Operator( // --
577 : IrOpcode::kLoop, Operator::kKontrol, // opcode
578 : "Loop", // name
579 56814 : 0, 0, kInputCount, 0, 0, 1) {} // counts
580 : };
581 : #define CACHED_LOOP(input_count) \
582 : LoopOperator<input_count> kLoop##input_count##Operator;
583 : CACHED_LOOP_LIST(CACHED_LOOP)
584 : #undef CACHED_LOOP
585 :
586 : template <size_t kInputCount>
587 0 : struct MergeOperator final : public Operator {
588 227256 : MergeOperator()
589 : : Operator( // --
590 : IrOpcode::kMerge, Operator::kKontrol, // opcode
591 : "Merge", // name
592 227256 : 0, 0, kInputCount, 0, 0, 1) {} // counts
593 : };
594 : #define CACHED_MERGE(input_count) \
595 : MergeOperator<input_count> kMerge##input_count##Operator;
596 : CACHED_MERGE_LIST(CACHED_MERGE)
597 : #undef CACHED_MERGE
598 :
599 : template <DeoptimizeKind kKind, DeoptimizeReason kReason>
600 0 : struct DeoptimizeOperator final : public Operator1<DeoptimizeParameters> {
601 142035 : DeoptimizeOperator()
602 : : Operator1<DeoptimizeParameters>( // --
603 : IrOpcode::kDeoptimize, // opcode
604 : Operator::kFoldable | Operator::kNoThrow, // properties
605 : "Deoptimize", // name
606 : 1, 1, 1, 0, 0, 1, // counts
607 142035 : DeoptimizeParameters(kKind, kReason)) {} // parameter
608 : };
609 : #define CACHED_DEOPTIMIZE(Kind, Reason) \
610 : DeoptimizeOperator<DeoptimizeKind::k##Kind, DeoptimizeReason::k##Reason> \
611 : kDeoptimize##Kind##Reason##Operator;
612 : CACHED_DEOPTIMIZE_LIST(CACHED_DEOPTIMIZE)
613 : #undef CACHED_DEOPTIMIZE
614 :
615 : template <DeoptimizeKind kKind, DeoptimizeReason kReason>
616 0 : struct DeoptimizeIfOperator final : public Operator1<DeoptimizeParameters> {
617 142035 : DeoptimizeIfOperator()
618 : : Operator1<DeoptimizeParameters>( // --
619 : IrOpcode::kDeoptimizeIf, // opcode
620 : Operator::kFoldable | Operator::kNoThrow, // properties
621 : "DeoptimizeIf", // name
622 : 2, 1, 1, 0, 1, 1, // counts
623 142035 : DeoptimizeParameters(kKind, kReason)) {} // parameter
624 : };
625 : #define CACHED_DEOPTIMIZE_IF(Kind, Reason) \
626 : DeoptimizeIfOperator<DeoptimizeKind::k##Kind, DeoptimizeReason::k##Reason> \
627 : kDeoptimizeIf##Kind##Reason##Operator;
628 : CACHED_DEOPTIMIZE_IF_LIST(CACHED_DEOPTIMIZE_IF)
629 : #undef CACHED_DEOPTIMIZE_IF
630 :
631 : template <DeoptimizeKind kKind, DeoptimizeReason kReason>
632 0 : struct DeoptimizeUnlessOperator final
633 : : public Operator1<DeoptimizeParameters> {
634 255663 : DeoptimizeUnlessOperator()
635 : : Operator1<DeoptimizeParameters>( // --
636 : IrOpcode::kDeoptimizeUnless, // opcode
637 : Operator::kFoldable | Operator::kNoThrow, // properties
638 : "DeoptimizeUnless", // name
639 : 2, 1, 1, 0, 1, 1, // counts
640 255663 : DeoptimizeParameters(kKind, kReason)) {} // parameter
641 : };
642 : #define CACHED_DEOPTIMIZE_UNLESS(Kind, Reason) \
643 : DeoptimizeUnlessOperator<DeoptimizeKind::k##Kind, \
644 : DeoptimizeReason::k##Reason> \
645 : kDeoptimizeUnless##Kind##Reason##Operator;
646 : CACHED_DEOPTIMIZE_UNLESS_LIST(CACHED_DEOPTIMIZE_UNLESS)
647 : #undef CACHED_DEOPTIMIZE_UNLESS
648 :
649 : template <int32_t trap_id>
650 0 : struct TrapIfOperator final : public Operator1<int32_t> {
651 56814 : TrapIfOperator()
652 : : Operator1<int32_t>( // --
653 : IrOpcode::kTrapIf, // opcode
654 : Operator::kFoldable | Operator::kNoThrow, // properties
655 : "TrapIf", // name
656 : 1, 1, 1, 0, 0, 1, // counts
657 56814 : trap_id) {} // parameter
658 : };
659 : #define CACHED_TRAP_IF(Trap) \
660 : TrapIfOperator<static_cast<int32_t>(Builtins::kThrowWasm##Trap)> \
661 : kTrapIf##Trap##Operator;
662 : CACHED_TRAP_IF_LIST(CACHED_TRAP_IF)
663 : #undef CACHED_TRAP_IF
664 :
665 : template <int32_t trap_id>
666 0 : struct TrapUnlessOperator final : public Operator1<int32_t> {
667 227256 : TrapUnlessOperator()
668 : : Operator1<int32_t>( // --
669 : IrOpcode::kTrapUnless, // opcode
670 : Operator::kFoldable | Operator::kNoThrow, // properties
671 : "TrapUnless", // name
672 : 1, 1, 1, 0, 0, 1, // counts
673 227256 : trap_id) {} // parameter
674 : };
675 : #define CACHED_TRAP_UNLESS(Trap) \
676 : TrapUnlessOperator<static_cast<int32_t>(Builtins::kThrowWasm##Trap)> \
677 : kTrapUnless##Trap##Operator;
678 : CACHED_TRAP_UNLESS_LIST(CACHED_TRAP_UNLESS)
679 : #undef CACHED_TRAP_UNLESS
680 :
681 : template <MachineRepresentation kRep, int kInputCount>
682 0 : struct PhiOperator final : public Operator1<MachineRepresentation> {
683 255663 : PhiOperator()
684 : : Operator1<MachineRepresentation>( //--
685 : IrOpcode::kPhi, Operator::kPure, // opcode
686 : "Phi", // name
687 : kInputCount, 0, 1, 1, 0, 0, // counts
688 255663 : kRep) {} // parameter
689 : };
690 : #define CACHED_PHI(rep, input_count) \
691 : PhiOperator<MachineRepresentation::rep, input_count> \
692 : kPhi##rep##input_count##Operator;
693 : CACHED_PHI_LIST(CACHED_PHI)
694 : #undef CACHED_PHI
695 :
696 : template <int kInputCount>
697 0 : struct InductionVariablePhiOperator final : public Operator {
698 113628 : InductionVariablePhiOperator()
699 : : Operator( //--
700 : IrOpcode::kInductionVariablePhi, Operator::kPure, // opcode
701 : "InductionVariablePhi", // name
702 113628 : kInputCount, 0, 1, 1, 0, 0) {} // counts
703 : };
704 : #define CACHED_INDUCTION_VARIABLE_PHI(input_count) \
705 : InductionVariablePhiOperator<input_count> \
706 : kInductionVariablePhi##input_count##Operator;
707 : CACHED_INDUCTION_VARIABLE_PHI_LIST(CACHED_INDUCTION_VARIABLE_PHI)
708 : #undef CACHED_INDUCTION_VARIABLE_PHI
709 :
710 : template <int kIndex>
711 0 : struct ParameterOperator final : public Operator1<ParameterInfo> {
712 198849 : ParameterOperator()
713 : : Operator1<ParameterInfo>( // --
714 : IrOpcode::kParameter, Operator::kPure, // opcode
715 : "Parameter", // name
716 : 1, 0, 0, 1, 0, 0, // counts,
717 198849 : ParameterInfo(kIndex, nullptr)) {} // parameter and name
718 : };
719 : #define CACHED_PARAMETER(index) \
720 : ParameterOperator<index> kParameter##index##Operator;
721 : CACHED_PARAMETER_LIST(CACHED_PARAMETER)
722 : #undef CACHED_PARAMETER
723 :
724 : template <size_t kIndex>
725 0 : struct ProjectionOperator final : public Operator1<size_t> {
726 56814 : ProjectionOperator()
727 : : Operator1<size_t>( // --
728 : IrOpcode::kProjection, // opcode
729 : Operator::kPure, // flags
730 : "Projection", // name
731 : 1, 0, 1, 1, 0, 0, // counts,
732 56814 : kIndex) {} // parameter
733 : };
734 : #define CACHED_PROJECTION(index) \
735 : ProjectionOperator<index> kProjection##index##Operator;
736 : CACHED_PROJECTION_LIST(CACHED_PROJECTION)
737 : #undef CACHED_PROJECTION
738 :
739 : template <int kInputCount>
740 0 : struct StateValuesOperator final : public Operator1<SparseInputMask> {
741 397698 : StateValuesOperator()
742 : : Operator1<SparseInputMask>( // --
743 : IrOpcode::kStateValues, // opcode
744 : Operator::kPure, // flags
745 : "StateValues", // name
746 : kInputCount, 0, 0, 1, 0, 0, // counts
747 397698 : SparseInputMask::Dense()) {} // parameter
748 : };
749 : #define CACHED_STATE_VALUES(input_count) \
750 : StateValuesOperator<input_count> kStateValues##input_count##Operator;
751 : CACHED_STATE_VALUES_LIST(CACHED_STATE_VALUES)
752 : #undef CACHED_STATE_VALUES
753 : };
754 :
755 : static base::LazyInstance<CommonOperatorGlobalCache>::type
756 : kCommonOperatorGlobalCache = LAZY_INSTANCE_INITIALIZER;
757 :
758 1569682 : CommonOperatorBuilder::CommonOperatorBuilder(Zone* zone)
759 1569683 : : cache_(kCommonOperatorGlobalCache.Get()), zone_(zone) {}
760 :
761 : #define CACHED(Name, properties, value_input_count, effect_input_count, \
762 : control_input_count, value_output_count, effect_output_count, \
763 : control_output_count) \
764 : const Operator* CommonOperatorBuilder::Name() { \
765 : return &cache_.k##Name##Operator; \
766 : }
767 18727492 : COMMON_CACHED_OP_LIST(CACHED)
768 : #undef CACHED
769 :
770 :
771 2368637 : const Operator* CommonOperatorBuilder::End(size_t control_input_count) {
772 1982594 : switch (control_input_count) {
773 : #define CACHED_END(input_count) \
774 : case input_count: \
775 : return &cache_.kEnd##input_count##Operator;
776 1145435 : CACHED_END_LIST(CACHED_END)
777 : #undef CACHED_END
778 : default:
779 : break;
780 : }
781 : // Uncached.
782 : return new (zone()) Operator( //--
783 : IrOpcode::kEnd, Operator::kKontrol, // opcode
784 : "End", // name
785 386043 : 0, 0, control_input_count, 0, 0, 0); // counts
786 : }
787 :
788 2008783 : const Operator* CommonOperatorBuilder::Return(int value_input_count) {
789 1733657 : switch (value_input_count) {
790 : #define CACHED_RETURN(input_count) \
791 : case input_count: \
792 : return &cache_.kReturn##input_count##Operator;
793 1456946 : CACHED_RETURN_LIST(CACHED_RETURN)
794 : #undef CACHED_RETURN
795 : default:
796 : break;
797 : }
798 : // Uncached.
799 : return new (zone()) Operator( //--
800 : IrOpcode::kReturn, Operator::kNoThrow, // opcode
801 : "Return", // name
802 275141 : value_input_count + 1, 1, 1, 0, 0, 1); // counts
803 : }
804 :
805 :
806 4118890 : const Operator* CommonOperatorBuilder::Branch(BranchHint hint) {
807 4118890 : switch (hint) {
808 : case BranchHint::kNone:
809 2722870 : return &cache_.kBranchNoneOperator;
810 : case BranchHint::kTrue:
811 863047 : return &cache_.kBranchTrueOperator;
812 : case BranchHint::kFalse:
813 532973 : return &cache_.kBranchFalseOperator;
814 : }
815 0 : UNREACHABLE();
816 : }
817 :
818 75966 : const Operator* CommonOperatorBuilder::Deoptimize(DeoptimizeKind kind,
819 57339 : DeoptimizeReason reason) {
820 : #define CACHED_DEOPTIMIZE(Kind, Reason) \
821 : if (kind == DeoptimizeKind::k##Kind && \
822 : reason == DeoptimizeReason::k##Reason) { \
823 : return &cache_.kDeoptimize##Kind##Reason##Operator; \
824 : }
825 75966 : CACHED_DEOPTIMIZE_LIST(CACHED_DEOPTIMIZE)
826 : #undef CACHED_DEOPTIMIZE
827 : // Uncached
828 : DeoptimizeParameters parameter(kind, reason);
829 : return new (zone()) Operator1<DeoptimizeParameters>( // --
830 : IrOpcode::kDeoptimize, // opcodes
831 : Operator::kFoldable | Operator::kNoThrow, // properties
832 : "Deoptimize", // name
833 : 1, 1, 1, 0, 0, 1, // counts
834 : parameter); // parameter
835 : }
836 :
837 127050 : const Operator* CommonOperatorBuilder::DeoptimizeIf(DeoptimizeKind kind,
838 1545 : DeoptimizeReason reason) {
839 : #define CACHED_DEOPTIMIZE_IF(Kind, Reason) \
840 : if (kind == DeoptimizeKind::k##Kind && \
841 : reason == DeoptimizeReason::k##Reason) { \
842 : return &cache_.kDeoptimizeIf##Kind##Reason##Operator; \
843 : }
844 127050 : CACHED_DEOPTIMIZE_IF_LIST(CACHED_DEOPTIMIZE_IF)
845 : #undef CACHED_DEOPTIMIZE_IF
846 : // Uncached
847 : DeoptimizeParameters parameter(kind, reason);
848 : return new (zone()) Operator1<DeoptimizeParameters>( // --
849 : IrOpcode::kDeoptimizeIf, // opcode
850 : Operator::kFoldable | Operator::kNoThrow, // properties
851 : "DeoptimizeIf", // name
852 : 2, 1, 1, 0, 1, 1, // counts
853 : parameter); // parameter
854 : }
855 :
856 198381 : const Operator* CommonOperatorBuilder::DeoptimizeUnless(
857 3453 : DeoptimizeKind kind, DeoptimizeReason reason) {
858 : #define CACHED_DEOPTIMIZE_UNLESS(Kind, Reason) \
859 : if (kind == DeoptimizeKind::k##Kind && \
860 : reason == DeoptimizeReason::k##Reason) { \
861 : return &cache_.kDeoptimizeUnless##Kind##Reason##Operator; \
862 : }
863 198381 : CACHED_DEOPTIMIZE_UNLESS_LIST(CACHED_DEOPTIMIZE_UNLESS)
864 : #undef CACHED_DEOPTIMIZE_UNLESS
865 : // Uncached
866 : DeoptimizeParameters parameter(kind, reason);
867 : return new (zone()) Operator1<DeoptimizeParameters>( // --
868 : IrOpcode::kDeoptimizeUnless, // opcode
869 : Operator::kFoldable | Operator::kNoThrow, // properties
870 : "DeoptimizeUnless", // name
871 : 2, 1, 1, 0, 1, 1, // counts
872 : parameter); // parameter
873 : }
874 :
875 3319 : const Operator* CommonOperatorBuilder::TrapIf(int32_t trap_id) {
876 1976 : switch (trap_id) {
877 : #define CACHED_TRAP_IF(Trap) \
878 : case Builtins::kThrowWasm##Trap: \
879 : return &cache_.kTrapIf##Trap##Operator;
880 250 : CACHED_TRAP_IF_LIST(CACHED_TRAP_IF)
881 : #undef CACHED_TRAP_IF
882 : default:
883 : break;
884 : }
885 : // Uncached
886 : return new (zone()) Operator1<int>( // --
887 : IrOpcode::kTrapIf, // opcode
888 : Operator::kFoldable | Operator::kNoThrow, // properties
889 : "TrapIf", // name
890 : 1, 1, 1, 0, 0, 1, // counts
891 : trap_id); // parameter
892 : }
893 :
894 230339 : const Operator* CommonOperatorBuilder::TrapUnless(int32_t trap_id) {
895 196467 : switch (trap_id) {
896 : #define CACHED_TRAP_UNLESS(Trap) \
897 : case Builtins::kThrowWasm##Trap: \
898 : return &cache_.kTrapUnless##Trap##Operator;
899 129911 : CACHED_TRAP_UNLESS_LIST(CACHED_TRAP_UNLESS)
900 : #undef CACHED_TRAP_UNLESS
901 : default:
902 : break;
903 : }
904 : // Uncached
905 : return new (zone()) Operator1<int>( // --
906 : IrOpcode::kTrapUnless, // opcode
907 : Operator::kFoldable | Operator::kNoThrow, // properties
908 : "TrapUnless", // name
909 : 1, 1, 1, 0, 0, 1, // counts
910 : trap_id); // parameter
911 : }
912 :
913 49186 : const Operator* CommonOperatorBuilder::Switch(size_t control_output_count) {
914 : return new (zone()) Operator( // --
915 : IrOpcode::kSwitch, Operator::kKontrol, // opcode
916 : "Switch", // name
917 24593 : 1, 0, 1, 0, 0, control_output_count); // counts
918 : }
919 :
920 :
921 336119 : const Operator* CommonOperatorBuilder::IfValue(int32_t index) {
922 : return new (zone()) Operator1<int32_t>( // --
923 : IrOpcode::kIfValue, Operator::kKontrol, // opcode
924 : "IfValue", // name
925 : 0, 0, 1, 0, 0, 1, // counts
926 336119 : index); // parameter
927 : }
928 :
929 :
930 3100516 : const Operator* CommonOperatorBuilder::Start(int value_output_count) {
931 : return new (zone()) Operator( // --
932 3100561 : IrOpcode::kStart, Operator::kFoldable | Operator::kNoThrow, // opcode
933 : "Start", // name
934 3100589 : 0, 0, 0, value_output_count, 1, 1); // counts
935 : }
936 :
937 :
938 702639 : const Operator* CommonOperatorBuilder::Loop(int control_input_count) {
939 701585 : switch (control_input_count) {
940 : #define CACHED_LOOP(input_count) \
941 : case input_count: \
942 : return &cache_.kLoop##input_count##Operator;
943 56081 : CACHED_LOOP_LIST(CACHED_LOOP)
944 : #undef CACHED_LOOP
945 : default:
946 : break;
947 : }
948 : // Uncached.
949 : return new (zone()) Operator( // --
950 : IrOpcode::kLoop, Operator::kKontrol, // opcode
951 : "Loop", // name
952 1054 : 0, 0, control_input_count, 0, 0, 1); // counts
953 : }
954 :
955 :
956 3897067 : const Operator* CommonOperatorBuilder::Merge(int control_input_count) {
957 3554036 : switch (control_input_count) {
958 : #define CACHED_MERGE(input_count) \
959 : case input_count: \
960 : return &cache_.kMerge##input_count##Operator;
961 669352 : CACHED_MERGE_LIST(CACHED_MERGE)
962 : #undef CACHED_MERGE
963 : default:
964 : break;
965 : }
966 : // Uncached.
967 : return new (zone()) Operator( // --
968 : IrOpcode::kMerge, Operator::kKontrol, // opcode
969 : "Merge", // name
970 343031 : 0, 0, control_input_count, 0, 0, 1); // counts
971 : }
972 :
973 :
974 4615020 : const Operator* CommonOperatorBuilder::Parameter(int index,
975 2756053 : const char* debug_name) {
976 4615020 : if (!debug_name) {
977 2920972 : switch (index) {
978 : #define CACHED_PARAMETER(index) \
979 : case index: \
980 : return &cache_.kParameter##index##Operator;
981 610480 : CACHED_PARAMETER_LIST(CACHED_PARAMETER)
982 : #undef CACHED_PARAMETER
983 : default:
984 : break;
985 : }
986 : }
987 : // Uncached.
988 : return new (zone()) Operator1<ParameterInfo>( // --
989 : IrOpcode::kParameter, Operator::kPure, // opcode
990 : "Parameter", // name
991 : 1, 0, 0, 1, 0, 0, // counts
992 : ParameterInfo(index, debug_name)); // parameter info
993 : }
994 :
995 52280 : const Operator* CommonOperatorBuilder::OsrValue(int index) {
996 : return new (zone()) Operator1<int>( // --
997 : IrOpcode::kOsrValue, Operator::kNoProperties, // opcode
998 : "OsrValue", // name
999 : 0, 0, 1, 1, 0, 0, // counts
1000 52280 : index); // parameter
1001 : }
1002 :
1003 7162667 : const Operator* CommonOperatorBuilder::Int32Constant(int32_t value) {
1004 : return new (zone()) Operator1<int32_t>( // --
1005 : IrOpcode::kInt32Constant, Operator::kPure, // opcode
1006 : "Int32Constant", // name
1007 : 0, 0, 0, 1, 0, 0, // counts
1008 7162832 : value); // parameter
1009 : }
1010 :
1011 :
1012 5828783 : const Operator* CommonOperatorBuilder::Int64Constant(int64_t value) {
1013 : return new (zone()) Operator1<int64_t>( // --
1014 : IrOpcode::kInt64Constant, Operator::kPure, // opcode
1015 : "Int64Constant", // name
1016 : 0, 0, 0, 1, 0, 0, // counts
1017 5828818 : value); // parameter
1018 : }
1019 :
1020 :
1021 755542 : const Operator* CommonOperatorBuilder::Float32Constant(volatile float value) {
1022 : return new (zone()) Operator1<float>( // --
1023 : IrOpcode::kFloat32Constant, Operator::kPure, // opcode
1024 : "Float32Constant", // name
1025 : 0, 0, 0, 1, 0, 0, // counts
1026 755546 : value); // parameter
1027 : }
1028 :
1029 :
1030 839682 : const Operator* CommonOperatorBuilder::Float64Constant(volatile double value) {
1031 : return new (zone()) Operator1<double>( // --
1032 : IrOpcode::kFloat64Constant, Operator::kPure, // opcode
1033 : "Float64Constant", // name
1034 : 0, 0, 0, 1, 0, 0, // counts
1035 839683 : value); // parameter
1036 : }
1037 :
1038 :
1039 1565820 : const Operator* CommonOperatorBuilder::ExternalConstant(
1040 1565820 : const ExternalReference& value) {
1041 : return new (zone()) Operator1<ExternalReference>( // --
1042 : IrOpcode::kExternalConstant, Operator::kPure, // opcode
1043 : "ExternalConstant", // name
1044 : 0, 0, 0, 1, 0, 0, // counts
1045 3131709 : value); // parameter
1046 : }
1047 :
1048 :
1049 7080264 : const Operator* CommonOperatorBuilder::NumberConstant(volatile double value) {
1050 : return new (zone()) Operator1<double>( // --
1051 : IrOpcode::kNumberConstant, Operator::kPure, // opcode
1052 : "NumberConstant", // name
1053 : 0, 0, 0, 1, 0, 0, // counts
1054 7080268 : value); // parameter
1055 : }
1056 :
1057 894 : const Operator* CommonOperatorBuilder::PointerConstant(intptr_t value) {
1058 : return new (zone()) Operator1<intptr_t>( // --
1059 : IrOpcode::kPointerConstant, Operator::kPure, // opcode
1060 : "PointerConstant", // name
1061 : 0, 0, 0, 1, 0, 0, // counts
1062 894 : value); // parameter
1063 : }
1064 :
1065 12268158 : const Operator* CommonOperatorBuilder::HeapConstant(
1066 12268158 : const Handle<HeapObject>& value) {
1067 : return new (zone()) Operator1<Handle<HeapObject>>( // --
1068 : IrOpcode::kHeapConstant, Operator::kPure, // opcode
1069 : "HeapConstant", // name
1070 : 0, 0, 0, 1, 0, 0, // counts
1071 24536368 : value); // parameter
1072 : }
1073 :
1074 2334 : const Operator* CommonOperatorBuilder::RelocatableInt32Constant(
1075 2334 : int32_t value, RelocInfo::Mode rmode) {
1076 : return new (zone()) Operator1<RelocatablePtrConstantInfo>( // --
1077 : IrOpcode::kRelocatableInt32Constant, Operator::kPure, // opcode
1078 : "RelocatableInt32Constant", // name
1079 : 0, 0, 0, 1, 0, 0, // counts
1080 2334 : RelocatablePtrConstantInfo(value, rmode)); // parameter
1081 : }
1082 :
1083 3680580 : const Operator* CommonOperatorBuilder::RelocatableInt64Constant(
1084 3680580 : int64_t value, RelocInfo::Mode rmode) {
1085 : return new (zone()) Operator1<RelocatablePtrConstantInfo>( // --
1086 : IrOpcode::kRelocatableInt64Constant, Operator::kPure, // opcode
1087 : "RelocatableInt64Constant", // name
1088 : 0, 0, 0, 1, 0, 0, // counts
1089 3680580 : RelocatablePtrConstantInfo(value, rmode)); // parameter
1090 : }
1091 :
1092 3510 : const Operator* CommonOperatorBuilder::ObjectId(uint32_t object_id) {
1093 : return new (zone()) Operator1<uint32_t>( // --
1094 : IrOpcode::kObjectId, Operator::kPure, // opcode
1095 : "ObjectId", // name
1096 : 0, 0, 0, 1, 0, 0, // counts
1097 3510 : object_id); // parameter
1098 : }
1099 :
1100 26437 : const Operator* CommonOperatorBuilder::Select(MachineRepresentation rep,
1101 26437 : BranchHint hint) {
1102 : return new (zone()) Operator1<SelectParameters>( // --
1103 : IrOpcode::kSelect, Operator::kPure, // opcode
1104 : "Select", // name
1105 : 3, 0, 0, 1, 0, 0, // counts
1106 26437 : SelectParameters(rep, hint)); // parameter
1107 : }
1108 :
1109 :
1110 3554236 : const Operator* CommonOperatorBuilder::Phi(MachineRepresentation rep,
1111 1120769 : int value_input_count) {
1112 : DCHECK_LT(0, value_input_count); // Disallow empty phis.
1113 : #define CACHED_PHI(kRep, kValueInputCount) \
1114 : if (MachineRepresentation::kRep == rep && \
1115 : kValueInputCount == value_input_count) { \
1116 : return &cache_.kPhi##kRep##kValueInputCount##Operator; \
1117 : }
1118 3554236 : CACHED_PHI_LIST(CACHED_PHI)
1119 : #undef CACHED_PHI
1120 : // Uncached.
1121 : return new (zone()) Operator1<MachineRepresentation>( // --
1122 : IrOpcode::kPhi, Operator::kPure, // opcode
1123 : "Phi", // name
1124 : value_input_count, 0, 1, 1, 0, 0, // counts
1125 1120769 : rep); // parameter
1126 : }
1127 :
1128 31712 : const Operator* CommonOperatorBuilder::TypeGuard(Type* type) {
1129 : return new (zone()) Operator1<Type*>( // --
1130 : IrOpcode::kTypeGuard, Operator::kPure, // opcode
1131 : "TypeGuard", // name
1132 : 1, 0, 1, 1, 0, 0, // counts
1133 31712 : type); // parameter
1134 : }
1135 :
1136 2320058 : const Operator* CommonOperatorBuilder::EffectPhi(int effect_input_count) {
1137 : DCHECK_LT(0, effect_input_count); // Disallow empty effect phis.
1138 2211776 : switch (effect_input_count) {
1139 : #define CACHED_EFFECT_PHI(input_count) \
1140 : case input_count: \
1141 : return &cache_.kEffectPhi##input_count##Operator;
1142 102787 : CACHED_EFFECT_PHI_LIST(CACHED_EFFECT_PHI)
1143 : #undef CACHED_EFFECT_PHI
1144 : default:
1145 : break;
1146 : }
1147 : // Uncached.
1148 : return new (zone()) Operator( // --
1149 : IrOpcode::kEffectPhi, Operator::kKontrol, // opcode
1150 : "EffectPhi", // name
1151 108282 : 0, effect_input_count, 1, 0, 1, 0); // counts
1152 : }
1153 :
1154 23507 : const Operator* CommonOperatorBuilder::InductionVariablePhi(int input_count) {
1155 : DCHECK_LE(4, input_count); // There must be always the entry, backedge,
1156 : // increment and at least one bound.
1157 23507 : switch (input_count) {
1158 : #define CACHED_INDUCTION_VARIABLE_PHI(input_count) \
1159 : case input_count: \
1160 : return &cache_.kInductionVariablePhi##input_count##Operator;
1161 23329 : CACHED_INDUCTION_VARIABLE_PHI_LIST(CACHED_INDUCTION_VARIABLE_PHI)
1162 : #undef CACHED_INDUCTION_VARIABLE_PHI
1163 : default:
1164 : break;
1165 : }
1166 : // Uncached.
1167 : return new (zone()) Operator( // --
1168 : IrOpcode::kInductionVariablePhi, Operator::kPure, // opcode
1169 : "InductionVariablePhi", // name
1170 0 : input_count, 0, 1, 1, 0, 0); // counts
1171 : }
1172 :
1173 186697 : const Operator* CommonOperatorBuilder::BeginRegion(
1174 : RegionObservability region_observability) {
1175 186697 : switch (region_observability) {
1176 : case RegionObservability::kObservable:
1177 20423 : return &cache_.kBeginRegionObservableOperator;
1178 : case RegionObservability::kNotObservable:
1179 166274 : return &cache_.kBeginRegionNotObservableOperator;
1180 : }
1181 0 : UNREACHABLE();
1182 : }
1183 :
1184 3674752 : const Operator* CommonOperatorBuilder::StateValues(int arguments,
1185 3020655 : SparseInputMask bitmask) {
1186 3674752 : if (bitmask.IsDense()) {
1187 655253 : switch (arguments) {
1188 : #define CACHED_STATE_VALUES(arguments) \
1189 : case arguments: \
1190 : return &cache_.kStateValues##arguments##Operator;
1191 190094 : CACHED_STATE_VALUES_LIST(CACHED_STATE_VALUES)
1192 : #undef CACHED_STATE_VALUES
1193 : default:
1194 : break;
1195 : }
1196 : }
1197 :
1198 : #if DEBUG
1199 : DCHECK(bitmask.IsDense() || bitmask.CountReal() == arguments);
1200 : #endif
1201 :
1202 : // Uncached.
1203 : return new (zone()) Operator1<SparseInputMask>( // --
1204 : IrOpcode::kStateValues, Operator::kPure, // opcode
1205 : "StateValues", // name
1206 : arguments, 0, 0, 1, 0, 0, // counts
1207 3020654 : bitmask); // parameter
1208 : }
1209 :
1210 4410877 : const Operator* CommonOperatorBuilder::TypedStateValues(
1211 4410877 : const ZoneVector<MachineType>* types, SparseInputMask bitmask) {
1212 : #if DEBUG
1213 : DCHECK(bitmask.IsDense() ||
1214 : bitmask.CountReal() == static_cast<int>(types->size()));
1215 : #endif
1216 :
1217 : return new (zone()) Operator1<TypedStateValueInfo>( // --
1218 : IrOpcode::kTypedStateValues, Operator::kPure, // opcode
1219 : "TypedStateValues", // name
1220 4410877 : static_cast<int>(types->size()), 0, 0, 1, 0, 0, // counts
1221 8821746 : TypedStateValueInfo(types, bitmask)); // parameters
1222 : }
1223 :
1224 3082 : const Operator* CommonOperatorBuilder::ArgumentsElementsState(
1225 3082 : ArgumentsStateType type) {
1226 : return new (zone()) Operator1<ArgumentsStateType>( // --
1227 : IrOpcode::kArgumentsElementsState, Operator::kPure, // opcode
1228 : "ArgumentsElementsState", // name
1229 : 0, 0, 0, 1, 0, 0, // counts
1230 3082 : type); // parameter
1231 : }
1232 :
1233 1534 : const Operator* CommonOperatorBuilder::ArgumentsLengthState(
1234 1534 : ArgumentsStateType type) {
1235 : return new (zone()) Operator1<ArgumentsStateType>( // --
1236 : IrOpcode::kArgumentsLengthState, Operator::kPure, // opcode
1237 : "ArgumentsLengthState", // name
1238 : 0, 0, 0, 1, 0, 0, // counts
1239 1534 : type); // parameter
1240 : }
1241 :
1242 18249 : ArgumentsStateType ArgumentsStateTypeOf(Operator const* op) {
1243 : DCHECK(op->opcode() == IrOpcode::kArgumentsElementsState ||
1244 : op->opcode() == IrOpcode::kArgumentsLengthState);
1245 18249 : return OpParameter<ArgumentsStateType>(op);
1246 : }
1247 :
1248 65171 : const Operator* CommonOperatorBuilder::ObjectState(uint32_t object_id,
1249 65171 : int pointer_slots) {
1250 : return new (zone()) Operator1<ObjectStateInfo>( // --
1251 : IrOpcode::kObjectState, Operator::kPure, // opcode
1252 : "ObjectState", // name
1253 : pointer_slots, 0, 0, 1, 0, 0, // counts
1254 130342 : ObjectStateInfo{object_id, pointer_slots}); // parameter
1255 : }
1256 :
1257 18337 : const Operator* CommonOperatorBuilder::TypedObjectState(
1258 18337 : uint32_t object_id, const ZoneVector<MachineType>* types) {
1259 : return new (zone()) Operator1<TypedObjectStateInfo>( // --
1260 : IrOpcode::kTypedObjectState, Operator::kPure, // opcode
1261 : "TypedObjectState", // name
1262 18337 : static_cast<int>(types->size()), 0, 0, 1, 0, 0, // counts
1263 36674 : TypedObjectStateInfo(object_id, types)); // parameter
1264 : }
1265 :
1266 78883 : uint32_t ObjectIdOf(Operator const* op) {
1267 78883 : switch (op->opcode()) {
1268 : case IrOpcode::kObjectState:
1269 18337 : return OpParameter<ObjectStateInfo>(op).object_id();
1270 : case IrOpcode::kTypedObjectState:
1271 46785 : return OpParameter<TypedObjectStateInfo>(op).object_id();
1272 : case IrOpcode::kObjectId:
1273 13761 : return OpParameter<uint32_t>(op);
1274 : default:
1275 0 : UNREACHABLE();
1276 : }
1277 : }
1278 :
1279 6925572 : const Operator* CommonOperatorBuilder::FrameState(
1280 : BailoutId bailout_id, OutputFrameStateCombine state_combine,
1281 6925572 : const FrameStateFunctionInfo* function_info) {
1282 : FrameStateInfo state_info(bailout_id, state_combine, function_info);
1283 : return new (zone()) Operator1<FrameStateInfo>( // --
1284 : IrOpcode::kFrameState, Operator::kPure, // opcode
1285 : "FrameState", // name
1286 : 5, 0, 0, 1, 0, 0, // counts
1287 6925573 : state_info); // parameter
1288 : }
1289 :
1290 :
1291 4390871 : const Operator* CommonOperatorBuilder::Call(const CallDescriptor* descriptor) {
1292 0 : class CallOperator final : public Operator1<const CallDescriptor*> {
1293 : public:
1294 8781794 : explicit CallOperator(const CallDescriptor* descriptor)
1295 : : Operator1<const CallDescriptor*>(
1296 : IrOpcode::kCall, descriptor->properties(), "Call",
1297 : descriptor->InputCount() + descriptor->FrameStateCount(),
1298 : Operator::ZeroIfPure(descriptor->properties()),
1299 : Operator::ZeroIfEliminatable(descriptor->properties()),
1300 : descriptor->ReturnCount(),
1301 : Operator::ZeroIfPure(descriptor->properties()),
1302 8781831 : Operator::ZeroIfNoThrow(descriptor->properties()), descriptor) {}
1303 :
1304 0 : void PrintParameter(std::ostream& os, PrintVerbosity verbose) const {
1305 0 : os << "[" << *parameter() << "]";
1306 0 : }
1307 : };
1308 4390915 : return new (zone()) CallOperator(descriptor);
1309 : }
1310 :
1311 192 : const Operator* CommonOperatorBuilder::CallWithCallerSavedRegisters(
1312 192 : const CallDescriptor* descriptor) {
1313 0 : class CallOperator final : public Operator1<const CallDescriptor*> {
1314 : public:
1315 384 : explicit CallOperator(const CallDescriptor* descriptor)
1316 : : Operator1<const CallDescriptor*>(
1317 : IrOpcode::kCallWithCallerSavedRegisters, descriptor->properties(),
1318 : "CallWithCallerSavedRegisters",
1319 : descriptor->InputCount() + descriptor->FrameStateCount(),
1320 : Operator::ZeroIfPure(descriptor->properties()),
1321 : Operator::ZeroIfEliminatable(descriptor->properties()),
1322 : descriptor->ReturnCount(),
1323 : Operator::ZeroIfPure(descriptor->properties()),
1324 384 : Operator::ZeroIfNoThrow(descriptor->properties()), descriptor) {}
1325 :
1326 0 : void PrintParameter(std::ostream& os, PrintVerbosity verbose) const {
1327 0 : os << "[" << *parameter() << "]";
1328 0 : }
1329 : };
1330 192 : return new (zone()) CallOperator(descriptor);
1331 : }
1332 :
1333 165918 : const Operator* CommonOperatorBuilder::TailCall(
1334 165918 : const CallDescriptor* descriptor) {
1335 0 : class TailCallOperator final : public Operator1<const CallDescriptor*> {
1336 : public:
1337 165918 : explicit TailCallOperator(const CallDescriptor* descriptor)
1338 : : Operator1<const CallDescriptor*>(
1339 : IrOpcode::kTailCall,
1340 : descriptor->properties() | Operator::kNoThrow, "TailCall",
1341 : descriptor->InputCount() + descriptor->FrameStateCount(), 1, 1, 0,
1342 331836 : 0, 1, descriptor) {}
1343 :
1344 0 : void PrintParameter(std::ostream& os, PrintVerbosity verbose) const {
1345 0 : os << "[" << *parameter() << "]";
1346 0 : }
1347 : };
1348 165918 : return new (zone()) TailCallOperator(descriptor);
1349 : }
1350 :
1351 479566 : const Operator* CommonOperatorBuilder::Projection(size_t index) {
1352 478039 : switch (index) {
1353 : #define CACHED_PROJECTION(index) \
1354 : case index: \
1355 : return &cache_.kProjection##index##Operator;
1356 238257 : CACHED_PROJECTION_LIST(CACHED_PROJECTION)
1357 : #undef CACHED_PROJECTION
1358 : default:
1359 : break;
1360 : }
1361 : // Uncached.
1362 : return new (zone()) Operator1<size_t>( // --
1363 : IrOpcode::kProjection, // opcode
1364 : Operator::kPure, // flags
1365 : "Projection", // name
1366 : 1, 0, 1, 1, 0, 0, // counts
1367 : index); // parameter
1368 : }
1369 :
1370 :
1371 829502 : const Operator* CommonOperatorBuilder::ResizeMergeOrPhi(const Operator* op,
1372 : int size) {
1373 829502 : if (op->opcode() == IrOpcode::kPhi) {
1374 299395 : return Phi(PhiRepresentationOf(op), size);
1375 530107 : } else if (op->opcode() == IrOpcode::kEffectPhi) {
1376 138655 : return EffectPhi(size);
1377 391452 : } else if (op->opcode() == IrOpcode::kMerge) {
1378 380262 : return Merge(size);
1379 11190 : } else if (op->opcode() == IrOpcode::kLoop) {
1380 11190 : return Loop(size);
1381 : } else {
1382 0 : UNREACHABLE();
1383 : }
1384 : }
1385 :
1386 : const FrameStateFunctionInfo*
1387 547350 : CommonOperatorBuilder::CreateFrameStateFunctionInfo(
1388 : FrameStateType type, int parameter_count, int local_count,
1389 547350 : Handle<SharedFunctionInfo> shared_info) {
1390 : return new (zone()->New(sizeof(FrameStateFunctionInfo)))
1391 1642051 : FrameStateFunctionInfo(type, parameter_count, local_count, shared_info);
1392 : }
1393 :
1394 : } // namespace compiler
1395 : } // namespace internal
1396 : } // namespace v8
|