blob: 0f32b0c9b8961d96eb977fd9567a689301918388 [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// Copyright 2012 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/simplified-operator.h"
6
7#include "src/base/lazy-instance.h"
8#include "src/compiler/opcodes.h"
9#include "src/compiler/operator.h"
Ben Murdoch097c5b22016-05-18 11:27:45 +010010#include "src/types.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000011
12namespace v8 {
13namespace internal {
14namespace compiler {
15
Ben Murdochc5610432016-08-08 18:44:38 +010016size_t hash_value(BaseTaggedness base_taggedness) {
17 return static_cast<uint8_t>(base_taggedness);
18}
19
Emily Bernierd0a1eb72015-03-24 16:35:39 -040020std::ostream& operator<<(std::ostream& os, BaseTaggedness base_taggedness) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000021 switch (base_taggedness) {
22 case kUntaggedBase:
23 return os << "untagged base";
24 case kTaggedBase:
25 return os << "tagged base";
26 }
27 UNREACHABLE();
28 return os;
29}
30
31
Emily Bernierd0a1eb72015-03-24 16:35:39 -040032MachineType BufferAccess::machine_type() const {
33 switch (external_array_type_) {
34 case kExternalUint8Array:
35 case kExternalUint8ClampedArray:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000036 return MachineType::Uint8();
Emily Bernierd0a1eb72015-03-24 16:35:39 -040037 case kExternalInt8Array:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000038 return MachineType::Int8();
Emily Bernierd0a1eb72015-03-24 16:35:39 -040039 case kExternalUint16Array:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000040 return MachineType::Uint16();
Emily Bernierd0a1eb72015-03-24 16:35:39 -040041 case kExternalInt16Array:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000042 return MachineType::Int16();
Emily Bernierd0a1eb72015-03-24 16:35:39 -040043 case kExternalUint32Array:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000044 return MachineType::Uint32();
Emily Bernierd0a1eb72015-03-24 16:35:39 -040045 case kExternalInt32Array:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000046 return MachineType::Int32();
Emily Bernierd0a1eb72015-03-24 16:35:39 -040047 case kExternalFloat32Array:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000048 return MachineType::Float32();
Emily Bernierd0a1eb72015-03-24 16:35:39 -040049 case kExternalFloat64Array:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000050 return MachineType::Float64();
Emily Bernierd0a1eb72015-03-24 16:35:39 -040051 }
52 UNREACHABLE();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000053 return MachineType::None();
Emily Bernierd0a1eb72015-03-24 16:35:39 -040054}
55
56
57bool operator==(BufferAccess lhs, BufferAccess rhs) {
58 return lhs.external_array_type() == rhs.external_array_type();
59}
60
61
62bool operator!=(BufferAccess lhs, BufferAccess rhs) { return !(lhs == rhs); }
63
64
65size_t hash_value(BufferAccess access) {
66 return base::hash<ExternalArrayType>()(access.external_array_type());
67}
68
69
70std::ostream& operator<<(std::ostream& os, BufferAccess access) {
71 switch (access.external_array_type()) {
72#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
73 case kExternal##Type##Array: \
74 return os << #Type;
75 TYPED_ARRAYS(TYPED_ARRAY_CASE)
76#undef TYPED_ARRAY_CASE
77 }
78 UNREACHABLE();
79 return os;
80}
81
82
83BufferAccess const BufferAccessOf(const Operator* op) {
84 DCHECK(op->opcode() == IrOpcode::kLoadBuffer ||
85 op->opcode() == IrOpcode::kStoreBuffer);
86 return OpParameter<BufferAccess>(op);
87}
88
89
90bool operator==(FieldAccess const& lhs, FieldAccess const& rhs) {
Ben Murdochc5610432016-08-08 18:44:38 +010091 // On purpose we don't include the write barrier kind here, as this method is
92 // really only relevant for eliminating loads and they don't care about the
93 // write barrier mode.
Emily Bernierd0a1eb72015-03-24 16:35:39 -040094 return lhs.base_is_tagged == rhs.base_is_tagged && lhs.offset == rhs.offset &&
95 lhs.machine_type == rhs.machine_type;
96}
97
98
99bool operator!=(FieldAccess const& lhs, FieldAccess const& rhs) {
100 return !(lhs == rhs);
101}
102
103
104size_t hash_value(FieldAccess const& access) {
Ben Murdochc5610432016-08-08 18:44:38 +0100105 // On purpose we don't include the write barrier kind here, as this method is
106 // really only relevant for eliminating loads and they don't care about the
107 // write barrier mode.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400108 return base::hash_combine(access.base_is_tagged, access.offset,
109 access.machine_type);
110}
111
112
113std::ostream& operator<<(std::ostream& os, FieldAccess const& access) {
114 os << "[" << access.base_is_tagged << ", " << access.offset << ", ";
115#ifdef OBJECT_PRINT
116 Handle<Name> name;
117 if (access.name.ToHandle(&name)) {
118 name->Print(os);
119 os << ", ";
120 }
121#endif
122 access.type->PrintTo(os);
Ben Murdochc5610432016-08-08 18:44:38 +0100123 os << ", " << access.machine_type << ", " << access.write_barrier_kind << "]";
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400124 return os;
125}
126
127
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000128bool operator==(ElementAccess const& lhs, ElementAccess const& rhs) {
Ben Murdochc5610432016-08-08 18:44:38 +0100129 // On purpose we don't include the write barrier kind here, as this method is
130 // really only relevant for eliminating loads and they don't care about the
131 // write barrier mode.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000132 return lhs.base_is_tagged == rhs.base_is_tagged &&
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400133 lhs.header_size == rhs.header_size &&
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000134 lhs.machine_type == rhs.machine_type;
135}
136
137
138bool operator!=(ElementAccess const& lhs, ElementAccess const& rhs) {
139 return !(lhs == rhs);
140}
141
142
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400143size_t hash_value(ElementAccess const& access) {
Ben Murdochc5610432016-08-08 18:44:38 +0100144 // On purpose we don't include the write barrier kind here, as this method is
145 // really only relevant for eliminating loads and they don't care about the
146 // write barrier mode.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400147 return base::hash_combine(access.base_is_tagged, access.header_size,
148 access.machine_type);
149}
150
151
152std::ostream& operator<<(std::ostream& os, ElementAccess const& access) {
153 os << access.base_is_tagged << ", " << access.header_size << ", ";
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000154 access.type->PrintTo(os);
Ben Murdochc5610432016-08-08 18:44:38 +0100155 os << ", " << access.machine_type << ", " << access.write_barrier_kind;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000156 return os;
157}
158
159
160const FieldAccess& FieldAccessOf(const Operator* op) {
161 DCHECK_NOT_NULL(op);
162 DCHECK(op->opcode() == IrOpcode::kLoadField ||
163 op->opcode() == IrOpcode::kStoreField);
164 return OpParameter<FieldAccess>(op);
165}
166
167
168const ElementAccess& ElementAccessOf(const Operator* op) {
169 DCHECK_NOT_NULL(op);
170 DCHECK(op->opcode() == IrOpcode::kLoadElement ||
171 op->opcode() == IrOpcode::kStoreElement);
172 return OpParameter<ElementAccess>(op);
173}
174
Ben Murdoch61f157c2016-09-16 13:49:30 +0100175size_t hash_value(CheckFloat64HoleMode mode) {
176 return static_cast<size_t>(mode);
177}
178
179std::ostream& operator<<(std::ostream& os, CheckFloat64HoleMode mode) {
180 switch (mode) {
181 case CheckFloat64HoleMode::kAllowReturnHole:
182 return os << "allow-return-hole";
183 case CheckFloat64HoleMode::kNeverReturnHole:
184 return os << "never-return-hole";
185 }
186 UNREACHABLE();
187 return os;
188}
189
190CheckFloat64HoleMode CheckFloat64HoleModeOf(const Operator* op) {
191 DCHECK_EQ(IrOpcode::kCheckFloat64Hole, op->opcode());
192 return OpParameter<CheckFloat64HoleMode>(op);
193}
194
195size_t hash_value(CheckTaggedHoleMode mode) {
196 return static_cast<size_t>(mode);
197}
198
199std::ostream& operator<<(std::ostream& os, CheckTaggedHoleMode mode) {
200 switch (mode) {
201 case CheckTaggedHoleMode::kConvertHoleToUndefined:
202 return os << "convert-hole-to-undefined";
203 case CheckTaggedHoleMode::kNeverReturnHole:
204 return os << "never-return-hole";
205 }
206 UNREACHABLE();
207 return os;
208}
209
210CheckTaggedHoleMode CheckTaggedHoleModeOf(const Operator* op) {
211 DCHECK_EQ(IrOpcode::kCheckTaggedHole, op->opcode());
212 return OpParameter<CheckTaggedHoleMode>(op);
213}
214
Ben Murdochc5610432016-08-08 18:44:38 +0100215Type* TypeOf(const Operator* op) {
216 DCHECK_EQ(IrOpcode::kTypeGuard, op->opcode());
217 return OpParameter<Type*>(op);
218}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000219
Ben Murdoch61f157c2016-09-16 13:49:30 +0100220BinaryOperationHints::Hint BinaryOperationHintOf(const Operator* op) {
221 DCHECK(op->opcode() == IrOpcode::kSpeculativeNumberAdd ||
222 op->opcode() == IrOpcode::kSpeculativeNumberSubtract ||
223 op->opcode() == IrOpcode::kSpeculativeNumberMultiply ||
224 op->opcode() == IrOpcode::kSpeculativeNumberDivide ||
225 op->opcode() == IrOpcode::kSpeculativeNumberModulus);
226 return OpParameter<BinaryOperationHints::Hint>(op);
227}
228
229CompareOperationHints::Hint CompareOperationHintOf(const Operator* op) {
230 DCHECK(op->opcode() == IrOpcode::kSpeculativeNumberEqual ||
231 op->opcode() == IrOpcode::kSpeculativeNumberLessThan ||
232 op->opcode() == IrOpcode::kSpeculativeNumberLessThanOrEqual);
233 return OpParameter<CompareOperationHints::Hint>(op);
234}
235
Ben Murdochc5610432016-08-08 18:44:38 +0100236#define PURE_OP_LIST(V) \
237 V(BooleanNot, Operator::kNoProperties, 1) \
238 V(BooleanToNumber, Operator::kNoProperties, 1) \
239 V(NumberEqual, Operator::kCommutative, 2) \
240 V(NumberLessThan, Operator::kNoProperties, 2) \
241 V(NumberLessThanOrEqual, Operator::kNoProperties, 2) \
242 V(NumberAdd, Operator::kCommutative, 2) \
243 V(NumberSubtract, Operator::kNoProperties, 2) \
244 V(NumberMultiply, Operator::kCommutative, 2) \
245 V(NumberDivide, Operator::kNoProperties, 2) \
246 V(NumberModulus, Operator::kNoProperties, 2) \
247 V(NumberBitwiseOr, Operator::kCommutative, 2) \
248 V(NumberBitwiseXor, Operator::kCommutative, 2) \
249 V(NumberBitwiseAnd, Operator::kCommutative, 2) \
250 V(NumberShiftLeft, Operator::kNoProperties, 2) \
251 V(NumberShiftRight, Operator::kNoProperties, 2) \
252 V(NumberShiftRightLogical, Operator::kNoProperties, 2) \
253 V(NumberImul, Operator::kCommutative, 2) \
Ben Murdoch61f157c2016-09-16 13:49:30 +0100254 V(NumberAbs, Operator::kNoProperties, 1) \
Ben Murdochc5610432016-08-08 18:44:38 +0100255 V(NumberClz32, Operator::kNoProperties, 1) \
256 V(NumberCeil, Operator::kNoProperties, 1) \
257 V(NumberFloor, Operator::kNoProperties, 1) \
Ben Murdoch61f157c2016-09-16 13:49:30 +0100258 V(NumberFround, Operator::kNoProperties, 1) \
259 V(NumberAtan, Operator::kNoProperties, 1) \
260 V(NumberAtan2, Operator::kNoProperties, 2) \
261 V(NumberAtanh, Operator::kNoProperties, 1) \
262 V(NumberCbrt, Operator::kNoProperties, 1) \
263 V(NumberCos, Operator::kNoProperties, 1) \
264 V(NumberExp, Operator::kNoProperties, 1) \
265 V(NumberExpm1, Operator::kNoProperties, 1) \
266 V(NumberLog, Operator::kNoProperties, 1) \
267 V(NumberLog1p, Operator::kNoProperties, 1) \
268 V(NumberLog10, Operator::kNoProperties, 1) \
269 V(NumberLog2, Operator::kNoProperties, 1) \
Ben Murdochc5610432016-08-08 18:44:38 +0100270 V(NumberRound, Operator::kNoProperties, 1) \
Ben Murdoch61f157c2016-09-16 13:49:30 +0100271 V(NumberSin, Operator::kNoProperties, 1) \
272 V(NumberSqrt, Operator::kNoProperties, 1) \
273 V(NumberTan, Operator::kNoProperties, 1) \
Ben Murdochc5610432016-08-08 18:44:38 +0100274 V(NumberTrunc, Operator::kNoProperties, 1) \
275 V(NumberToInt32, Operator::kNoProperties, 1) \
276 V(NumberToUint32, Operator::kNoProperties, 1) \
Ben Murdoch61f157c2016-09-16 13:49:30 +0100277 V(NumberSilenceNaN, Operator::kNoProperties, 1) \
278 V(StringFromCharCode, Operator::kNoProperties, 1) \
Ben Murdochc5610432016-08-08 18:44:38 +0100279 V(StringToNumber, Operator::kNoProperties, 1) \
Ben Murdoch61f157c2016-09-16 13:49:30 +0100280 V(PlainPrimitiveToNumber, Operator::kNoProperties, 1) \
281 V(PlainPrimitiveToWord32, Operator::kNoProperties, 1) \
282 V(PlainPrimitiveToFloat64, Operator::kNoProperties, 1) \
Ben Murdochc5610432016-08-08 18:44:38 +0100283 V(ChangeTaggedSignedToInt32, Operator::kNoProperties, 1) \
284 V(ChangeTaggedToInt32, Operator::kNoProperties, 1) \
285 V(ChangeTaggedToUint32, Operator::kNoProperties, 1) \
286 V(ChangeTaggedToFloat64, Operator::kNoProperties, 1) \
287 V(ChangeInt31ToTaggedSigned, Operator::kNoProperties, 1) \
288 V(ChangeInt32ToTagged, Operator::kNoProperties, 1) \
289 V(ChangeUint32ToTagged, Operator::kNoProperties, 1) \
290 V(ChangeFloat64ToTagged, Operator::kNoProperties, 1) \
291 V(ChangeTaggedToBit, Operator::kNoProperties, 1) \
292 V(ChangeBitToTagged, Operator::kNoProperties, 1) \
293 V(TruncateTaggedToWord32, Operator::kNoProperties, 1) \
Ben Murdoch61f157c2016-09-16 13:49:30 +0100294 V(TruncateTaggedToFloat64, Operator::kNoProperties, 1) \
Ben Murdochc5610432016-08-08 18:44:38 +0100295 V(ObjectIsCallable, Operator::kNoProperties, 1) \
296 V(ObjectIsNumber, Operator::kNoProperties, 1) \
297 V(ObjectIsReceiver, Operator::kNoProperties, 1) \
298 V(ObjectIsSmi, Operator::kNoProperties, 1) \
299 V(ObjectIsString, Operator::kNoProperties, 1) \
300 V(ObjectIsUndetectable, Operator::kNoProperties, 1) \
301 V(StringEqual, Operator::kCommutative, 2) \
302 V(StringLessThan, Operator::kNoProperties, 2) \
303 V(StringLessThanOrEqual, Operator::kNoProperties, 2)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000304
Ben Murdoch61f157c2016-09-16 13:49:30 +0100305#define SPECULATIVE_BINOP_LIST(V) \
306 V(SpeculativeNumberAdd) \
307 V(SpeculativeNumberSubtract) \
308 V(SpeculativeNumberDivide) \
309 V(SpeculativeNumberMultiply) \
310 V(SpeculativeNumberModulus)
311
312#define CHECKED_OP_LIST(V) \
313 V(CheckTaggedPointer, 1) \
314 V(CheckTaggedSigned, 1) \
315 V(CheckedInt32Add, 2) \
316 V(CheckedInt32Sub, 2) \
317 V(CheckedUint32ToInt32, 1) \
318 V(CheckedFloat64ToInt32, 1) \
319 V(CheckedTaggedToInt32, 1) \
320 V(CheckedTaggedToFloat64, 1)
321
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000322struct SimplifiedOperatorGlobalCache final {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400323#define PURE(Name, properties, input_count) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000324 struct Name##Operator final : public Operator { \
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400325 Name##Operator() \
326 : Operator(IrOpcode::k##Name, Operator::kPure | properties, #Name, \
327 input_count, 0, 0, 1, 0, 0) {} \
328 }; \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000329 Name##Operator k##Name;
330 PURE_OP_LIST(PURE)
331#undef PURE
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400332
Ben Murdoch61f157c2016-09-16 13:49:30 +0100333#define CHECKED(Name, value_input_count) \
334 struct Name##Operator final : public Operator { \
335 Name##Operator() \
336 : Operator(IrOpcode::k##Name, \
337 Operator::kFoldable | Operator::kNoThrow, #Name, \
338 value_input_count, 1, 1, 1, 1, 0) {} \
339 }; \
340 Name##Operator k##Name;
341 CHECKED_OP_LIST(CHECKED)
342#undef CHECKED
343
344 template <CheckFloat64HoleMode kMode>
345 struct CheckFloat64HoleNaNOperator final
346 : public Operator1<CheckFloat64HoleMode> {
347 CheckFloat64HoleNaNOperator()
348 : Operator1<CheckFloat64HoleMode>(
349 IrOpcode::kCheckFloat64Hole,
350 Operator::kFoldable | Operator::kNoThrow, "CheckFloat64Hole", 1,
351 1, 1, 1, 1, 0, kMode) {}
352 };
353 CheckFloat64HoleNaNOperator<CheckFloat64HoleMode::kAllowReturnHole>
354 kCheckFloat64HoleAllowReturnHoleOperator;
355 CheckFloat64HoleNaNOperator<CheckFloat64HoleMode::kNeverReturnHole>
356 kCheckFloat64HoleNeverReturnHoleOperator;
357
358 template <CheckTaggedHoleMode kMode>
359 struct CheckTaggedHoleOperator final : public Operator1<CheckTaggedHoleMode> {
360 CheckTaggedHoleOperator()
361 : Operator1<CheckTaggedHoleMode>(
362 IrOpcode::kCheckTaggedHole,
363 Operator::kFoldable | Operator::kNoThrow, "CheckTaggedHole", 1, 1,
364 1, 1, 1, 0, kMode) {}
365 };
366 CheckTaggedHoleOperator<CheckTaggedHoleMode::kConvertHoleToUndefined>
367 kCheckTaggedHoleConvertHoleToUndefinedOperator;
368 CheckTaggedHoleOperator<CheckTaggedHoleMode::kNeverReturnHole>
369 kCheckTaggedHoleNeverReturnHoleOperator;
370
Ben Murdochc5610432016-08-08 18:44:38 +0100371 template <PretenureFlag kPretenure>
372 struct AllocateOperator final : public Operator1<PretenureFlag> {
373 AllocateOperator()
Ben Murdoch61f157c2016-09-16 13:49:30 +0100374 : Operator1<PretenureFlag>(
375 IrOpcode::kAllocate,
376 Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoWrite,
377 "Allocate", 1, 1, 1, 1, 1, 0, kPretenure) {}
Ben Murdochc5610432016-08-08 18:44:38 +0100378 };
379 AllocateOperator<NOT_TENURED> kAllocateNotTenuredOperator;
380 AllocateOperator<TENURED> kAllocateTenuredOperator;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000381
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400382#define BUFFER_ACCESS(Type, type, TYPE, ctype, size) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000383 struct LoadBuffer##Type##Operator final : public Operator1<BufferAccess> { \
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400384 LoadBuffer##Type##Operator() \
Ben Murdoch61f157c2016-09-16 13:49:30 +0100385 : Operator1<BufferAccess>( \
386 IrOpcode::kLoadBuffer, \
387 Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoWrite, \
388 "LoadBuffer", 3, 1, 1, 1, 1, 0, \
389 BufferAccess(kExternal##Type##Array)) {} \
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400390 }; \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000391 struct StoreBuffer##Type##Operator final : public Operator1<BufferAccess> { \
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400392 StoreBuffer##Type##Operator() \
Ben Murdoch61f157c2016-09-16 13:49:30 +0100393 : Operator1<BufferAccess>( \
394 IrOpcode::kStoreBuffer, \
395 Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow, \
396 "StoreBuffer", 4, 1, 1, 0, 1, 0, \
397 BufferAccess(kExternal##Type##Array)) {} \
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400398 }; \
399 LoadBuffer##Type##Operator kLoadBuffer##Type; \
400 StoreBuffer##Type##Operator kStoreBuffer##Type;
401 TYPED_ARRAYS(BUFFER_ACCESS)
402#undef BUFFER_ACCESS
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000403};
404
405
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400406static base::LazyInstance<SimplifiedOperatorGlobalCache>::type kCache =
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000407 LAZY_INSTANCE_INITIALIZER;
408
409
410SimplifiedOperatorBuilder::SimplifiedOperatorBuilder(Zone* zone)
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400411 : cache_(kCache.Get()), zone_(zone) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000412
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000413#define GET_FROM_CACHE(Name, properties, input_count) \
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400414 const Operator* SimplifiedOperatorBuilder::Name() { return &cache_.k##Name; }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000415PURE_OP_LIST(GET_FROM_CACHE)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000416#undef GET_FROM_CACHE
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000417
Ben Murdoch61f157c2016-09-16 13:49:30 +0100418#define GET_FROM_CACHE(Name, value_input_count) \
419 const Operator* SimplifiedOperatorBuilder::Name() { return &cache_.k##Name; }
420CHECKED_OP_LIST(GET_FROM_CACHE)
421#undef GET_FROM_CACHE
422
423const Operator* SimplifiedOperatorBuilder::CheckFloat64Hole(
424 CheckFloat64HoleMode mode) {
425 switch (mode) {
426 case CheckFloat64HoleMode::kAllowReturnHole:
427 return &cache_.kCheckFloat64HoleAllowReturnHoleOperator;
428 case CheckFloat64HoleMode::kNeverReturnHole:
429 return &cache_.kCheckFloat64HoleNeverReturnHoleOperator;
430 }
431 UNREACHABLE();
432 return nullptr;
433}
434
435const Operator* SimplifiedOperatorBuilder::CheckTaggedHole(
436 CheckTaggedHoleMode mode) {
437 switch (mode) {
438 case CheckTaggedHoleMode::kConvertHoleToUndefined:
439 return &cache_.kCheckTaggedHoleConvertHoleToUndefinedOperator;
440 case CheckTaggedHoleMode::kNeverReturnHole:
441 return &cache_.kCheckTaggedHoleNeverReturnHoleOperator;
442 }
443 UNREACHABLE();
444 return nullptr;
445}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000446
447const Operator* SimplifiedOperatorBuilder::ReferenceEqual(Type* type) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400448 return new (zone()) Operator(IrOpcode::kReferenceEqual,
449 Operator::kCommutative | Operator::kPure,
450 "ReferenceEqual", 2, 0, 0, 1, 0, 0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000451}
452
Ben Murdoch61f157c2016-09-16 13:49:30 +0100453const Operator* SimplifiedOperatorBuilder::CheckBounds() {
454 // TODO(bmeurer): Cache this operator. Make it pure!
455 return new (zone())
456 Operator(IrOpcode::kCheckBounds, Operator::kFoldable | Operator::kNoThrow,
457 "CheckBounds", 2, 1, 1, 1, 1, 0);
458}
459
Ben Murdochc5610432016-08-08 18:44:38 +0100460const Operator* SimplifiedOperatorBuilder::TypeGuard(Type* type) {
461 class TypeGuardOperator final : public Operator1<Type*> {
462 public:
463 explicit TypeGuardOperator(Type* type)
464 : Operator1<Type*>( // --
465 IrOpcode::kTypeGuard, Operator::kPure, // opcode
466 "TypeGuard", // name
467 1, 0, 1, 1, 0, 0, // counts
468 type) {} // parameter
469
470 void PrintParameter(std::ostream& os) const final {
471 parameter()->PrintTo(os);
472 }
473 };
474 return new (zone()) TypeGuardOperator(type);
475}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000476
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000477const Operator* SimplifiedOperatorBuilder::Allocate(PretenureFlag pretenure) {
Ben Murdochc5610432016-08-08 18:44:38 +0100478 switch (pretenure) {
479 case NOT_TENURED:
480 return &cache_.kAllocateNotTenuredOperator;
481 case TENURED:
482 return &cache_.kAllocateTenuredOperator;
483 }
484 UNREACHABLE();
485 return nullptr;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000486}
487
488
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400489const Operator* SimplifiedOperatorBuilder::LoadBuffer(BufferAccess access) {
490 switch (access.external_array_type()) {
491#define LOAD_BUFFER(Type, type, TYPE, ctype, size) \
492 case kExternal##Type##Array: \
493 return &cache_.kLoadBuffer##Type;
494 TYPED_ARRAYS(LOAD_BUFFER)
495#undef LOAD_BUFFER
496 }
497 UNREACHABLE();
498 return nullptr;
499}
500
501
502const Operator* SimplifiedOperatorBuilder::StoreBuffer(BufferAccess access) {
503 switch (access.external_array_type()) {
504#define STORE_BUFFER(Type, type, TYPE, ctype, size) \
505 case kExternal##Type##Array: \
506 return &cache_.kStoreBuffer##Type;
507 TYPED_ARRAYS(STORE_BUFFER)
508#undef STORE_BUFFER
509 }
510 UNREACHABLE();
511 return nullptr;
512}
513
Ben Murdoch61f157c2016-09-16 13:49:30 +0100514#define SPECULATIVE_BINOP_DEF(Name) \
515 const Operator* SimplifiedOperatorBuilder::Name( \
516 BinaryOperationHints::Hint hint) { \
517 return new (zone()) Operator1<BinaryOperationHints::Hint>( \
518 IrOpcode::k##Name, Operator::kFoldable | Operator::kNoThrow, #Name, 2, \
519 1, 1, 1, 1, 0, hint); \
520 }
521SPECULATIVE_BINOP_LIST(SPECULATIVE_BINOP_DEF)
522#undef SPECULATIVE_BINOP_DEF
523
524const Operator* SimplifiedOperatorBuilder::SpeculativeNumberEqual(
525 CompareOperationHints::Hint hint) {
526 return new (zone()) Operator1<CompareOperationHints::Hint>(
527 IrOpcode::kSpeculativeNumberEqual,
528 Operator::kFoldable | Operator::kNoThrow, "SpeculativeNumberEqual", 2, 1,
529 1, 1, 1, 0, hint);
530}
531
532const Operator* SimplifiedOperatorBuilder::SpeculativeNumberLessThan(
533 CompareOperationHints::Hint hint) {
534 return new (zone()) Operator1<CompareOperationHints::Hint>(
535 IrOpcode::kSpeculativeNumberLessThan,
536 Operator::kFoldable | Operator::kNoThrow, "SpeculativeNumberLessThan", 2,
537 1, 1, 1, 1, 0, hint);
538}
539
540const Operator* SimplifiedOperatorBuilder::SpeculativeNumberLessThanOrEqual(
541 CompareOperationHints::Hint hint) {
542 return new (zone()) Operator1<CompareOperationHints::Hint>(
543 IrOpcode::kSpeculativeNumberLessThanOrEqual,
544 Operator::kFoldable | Operator::kNoThrow,
545 "SpeculativeNumberLessThanOrEqual", 2, 1, 1, 1, 1, 0, hint);
546}
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400547
548#define ACCESS_OP_LIST(V) \
549 V(LoadField, FieldAccess, Operator::kNoWrite, 1, 1, 1) \
550 V(StoreField, FieldAccess, Operator::kNoRead, 2, 1, 0) \
551 V(LoadElement, ElementAccess, Operator::kNoWrite, 2, 1, 1) \
552 V(StoreElement, ElementAccess, Operator::kNoRead, 3, 1, 0)
553
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400554#define ACCESS(Name, Type, properties, value_input_count, control_input_count, \
555 output_count) \
556 const Operator* SimplifiedOperatorBuilder::Name(const Type& access) { \
557 return new (zone()) \
Ben Murdoch61f157c2016-09-16 13:49:30 +0100558 Operator1<Type>(IrOpcode::k##Name, \
559 Operator::kNoDeopt | Operator::kNoThrow | properties, \
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400560 #Name, value_input_count, 1, control_input_count, \
561 output_count, 1, 0, access); \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000562 }
563ACCESS_OP_LIST(ACCESS)
564#undef ACCESS
565
566} // namespace compiler
567} // namespace internal
568} // namespace v8