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