• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 namespace v8 {
18 namespace internal {
19 namespace compiler {
20 
operator <<(std::ostream & os,BranchHint hint)21 std::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 
BranchHintOf(const Operator * const op)35 BranchHint BranchHintOf(const Operator* const op) {
36   DCHECK_EQ(IrOpcode::kBranch, op->opcode());
37   return OpParameter<BranchHint>(op);
38 }
39 
ValueInputCountOfReturn(Operator const * const op)40 int 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 
operator ==(DeoptimizeParameters lhs,DeoptimizeParameters rhs)47 bool operator==(DeoptimizeParameters lhs, DeoptimizeParameters rhs) {
48   return lhs.kind() == rhs.kind() && lhs.reason() == rhs.reason();
49 }
50 
operator !=(DeoptimizeParameters lhs,DeoptimizeParameters rhs)51 bool operator!=(DeoptimizeParameters lhs, DeoptimizeParameters rhs) {
52   return !(lhs == rhs);
53 }
54 
hash_value(DeoptimizeParameters p)55 size_t hash_value(DeoptimizeParameters p) {
56   return base::hash_combine(p.kind(), p.reason());
57 }
58 
operator <<(std::ostream & os,DeoptimizeParameters p)59 std::ostream& operator<<(std::ostream& os, DeoptimizeParameters p) {
60   return os << p.kind() << ":" << p.reason();
61 }
62 
DeoptimizeParametersOf(Operator const * const op)63 DeoptimizeParameters 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 
operator ==(SelectParameters const & lhs,SelectParameters const & rhs)71 bool operator==(SelectParameters const& lhs, SelectParameters const& rhs) {
72   return lhs.representation() == rhs.representation() &&
73          lhs.hint() == rhs.hint();
74 }
75 
76 
operator !=(SelectParameters const & lhs,SelectParameters const & rhs)77 bool operator!=(SelectParameters const& lhs, SelectParameters const& rhs) {
78   return !(lhs == rhs);
79 }
80 
81 
hash_value(SelectParameters const & p)82 size_t hash_value(SelectParameters const& p) {
83   return base::hash_combine(p.representation(), p.hint());
84 }
85 
86 
operator <<(std::ostream & os,SelectParameters const & p)87 std::ostream& operator<<(std::ostream& os, SelectParameters const& p) {
88   return os << p.representation() << "|" << p.hint();
89 }
90 
91 
SelectParametersOf(const Operator * const op)92 SelectParameters const& SelectParametersOf(const Operator* const op) {
93   DCHECK_EQ(IrOpcode::kSelect, op->opcode());
94   return OpParameter<SelectParameters>(op);
95 }
96 
CallDescriptorOf(const Operator * const op)97 CallDescriptor 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 
ProjectionIndexOf(const Operator * const op)103 size_t ProjectionIndexOf(const Operator* const op) {
104   DCHECK_EQ(IrOpcode::kProjection, op->opcode());
105   return OpParameter<size_t>(op);
106 }
107 
108 
PhiRepresentationOf(const Operator * const op)109 MachineRepresentation PhiRepresentationOf(const Operator* const op) {
110   DCHECK_EQ(IrOpcode::kPhi, op->opcode());
111   return OpParameter<MachineRepresentation>(op);
112 }
113 
114 
ParameterIndexOf(const Operator * const op)115 int ParameterIndexOf(const Operator* const op) {
116   DCHECK_EQ(IrOpcode::kParameter, op->opcode());
117   return OpParameter<ParameterInfo>(op).index();
118 }
119 
120 
ParameterInfoOf(const Operator * const op)121 const ParameterInfo& ParameterInfoOf(const Operator* const op) {
122   DCHECK_EQ(IrOpcode::kParameter, op->opcode());
123   return OpParameter<ParameterInfo>(op);
124 }
125 
126 
operator ==(ParameterInfo const & lhs,ParameterInfo const & rhs)127 bool operator==(ParameterInfo const& lhs, ParameterInfo const& rhs) {
128   return lhs.index() == rhs.index();
129 }
130 
131 
operator !=(ParameterInfo const & lhs,ParameterInfo const & rhs)132 bool operator!=(ParameterInfo const& lhs, ParameterInfo const& rhs) {
133   return !(lhs == rhs);
134 }
135 
136 
hash_value(ParameterInfo const & p)137 size_t hash_value(ParameterInfo const& p) { return p.index(); }
138 
139 
operator <<(std::ostream & os,ParameterInfo const & i)140 std::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 
operator ==(RelocatablePtrConstantInfo const & lhs,RelocatablePtrConstantInfo const & rhs)146 bool 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 
operator !=(RelocatablePtrConstantInfo const & lhs,RelocatablePtrConstantInfo const & rhs)152 bool operator!=(RelocatablePtrConstantInfo const& lhs,
153                 RelocatablePtrConstantInfo const& rhs) {
154   return !(lhs == rhs);
155 }
156 
hash_value(RelocatablePtrConstantInfo const & p)157 size_t hash_value(RelocatablePtrConstantInfo const& p) {
158   return base::hash_combine(p.value(), p.rmode(), p.type());
159 }
160 
operator <<(std::ostream & os,RelocatablePtrConstantInfo const & p)161 std::ostream& operator<<(std::ostream& os,
162                          RelocatablePtrConstantInfo const& p) {
163   return os << p.value() << "|" << p.rmode() << "|" << p.type();
164 }
165 
InputIterator(SparseInputMask::BitMaskType bit_mask,Node * parent)166 SparseInputMask::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 
Advance()178 void SparseInputMask::InputIterator::Advance() {
179   DCHECK(!IsEnd());
180 
181   if (IsReal()) {
182     ++real_index_;
183   }
184   bit_mask_ >>= 1;
185 }
186 
GetReal() const187 Node* SparseInputMask::InputIterator::GetReal() const {
188   DCHECK(IsReal());
189   return parent_->InputAt(real_index_);
190 }
191 
IsReal() const192 bool SparseInputMask::InputIterator::IsReal() const {
193   return bit_mask_ == SparseInputMask::kDenseBitMask ||
194          (bit_mask_ & kEntryMask);
195 }
196 
IsEnd() const197 bool SparseInputMask::InputIterator::IsEnd() const {
198   return (bit_mask_ == kEndMarker) ||
199          (bit_mask_ == SparseInputMask::kDenseBitMask &&
200           real_index_ >= parent_->InputCount());
201 }
202 
CountReal() const203 int SparseInputMask::CountReal() const {
204   DCHECK(!IsDense());
205   return base::bits::CountPopulation(bit_mask_) -
206          base::bits::CountPopulation(kEndMarker);
207 }
208 
IterateOverInputs(Node * node)209 SparseInputMask::InputIterator SparseInputMask::IterateOverInputs(Node* node) {
210   DCHECK(IsDense() || CountReal() == node->InputCount());
211   return InputIterator(bit_mask_, node);
212 }
213 
operator ==(SparseInputMask const & lhs,SparseInputMask const & rhs)214 bool operator==(SparseInputMask const& lhs, SparseInputMask const& rhs) {
215   return lhs.mask() == rhs.mask();
216 }
217 
operator !=(SparseInputMask const & lhs,SparseInputMask const & rhs)218 bool operator!=(SparseInputMask const& lhs, SparseInputMask const& rhs) {
219   return !(lhs == rhs);
220 }
221 
hash_value(SparseInputMask const & p)222 size_t hash_value(SparseInputMask const& p) {
223   return base::hash_value(p.mask());
224 }
225 
operator <<(std::ostream & os,SparseInputMask const & p)226 std::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 
operator ==(TypedStateValueInfo const & lhs,TypedStateValueInfo const & rhs)247 bool 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 
operator !=(TypedStateValueInfo const & lhs,TypedStateValueInfo const & rhs)253 bool operator!=(TypedStateValueInfo const& lhs,
254                 TypedStateValueInfo const& rhs) {
255   return !(lhs == rhs);
256 }
257 
hash_value(TypedStateValueInfo const & p)258 size_t hash_value(TypedStateValueInfo const& p) {
259   return base::hash_combine(p.machine_types(), p.sparse_input_mask());
260 }
261 
operator <<(std::ostream & os,TypedStateValueInfo const & p)262 std::ostream& operator<<(std::ostream& os, TypedStateValueInfo const& p) {
263   return os << p.machine_types() << "|" << p.sparse_input_mask();
264 }
265 
hash_value(RegionObservability observability)266 size_t hash_value(RegionObservability observability) {
267   return static_cast<size_t>(observability);
268 }
269 
operator <<(std::ostream & os,RegionObservability observability)270 std::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 
RegionObservabilityOf(Operator const * op)281 RegionObservability RegionObservabilityOf(Operator const* op) {
282   DCHECK_EQ(IrOpcode::kBeginRegion, op->opcode());
283   return OpParameter<RegionObservability>(op);
284 }
285 
TypeGuardTypeOf(Operator const * op)286 Type* TypeGuardTypeOf(Operator const* op) {
287   DCHECK_EQ(IrOpcode::kTypeGuard, op->opcode());
288   return OpParameter<Type*>(op);
289 }
290 
operator <<(std::ostream & os,const ZoneVector<MachineType> * types)291 std::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 
OsrValueIndexOf(Operator const * op)305 int OsrValueIndexOf(Operator const* op) {
306   DCHECK_EQ(IrOpcode::kOsrValue, op->opcode());
307   return OpParameter<int>(op);
308 }
309 
hash_value(OsrGuardType type)310 size_t hash_value(OsrGuardType type) { return static_cast<size_t>(type); }
311 
operator <<(std::ostream & os,OsrGuardType type)312 std::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 
OsrGuardTypeOf(Operator const * op)325 OsrGuardType OsrGuardTypeOf(Operator const* op) {
326   DCHECK_EQ(IrOpcode::kOsrGuard, op->opcode());
327   return OpParameter<OsrGuardType>(op);
328 }
329 
SparseInputMaskOf(Operator const * op)330 SparseInputMask 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 
MachineTypesOf(Operator const * op)340 ZoneVector<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 
498 struct 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 {
EndOperatorv8::internal::compiler::CommonOperatorGlobalCache::EndOperator515     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 {
ReturnOperatorv8::internal::compiler::CommonOperatorGlobalCache::ReturnOperator528     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> {
BranchOperatorv8::internal::compiler::CommonOperatorGlobalCache::BranchOperator541     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 {
EffectPhiOperatorv8::internal::compiler::CommonOperatorGlobalCache::EffectPhiOperator554     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> {
BeginRegionOperatorv8::internal::compiler::CommonOperatorGlobalCache::BeginRegionOperator567     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 {
LoopOperatorv8::internal::compiler::CommonOperatorGlobalCache::LoopOperator581     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 {
MergeOperatorv8::internal::compiler::CommonOperatorGlobalCache::MergeOperator594     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> {
DeoptimizeOperatorv8::internal::compiler::CommonOperatorGlobalCache::DeoptimizeOperator607     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> {
DeoptimizeIfOperatorv8::internal::compiler::CommonOperatorGlobalCache::DeoptimizeIfOperator623     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> {
DeoptimizeUnlessOperatorv8::internal::compiler::CommonOperatorGlobalCache::DeoptimizeUnlessOperator640     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> {
TrapIfOperatorv8::internal::compiler::CommonOperatorGlobalCache::TrapIfOperator657     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> {
TrapUnlessOperatorv8::internal::compiler::CommonOperatorGlobalCache::TrapUnlessOperator673     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> {
PhiOperatorv8::internal::compiler::CommonOperatorGlobalCache::PhiOperator689     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 {
InductionVariablePhiOperatorv8::internal::compiler::CommonOperatorGlobalCache::InductionVariablePhiOperator704     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> {
ParameterOperatorv8::internal::compiler::CommonOperatorGlobalCache::ParameterOperator718     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> {
ProjectionOperatorv8::internal::compiler::CommonOperatorGlobalCache::ProjectionOperator732     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> {
StateValuesOperatorv8::internal::compiler::CommonOperatorGlobalCache::StateValuesOperator747     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 
762 static base::LazyInstance<CommonOperatorGlobalCache>::type kCache =
763     LAZY_INSTANCE_INITIALIZER;
764 
765 
CommonOperatorBuilder(Zone * zone)766 CommonOperatorBuilder::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   }
CACHED_OP_LIST(CACHED) const776 CACHED_OP_LIST(CACHED)
777 #undef CACHED
778 
779 
780 const 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 
Return(int value_input_count)797 const 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 
Branch(BranchHint hint)815 const 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 
Deoptimize(DeoptimizeKind kind,DeoptimizeReason reason)828 const 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 
DeoptimizeIf(DeoptimizeKind kind,DeoptimizeReason reason)847 const 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 
DeoptimizeUnless(DeoptimizeKind kind,DeoptimizeReason reason)866 const 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 
TrapIf(int32_t trap_id)885 const 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 
TrapUnless(int32_t trap_id)904 const 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 
Switch(size_t control_output_count)923 const 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 
IfValue(int32_t index)931 const 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 
Start(int value_output_count)940 const 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 
Loop(int control_input_count)948 const 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 
Merge(int control_input_count)966 const 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 
Parameter(int index,const char * debug_name)984 const 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 
OsrValue(int index)1005 const 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 
OsrGuard(OsrGuardType type)1013 const 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 
Int32Constant(int32_t value)1021 const 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 
Int64Constant(int64_t value)1030 const 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 
Float32Constant(volatile float value)1039 const 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 
Float64Constant(volatile double value)1048 const 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 
ExternalConstant(const ExternalReference & value)1057 const 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 
NumberConstant(volatile double value)1067 const 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 
PointerConstant(intptr_t value)1075 const 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 
HeapConstant(const Handle<HeapObject> & value)1083 const 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 
RelocatableInt32Constant(int32_t value,RelocInfo::Mode rmode)1092 const 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 
RelocatableInt64Constant(int64_t value,RelocInfo::Mode rmode)1101 const 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 
Select(MachineRepresentation rep,BranchHint hint)1110 const 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 
Phi(MachineRepresentation rep,int value_input_count)1120 const 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 
TypeGuard(Type * type)1138 const 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 
EffectPhi(int effect_input_count)1146 const 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 
InductionVariablePhi(int input_count)1164 const 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 
BeginRegion(RegionObservability region_observability)1183 const 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 
StateValues(int arguments,SparseInputMask bitmask)1195 const 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 
TypedStateValues(const ZoneVector<MachineType> * types,SparseInputMask bitmask)1221 const 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 
ArgumentsObjectState()1235 const 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 
ObjectState(int pointer_slots)1242 const 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 
TypedObjectState(const ZoneVector<MachineType> * types)1250 const 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 
FrameState(BailoutId bailout_id,OutputFrameStateCombine state_combine,const FrameStateFunctionInfo * function_info)1259 const 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 
Call(const CallDescriptor * descriptor)1271 const 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 
TailCall(const CallDescriptor * descriptor)1292 const 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 
Projection(size_t index)1311 const 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 
ResizeMergeOrPhi(const Operator * op,int size)1331 const 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 
1347 const FrameStateFunctionInfo*
CreateFrameStateFunctionInfo(FrameStateType type,int parameter_count,int local_count,Handle<SharedFunctionInfo> shared_info)1348 CommonOperatorBuilder::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