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