• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "src/compiler/common-operator.h"
6 
7 #include "src/assembler.h"
8 #include "src/base/lazy-instance.h"
9 #include "src/compiler/linkage.h"
10 #include "src/compiler/opcodes.h"
11 #include "src/compiler/operator.h"
12 #include "src/handles-inl.h"
13 #include "src/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 
38 
hash_value(DeoptimizeKind kind)39 size_t hash_value(DeoptimizeKind kind) { return static_cast<size_t>(kind); }
40 
41 
operator <<(std::ostream & os,DeoptimizeKind kind)42 std::ostream& operator<<(std::ostream& os, DeoptimizeKind kind) {
43   switch (kind) {
44     case DeoptimizeKind::kEager:
45       return os << "Eager";
46     case DeoptimizeKind::kSoft:
47       return os << "Soft";
48   }
49   UNREACHABLE();
50   return os;
51 }
52 
53 
DeoptimizeKindOf(const Operator * const op)54 DeoptimizeKind DeoptimizeKindOf(const Operator* const op) {
55   DCHECK_EQ(IrOpcode::kDeoptimize, op->opcode());
56   return OpParameter<DeoptimizeKind>(op);
57 }
58 
59 
hash_value(IfExceptionHint hint)60 size_t hash_value(IfExceptionHint hint) { return static_cast<size_t>(hint); }
61 
62 
operator <<(std::ostream & os,IfExceptionHint hint)63 std::ostream& operator<<(std::ostream& os, IfExceptionHint hint) {
64   switch (hint) {
65     case IfExceptionHint::kLocallyCaught:
66       return os << "Caught";
67     case IfExceptionHint::kLocallyUncaught:
68       return os << "Uncaught";
69   }
70   UNREACHABLE();
71   return os;
72 }
73 
74 
operator ==(SelectParameters const & lhs,SelectParameters const & rhs)75 bool operator==(SelectParameters const& lhs, SelectParameters const& rhs) {
76   return lhs.representation() == rhs.representation() &&
77          lhs.hint() == rhs.hint();
78 }
79 
80 
operator !=(SelectParameters const & lhs,SelectParameters const & rhs)81 bool operator!=(SelectParameters const& lhs, SelectParameters const& rhs) {
82   return !(lhs == rhs);
83 }
84 
85 
hash_value(SelectParameters const & p)86 size_t hash_value(SelectParameters const& p) {
87   return base::hash_combine(p.representation(), p.hint());
88 }
89 
90 
operator <<(std::ostream & os,SelectParameters const & p)91 std::ostream& operator<<(std::ostream& os, SelectParameters const& p) {
92   return os << p.representation() << "|" << p.hint();
93 }
94 
95 
SelectParametersOf(const Operator * const op)96 SelectParameters const& SelectParametersOf(const Operator* const op) {
97   DCHECK_EQ(IrOpcode::kSelect, op->opcode());
98   return OpParameter<SelectParameters>(op);
99 }
100 
CallDescriptorOf(const Operator * const op)101 CallDescriptor const* CallDescriptorOf(const Operator* const op) {
102   DCHECK(op->opcode() == IrOpcode::kCall ||
103          op->opcode() == IrOpcode::kTailCall);
104   return OpParameter<CallDescriptor const*>(op);
105 }
106 
ProjectionIndexOf(const Operator * const op)107 size_t ProjectionIndexOf(const Operator* const op) {
108   DCHECK_EQ(IrOpcode::kProjection, op->opcode());
109   return OpParameter<size_t>(op);
110 }
111 
112 
PhiRepresentationOf(const Operator * const op)113 MachineRepresentation PhiRepresentationOf(const Operator* const op) {
114   DCHECK_EQ(IrOpcode::kPhi, op->opcode());
115   return OpParameter<MachineRepresentation>(op);
116 }
117 
118 
ParameterIndexOf(const Operator * const op)119 int ParameterIndexOf(const Operator* const op) {
120   DCHECK_EQ(IrOpcode::kParameter, op->opcode());
121   return OpParameter<ParameterInfo>(op).index();
122 }
123 
124 
ParameterInfoOf(const Operator * const op)125 const ParameterInfo& ParameterInfoOf(const Operator* const op) {
126   DCHECK_EQ(IrOpcode::kParameter, op->opcode());
127   return OpParameter<ParameterInfo>(op);
128 }
129 
130 
operator ==(ParameterInfo const & lhs,ParameterInfo const & rhs)131 bool operator==(ParameterInfo const& lhs, ParameterInfo const& rhs) {
132   return lhs.index() == rhs.index();
133 }
134 
135 
operator !=(ParameterInfo const & lhs,ParameterInfo const & rhs)136 bool operator!=(ParameterInfo const& lhs, ParameterInfo const& rhs) {
137   return !(lhs == rhs);
138 }
139 
140 
hash_value(ParameterInfo const & p)141 size_t hash_value(ParameterInfo const& p) { return p.index(); }
142 
143 
operator <<(std::ostream & os,ParameterInfo const & i)144 std::ostream& operator<<(std::ostream& os, ParameterInfo const& i) {
145   if (i.debug_name()) os << i.debug_name() << '#';
146   os << i.index();
147   return os;
148 }
149 
operator ==(RelocatablePtrConstantInfo const & lhs,RelocatablePtrConstantInfo const & rhs)150 bool operator==(RelocatablePtrConstantInfo const& lhs,
151                 RelocatablePtrConstantInfo const& rhs) {
152   return lhs.rmode() == rhs.rmode() && lhs.value() == rhs.value() &&
153          lhs.type() == rhs.type();
154 }
155 
operator !=(RelocatablePtrConstantInfo const & lhs,RelocatablePtrConstantInfo const & rhs)156 bool operator!=(RelocatablePtrConstantInfo const& lhs,
157                 RelocatablePtrConstantInfo const& rhs) {
158   return !(lhs == rhs);
159 }
160 
hash_value(RelocatablePtrConstantInfo const & p)161 size_t hash_value(RelocatablePtrConstantInfo const& p) {
162   return base::hash_combine(p.value(), p.rmode(), p.type());
163 }
164 
operator <<(std::ostream & os,RelocatablePtrConstantInfo const & p)165 std::ostream& operator<<(std::ostream& os,
166                          RelocatablePtrConstantInfo const& p) {
167   return os << p.value() << "|" << p.rmode() << "|" << p.type();
168 }
169 
hash_value(RegionObservability observability)170 size_t hash_value(RegionObservability observability) {
171   return static_cast<size_t>(observability);
172 }
173 
operator <<(std::ostream & os,RegionObservability observability)174 std::ostream& operator<<(std::ostream& os, RegionObservability observability) {
175   switch (observability) {
176     case RegionObservability::kObservable:
177       return os << "observable";
178     case RegionObservability::kNotObservable:
179       return os << "not-observable";
180   }
181   UNREACHABLE();
182   return os;
183 }
184 
RegionObservabilityOf(Operator const * op)185 RegionObservability RegionObservabilityOf(Operator const* op) {
186   DCHECK_EQ(IrOpcode::kBeginRegion, op->opcode());
187   return OpParameter<RegionObservability>(op);
188 }
189 
operator <<(std::ostream & os,const ZoneVector<MachineType> * types)190 std::ostream& operator<<(std::ostream& os,
191                          const ZoneVector<MachineType>* types) {
192   // Print all the MachineTypes, separated by commas.
193   bool first = true;
194   for (MachineType elem : *types) {
195     if (!first) {
196       os << ", ";
197     }
198     first = false;
199     os << elem;
200   }
201   return os;
202 }
203 
204 #define CACHED_OP_LIST(V)                                    \
205   V(Dead, Operator::kFoldable, 0, 0, 0, 1, 1, 1)             \
206   V(DeoptimizeIf, Operator::kFoldable, 2, 1, 1, 0, 1, 1)     \
207   V(DeoptimizeUnless, Operator::kFoldable, 2, 1, 1, 0, 1, 1) \
208   V(IfTrue, Operator::kKontrol, 0, 0, 1, 0, 0, 1)            \
209   V(IfFalse, Operator::kKontrol, 0, 0, 1, 0, 0, 1)           \
210   V(IfSuccess, Operator::kKontrol, 0, 0, 1, 0, 0, 1)         \
211   V(IfDefault, Operator::kKontrol, 0, 0, 1, 0, 0, 1)         \
212   V(Throw, Operator::kKontrol, 1, 1, 1, 0, 0, 1)             \
213   V(Terminate, Operator::kKontrol, 0, 1, 1, 0, 0, 1)         \
214   V(OsrNormalEntry, Operator::kFoldable, 0, 1, 1, 0, 1, 1)   \
215   V(OsrLoopEntry, Operator::kFoldable, 0, 1, 1, 0, 1, 1)     \
216   V(Checkpoint, Operator::kKontrol, 0, 1, 1, 0, 1, 0)        \
217   V(FinishRegion, Operator::kKontrol, 1, 1, 0, 1, 1, 0)
218 
219 #define CACHED_RETURN_LIST(V) \
220   V(1)                        \
221   V(2)                        \
222   V(3)
223 
224 
225 #define CACHED_END_LIST(V) \
226   V(1)                     \
227   V(2)                     \
228   V(3)                     \
229   V(4)                     \
230   V(5)                     \
231   V(6)                     \
232   V(7)                     \
233   V(8)
234 
235 
236 #define CACHED_EFFECT_PHI_LIST(V) \
237   V(1)                            \
238   V(2)                            \
239   V(3)                            \
240   V(4)                            \
241   V(5)                            \
242   V(6)
243 
244 
245 #define CACHED_LOOP_LIST(V) \
246   V(1)                      \
247   V(2)
248 
249 
250 #define CACHED_MERGE_LIST(V) \
251   V(1)                       \
252   V(2)                       \
253   V(3)                       \
254   V(4)                       \
255   V(5)                       \
256   V(6)                       \
257   V(7)                       \
258   V(8)
259 
260 
261 #define CACHED_PARAMETER_LIST(V) \
262   V(0)                           \
263   V(1)                           \
264   V(2)                           \
265   V(3)                           \
266   V(4)                           \
267   V(5)                           \
268   V(6)
269 
270 
271 #define CACHED_PHI_LIST(V) \
272   V(kTagged, 1)            \
273   V(kTagged, 2)            \
274   V(kTagged, 3)            \
275   V(kTagged, 4)            \
276   V(kTagged, 5)            \
277   V(kTagged, 6)            \
278   V(kBit, 2)               \
279   V(kFloat64, 2)           \
280   V(kWord32, 2)
281 
282 
283 #define CACHED_PROJECTION_LIST(V) \
284   V(0)                            \
285   V(1)
286 
287 
288 #define CACHED_STATE_VALUES_LIST(V) \
289   V(0)                              \
290   V(1)                              \
291   V(2)                              \
292   V(3)                              \
293   V(4)                              \
294   V(5)                              \
295   V(6)                              \
296   V(7)                              \
297   V(8)                              \
298   V(10)                             \
299   V(11)                             \
300   V(12)                             \
301   V(13)                             \
302   V(14)
303 
304 
305 struct CommonOperatorGlobalCache final {
306 #define CACHED(Name, properties, value_input_count, effect_input_count,      \
307                control_input_count, value_output_count, effect_output_count, \
308                control_output_count)                                         \
309   struct Name##Operator final : public Operator {                            \
310     Name##Operator()                                                         \
311         : Operator(IrOpcode::k##Name, properties, #Name, value_input_count,  \
312                    effect_input_count, control_input_count,                  \
313                    value_output_count, effect_output_count,                  \
314                    control_output_count) {}                                  \
315   };                                                                         \
316   Name##Operator k##Name##Operator;
317   CACHED_OP_LIST(CACHED)
318 #undef CACHED
319 
320   template <DeoptimizeKind kKind>
321   struct DeoptimizeOperator final : public Operator1<DeoptimizeKind> {
DeoptimizeOperatorv8::internal::compiler::CommonOperatorGlobalCache::DeoptimizeOperator322     DeoptimizeOperator()
323         : Operator1<DeoptimizeKind>(                      // --
324               IrOpcode::kDeoptimize, Operator::kNoThrow,  // opcode
325               "Deoptimize",                               // name
326               1, 1, 1, 0, 0, 1,                           // counts
327               kKind) {}                                   // parameter
328   };
329   DeoptimizeOperator<DeoptimizeKind::kEager> kDeoptimizeEagerOperator;
330   DeoptimizeOperator<DeoptimizeKind::kSoft> kDeoptimizeSoftOperator;
331 
332   template <IfExceptionHint kCaughtLocally>
333   struct IfExceptionOperator final : public Operator1<IfExceptionHint> {
IfExceptionOperatorv8::internal::compiler::CommonOperatorGlobalCache::IfExceptionOperator334     IfExceptionOperator()
335         : Operator1<IfExceptionHint>(                      // --
336               IrOpcode::kIfException, Operator::kKontrol,  // opcode
337               "IfException",                               // name
338               0, 1, 1, 1, 1, 1,                            // counts
339               kCaughtLocally) {}                           // parameter
340   };
341   IfExceptionOperator<IfExceptionHint::kLocallyCaught> kIfExceptionCOperator;
342   IfExceptionOperator<IfExceptionHint::kLocallyUncaught> kIfExceptionUOperator;
343 
344   template <size_t kInputCount>
345   struct EndOperator final : public Operator {
EndOperatorv8::internal::compiler::CommonOperatorGlobalCache::EndOperator346     EndOperator()
347         : Operator(                                // --
348               IrOpcode::kEnd, Operator::kKontrol,  // opcode
349               "End",                               // name
350               0, 0, kInputCount, 0, 0, 0) {}       // counts
351   };
352 #define CACHED_END(input_count) \
353   EndOperator<input_count> kEnd##input_count##Operator;
354   CACHED_END_LIST(CACHED_END)
355 #undef CACHED_END
356 
357   template <size_t kInputCount>
358   struct ReturnOperator final : public Operator {
ReturnOperatorv8::internal::compiler::CommonOperatorGlobalCache::ReturnOperator359     ReturnOperator()
360         : Operator(                                   // --
361               IrOpcode::kReturn, Operator::kNoThrow,  // opcode
362               "Return",                               // name
363               kInputCount, 1, 1, 0, 0, 1) {}          // counts
364   };
365 #define CACHED_RETURN(input_count) \
366   ReturnOperator<input_count> kReturn##input_count##Operator;
367   CACHED_RETURN_LIST(CACHED_RETURN)
368 #undef CACHED_RETURN
369 
370   template <BranchHint kBranchHint>
371   struct BranchOperator final : public Operator1<BranchHint> {
BranchOperatorv8::internal::compiler::CommonOperatorGlobalCache::BranchOperator372     BranchOperator()
373         : Operator1<BranchHint>(                      // --
374               IrOpcode::kBranch, Operator::kKontrol,  // opcode
375               "Branch",                               // name
376               1, 0, 1, 0, 0, 2,                       // counts
377               kBranchHint) {}                         // parameter
378   };
379   BranchOperator<BranchHint::kNone> kBranchNoneOperator;
380   BranchOperator<BranchHint::kTrue> kBranchTrueOperator;
381   BranchOperator<BranchHint::kFalse> kBranchFalseOperator;
382 
383   template <int kEffectInputCount>
384   struct EffectPhiOperator final : public Operator {
EffectPhiOperatorv8::internal::compiler::CommonOperatorGlobalCache::EffectPhiOperator385     EffectPhiOperator()
386         : Operator(                                   // --
387               IrOpcode::kEffectPhi, Operator::kPure,  // opcode
388               "EffectPhi",                            // name
389               0, kEffectInputCount, 1, 0, 1, 0) {}    // counts
390   };
391 #define CACHED_EFFECT_PHI(input_count) \
392   EffectPhiOperator<input_count> kEffectPhi##input_count##Operator;
393   CACHED_EFFECT_PHI_LIST(CACHED_EFFECT_PHI)
394 #undef CACHED_EFFECT_PHI
395 
396   template <RegionObservability kRegionObservability>
397   struct BeginRegionOperator final : public Operator1<RegionObservability> {
BeginRegionOperatorv8::internal::compiler::CommonOperatorGlobalCache::BeginRegionOperator398     BeginRegionOperator()
399         : Operator1<RegionObservability>(                  // --
400               IrOpcode::kBeginRegion, Operator::kKontrol,  // opcode
401               "BeginRegion",                               // name
402               0, 1, 0, 0, 1, 0,                            // counts
403               kRegionObservability) {}                     // parameter
404   };
405   BeginRegionOperator<RegionObservability::kObservable>
406       kBeginRegionObservableOperator;
407   BeginRegionOperator<RegionObservability::kNotObservable>
408       kBeginRegionNotObservableOperator;
409 
410   template <size_t kInputCount>
411   struct LoopOperator final : public Operator {
LoopOperatorv8::internal::compiler::CommonOperatorGlobalCache::LoopOperator412     LoopOperator()
413         : Operator(                                 // --
414               IrOpcode::kLoop, Operator::kKontrol,  // opcode
415               "Loop",                               // name
416               0, 0, kInputCount, 0, 0, 1) {}        // counts
417   };
418 #define CACHED_LOOP(input_count) \
419   LoopOperator<input_count> kLoop##input_count##Operator;
420   CACHED_LOOP_LIST(CACHED_LOOP)
421 #undef CACHED_LOOP
422 
423   template <size_t kInputCount>
424   struct MergeOperator final : public Operator {
MergeOperatorv8::internal::compiler::CommonOperatorGlobalCache::MergeOperator425     MergeOperator()
426         : Operator(                                  // --
427               IrOpcode::kMerge, Operator::kKontrol,  // opcode
428               "Merge",                               // name
429               0, 0, kInputCount, 0, 0, 1) {}         // counts
430   };
431 #define CACHED_MERGE(input_count) \
432   MergeOperator<input_count> kMerge##input_count##Operator;
433   CACHED_MERGE_LIST(CACHED_MERGE)
434 #undef CACHED_MERGE
435 
436   template <MachineRepresentation kRep, int kInputCount>
437   struct PhiOperator final : public Operator1<MachineRepresentation> {
PhiOperatorv8::internal::compiler::CommonOperatorGlobalCache::PhiOperator438     PhiOperator()
439         : Operator1<MachineRepresentation>(     //--
440               IrOpcode::kPhi, Operator::kPure,  // opcode
441               "Phi",                            // name
442               kInputCount, 0, 1, 1, 0, 0,       // counts
443               kRep) {}                          // parameter
444   };
445 #define CACHED_PHI(rep, input_count)                   \
446   PhiOperator<MachineRepresentation::rep, input_count> \
447       kPhi##rep##input_count##Operator;
448   CACHED_PHI_LIST(CACHED_PHI)
449 #undef CACHED_PHI
450 
451   template <int kIndex>
452   struct ParameterOperator final : public Operator1<ParameterInfo> {
ParameterOperatorv8::internal::compiler::CommonOperatorGlobalCache::ParameterOperator453     ParameterOperator()
454         : Operator1<ParameterInfo>(                   // --
455               IrOpcode::kParameter, Operator::kPure,  // opcode
456               "Parameter",                            // name
457               1, 0, 0, 1, 0, 0,                       // counts,
458               ParameterInfo(kIndex, nullptr)) {}      // parameter and name
459   };
460 #define CACHED_PARAMETER(index) \
461   ParameterOperator<index> kParameter##index##Operator;
462   CACHED_PARAMETER_LIST(CACHED_PARAMETER)
463 #undef CACHED_PARAMETER
464 
465   template <size_t kIndex>
466   struct ProjectionOperator final : public Operator1<size_t> {
ProjectionOperatorv8::internal::compiler::CommonOperatorGlobalCache::ProjectionOperator467     ProjectionOperator()
468         : Operator1<size_t>(          // --
469               IrOpcode::kProjection,  // opcode
470               Operator::kPure,        // flags
471               "Projection",           // name
472               1, 0, 1, 1, 0, 0,       // counts,
473               kIndex) {}              // parameter
474   };
475 #define CACHED_PROJECTION(index) \
476   ProjectionOperator<index> kProjection##index##Operator;
477   CACHED_PROJECTION_LIST(CACHED_PROJECTION)
478 #undef CACHED_PROJECTION
479 
480   template <int kInputCount>
481   struct StateValuesOperator final : public Operator {
StateValuesOperatorv8::internal::compiler::CommonOperatorGlobalCache::StateValuesOperator482     StateValuesOperator()
483         : Operator(                           // --
484               IrOpcode::kStateValues,         // opcode
485               Operator::kPure,                // flags
486               "StateValues",                  // name
487               kInputCount, 0, 0, 1, 0, 0) {}  // counts
488   };
489 #define CACHED_STATE_VALUES(input_count) \
490   StateValuesOperator<input_count> kStateValues##input_count##Operator;
491   CACHED_STATE_VALUES_LIST(CACHED_STATE_VALUES)
492 #undef CACHED_STATE_VALUES
493 };
494 
495 
496 static base::LazyInstance<CommonOperatorGlobalCache>::type kCache =
497     LAZY_INSTANCE_INITIALIZER;
498 
499 
CommonOperatorBuilder(Zone * zone)500 CommonOperatorBuilder::CommonOperatorBuilder(Zone* zone)
501     : cache_(kCache.Get()), zone_(zone) {}
502 
503 
504 #define CACHED(Name, properties, value_input_count, effect_input_count,      \
505                control_input_count, value_output_count, effect_output_count, \
506                control_output_count)                                         \
507   const Operator* CommonOperatorBuilder::Name() {                            \
508     return &cache_.k##Name##Operator;                                        \
509   }
CACHED_OP_LIST(CACHED) const510 CACHED_OP_LIST(CACHED)
511 #undef CACHED
512 
513 
514 const Operator* CommonOperatorBuilder::End(size_t control_input_count) {
515   switch (control_input_count) {
516 #define CACHED_END(input_count) \
517   case input_count:             \
518     return &cache_.kEnd##input_count##Operator;
519     CACHED_END_LIST(CACHED_END)
520 #undef CACHED_END
521     default:
522       break;
523   }
524   // Uncached.
525   return new (zone()) Operator(             //--
526       IrOpcode::kEnd, Operator::kKontrol,   // opcode
527       "End",                                // name
528       0, 0, control_input_count, 0, 0, 0);  // counts
529 }
530 
531 
Return(int value_input_count)532 const Operator* CommonOperatorBuilder::Return(int value_input_count) {
533   switch (value_input_count) {
534 #define CACHED_RETURN(input_count) \
535   case input_count:                \
536     return &cache_.kReturn##input_count##Operator;
537     CACHED_RETURN_LIST(CACHED_RETURN)
538 #undef CACHED_RETURN
539     default:
540       break;
541   }
542   // Uncached.
543   return new (zone()) Operator(               //--
544       IrOpcode::kReturn, Operator::kNoThrow,  // opcode
545       "Return",                               // name
546       value_input_count, 1, 1, 0, 0, 1);      // counts
547 }
548 
549 
Branch(BranchHint hint)550 const Operator* CommonOperatorBuilder::Branch(BranchHint hint) {
551   switch (hint) {
552     case BranchHint::kNone:
553       return &cache_.kBranchNoneOperator;
554     case BranchHint::kTrue:
555       return &cache_.kBranchTrueOperator;
556     case BranchHint::kFalse:
557       return &cache_.kBranchFalseOperator;
558   }
559   UNREACHABLE();
560   return nullptr;
561 }
562 
563 
Deoptimize(DeoptimizeKind kind)564 const Operator* CommonOperatorBuilder::Deoptimize(DeoptimizeKind kind) {
565   switch (kind) {
566     case DeoptimizeKind::kEager:
567       return &cache_.kDeoptimizeEagerOperator;
568     case DeoptimizeKind::kSoft:
569       return &cache_.kDeoptimizeSoftOperator;
570   }
571   UNREACHABLE();
572   return nullptr;
573 }
574 
575 
IfException(IfExceptionHint hint)576 const Operator* CommonOperatorBuilder::IfException(IfExceptionHint hint) {
577   switch (hint) {
578     case IfExceptionHint::kLocallyCaught:
579       return &cache_.kIfExceptionCOperator;
580     case IfExceptionHint::kLocallyUncaught:
581       return &cache_.kIfExceptionUOperator;
582   }
583   UNREACHABLE();
584   return nullptr;
585 }
586 
587 
Switch(size_t control_output_count)588 const Operator* CommonOperatorBuilder::Switch(size_t control_output_count) {
589   return new (zone()) Operator(               // --
590       IrOpcode::kSwitch, Operator::kKontrol,  // opcode
591       "Switch",                               // name
592       1, 0, 1, 0, 0, control_output_count);   // counts
593 }
594 
595 
IfValue(int32_t index)596 const Operator* CommonOperatorBuilder::IfValue(int32_t index) {
597   return new (zone()) Operator1<int32_t>(      // --
598       IrOpcode::kIfValue, Operator::kKontrol,  // opcode
599       "IfValue",                               // name
600       0, 0, 1, 0, 0, 1,                        // counts
601       index);                                  // parameter
602 }
603 
604 
Start(int value_output_count)605 const Operator* CommonOperatorBuilder::Start(int value_output_count) {
606   return new (zone()) Operator(               // --
607       IrOpcode::kStart, Operator::kFoldable,  // opcode
608       "Start",                                // name
609       0, 0, 0, value_output_count, 1, 1);     // counts
610 }
611 
612 
Loop(int control_input_count)613 const Operator* CommonOperatorBuilder::Loop(int control_input_count) {
614   switch (control_input_count) {
615 #define CACHED_LOOP(input_count) \
616   case input_count:              \
617     return &cache_.kLoop##input_count##Operator;
618     CACHED_LOOP_LIST(CACHED_LOOP)
619 #undef CACHED_LOOP
620     default:
621       break;
622   }
623   // Uncached.
624   return new (zone()) Operator(             // --
625       IrOpcode::kLoop, Operator::kKontrol,  // opcode
626       "Loop",                               // name
627       0, 0, control_input_count, 0, 0, 1);  // counts
628 }
629 
630 
Merge(int control_input_count)631 const Operator* CommonOperatorBuilder::Merge(int control_input_count) {
632   switch (control_input_count) {
633 #define CACHED_MERGE(input_count) \
634   case input_count:               \
635     return &cache_.kMerge##input_count##Operator;
636     CACHED_MERGE_LIST(CACHED_MERGE)
637 #undef CACHED_MERGE
638     default:
639       break;
640   }
641   // Uncached.
642   return new (zone()) Operator(              // --
643       IrOpcode::kMerge, Operator::kKontrol,  // opcode
644       "Merge",                               // name
645       0, 0, control_input_count, 0, 0, 1);   // counts
646 }
647 
648 
Parameter(int index,const char * debug_name)649 const Operator* CommonOperatorBuilder::Parameter(int index,
650                                                  const char* debug_name) {
651   if (!debug_name) {
652     switch (index) {
653 #define CACHED_PARAMETER(index) \
654   case index:                   \
655     return &cache_.kParameter##index##Operator;
656       CACHED_PARAMETER_LIST(CACHED_PARAMETER)
657 #undef CACHED_PARAMETER
658       default:
659         break;
660     }
661   }
662   // Uncached.
663   return new (zone()) Operator1<ParameterInfo>(  // --
664       IrOpcode::kParameter, Operator::kPure,     // opcode
665       "Parameter",                               // name
666       1, 0, 0, 1, 0, 0,                          // counts
667       ParameterInfo(index, debug_name));         // parameter info
668 }
669 
670 
OsrValue(int index)671 const Operator* CommonOperatorBuilder::OsrValue(int index) {
672   return new (zone()) Operator1<int>(                // --
673       IrOpcode::kOsrValue, Operator::kNoProperties,  // opcode
674       "OsrValue",                                    // name
675       0, 0, 1, 1, 0, 0,                              // counts
676       index);                                        // parameter
677 }
678 
679 
Int32Constant(int32_t value)680 const Operator* CommonOperatorBuilder::Int32Constant(int32_t value) {
681   return new (zone()) Operator1<int32_t>(         // --
682       IrOpcode::kInt32Constant, Operator::kPure,  // opcode
683       "Int32Constant",                            // name
684       0, 0, 0, 1, 0, 0,                           // counts
685       value);                                     // parameter
686 }
687 
688 
Int64Constant(int64_t value)689 const Operator* CommonOperatorBuilder::Int64Constant(int64_t value) {
690   return new (zone()) Operator1<int64_t>(         // --
691       IrOpcode::kInt64Constant, Operator::kPure,  // opcode
692       "Int64Constant",                            // name
693       0, 0, 0, 1, 0, 0,                           // counts
694       value);                                     // parameter
695 }
696 
697 
Float32Constant(volatile float value)698 const Operator* CommonOperatorBuilder::Float32Constant(volatile float value) {
699   return new (zone()) Operator1<float>(             // --
700       IrOpcode::kFloat32Constant, Operator::kPure,  // opcode
701       "Float32Constant",                            // name
702       0, 0, 0, 1, 0, 0,                             // counts
703       value);                                       // parameter
704 }
705 
706 
Float64Constant(volatile double value)707 const Operator* CommonOperatorBuilder::Float64Constant(volatile double value) {
708   return new (zone()) Operator1<double>(            // --
709       IrOpcode::kFloat64Constant, Operator::kPure,  // opcode
710       "Float64Constant",                            // name
711       0, 0, 0, 1, 0, 0,                             // counts
712       value);                                       // parameter
713 }
714 
715 
ExternalConstant(const ExternalReference & value)716 const Operator* CommonOperatorBuilder::ExternalConstant(
717     const ExternalReference& value) {
718   return new (zone()) Operator1<ExternalReference>(  // --
719       IrOpcode::kExternalConstant, Operator::kPure,  // opcode
720       "ExternalConstant",                            // name
721       0, 0, 0, 1, 0, 0,                              // counts
722       value);                                        // parameter
723 }
724 
725 
NumberConstant(volatile double value)726 const Operator* CommonOperatorBuilder::NumberConstant(volatile double value) {
727   return new (zone()) Operator1<double>(           // --
728       IrOpcode::kNumberConstant, Operator::kPure,  // opcode
729       "NumberConstant",                            // name
730       0, 0, 0, 1, 0, 0,                            // counts
731       value);                                      // parameter
732 }
733 
734 
HeapConstant(const Handle<HeapObject> & value)735 const Operator* CommonOperatorBuilder::HeapConstant(
736     const Handle<HeapObject>& value) {
737   return new (zone()) Operator1<Handle<HeapObject>>(  // --
738       IrOpcode::kHeapConstant, Operator::kPure,       // opcode
739       "HeapConstant",                                 // name
740       0, 0, 0, 1, 0, 0,                               // counts
741       value);                                         // parameter
742 }
743 
RelocatableInt32Constant(int32_t value,RelocInfo::Mode rmode)744 const Operator* CommonOperatorBuilder::RelocatableInt32Constant(
745     int32_t value, RelocInfo::Mode rmode) {
746   return new (zone()) Operator1<RelocatablePtrConstantInfo>(  // --
747       IrOpcode::kRelocatableInt32Constant, Operator::kPure,   // opcode
748       "RelocatableInt32Constant",                             // name
749       0, 0, 0, 1, 0, 0,                                       // counts
750       RelocatablePtrConstantInfo(value, rmode));              // parameter
751 }
752 
RelocatableInt64Constant(int64_t value,RelocInfo::Mode rmode)753 const Operator* CommonOperatorBuilder::RelocatableInt64Constant(
754     int64_t value, RelocInfo::Mode rmode) {
755   return new (zone()) Operator1<RelocatablePtrConstantInfo>(  // --
756       IrOpcode::kRelocatableInt64Constant, Operator::kPure,   // opcode
757       "RelocatableInt64Constant",                             // name
758       0, 0, 0, 1, 0, 0,                                       // counts
759       RelocatablePtrConstantInfo(value, rmode));              // parameter
760 }
761 
Select(MachineRepresentation rep,BranchHint hint)762 const Operator* CommonOperatorBuilder::Select(MachineRepresentation rep,
763                                               BranchHint hint) {
764   return new (zone()) Operator1<SelectParameters>(  // --
765       IrOpcode::kSelect, Operator::kPure,           // opcode
766       "Select",                                     // name
767       3, 0, 0, 1, 0, 0,                             // counts
768       SelectParameters(rep, hint));                 // parameter
769 }
770 
771 
Phi(MachineRepresentation rep,int value_input_count)772 const Operator* CommonOperatorBuilder::Phi(MachineRepresentation rep,
773                                            int value_input_count) {
774   DCHECK(value_input_count > 0);  // Disallow empty phis.
775 #define CACHED_PHI(kRep, kValueInputCount)                 \
776   if (MachineRepresentation::kRep == rep &&                \
777       kValueInputCount == value_input_count) {             \
778     return &cache_.kPhi##kRep##kValueInputCount##Operator; \
779   }
780   CACHED_PHI_LIST(CACHED_PHI)
781 #undef CACHED_PHI
782   // Uncached.
783   return new (zone()) Operator1<MachineRepresentation>(  // --
784       IrOpcode::kPhi, Operator::kPure,                   // opcode
785       "Phi",                                             // name
786       value_input_count, 0, 1, 1, 0, 0,                  // counts
787       rep);                                              // parameter
788 }
789 
790 
EffectPhi(int effect_input_count)791 const Operator* CommonOperatorBuilder::EffectPhi(int effect_input_count) {
792   DCHECK(effect_input_count > 0);  // Disallow empty effect phis.
793   switch (effect_input_count) {
794 #define CACHED_EFFECT_PHI(input_count) \
795   case input_count:                    \
796     return &cache_.kEffectPhi##input_count##Operator;
797     CACHED_EFFECT_PHI_LIST(CACHED_EFFECT_PHI)
798 #undef CACHED_EFFECT_PHI
799     default:
800       break;
801   }
802   // Uncached.
803   return new (zone()) Operator(               // --
804       IrOpcode::kEffectPhi, Operator::kPure,  // opcode
805       "EffectPhi",                            // name
806       0, effect_input_count, 1, 0, 1, 0);     // counts
807 }
808 
BeginRegion(RegionObservability region_observability)809 const Operator* CommonOperatorBuilder::BeginRegion(
810     RegionObservability region_observability) {
811   switch (region_observability) {
812     case RegionObservability::kObservable:
813       return &cache_.kBeginRegionObservableOperator;
814     case RegionObservability::kNotObservable:
815       return &cache_.kBeginRegionNotObservableOperator;
816   }
817   UNREACHABLE();
818   return nullptr;
819 }
820 
StateValues(int arguments)821 const Operator* CommonOperatorBuilder::StateValues(int arguments) {
822   switch (arguments) {
823 #define CACHED_STATE_VALUES(arguments) \
824   case arguments:                      \
825     return &cache_.kStateValues##arguments##Operator;
826     CACHED_STATE_VALUES_LIST(CACHED_STATE_VALUES)
827 #undef CACHED_STATE_VALUES
828     default:
829       break;
830   }
831   // Uncached.
832   return new (zone()) Operator(                 // --
833       IrOpcode::kStateValues, Operator::kPure,  // opcode
834       "StateValues",                            // name
835       arguments, 0, 0, 1, 0, 0);                // counts
836 }
837 
838 
ObjectState(int pointer_slots,int id)839 const Operator* CommonOperatorBuilder::ObjectState(int pointer_slots, int id) {
840   return new (zone()) Operator1<int>(           // --
841       IrOpcode::kObjectState, Operator::kPure,  // opcode
842       "ObjectState",                            // name
843       pointer_slots, 0, 0, 1, 0, 0, id);        // counts
844 }
845 
846 
TypedStateValues(const ZoneVector<MachineType> * types)847 const Operator* CommonOperatorBuilder::TypedStateValues(
848     const ZoneVector<MachineType>* types) {
849   return new (zone()) Operator1<const ZoneVector<MachineType>*>(  // --
850       IrOpcode::kTypedStateValues, Operator::kPure,               // opcode
851       "TypedStateValues",                                         // name
852       static_cast<int>(types->size()), 0, 0, 1, 0, 0, types);     // counts
853 }
854 
855 
FrameState(BailoutId bailout_id,OutputFrameStateCombine state_combine,const FrameStateFunctionInfo * function_info)856 const Operator* CommonOperatorBuilder::FrameState(
857     BailoutId bailout_id, OutputFrameStateCombine state_combine,
858     const FrameStateFunctionInfo* function_info) {
859   FrameStateInfo state_info(bailout_id, state_combine, function_info);
860   return new (zone()) Operator1<FrameStateInfo>(  // --
861       IrOpcode::kFrameState, Operator::kPure,     // opcode
862       "FrameState",                               // name
863       5, 0, 0, 1, 0, 0,                           // counts
864       state_info);                                // parameter
865 }
866 
867 
Call(const CallDescriptor * descriptor)868 const Operator* CommonOperatorBuilder::Call(const CallDescriptor* descriptor) {
869   class CallOperator final : public Operator1<const CallDescriptor*> {
870    public:
871     explicit CallOperator(const CallDescriptor* descriptor)
872         : Operator1<const CallDescriptor*>(
873               IrOpcode::kCall, descriptor->properties(), "Call",
874               descriptor->InputCount() + descriptor->FrameStateCount(),
875               Operator::ZeroIfPure(descriptor->properties()),
876               Operator::ZeroIfEliminatable(descriptor->properties()),
877               descriptor->ReturnCount(),
878               Operator::ZeroIfPure(descriptor->properties()),
879               Operator::ZeroIfNoThrow(descriptor->properties()), descriptor) {}
880 
881     void PrintParameter(std::ostream& os) const override {
882       os << "[" << *parameter() << "]";
883     }
884   };
885   return new (zone()) CallOperator(descriptor);
886 }
887 
888 
TailCall(const CallDescriptor * descriptor)889 const Operator* CommonOperatorBuilder::TailCall(
890     const CallDescriptor* descriptor) {
891   class TailCallOperator final : public Operator1<const CallDescriptor*> {
892    public:
893     explicit TailCallOperator(const CallDescriptor* descriptor)
894         : Operator1<const CallDescriptor*>(
895               IrOpcode::kTailCall, descriptor->properties(), "TailCall",
896               descriptor->InputCount() + descriptor->FrameStateCount(), 1, 1, 0,
897               0, 1, descriptor) {}
898 
899     void PrintParameter(std::ostream& os) const override {
900       os << "[" << *parameter() << "]";
901     }
902   };
903   return new (zone()) TailCallOperator(descriptor);
904 }
905 
906 
Projection(size_t index)907 const Operator* CommonOperatorBuilder::Projection(size_t index) {
908   switch (index) {
909 #define CACHED_PROJECTION(index) \
910   case index:                    \
911     return &cache_.kProjection##index##Operator;
912     CACHED_PROJECTION_LIST(CACHED_PROJECTION)
913 #undef CACHED_PROJECTION
914     default:
915       break;
916   }
917   // Uncached.
918   return new (zone()) Operator1<size_t>(  // --
919       IrOpcode::kProjection,              // opcode
920       Operator::kPure,                    // flags
921       "Projection",                       // name
922       1, 0, 1, 1, 0, 0,                   // counts
923       index);                             // parameter
924 }
925 
926 
ResizeMergeOrPhi(const Operator * op,int size)927 const Operator* CommonOperatorBuilder::ResizeMergeOrPhi(const Operator* op,
928                                                         int size) {
929   if (op->opcode() == IrOpcode::kPhi) {
930     return Phi(PhiRepresentationOf(op), size);
931   } else if (op->opcode() == IrOpcode::kEffectPhi) {
932     return EffectPhi(size);
933   } else if (op->opcode() == IrOpcode::kMerge) {
934     return Merge(size);
935   } else if (op->opcode() == IrOpcode::kLoop) {
936     return Loop(size);
937   } else {
938     UNREACHABLE();
939     return nullptr;
940   }
941 }
942 
943 
944 const FrameStateFunctionInfo*
CreateFrameStateFunctionInfo(FrameStateType type,int parameter_count,int local_count,Handle<SharedFunctionInfo> shared_info)945 CommonOperatorBuilder::CreateFrameStateFunctionInfo(
946     FrameStateType type, int parameter_count, int local_count,
947     Handle<SharedFunctionInfo> shared_info) {
948   return new (zone()->New(sizeof(FrameStateFunctionInfo)))
949       FrameStateFunctionInfo(type, parameter_count, local_count, shared_info);
950 }
951 
952 }  // namespace compiler
953 }  // namespace internal
954 }  // namespace v8
955