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