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