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