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