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 
101 
ProjectionIndexOf(const Operator * const op)102 size_t ProjectionIndexOf(const Operator* const op) {
103   DCHECK_EQ(IrOpcode::kProjection, op->opcode());
104   return OpParameter<size_t>(op);
105 }
106 
107 
PhiRepresentationOf(const Operator * const op)108 MachineRepresentation PhiRepresentationOf(const Operator* const op) {
109   DCHECK_EQ(IrOpcode::kPhi, op->opcode());
110   return OpParameter<MachineRepresentation>(op);
111 }
112 
113 
ParameterIndexOf(const Operator * const op)114 int ParameterIndexOf(const Operator* const op) {
115   DCHECK_EQ(IrOpcode::kParameter, op->opcode());
116   return OpParameter<ParameterInfo>(op).index();
117 }
118 
119 
ParameterInfoOf(const Operator * const op)120 const ParameterInfo& ParameterInfoOf(const Operator* const op) {
121   DCHECK_EQ(IrOpcode::kParameter, op->opcode());
122   return OpParameter<ParameterInfo>(op);
123 }
124 
125 
operator ==(ParameterInfo const & lhs,ParameterInfo const & rhs)126 bool operator==(ParameterInfo const& lhs, ParameterInfo const& rhs) {
127   return lhs.index() == rhs.index();
128 }
129 
130 
operator !=(ParameterInfo const & lhs,ParameterInfo const & rhs)131 bool operator!=(ParameterInfo const& lhs, ParameterInfo const& rhs) {
132   return !(lhs == rhs);
133 }
134 
135 
hash_value(ParameterInfo const & p)136 size_t hash_value(ParameterInfo const& p) { return p.index(); }
137 
138 
operator <<(std::ostream & os,ParameterInfo const & i)139 std::ostream& operator<<(std::ostream& os, ParameterInfo const& i) {
140   if (i.debug_name()) os << i.debug_name() << '#';
141   os << i.index();
142   return os;
143 }
144 
145 
146 #define CACHED_OP_LIST(V)                                  \
147   V(Dead, Operator::kFoldable, 0, 0, 0, 1, 1, 1)           \
148   V(IfTrue, Operator::kKontrol, 0, 0, 1, 0, 0, 1)          \
149   V(IfFalse, Operator::kKontrol, 0, 0, 1, 0, 0, 1)         \
150   V(IfSuccess, Operator::kKontrol, 0, 0, 1, 0, 0, 1)       \
151   V(IfDefault, Operator::kKontrol, 0, 0, 1, 0, 0, 1)       \
152   V(Throw, Operator::kKontrol, 1, 1, 1, 0, 0, 1)           \
153   V(Terminate, Operator::kKontrol, 0, 1, 1, 0, 0, 1)       \
154   V(OsrNormalEntry, Operator::kFoldable, 0, 1, 1, 0, 1, 1) \
155   V(OsrLoopEntry, Operator::kFoldable, 0, 1, 1, 0, 1, 1)   \
156   V(BeginRegion, Operator::kNoThrow, 0, 1, 0, 0, 1, 0)     \
157   V(FinishRegion, Operator::kNoThrow, 1, 1, 0, 1, 1, 0)
158 
159 
160 #define CACHED_RETURN_LIST(V) \
161   V(1)                        \
162   V(2)                        \
163   V(3)
164 
165 
166 #define CACHED_END_LIST(V) \
167   V(1)                     \
168   V(2)                     \
169   V(3)                     \
170   V(4)                     \
171   V(5)                     \
172   V(6)                     \
173   V(7)                     \
174   V(8)
175 
176 
177 #define CACHED_EFFECT_PHI_LIST(V) \
178   V(1)                            \
179   V(2)                            \
180   V(3)                            \
181   V(4)                            \
182   V(5)                            \
183   V(6)
184 
185 
186 #define CACHED_LOOP_LIST(V) \
187   V(1)                      \
188   V(2)
189 
190 
191 #define CACHED_MERGE_LIST(V) \
192   V(1)                       \
193   V(2)                       \
194   V(3)                       \
195   V(4)                       \
196   V(5)                       \
197   V(6)                       \
198   V(7)                       \
199   V(8)
200 
201 
202 #define CACHED_PARAMETER_LIST(V) \
203   V(0)                           \
204   V(1)                           \
205   V(2)                           \
206   V(3)                           \
207   V(4)                           \
208   V(5)                           \
209   V(6)
210 
211 
212 #define CACHED_PHI_LIST(V) \
213   V(kTagged, 1)            \
214   V(kTagged, 2)            \
215   V(kTagged, 3)            \
216   V(kTagged, 4)            \
217   V(kTagged, 5)            \
218   V(kTagged, 6)            \
219   V(kBit, 2)               \
220   V(kFloat64, 2)           \
221   V(kWord32, 2)
222 
223 
224 #define CACHED_PROJECTION_LIST(V) \
225   V(0)                            \
226   V(1)
227 
228 
229 #define CACHED_STATE_VALUES_LIST(V) \
230   V(0)                              \
231   V(1)                              \
232   V(2)                              \
233   V(3)                              \
234   V(4)                              \
235   V(5)                              \
236   V(6)                              \
237   V(7)                              \
238   V(8)                              \
239   V(10)                             \
240   V(11)                             \
241   V(12)                             \
242   V(13)                             \
243   V(14)
244 
245 
246 struct CommonOperatorGlobalCache final {
247 #define CACHED(Name, properties, value_input_count, effect_input_count,      \
248                control_input_count, value_output_count, effect_output_count, \
249                control_output_count)                                         \
250   struct Name##Operator final : public Operator {                            \
251     Name##Operator()                                                         \
252         : Operator(IrOpcode::k##Name, properties, #Name, value_input_count,  \
253                    effect_input_count, control_input_count,                  \
254                    value_output_count, effect_output_count,                  \
255                    control_output_count) {}                                  \
256   };                                                                         \
257   Name##Operator k##Name##Operator;
258   CACHED_OP_LIST(CACHED)
259 #undef CACHED
260 
261   template <DeoptimizeKind kKind>
262   struct DeoptimizeOperator final : public Operator1<DeoptimizeKind> {
DeoptimizeOperatorv8::internal::compiler::CommonOperatorGlobalCache::DeoptimizeOperator263     DeoptimizeOperator()
264         : Operator1<DeoptimizeKind>(                      // --
265               IrOpcode::kDeoptimize, Operator::kNoThrow,  // opcode
266               "Deoptimize",                               // name
267               1, 1, 1, 0, 0, 1,                           // counts
268               kKind) {}                                   // parameter
269   };
270   DeoptimizeOperator<DeoptimizeKind::kEager> kDeoptimizeEagerOperator;
271   DeoptimizeOperator<DeoptimizeKind::kSoft> kDeoptimizeSoftOperator;
272 
273   template <IfExceptionHint kCaughtLocally>
274   struct IfExceptionOperator final : public Operator1<IfExceptionHint> {
IfExceptionOperatorv8::internal::compiler::CommonOperatorGlobalCache::IfExceptionOperator275     IfExceptionOperator()
276         : Operator1<IfExceptionHint>(                      // --
277               IrOpcode::kIfException, Operator::kKontrol,  // opcode
278               "IfException",                               // name
279               0, 1, 1, 1, 1, 1,                            // counts
280               kCaughtLocally) {}                           // parameter
281   };
282   IfExceptionOperator<IfExceptionHint::kLocallyCaught> kIfExceptionCOperator;
283   IfExceptionOperator<IfExceptionHint::kLocallyUncaught> kIfExceptionUOperator;
284 
285   template <size_t kInputCount>
286   struct EndOperator final : public Operator {
EndOperatorv8::internal::compiler::CommonOperatorGlobalCache::EndOperator287     EndOperator()
288         : Operator(                                // --
289               IrOpcode::kEnd, Operator::kKontrol,  // opcode
290               "End",                               // name
291               0, 0, kInputCount, 0, 0, 0) {}       // counts
292   };
293 #define CACHED_END(input_count) \
294   EndOperator<input_count> kEnd##input_count##Operator;
295   CACHED_END_LIST(CACHED_END)
296 #undef CACHED_END
297 
298   template <size_t kInputCount>
299   struct ReturnOperator final : public Operator {
ReturnOperatorv8::internal::compiler::CommonOperatorGlobalCache::ReturnOperator300     ReturnOperator()
301         : Operator(                                   // --
302               IrOpcode::kReturn, Operator::kNoThrow,  // opcode
303               "Return",                               // name
304               kInputCount, 1, 1, 0, 0, 1) {}          // counts
305   };
306 #define CACHED_RETURN(input_count) \
307   ReturnOperator<input_count> kReturn##input_count##Operator;
308   CACHED_RETURN_LIST(CACHED_RETURN)
309 #undef CACHED_RETURN
310 
311   template <BranchHint kBranchHint>
312   struct BranchOperator final : public Operator1<BranchHint> {
BranchOperatorv8::internal::compiler::CommonOperatorGlobalCache::BranchOperator313     BranchOperator()
314         : Operator1<BranchHint>(                      // --
315               IrOpcode::kBranch, Operator::kKontrol,  // opcode
316               "Branch",                               // name
317               1, 0, 1, 0, 0, 2,                       // counts
318               kBranchHint) {}                         // parameter
319   };
320   BranchOperator<BranchHint::kNone> kBranchNoneOperator;
321   BranchOperator<BranchHint::kTrue> kBranchTrueOperator;
322   BranchOperator<BranchHint::kFalse> kBranchFalseOperator;
323 
324   template <int kEffectInputCount>
325   struct EffectPhiOperator final : public Operator {
EffectPhiOperatorv8::internal::compiler::CommonOperatorGlobalCache::EffectPhiOperator326     EffectPhiOperator()
327         : Operator(                                   // --
328               IrOpcode::kEffectPhi, Operator::kPure,  // opcode
329               "EffectPhi",                            // name
330               0, kEffectInputCount, 1, 0, 1, 0) {}    // counts
331   };
332 #define CACHED_EFFECT_PHI(input_count) \
333   EffectPhiOperator<input_count> kEffectPhi##input_count##Operator;
334   CACHED_EFFECT_PHI_LIST(CACHED_EFFECT_PHI)
335 #undef CACHED_EFFECT_PHI
336 
337   template <size_t kInputCount>
338   struct LoopOperator final : public Operator {
LoopOperatorv8::internal::compiler::CommonOperatorGlobalCache::LoopOperator339     LoopOperator()
340         : Operator(                                 // --
341               IrOpcode::kLoop, Operator::kKontrol,  // opcode
342               "Loop",                               // name
343               0, 0, kInputCount, 0, 0, 1) {}        // counts
344   };
345 #define CACHED_LOOP(input_count) \
346   LoopOperator<input_count> kLoop##input_count##Operator;
347   CACHED_LOOP_LIST(CACHED_LOOP)
348 #undef CACHED_LOOP
349 
350   template <size_t kInputCount>
351   struct MergeOperator final : public Operator {
MergeOperatorv8::internal::compiler::CommonOperatorGlobalCache::MergeOperator352     MergeOperator()
353         : Operator(                                  // --
354               IrOpcode::kMerge, Operator::kKontrol,  // opcode
355               "Merge",                               // name
356               0, 0, kInputCount, 0, 0, 1) {}         // counts
357   };
358 #define CACHED_MERGE(input_count) \
359   MergeOperator<input_count> kMerge##input_count##Operator;
360   CACHED_MERGE_LIST(CACHED_MERGE)
361 #undef CACHED_MERGE
362 
363   template <MachineRepresentation kRep, int kInputCount>
364   struct PhiOperator final : public Operator1<MachineRepresentation> {
PhiOperatorv8::internal::compiler::CommonOperatorGlobalCache::PhiOperator365     PhiOperator()
366         : Operator1<MachineRepresentation>(     //--
367               IrOpcode::kPhi, Operator::kPure,  // opcode
368               "Phi",                            // name
369               kInputCount, 0, 1, 1, 0, 0,       // counts
370               kRep) {}                          // parameter
371   };
372 #define CACHED_PHI(rep, input_count)                   \
373   PhiOperator<MachineRepresentation::rep, input_count> \
374       kPhi##rep##input_count##Operator;
375   CACHED_PHI_LIST(CACHED_PHI)
376 #undef CACHED_PHI
377 
378   template <int kIndex>
379   struct ParameterOperator final : public Operator1<ParameterInfo> {
ParameterOperatorv8::internal::compiler::CommonOperatorGlobalCache::ParameterOperator380     ParameterOperator()
381         : Operator1<ParameterInfo>(                   // --
382               IrOpcode::kParameter, Operator::kPure,  // opcode
383               "Parameter",                            // name
384               1, 0, 0, 1, 0, 0,                       // counts,
385               ParameterInfo(kIndex, nullptr)) {}      // parameter and name
386   };
387 #define CACHED_PARAMETER(index) \
388   ParameterOperator<index> kParameter##index##Operator;
389   CACHED_PARAMETER_LIST(CACHED_PARAMETER)
390 #undef CACHED_PARAMETER
391 
392   template <size_t kIndex>
393   struct ProjectionOperator final : public Operator1<size_t> {
ProjectionOperatorv8::internal::compiler::CommonOperatorGlobalCache::ProjectionOperator394     ProjectionOperator()
395         : Operator1<size_t>(          // --
396               IrOpcode::kProjection,  // opcode
397               Operator::kPure,        // flags
398               "Projection",           // name
399               1, 0, 0, 1, 0, 0,       // counts,
400               kIndex) {}              // parameter
401   };
402 #define CACHED_PROJECTION(index) \
403   ProjectionOperator<index> kProjection##index##Operator;
404   CACHED_PROJECTION_LIST(CACHED_PROJECTION)
405 #undef CACHED_PROJECTION
406 
407   template <int kInputCount>
408   struct StateValuesOperator final : public Operator {
StateValuesOperatorv8::internal::compiler::CommonOperatorGlobalCache::StateValuesOperator409     StateValuesOperator()
410         : Operator(                           // --
411               IrOpcode::kStateValues,         // opcode
412               Operator::kPure,                // flags
413               "StateValues",                  // name
414               kInputCount, 0, 0, 1, 0, 0) {}  // counts
415   };
416 #define CACHED_STATE_VALUES(input_count) \
417   StateValuesOperator<input_count> kStateValues##input_count##Operator;
418   CACHED_STATE_VALUES_LIST(CACHED_STATE_VALUES)
419 #undef CACHED_STATE_VALUES
420 };
421 
422 
423 static base::LazyInstance<CommonOperatorGlobalCache>::type kCache =
424     LAZY_INSTANCE_INITIALIZER;
425 
426 
CommonOperatorBuilder(Zone * zone)427 CommonOperatorBuilder::CommonOperatorBuilder(Zone* zone)
428     : cache_(kCache.Get()), zone_(zone) {}
429 
430 
431 #define CACHED(Name, properties, value_input_count, effect_input_count,      \
432                control_input_count, value_output_count, effect_output_count, \
433                control_output_count)                                         \
434   const Operator* CommonOperatorBuilder::Name() {                            \
435     return &cache_.k##Name##Operator;                                        \
436   }
CACHED_OP_LIST(CACHED) const437 CACHED_OP_LIST(CACHED)
438 #undef CACHED
439 
440 
441 const Operator* CommonOperatorBuilder::End(size_t control_input_count) {
442   switch (control_input_count) {
443 #define CACHED_END(input_count) \
444   case input_count:             \
445     return &cache_.kEnd##input_count##Operator;
446     CACHED_END_LIST(CACHED_END)
447 #undef CACHED_END
448     default:
449       break;
450   }
451   // Uncached.
452   return new (zone()) Operator(             //--
453       IrOpcode::kEnd, Operator::kKontrol,   // opcode
454       "End",                                // name
455       0, 0, control_input_count, 0, 0, 0);  // counts
456 }
457 
458 
Return(int value_input_count)459 const Operator* CommonOperatorBuilder::Return(int value_input_count) {
460   switch (value_input_count) {
461 #define CACHED_RETURN(input_count) \
462   case input_count:                \
463     return &cache_.kReturn##input_count##Operator;
464     CACHED_RETURN_LIST(CACHED_RETURN)
465 #undef CACHED_RETURN
466     default:
467       break;
468   }
469   // Uncached.
470   return new (zone()) Operator(               //--
471       IrOpcode::kReturn, Operator::kNoThrow,  // opcode
472       "Return",                               // name
473       value_input_count, 1, 1, 0, 0, 1);      // counts
474 }
475 
476 
Branch(BranchHint hint)477 const Operator* CommonOperatorBuilder::Branch(BranchHint hint) {
478   switch (hint) {
479     case BranchHint::kNone:
480       return &cache_.kBranchNoneOperator;
481     case BranchHint::kTrue:
482       return &cache_.kBranchTrueOperator;
483     case BranchHint::kFalse:
484       return &cache_.kBranchFalseOperator;
485   }
486   UNREACHABLE();
487   return nullptr;
488 }
489 
490 
Deoptimize(DeoptimizeKind kind)491 const Operator* CommonOperatorBuilder::Deoptimize(DeoptimizeKind kind) {
492   switch (kind) {
493     case DeoptimizeKind::kEager:
494       return &cache_.kDeoptimizeEagerOperator;
495     case DeoptimizeKind::kSoft:
496       return &cache_.kDeoptimizeSoftOperator;
497   }
498   UNREACHABLE();
499   return nullptr;
500 }
501 
502 
IfException(IfExceptionHint hint)503 const Operator* CommonOperatorBuilder::IfException(IfExceptionHint hint) {
504   switch (hint) {
505     case IfExceptionHint::kLocallyCaught:
506       return &cache_.kIfExceptionCOperator;
507     case IfExceptionHint::kLocallyUncaught:
508       return &cache_.kIfExceptionUOperator;
509   }
510   UNREACHABLE();
511   return nullptr;
512 }
513 
514 
Switch(size_t control_output_count)515 const Operator* CommonOperatorBuilder::Switch(size_t control_output_count) {
516   return new (zone()) Operator(               // --
517       IrOpcode::kSwitch, Operator::kKontrol,  // opcode
518       "Switch",                               // name
519       1, 0, 1, 0, 0, control_output_count);   // counts
520 }
521 
522 
IfValue(int32_t index)523 const Operator* CommonOperatorBuilder::IfValue(int32_t index) {
524   return new (zone()) Operator1<int32_t>(      // --
525       IrOpcode::kIfValue, Operator::kKontrol,  // opcode
526       "IfValue",                               // name
527       0, 0, 1, 0, 0, 1,                        // counts
528       index);                                  // parameter
529 }
530 
531 
Start(int value_output_count)532 const Operator* CommonOperatorBuilder::Start(int value_output_count) {
533   return new (zone()) Operator(               // --
534       IrOpcode::kStart, Operator::kFoldable,  // opcode
535       "Start",                                // name
536       0, 0, 0, value_output_count, 1, 1);     // counts
537 }
538 
539 
Loop(int control_input_count)540 const Operator* CommonOperatorBuilder::Loop(int control_input_count) {
541   switch (control_input_count) {
542 #define CACHED_LOOP(input_count) \
543   case input_count:              \
544     return &cache_.kLoop##input_count##Operator;
545     CACHED_LOOP_LIST(CACHED_LOOP)
546 #undef CACHED_LOOP
547     default:
548       break;
549   }
550   // Uncached.
551   return new (zone()) Operator(             // --
552       IrOpcode::kLoop, Operator::kKontrol,  // opcode
553       "Loop",                               // name
554       0, 0, control_input_count, 0, 0, 1);  // counts
555 }
556 
557 
Merge(int control_input_count)558 const Operator* CommonOperatorBuilder::Merge(int control_input_count) {
559   switch (control_input_count) {
560 #define CACHED_MERGE(input_count) \
561   case input_count:               \
562     return &cache_.kMerge##input_count##Operator;
563     CACHED_MERGE_LIST(CACHED_MERGE)
564 #undef CACHED_MERGE
565     default:
566       break;
567   }
568   // Uncached.
569   return new (zone()) Operator(              // --
570       IrOpcode::kMerge, Operator::kKontrol,  // opcode
571       "Merge",                               // name
572       0, 0, control_input_count, 0, 0, 1);   // counts
573 }
574 
575 
Parameter(int index,const char * debug_name)576 const Operator* CommonOperatorBuilder::Parameter(int index,
577                                                  const char* debug_name) {
578   if (!debug_name) {
579     switch (index) {
580 #define CACHED_PARAMETER(index) \
581   case index:                   \
582     return &cache_.kParameter##index##Operator;
583       CACHED_PARAMETER_LIST(CACHED_PARAMETER)
584 #undef CACHED_PARAMETER
585       default:
586         break;
587     }
588   }
589   // Uncached.
590   return new (zone()) Operator1<ParameterInfo>(  // --
591       IrOpcode::kParameter, Operator::kPure,     // opcode
592       "Parameter",                               // name
593       1, 0, 0, 1, 0, 0,                          // counts
594       ParameterInfo(index, debug_name));         // parameter info
595 }
596 
597 
OsrValue(int index)598 const Operator* CommonOperatorBuilder::OsrValue(int index) {
599   return new (zone()) Operator1<int>(                // --
600       IrOpcode::kOsrValue, Operator::kNoProperties,  // opcode
601       "OsrValue",                                    // name
602       0, 0, 1, 1, 0, 0,                              // counts
603       index);                                        // parameter
604 }
605 
606 
Int32Constant(int32_t value)607 const Operator* CommonOperatorBuilder::Int32Constant(int32_t value) {
608   return new (zone()) Operator1<int32_t>(         // --
609       IrOpcode::kInt32Constant, Operator::kPure,  // opcode
610       "Int32Constant",                            // name
611       0, 0, 0, 1, 0, 0,                           // counts
612       value);                                     // parameter
613 }
614 
615 
Int64Constant(int64_t value)616 const Operator* CommonOperatorBuilder::Int64Constant(int64_t value) {
617   return new (zone()) Operator1<int64_t>(         // --
618       IrOpcode::kInt64Constant, Operator::kPure,  // opcode
619       "Int64Constant",                            // name
620       0, 0, 0, 1, 0, 0,                           // counts
621       value);                                     // parameter
622 }
623 
624 
Float32Constant(volatile float value)625 const Operator* CommonOperatorBuilder::Float32Constant(volatile float value) {
626   return new (zone()) Operator1<float>(             // --
627       IrOpcode::kFloat32Constant, Operator::kPure,  // opcode
628       "Float32Constant",                            // name
629       0, 0, 0, 1, 0, 0,                             // counts
630       value);                                       // parameter
631 }
632 
633 
Float64Constant(volatile double value)634 const Operator* CommonOperatorBuilder::Float64Constant(volatile double value) {
635   return new (zone()) Operator1<double>(            // --
636       IrOpcode::kFloat64Constant, Operator::kPure,  // opcode
637       "Float64Constant",                            // name
638       0, 0, 0, 1, 0, 0,                             // counts
639       value);                                       // parameter
640 }
641 
642 
ExternalConstant(const ExternalReference & value)643 const Operator* CommonOperatorBuilder::ExternalConstant(
644     const ExternalReference& value) {
645   return new (zone()) Operator1<ExternalReference>(  // --
646       IrOpcode::kExternalConstant, Operator::kPure,  // opcode
647       "ExternalConstant",                            // name
648       0, 0, 0, 1, 0, 0,                              // counts
649       value);                                        // parameter
650 }
651 
652 
NumberConstant(volatile double value)653 const Operator* CommonOperatorBuilder::NumberConstant(volatile double value) {
654   return new (zone()) Operator1<double>(           // --
655       IrOpcode::kNumberConstant, Operator::kPure,  // opcode
656       "NumberConstant",                            // name
657       0, 0, 0, 1, 0, 0,                            // counts
658       value);                                      // parameter
659 }
660 
661 
HeapConstant(const Handle<HeapObject> & value)662 const Operator* CommonOperatorBuilder::HeapConstant(
663     const Handle<HeapObject>& value) {
664   return new (zone()) Operator1<Handle<HeapObject>>(  // --
665       IrOpcode::kHeapConstant, Operator::kPure,       // opcode
666       "HeapConstant",                                 // name
667       0, 0, 0, 1, 0, 0,                               // counts
668       value);                                         // parameter
669 }
670 
671 
Select(MachineRepresentation rep,BranchHint hint)672 const Operator* CommonOperatorBuilder::Select(MachineRepresentation rep,
673                                               BranchHint hint) {
674   return new (zone()) Operator1<SelectParameters>(  // --
675       IrOpcode::kSelect, Operator::kPure,           // opcode
676       "Select",                                     // name
677       3, 0, 0, 1, 0, 0,                             // counts
678       SelectParameters(rep, hint));                 // parameter
679 }
680 
681 
Phi(MachineRepresentation rep,int value_input_count)682 const Operator* CommonOperatorBuilder::Phi(MachineRepresentation rep,
683                                            int value_input_count) {
684   DCHECK(value_input_count > 0);  // Disallow empty phis.
685 #define CACHED_PHI(kRep, kValueInputCount)                 \
686   if (MachineRepresentation::kRep == rep &&                \
687       kValueInputCount == value_input_count) {             \
688     return &cache_.kPhi##kRep##kValueInputCount##Operator; \
689   }
690   CACHED_PHI_LIST(CACHED_PHI)
691 #undef CACHED_PHI
692   // Uncached.
693   return new (zone()) Operator1<MachineRepresentation>(  // --
694       IrOpcode::kPhi, Operator::kPure,                   // opcode
695       "Phi",                                             // name
696       value_input_count, 0, 1, 1, 0, 0,                  // counts
697       rep);                                              // parameter
698 }
699 
700 
EffectPhi(int effect_input_count)701 const Operator* CommonOperatorBuilder::EffectPhi(int effect_input_count) {
702   DCHECK(effect_input_count > 0);  // Disallow empty effect phis.
703   switch (effect_input_count) {
704 #define CACHED_EFFECT_PHI(input_count) \
705   case input_count:                    \
706     return &cache_.kEffectPhi##input_count##Operator;
707     CACHED_EFFECT_PHI_LIST(CACHED_EFFECT_PHI)
708 #undef CACHED_EFFECT_PHI
709     default:
710       break;
711   }
712   // Uncached.
713   return new (zone()) Operator(               // --
714       IrOpcode::kEffectPhi, Operator::kPure,  // opcode
715       "EffectPhi",                            // name
716       0, effect_input_count, 1, 0, 1, 0);     // counts
717 }
718 
719 
Guard(Type * type)720 const Operator* CommonOperatorBuilder::Guard(Type* type) {
721   return new (zone()) Operator1<Type*>(      // --
722       IrOpcode::kGuard, Operator::kKontrol,  // opcode
723       "Guard",                               // name
724       1, 0, 1, 1, 0, 0,                      // counts
725       type);                                 // parameter
726 }
727 
728 
EffectSet(int arguments)729 const Operator* CommonOperatorBuilder::EffectSet(int arguments) {
730   DCHECK(arguments > 1);                      // Disallow empty/singleton sets.
731   return new (zone()) Operator(               // --
732       IrOpcode::kEffectSet, Operator::kPure,  // opcode
733       "EffectSet",                            // name
734       0, arguments, 0, 0, 1, 0);              // counts
735 }
736 
737 
StateValues(int arguments)738 const Operator* CommonOperatorBuilder::StateValues(int arguments) {
739   switch (arguments) {
740 #define CACHED_STATE_VALUES(arguments) \
741   case arguments:                      \
742     return &cache_.kStateValues##arguments##Operator;
743     CACHED_STATE_VALUES_LIST(CACHED_STATE_VALUES)
744 #undef CACHED_STATE_VALUES
745     default:
746       break;
747   }
748   // Uncached.
749   return new (zone()) Operator(                 // --
750       IrOpcode::kStateValues, Operator::kPure,  // opcode
751       "StateValues",                            // name
752       arguments, 0, 0, 1, 0, 0);                // counts
753 }
754 
755 
ObjectState(int pointer_slots,int id)756 const Operator* CommonOperatorBuilder::ObjectState(int pointer_slots, int id) {
757   return new (zone()) Operator1<int>(           // --
758       IrOpcode::kObjectState, Operator::kPure,  // opcode
759       "ObjectState",                            // name
760       pointer_slots, 0, 0, 1, 0, 0, id);        // counts
761 }
762 
763 
TypedStateValues(const ZoneVector<MachineType> * types)764 const Operator* CommonOperatorBuilder::TypedStateValues(
765     const ZoneVector<MachineType>* types) {
766   return new (zone()) Operator1<const ZoneVector<MachineType>*>(  // --
767       IrOpcode::kTypedStateValues, Operator::kPure,               // opcode
768       "TypedStateValues",                                         // name
769       static_cast<int>(types->size()), 0, 0, 1, 0, 0, types);     // counts
770 }
771 
772 
FrameState(BailoutId bailout_id,OutputFrameStateCombine state_combine,const FrameStateFunctionInfo * function_info)773 const Operator* CommonOperatorBuilder::FrameState(
774     BailoutId bailout_id, OutputFrameStateCombine state_combine,
775     const FrameStateFunctionInfo* function_info) {
776   FrameStateInfo state_info(bailout_id, state_combine, function_info);
777   return new (zone()) Operator1<FrameStateInfo>(  // --
778       IrOpcode::kFrameState, Operator::kPure,     // opcode
779       "FrameState",                               // name
780       5, 0, 0, 1, 0, 0,                           // counts
781       state_info);                                // parameter
782 }
783 
784 
Call(const CallDescriptor * descriptor)785 const Operator* CommonOperatorBuilder::Call(const CallDescriptor* descriptor) {
786   class CallOperator final : public Operator1<const CallDescriptor*> {
787    public:
788     explicit CallOperator(const CallDescriptor* descriptor)
789         : Operator1<const CallDescriptor*>(
790               IrOpcode::kCall, descriptor->properties(), "Call",
791               descriptor->InputCount() + descriptor->FrameStateCount(),
792               Operator::ZeroIfPure(descriptor->properties()),
793               Operator::ZeroIfEliminatable(descriptor->properties()),
794               descriptor->ReturnCount(),
795               Operator::ZeroIfPure(descriptor->properties()),
796               Operator::ZeroIfNoThrow(descriptor->properties()), descriptor) {}
797 
798     void PrintParameter(std::ostream& os) const override {
799       os << "[" << *parameter() << "]";
800     }
801   };
802   return new (zone()) CallOperator(descriptor);
803 }
804 
805 
LazyBailout()806 const Operator* CommonOperatorBuilder::LazyBailout() {
807   return Call(Linkage::GetLazyBailoutDescriptor(zone()));
808 }
809 
810 
TailCall(const CallDescriptor * descriptor)811 const Operator* CommonOperatorBuilder::TailCall(
812     const CallDescriptor* descriptor) {
813   class TailCallOperator final : public Operator1<const CallDescriptor*> {
814    public:
815     explicit TailCallOperator(const CallDescriptor* descriptor)
816         : Operator1<const CallDescriptor*>(
817               IrOpcode::kTailCall, descriptor->properties(), "TailCall",
818               descriptor->InputCount() + descriptor->FrameStateCount(), 1, 1, 0,
819               0, 1, descriptor) {}
820 
821     void PrintParameter(std::ostream& os) const override {
822       os << "[" << *parameter() << "]";
823     }
824   };
825   return new (zone()) TailCallOperator(descriptor);
826 }
827 
828 
Projection(size_t index)829 const Operator* CommonOperatorBuilder::Projection(size_t index) {
830   switch (index) {
831 #define CACHED_PROJECTION(index) \
832   case index:                    \
833     return &cache_.kProjection##index##Operator;
834     CACHED_PROJECTION_LIST(CACHED_PROJECTION)
835 #undef CACHED_PROJECTION
836     default:
837       break;
838   }
839   // Uncached.
840   return new (zone()) Operator1<size_t>(         // --
841       IrOpcode::kProjection,                     // opcode
842       Operator::kFoldable | Operator::kNoThrow,  // flags
843       "Projection",                              // name
844       1, 0, 0, 1, 0, 0,                          // counts
845       index);                                    // parameter
846 }
847 
848 
ResizeMergeOrPhi(const Operator * op,int size)849 const Operator* CommonOperatorBuilder::ResizeMergeOrPhi(const Operator* op,
850                                                         int size) {
851   if (op->opcode() == IrOpcode::kPhi) {
852     return Phi(PhiRepresentationOf(op), size);
853   } else if (op->opcode() == IrOpcode::kEffectPhi) {
854     return EffectPhi(size);
855   } else if (op->opcode() == IrOpcode::kMerge) {
856     return Merge(size);
857   } else if (op->opcode() == IrOpcode::kLoop) {
858     return Loop(size);
859   } else {
860     UNREACHABLE();
861     return nullptr;
862   }
863 }
864 
865 
866 const FrameStateFunctionInfo*
CreateFrameStateFunctionInfo(FrameStateType type,int parameter_count,int local_count,Handle<SharedFunctionInfo> shared_info,ContextCallingMode context_calling_mode)867 CommonOperatorBuilder::CreateFrameStateFunctionInfo(
868     FrameStateType type, int parameter_count, int local_count,
869     Handle<SharedFunctionInfo> shared_info,
870     ContextCallingMode context_calling_mode) {
871   return new (zone()->New(sizeof(FrameStateFunctionInfo)))
872       FrameStateFunctionInfo(type, parameter_count, local_count, shared_info,
873                              context_calling_mode);
874 }
875 
876 }  // namespace compiler
877 }  // namespace internal
878 }  // namespace v8
879