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