blob: 3bb1b34495fbcef242e04a7257c9b579a7552de0 [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040010#include "src/compiler/opcodes.h"
11#include "src/compiler/operator.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000012#include "src/handles-inl.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000013#include "src/zone.h"
14
15namespace v8 {
16namespace internal {
17namespace compiler {
18
Emily Bernierd0a1eb72015-03-24 16:35:39 -040019std::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";
Ben Murdochb8a8cc12014-11-26 15:28:44 +000027 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -040028 UNREACHABLE();
29 return os;
30}
31
32
33BranchHint BranchHintOf(const Operator* const op) {
34 DCHECK_EQ(IrOpcode::kBranch, op->opcode());
35 return OpParameter<BranchHint>(op);
36}
37
38
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000039size_t hash_value(DeoptimizeKind kind) { return static_cast<size_t>(kind); }
40
41
42std::ostream& operator<<(std::ostream& os, DeoptimizeKind kind) {
43 switch (kind) {
44 case DeoptimizeKind::kEager:
45 return os << "Eager";
46 case DeoptimizeKind::kSoft:
47 return os << "Soft";
48 }
49 UNREACHABLE();
50 return os;
51}
52
53
54DeoptimizeKind DeoptimizeKindOf(const Operator* const op) {
55 DCHECK_EQ(IrOpcode::kDeoptimize, op->opcode());
56 return OpParameter<DeoptimizeKind>(op);
57}
58
59
60size_t hash_value(IfExceptionHint hint) { return static_cast<size_t>(hint); }
61
62
63std::ostream& operator<<(std::ostream& os, IfExceptionHint hint) {
64 switch (hint) {
65 case IfExceptionHint::kLocallyCaught:
66 return os << "Caught";
67 case IfExceptionHint::kLocallyUncaught:
68 return os << "Uncaught";
69 }
70 UNREACHABLE();
71 return os;
72}
73
74
Emily Bernierd0a1eb72015-03-24 16:35:39 -040075bool operator==(SelectParameters const& lhs, SelectParameters const& rhs) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000076 return lhs.representation() == rhs.representation() &&
77 lhs.hint() == rhs.hint();
Emily Bernierd0a1eb72015-03-24 16:35:39 -040078}
79
80
81bool operator!=(SelectParameters const& lhs, SelectParameters const& rhs) {
82 return !(lhs == rhs);
83}
84
85
86size_t hash_value(SelectParameters const& p) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000087 return base::hash_combine(p.representation(), p.hint());
Emily Bernierd0a1eb72015-03-24 16:35:39 -040088}
89
90
91std::ostream& operator<<(std::ostream& os, SelectParameters const& p) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000092 return os << p.representation() << "|" << p.hint();
Emily Bernierd0a1eb72015-03-24 16:35:39 -040093}
94
95
96SelectParameters const& SelectParametersOf(const Operator* const op) {
97 DCHECK_EQ(IrOpcode::kSelect, op->opcode());
98 return OpParameter<SelectParameters>(op);
99}
100
101
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000102size_t ProjectionIndexOf(const Operator* const op) {
103 DCHECK_EQ(IrOpcode::kProjection, op->opcode());
104 return OpParameter<size_t>(op);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400105}
106
107
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000108MachineRepresentation PhiRepresentationOf(const Operator* const op) {
109 DCHECK_EQ(IrOpcode::kPhi, op->opcode());
110 return OpParameter<MachineRepresentation>(op);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400111}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000112
113
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000114int ParameterIndexOf(const Operator* const op) {
115 DCHECK_EQ(IrOpcode::kParameter, op->opcode());
116 return OpParameter<ParameterInfo>(op).index();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400117}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000118
119
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000120const ParameterInfo& ParameterInfoOf(const Operator* const op) {
121 DCHECK_EQ(IrOpcode::kParameter, op->opcode());
122 return OpParameter<ParameterInfo>(op);
123}
124
125
126bool operator==(ParameterInfo const& lhs, ParameterInfo const& rhs) {
127 return lhs.index() == rhs.index();
128}
129
130
131bool operator!=(ParameterInfo const& lhs, ParameterInfo const& rhs) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400132 return !(lhs == rhs);
133}
134
135
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000136size_t hash_value(ParameterInfo const& p) { return p.index(); }
137
138
139std::ostream& operator<<(std::ostream& os, ParameterInfo const& i) {
140 if (i.debug_name()) os << i.debug_name() << '#';
141 os << i.index();
142 return os;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400143}
144
Ben Murdochda12d292016-06-02 14:46:10 +0100145#define CACHED_OP_LIST(V) \
146 V(Dead, Operator::kFoldable, 0, 0, 0, 1, 1, 1) \
147 V(DeoptimizeIf, Operator::kFoldable, 2, 1, 1, 0, 0, 1) \
148 V(DeoptimizeUnless, Operator::kFoldable, 2, 1, 1, 0, 0, 1) \
149 V(IfTrue, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \
150 V(IfFalse, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \
151 V(IfSuccess, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \
152 V(IfDefault, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \
153 V(Throw, Operator::kKontrol, 1, 1, 1, 0, 0, 1) \
154 V(Terminate, Operator::kKontrol, 0, 1, 1, 0, 0, 1) \
155 V(OsrNormalEntry, Operator::kFoldable, 0, 1, 1, 0, 1, 1) \
156 V(OsrLoopEntry, Operator::kFoldable, 0, 1, 1, 0, 1, 1) \
157 V(BeginRegion, Operator::kNoThrow, 0, 1, 0, 0, 1, 0) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000158 V(FinishRegion, Operator::kNoThrow, 1, 1, 0, 1, 1, 0)
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400159
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000160#define CACHED_RETURN_LIST(V) \
161 V(1) \
162 V(2) \
163 V(3)
164
165
166#define CACHED_END_LIST(V) \
167 V(1) \
168 V(2) \
169 V(3) \
170 V(4) \
171 V(5) \
172 V(6) \
173 V(7) \
174 V(8)
175
176
177#define CACHED_EFFECT_PHI_LIST(V) \
178 V(1) \
179 V(2) \
180 V(3) \
181 V(4) \
182 V(5) \
183 V(6)
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400184
185
186#define CACHED_LOOP_LIST(V) \
187 V(1) \
188 V(2)
189
190
191#define CACHED_MERGE_LIST(V) \
192 V(1) \
193 V(2) \
194 V(3) \
195 V(4) \
196 V(5) \
197 V(6) \
198 V(7) \
199 V(8)
200
201
202#define CACHED_PARAMETER_LIST(V) \
203 V(0) \
204 V(1) \
205 V(2) \
206 V(3) \
207 V(4) \
208 V(5) \
209 V(6)
210
211
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000212#define CACHED_PHI_LIST(V) \
213 V(kTagged, 1) \
214 V(kTagged, 2) \
215 V(kTagged, 3) \
216 V(kTagged, 4) \
217 V(kTagged, 5) \
218 V(kTagged, 6) \
219 V(kBit, 2) \
220 V(kFloat64, 2) \
221 V(kWord32, 2)
222
223
224#define CACHED_PROJECTION_LIST(V) \
225 V(0) \
226 V(1)
227
228
229#define CACHED_STATE_VALUES_LIST(V) \
230 V(0) \
231 V(1) \
232 V(2) \
233 V(3) \
234 V(4) \
235 V(5) \
236 V(6) \
237 V(7) \
238 V(8) \
239 V(10) \
240 V(11) \
241 V(12) \
242 V(13) \
243 V(14)
244
245
246struct CommonOperatorGlobalCache final {
247#define CACHED(Name, properties, value_input_count, effect_input_count, \
248 control_input_count, value_output_count, effect_output_count, \
249 control_output_count) \
250 struct Name##Operator final : public Operator { \
251 Name##Operator() \
252 : Operator(IrOpcode::k##Name, properties, #Name, value_input_count, \
253 effect_input_count, control_input_count, \
254 value_output_count, effect_output_count, \
255 control_output_count) {} \
256 }; \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000257 Name##Operator k##Name##Operator;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400258 CACHED_OP_LIST(CACHED)
259#undef CACHED
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000260
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000261 template <DeoptimizeKind kKind>
262 struct DeoptimizeOperator final : public Operator1<DeoptimizeKind> {
263 DeoptimizeOperator()
264 : Operator1<DeoptimizeKind>( // --
265 IrOpcode::kDeoptimize, Operator::kNoThrow, // opcode
266 "Deoptimize", // name
267 1, 1, 1, 0, 0, 1, // counts
268 kKind) {} // parameter
269 };
270 DeoptimizeOperator<DeoptimizeKind::kEager> kDeoptimizeEagerOperator;
271 DeoptimizeOperator<DeoptimizeKind::kSoft> kDeoptimizeSoftOperator;
272
273 template <IfExceptionHint kCaughtLocally>
274 struct IfExceptionOperator final : public Operator1<IfExceptionHint> {
275 IfExceptionOperator()
276 : Operator1<IfExceptionHint>( // --
277 IrOpcode::kIfException, Operator::kKontrol, // opcode
278 "IfException", // name
279 0, 1, 1, 1, 1, 1, // counts
280 kCaughtLocally) {} // parameter
281 };
282 IfExceptionOperator<IfExceptionHint::kLocallyCaught> kIfExceptionCOperator;
283 IfExceptionOperator<IfExceptionHint::kLocallyUncaught> kIfExceptionUOperator;
284
285 template <size_t kInputCount>
286 struct EndOperator final : public Operator {
287 EndOperator()
288 : Operator( // --
289 IrOpcode::kEnd, Operator::kKontrol, // opcode
290 "End", // name
291 0, 0, kInputCount, 0, 0, 0) {} // counts
292 };
293#define CACHED_END(input_count) \
294 EndOperator<input_count> kEnd##input_count##Operator;
295 CACHED_END_LIST(CACHED_END)
296#undef CACHED_END
297
298 template <size_t kInputCount>
299 struct ReturnOperator final : public Operator {
300 ReturnOperator()
301 : Operator( // --
302 IrOpcode::kReturn, Operator::kNoThrow, // opcode
303 "Return", // name
304 kInputCount, 1, 1, 0, 0, 1) {} // counts
305 };
306#define CACHED_RETURN(input_count) \
307 ReturnOperator<input_count> kReturn##input_count##Operator;
308 CACHED_RETURN_LIST(CACHED_RETURN)
309#undef CACHED_RETURN
310
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400311 template <BranchHint kBranchHint>
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000312 struct BranchOperator final : public Operator1<BranchHint> {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400313 BranchOperator()
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000314 : Operator1<BranchHint>( // --
315 IrOpcode::kBranch, Operator::kKontrol, // opcode
316 "Branch", // name
317 1, 0, 1, 0, 0, 2, // counts
318 kBranchHint) {} // parameter
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000319 };
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400320 BranchOperator<BranchHint::kNone> kBranchNoneOperator;
321 BranchOperator<BranchHint::kTrue> kBranchTrueOperator;
322 BranchOperator<BranchHint::kFalse> kBranchFalseOperator;
323
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000324 template <int kEffectInputCount>
325 struct EffectPhiOperator final : public Operator {
326 EffectPhiOperator()
327 : Operator( // --
328 IrOpcode::kEffectPhi, Operator::kPure, // opcode
329 "EffectPhi", // name
330 0, kEffectInputCount, 1, 0, 1, 0) {} // counts
331 };
332#define CACHED_EFFECT_PHI(input_count) \
333 EffectPhiOperator<input_count> kEffectPhi##input_count##Operator;
334 CACHED_EFFECT_PHI_LIST(CACHED_EFFECT_PHI)
335#undef CACHED_EFFECT_PHI
336
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400337 template <size_t kInputCount>
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000338 struct LoopOperator final : public Operator {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400339 LoopOperator()
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000340 : Operator( // --
341 IrOpcode::kLoop, Operator::kKontrol, // opcode
342 "Loop", // name
343 0, 0, kInputCount, 0, 0, 1) {} // counts
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400344 };
345#define CACHED_LOOP(input_count) \
346 LoopOperator<input_count> kLoop##input_count##Operator;
347 CACHED_LOOP_LIST(CACHED_LOOP)
348#undef CACHED_LOOP
349
350 template <size_t kInputCount>
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000351 struct MergeOperator final : public Operator {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400352 MergeOperator()
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000353 : Operator( // --
354 IrOpcode::kMerge, Operator::kKontrol, // opcode
355 "Merge", // name
356 0, 0, kInputCount, 0, 0, 1) {} // counts
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400357 };
358#define CACHED_MERGE(input_count) \
359 MergeOperator<input_count> kMerge##input_count##Operator;
360 CACHED_MERGE_LIST(CACHED_MERGE)
361#undef CACHED_MERGE
362
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000363 template <MachineRepresentation kRep, int kInputCount>
364 struct PhiOperator final : public Operator1<MachineRepresentation> {
365 PhiOperator()
366 : Operator1<MachineRepresentation>( //--
367 IrOpcode::kPhi, Operator::kPure, // opcode
368 "Phi", // name
369 kInputCount, 0, 1, 1, 0, 0, // counts
370 kRep) {} // parameter
371 };
372#define CACHED_PHI(rep, input_count) \
373 PhiOperator<MachineRepresentation::rep, input_count> \
374 kPhi##rep##input_count##Operator;
375 CACHED_PHI_LIST(CACHED_PHI)
376#undef CACHED_PHI
377
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400378 template <int kIndex>
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000379 struct ParameterOperator final : public Operator1<ParameterInfo> {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400380 ParameterOperator()
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000381 : Operator1<ParameterInfo>( // --
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400382 IrOpcode::kParameter, Operator::kPure, // opcode
383 "Parameter", // name
384 1, 0, 0, 1, 0, 0, // counts,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000385 ParameterInfo(kIndex, nullptr)) {} // parameter and name
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400386 };
387#define CACHED_PARAMETER(index) \
388 ParameterOperator<index> kParameter##index##Operator;
389 CACHED_PARAMETER_LIST(CACHED_PARAMETER)
390#undef CACHED_PARAMETER
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000391
392 template <size_t kIndex>
393 struct ProjectionOperator final : public Operator1<size_t> {
394 ProjectionOperator()
395 : Operator1<size_t>( // --
396 IrOpcode::kProjection, // opcode
397 Operator::kPure, // flags
398 "Projection", // name
399 1, 0, 0, 1, 0, 0, // counts,
400 kIndex) {} // parameter
401 };
402#define CACHED_PROJECTION(index) \
403 ProjectionOperator<index> kProjection##index##Operator;
404 CACHED_PROJECTION_LIST(CACHED_PROJECTION)
405#undef CACHED_PROJECTION
406
407 template <int kInputCount>
408 struct StateValuesOperator final : public Operator {
409 StateValuesOperator()
410 : Operator( // --
411 IrOpcode::kStateValues, // opcode
412 Operator::kPure, // flags
413 "StateValues", // name
414 kInputCount, 0, 0, 1, 0, 0) {} // counts
415 };
416#define CACHED_STATE_VALUES(input_count) \
417 StateValuesOperator<input_count> kStateValues##input_count##Operator;
418 CACHED_STATE_VALUES_LIST(CACHED_STATE_VALUES)
419#undef CACHED_STATE_VALUES
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000420};
421
422
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400423static base::LazyInstance<CommonOperatorGlobalCache>::type kCache =
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000424 LAZY_INSTANCE_INITIALIZER;
425
426
427CommonOperatorBuilder::CommonOperatorBuilder(Zone* zone)
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400428 : cache_(kCache.Get()), zone_(zone) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000429
430
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000431#define CACHED(Name, properties, value_input_count, effect_input_count, \
432 control_input_count, value_output_count, effect_output_count, \
433 control_output_count) \
434 const Operator* CommonOperatorBuilder::Name() { \
435 return &cache_.k##Name##Operator; \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000436 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400437CACHED_OP_LIST(CACHED)
438#undef CACHED
439
440
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000441const Operator* CommonOperatorBuilder::End(size_t control_input_count) {
442 switch (control_input_count) {
443#define CACHED_END(input_count) \
444 case input_count: \
445 return &cache_.kEnd##input_count##Operator;
446 CACHED_END_LIST(CACHED_END)
447#undef CACHED_END
448 default:
449 break;
450 }
451 // Uncached.
452 return new (zone()) Operator( //--
453 IrOpcode::kEnd, Operator::kKontrol, // opcode
454 "End", // name
455 0, 0, control_input_count, 0, 0, 0); // counts
456}
457
458
459const Operator* CommonOperatorBuilder::Return(int value_input_count) {
460 switch (value_input_count) {
461#define CACHED_RETURN(input_count) \
462 case input_count: \
463 return &cache_.kReturn##input_count##Operator;
464 CACHED_RETURN_LIST(CACHED_RETURN)
465#undef CACHED_RETURN
466 default:
467 break;
468 }
469 // Uncached.
470 return new (zone()) Operator( //--
471 IrOpcode::kReturn, Operator::kNoThrow, // opcode
472 "Return", // name
473 value_input_count, 1, 1, 0, 0, 1); // counts
474}
475
476
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400477const Operator* CommonOperatorBuilder::Branch(BranchHint hint) {
478 switch (hint) {
479 case BranchHint::kNone:
480 return &cache_.kBranchNoneOperator;
481 case BranchHint::kTrue:
482 return &cache_.kBranchTrueOperator;
483 case BranchHint::kFalse:
484 return &cache_.kBranchFalseOperator;
485 }
486 UNREACHABLE();
487 return nullptr;
488}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000489
490
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000491const Operator* CommonOperatorBuilder::Deoptimize(DeoptimizeKind kind) {
492 switch (kind) {
493 case DeoptimizeKind::kEager:
494 return &cache_.kDeoptimizeEagerOperator;
495 case DeoptimizeKind::kSoft:
496 return &cache_.kDeoptimizeSoftOperator;
497 }
498 UNREACHABLE();
499 return nullptr;
500}
501
502
503const Operator* CommonOperatorBuilder::IfException(IfExceptionHint hint) {
504 switch (hint) {
505 case IfExceptionHint::kLocallyCaught:
506 return &cache_.kIfExceptionCOperator;
507 case IfExceptionHint::kLocallyUncaught:
508 return &cache_.kIfExceptionUOperator;
509 }
510 UNREACHABLE();
511 return nullptr;
512}
513
514
515const Operator* CommonOperatorBuilder::Switch(size_t control_output_count) {
516 return new (zone()) Operator( // --
517 IrOpcode::kSwitch, Operator::kKontrol, // opcode
518 "Switch", // name
519 1, 0, 1, 0, 0, control_output_count); // counts
520}
521
522
523const Operator* CommonOperatorBuilder::IfValue(int32_t index) {
524 return new (zone()) Operator1<int32_t>( // --
525 IrOpcode::kIfValue, Operator::kKontrol, // opcode
526 "IfValue", // name
527 0, 0, 1, 0, 0, 1, // counts
528 index); // parameter
529}
530
531
532const Operator* CommonOperatorBuilder::Start(int value_output_count) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400533 return new (zone()) Operator( // --
534 IrOpcode::kStart, Operator::kFoldable, // opcode
535 "Start", // name
536 0, 0, 0, value_output_count, 1, 1); // counts
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000537}
538
539
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400540const Operator* CommonOperatorBuilder::Loop(int control_input_count) {
541 switch (control_input_count) {
542#define CACHED_LOOP(input_count) \
543 case input_count: \
544 return &cache_.kLoop##input_count##Operator;
545 CACHED_LOOP_LIST(CACHED_LOOP)
546#undef CACHED_LOOP
547 default:
548 break;
549 }
550 // Uncached.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000551 return new (zone()) Operator( // --
552 IrOpcode::kLoop, Operator::kKontrol, // opcode
553 "Loop", // name
554 0, 0, control_input_count, 0, 0, 1); // counts
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000555}
556
557
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400558const Operator* CommonOperatorBuilder::Merge(int control_input_count) {
559 switch (control_input_count) {
560#define CACHED_MERGE(input_count) \
561 case input_count: \
562 return &cache_.kMerge##input_count##Operator;
563 CACHED_MERGE_LIST(CACHED_MERGE)
564#undef CACHED_MERGE
565 default:
566 break;
567 }
568 // Uncached.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000569 return new (zone()) Operator( // --
570 IrOpcode::kMerge, Operator::kKontrol, // opcode
571 "Merge", // name
572 0, 0, control_input_count, 0, 0, 1); // counts
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400573}
574
575
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000576const Operator* CommonOperatorBuilder::Parameter(int index,
577 const char* debug_name) {
578 if (!debug_name) {
579 switch (index) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400580#define CACHED_PARAMETER(index) \
581 case index: \
582 return &cache_.kParameter##index##Operator;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000583 CACHED_PARAMETER_LIST(CACHED_PARAMETER)
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400584#undef CACHED_PARAMETER
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000585 default:
586 break;
587 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400588 }
589 // Uncached.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000590 return new (zone()) Operator1<ParameterInfo>( // --
591 IrOpcode::kParameter, Operator::kPure, // opcode
592 "Parameter", // name
593 1, 0, 0, 1, 0, 0, // counts
594 ParameterInfo(index, debug_name)); // parameter info
595}
596
597
598const Operator* CommonOperatorBuilder::OsrValue(int index) {
599 return new (zone()) Operator1<int>( // --
600 IrOpcode::kOsrValue, Operator::kNoProperties, // opcode
601 "OsrValue", // name
602 0, 0, 1, 1, 0, 0, // counts
603 index); // parameter
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000604}
605
606
607const Operator* CommonOperatorBuilder::Int32Constant(int32_t value) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400608 return new (zone()) Operator1<int32_t>( // --
609 IrOpcode::kInt32Constant, Operator::kPure, // opcode
610 "Int32Constant", // name
611 0, 0, 0, 1, 0, 0, // counts
612 value); // parameter
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000613}
614
615
616const Operator* CommonOperatorBuilder::Int64Constant(int64_t value) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400617 return new (zone()) Operator1<int64_t>( // --
618 IrOpcode::kInt64Constant, Operator::kPure, // opcode
619 "Int64Constant", // name
620 0, 0, 0, 1, 0, 0, // counts
621 value); // parameter
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000622}
623
624
625const Operator* CommonOperatorBuilder::Float32Constant(volatile float value) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000626 return new (zone()) Operator1<float>( // --
627 IrOpcode::kFloat32Constant, Operator::kPure, // opcode
628 "Float32Constant", // name
629 0, 0, 0, 1, 0, 0, // counts
630 value); // parameter
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000631}
632
633
634const Operator* CommonOperatorBuilder::Float64Constant(volatile double value) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000635 return new (zone()) Operator1<double>( // --
636 IrOpcode::kFloat64Constant, Operator::kPure, // opcode
637 "Float64Constant", // name
638 0, 0, 0, 1, 0, 0, // counts
639 value); // parameter
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000640}
641
642
643const Operator* CommonOperatorBuilder::ExternalConstant(
644 const ExternalReference& value) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400645 return new (zone()) Operator1<ExternalReference>( // --
646 IrOpcode::kExternalConstant, Operator::kPure, // opcode
647 "ExternalConstant", // name
648 0, 0, 0, 1, 0, 0, // counts
649 value); // parameter
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000650}
651
652
653const Operator* CommonOperatorBuilder::NumberConstant(volatile double value) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000654 return new (zone()) Operator1<double>( // --
655 IrOpcode::kNumberConstant, Operator::kPure, // opcode
656 "NumberConstant", // name
657 0, 0, 0, 1, 0, 0, // counts
658 value); // parameter
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000659}
660
661
662const Operator* CommonOperatorBuilder::HeapConstant(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000663 const Handle<HeapObject>& value) {
664 return new (zone()) Operator1<Handle<HeapObject>>( // --
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400665 IrOpcode::kHeapConstant, Operator::kPure, // opcode
666 "HeapConstant", // name
667 0, 0, 0, 1, 0, 0, // counts
668 value); // parameter
669}
670
671
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000672const Operator* CommonOperatorBuilder::Select(MachineRepresentation rep,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400673 BranchHint hint) {
674 return new (zone()) Operator1<SelectParameters>( // --
675 IrOpcode::kSelect, Operator::kPure, // opcode
676 "Select", // name
677 3, 0, 0, 1, 0, 0, // counts
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000678 SelectParameters(rep, hint)); // parameter
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000679}
680
681
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000682const Operator* CommonOperatorBuilder::Phi(MachineRepresentation rep,
683 int value_input_count) {
684 DCHECK(value_input_count > 0); // Disallow empty phis.
685#define CACHED_PHI(kRep, kValueInputCount) \
686 if (MachineRepresentation::kRep == rep && \
687 kValueInputCount == value_input_count) { \
688 return &cache_.kPhi##kRep##kValueInputCount##Operator; \
689 }
690 CACHED_PHI_LIST(CACHED_PHI)
691#undef CACHED_PHI
692 // Uncached.
693 return new (zone()) Operator1<MachineRepresentation>( // --
694 IrOpcode::kPhi, Operator::kPure, // opcode
695 "Phi", // name
696 value_input_count, 0, 1, 1, 0, 0, // counts
697 rep); // parameter
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000698}
699
700
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000701const Operator* CommonOperatorBuilder::EffectPhi(int effect_input_count) {
702 DCHECK(effect_input_count > 0); // Disallow empty effect phis.
703 switch (effect_input_count) {
704#define CACHED_EFFECT_PHI(input_count) \
705 case input_count: \
706 return &cache_.kEffectPhi##input_count##Operator;
707 CACHED_EFFECT_PHI_LIST(CACHED_EFFECT_PHI)
708#undef CACHED_EFFECT_PHI
709 default:
710 break;
711 }
712 // Uncached.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400713 return new (zone()) Operator( // --
714 IrOpcode::kEffectPhi, Operator::kPure, // opcode
715 "EffectPhi", // name
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000716 0, effect_input_count, 1, 0, 1, 0); // counts
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000717}
718
719
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000720const Operator* CommonOperatorBuilder::Guard(Type* type) {
721 return new (zone()) Operator1<Type*>( // --
722 IrOpcode::kGuard, Operator::kKontrol, // opcode
723 "Guard", // name
724 1, 0, 1, 1, 0, 0, // counts
725 type); // parameter
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000726}
727
728
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000729const Operator* CommonOperatorBuilder::EffectSet(int arguments) {
730 DCHECK(arguments > 1); // Disallow empty/singleton sets.
731 return new (zone()) Operator( // --
732 IrOpcode::kEffectSet, Operator::kPure, // opcode
733 "EffectSet", // name
734 0, arguments, 0, 0, 1, 0); // counts
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000735}
736
737
738const Operator* CommonOperatorBuilder::StateValues(int arguments) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000739 switch (arguments) {
740#define CACHED_STATE_VALUES(arguments) \
741 case arguments: \
742 return &cache_.kStateValues##arguments##Operator;
743 CACHED_STATE_VALUES_LIST(CACHED_STATE_VALUES)
744#undef CACHED_STATE_VALUES
745 default:
746 break;
747 }
748 // Uncached.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400749 return new (zone()) Operator( // --
750 IrOpcode::kStateValues, Operator::kPure, // opcode
751 "StateValues", // name
752 arguments, 0, 0, 1, 0, 0); // counts
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000753}
754
755
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000756const Operator* CommonOperatorBuilder::ObjectState(int pointer_slots, int id) {
757 return new (zone()) Operator1<int>( // --
758 IrOpcode::kObjectState, Operator::kPure, // opcode
759 "ObjectState", // name
760 pointer_slots, 0, 0, 1, 0, 0, id); // counts
761}
762
763
764const Operator* CommonOperatorBuilder::TypedStateValues(
765 const ZoneVector<MachineType>* types) {
766 return new (zone()) Operator1<const ZoneVector<MachineType>*>( // --
767 IrOpcode::kTypedStateValues, Operator::kPure, // opcode
768 "TypedStateValues", // name
769 static_cast<int>(types->size()), 0, 0, 1, 0, 0, types); // counts
770}
771
772
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000773const Operator* CommonOperatorBuilder::FrameState(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000774 BailoutId bailout_id, OutputFrameStateCombine state_combine,
775 const FrameStateFunctionInfo* function_info) {
776 FrameStateInfo state_info(bailout_id, state_combine, function_info);
777 return new (zone()) Operator1<FrameStateInfo>( // --
778 IrOpcode::kFrameState, Operator::kPure, // opcode
779 "FrameState", // name
780 5, 0, 0, 1, 0, 0, // counts
781 state_info); // parameter
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000782}
783
784
785const Operator* CommonOperatorBuilder::Call(const CallDescriptor* descriptor) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000786 class CallOperator final : public Operator1<const CallDescriptor*> {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000787 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000788 explicit CallOperator(const CallDescriptor* descriptor)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000789 : Operator1<const CallDescriptor*>(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000790 IrOpcode::kCall, descriptor->properties(), "Call",
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400791 descriptor->InputCount() + descriptor->FrameStateCount(),
792 Operator::ZeroIfPure(descriptor->properties()),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000793 Operator::ZeroIfEliminatable(descriptor->properties()),
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400794 descriptor->ReturnCount(),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000795 Operator::ZeroIfPure(descriptor->properties()),
796 Operator::ZeroIfNoThrow(descriptor->properties()), descriptor) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000797
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000798 void PrintParameter(std::ostream& os) const override {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400799 os << "[" << *parameter() << "]";
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000800 }
801 };
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000802 return new (zone()) CallOperator(descriptor);
803}
804
805
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000806const Operator* CommonOperatorBuilder::TailCall(
807 const CallDescriptor* descriptor) {
808 class TailCallOperator final : public Operator1<const CallDescriptor*> {
809 public:
810 explicit TailCallOperator(const CallDescriptor* descriptor)
811 : Operator1<const CallDescriptor*>(
812 IrOpcode::kTailCall, descriptor->properties(), "TailCall",
813 descriptor->InputCount() + descriptor->FrameStateCount(), 1, 1, 0,
814 0, 1, descriptor) {}
815
816 void PrintParameter(std::ostream& os) const override {
817 os << "[" << *parameter() << "]";
818 }
819 };
820 return new (zone()) TailCallOperator(descriptor);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000821}
822
823
824const Operator* CommonOperatorBuilder::Projection(size_t index) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000825 switch (index) {
826#define CACHED_PROJECTION(index) \
827 case index: \
828 return &cache_.kProjection##index##Operator;
829 CACHED_PROJECTION_LIST(CACHED_PROJECTION)
830#undef CACHED_PROJECTION
831 default:
832 break;
833 }
834 // Uncached.
835 return new (zone()) Operator1<size_t>( // --
836 IrOpcode::kProjection, // opcode
837 Operator::kFoldable | Operator::kNoThrow, // flags
838 "Projection", // name
839 1, 0, 0, 1, 0, 0, // counts
840 index); // parameter
841}
842
843
844const Operator* CommonOperatorBuilder::ResizeMergeOrPhi(const Operator* op,
845 int size) {
846 if (op->opcode() == IrOpcode::kPhi) {
847 return Phi(PhiRepresentationOf(op), size);
848 } else if (op->opcode() == IrOpcode::kEffectPhi) {
849 return EffectPhi(size);
850 } else if (op->opcode() == IrOpcode::kMerge) {
851 return Merge(size);
852 } else if (op->opcode() == IrOpcode::kLoop) {
853 return Loop(size);
854 } else {
855 UNREACHABLE();
856 return nullptr;
857 }
858}
859
860
861const FrameStateFunctionInfo*
862CommonOperatorBuilder::CreateFrameStateFunctionInfo(
863 FrameStateType type, int parameter_count, int local_count,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100864 Handle<SharedFunctionInfo> shared_info) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000865 return new (zone()->New(sizeof(FrameStateFunctionInfo)))
Ben Murdoch097c5b22016-05-18 11:27:45 +0100866 FrameStateFunctionInfo(type, parameter_count, local_count, shared_info);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000867}
868
869} // namespace compiler
870} // namespace internal
871} // namespace v8