blob: 22d809b9d676492149d604336de71549576db2e0 [file] [log] [blame]
Ben Murdoch014dc512016-03-22 12:00:34 +00001// Copyright 2015 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/representation-change.h"
6
7#include <sstream>
8
9#include "src/base/bits.h"
10#include "src/code-factory.h"
11#include "src/compiler/machine-operator.h"
12
13namespace v8 {
14namespace internal {
15namespace compiler {
16
17const char* Truncation::description() const {
18 switch (kind()) {
19 case TruncationKind::kNone:
20 return "no-value-use";
21 case TruncationKind::kBool:
22 return "truncate-to-bool";
23 case TruncationKind::kWord32:
24 return "truncate-to-word32";
25 case TruncationKind::kWord64:
26 return "truncate-to-word64";
27 case TruncationKind::kFloat32:
28 return "truncate-to-float32";
29 case TruncationKind::kFloat64:
30 return "truncate-to-float64";
31 case TruncationKind::kAny:
32 return "no-truncation";
33 }
34 UNREACHABLE();
35 return nullptr;
36}
37
38
39// Partial order for truncations:
40//
41// kWord64 kAny
42// ^ ^
43// \ |
44// \ kFloat64 <--+
45// \ ^ ^ |
46// \ / | |
47// kWord32 kFloat32 kBool
48// ^ ^ ^
49// \ | /
50// \ | /
51// \ | /
52// \ | /
53// \ | /
54// kNone
55
56// static
57Truncation::TruncationKind Truncation::Generalize(TruncationKind rep1,
58 TruncationKind rep2) {
59 if (LessGeneral(rep1, rep2)) return rep2;
60 if (LessGeneral(rep2, rep1)) return rep1;
61 // Handle the generalization of float64-representable values.
62 if (LessGeneral(rep1, TruncationKind::kFloat64) &&
63 LessGeneral(rep2, TruncationKind::kFloat64)) {
64 return TruncationKind::kFloat64;
65 }
Ben Murdochf91f0612016-11-29 16:50:11 +000066 // Handle the generalization of any-representable values.
67 if (LessGeneral(rep1, TruncationKind::kAny) &&
68 LessGeneral(rep2, TruncationKind::kAny)) {
69 return TruncationKind::kAny;
70 }
Ben Murdoch014dc512016-03-22 12:00:34 +000071 // All other combinations are illegal.
72 FATAL("Tried to combine incompatible truncations");
73 return TruncationKind::kNone;
74}
75
76
77// static
78bool Truncation::LessGeneral(TruncationKind rep1, TruncationKind rep2) {
79 switch (rep1) {
80 case TruncationKind::kNone:
81 return true;
82 case TruncationKind::kBool:
83 return rep2 == TruncationKind::kBool || rep2 == TruncationKind::kAny;
84 case TruncationKind::kWord32:
85 return rep2 == TruncationKind::kWord32 ||
86 rep2 == TruncationKind::kWord64 ||
87 rep2 == TruncationKind::kFloat64 || rep2 == TruncationKind::kAny;
88 case TruncationKind::kWord64:
89 return rep2 == TruncationKind::kWord64;
90 case TruncationKind::kFloat32:
91 return rep2 == TruncationKind::kFloat32 ||
92 rep2 == TruncationKind::kFloat64 || rep2 == TruncationKind::kAny;
93 case TruncationKind::kFloat64:
94 return rep2 == TruncationKind::kFloat64 || rep2 == TruncationKind::kAny;
95 case TruncationKind::kAny:
96 return rep2 == TruncationKind::kAny;
97 }
98 UNREACHABLE();
99 return false;
100}
101
102
103namespace {
104
Ben Murdoch014dc512016-03-22 12:00:34 +0000105bool IsWord(MachineRepresentation rep) {
106 return rep == MachineRepresentation::kWord8 ||
107 rep == MachineRepresentation::kWord16 ||
108 rep == MachineRepresentation::kWord32;
109}
110
111} // namespace
112
Ben Murdoch014dc512016-03-22 12:00:34 +0000113// Changes representation from {output_rep} to {use_rep}. The {truncation}
114// parameter is only used for sanity checking - if the changer cannot figure
115// out signedness for the word32->float64 conversion, then we check that the
116// uses truncate to word32 (so they do not care about signedness).
117Node* RepresentationChanger::GetRepresentationFor(
118 Node* node, MachineRepresentation output_rep, Type* output_type,
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100119 Node* use_node, UseInfo use_info) {
Ben Murdochf91f0612016-11-29 16:50:11 +0000120 if (output_rep == MachineRepresentation::kNone &&
121 output_type->IsInhabited()) {
122 // The output representation should be set if the type is inhabited (i.e.,
123 // if the value is possible).
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100124 return TypeError(node, output_rep, output_type, use_info.representation());
Ben Murdoch014dc512016-03-22 12:00:34 +0000125 }
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100126
127 // Handle the no-op shortcuts when no checking is necessary.
128 if (use_info.type_check() == TypeCheckKind::kNone ||
129 output_rep != MachineRepresentation::kWord32) {
130 if (use_info.representation() == output_rep) {
131 // Representations are the same. That's a no-op.
132 return node;
133 }
134 if (IsWord(use_info.representation()) && IsWord(output_rep)) {
135 // Both are words less than or equal to 32-bits.
136 // Since loads of integers from memory implicitly sign or zero extend the
137 // value to the full machine word size and stores implicitly truncate,
138 // no representation change is necessary.
139 return node;
140 }
Ben Murdoch014dc512016-03-22 12:00:34 +0000141 }
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100142
143 switch (use_info.representation()) {
Ben Murdochf91f0612016-11-29 16:50:11 +0000144 case MachineRepresentation::kTaggedSigned:
Ben Murdochf3b273f2017-01-17 12:11:28 +0000145 DCHECK(use_info.type_check() == TypeCheckKind::kNone ||
146 use_info.type_check() == TypeCheckKind::kSignedSmall);
147 return GetTaggedSignedRepresentationFor(node, output_rep, output_type,
148 use_node, use_info);
Ben Murdochf91f0612016-11-29 16:50:11 +0000149 case MachineRepresentation::kTaggedPointer:
Ben Murdochf3b273f2017-01-17 12:11:28 +0000150 DCHECK(use_info.type_check() == TypeCheckKind::kNone);
151 return GetTaggedPointerRepresentationFor(node, output_rep, output_type);
Ben Murdoch014dc512016-03-22 12:00:34 +0000152 case MachineRepresentation::kTagged:
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100153 DCHECK(use_info.type_check() == TypeCheckKind::kNone);
Ben Murdochf3b273f2017-01-17 12:11:28 +0000154 return GetTaggedRepresentationFor(node, output_rep, output_type,
155 use_info.truncation());
Ben Murdoch014dc512016-03-22 12:00:34 +0000156 case MachineRepresentation::kFloat32:
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100157 DCHECK(use_info.type_check() == TypeCheckKind::kNone);
Ben Murdoch014dc512016-03-22 12:00:34 +0000158 return GetFloat32RepresentationFor(node, output_rep, output_type,
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100159 use_info.truncation());
Ben Murdoch014dc512016-03-22 12:00:34 +0000160 case MachineRepresentation::kFloat64:
161 return GetFloat64RepresentationFor(node, output_rep, output_type,
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100162 use_node, use_info);
Ben Murdoch014dc512016-03-22 12:00:34 +0000163 case MachineRepresentation::kBit:
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100164 DCHECK(use_info.type_check() == TypeCheckKind::kNone);
Ben Murdoch014dc512016-03-22 12:00:34 +0000165 return GetBitRepresentationFor(node, output_rep, output_type);
166 case MachineRepresentation::kWord8:
167 case MachineRepresentation::kWord16:
168 case MachineRepresentation::kWord32:
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100169 return GetWord32RepresentationFor(node, output_rep, output_type, use_node,
170 use_info);
Ben Murdoch014dc512016-03-22 12:00:34 +0000171 case MachineRepresentation::kWord64:
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100172 DCHECK(use_info.type_check() == TypeCheckKind::kNone);
Ben Murdoch014dc512016-03-22 12:00:34 +0000173 return GetWord64RepresentationFor(node, output_rep, output_type);
Ben Murdoch109988c2016-05-18 11:27:45 +0100174 case MachineRepresentation::kSimd128: // Fall through.
175 // TODO(bbudge) Handle conversions between tagged and untagged.
176 break;
Ben Murdoch014dc512016-03-22 12:00:34 +0000177 case MachineRepresentation::kNone:
178 return node;
179 }
180 UNREACHABLE();
181 return nullptr;
182}
183
Ben Murdochf3b273f2017-01-17 12:11:28 +0000184Node* RepresentationChanger::GetTaggedSignedRepresentationFor(
185 Node* node, MachineRepresentation output_rep, Type* output_type,
186 Node* use_node, UseInfo use_info) {
187 // Eagerly fold representation changes for constants.
188 switch (node->opcode()) {
189 case IrOpcode::kNumberConstant:
190 if (output_type->Is(Type::SignedSmall())) {
191 return node;
192 }
193 break;
194 default:
195 break;
196 }
197 // Select the correct X -> Tagged operator.
198 const Operator* op;
199 if (output_type->Is(Type::None())) {
200 // This is an impossible value; it should not be used at runtime.
201 // We just provide a dummy value here.
202 return jsgraph()->Constant(0);
203 } else if (IsWord(output_rep)) {
204 if (output_type->Is(Type::Signed31())) {
205 op = simplified()->ChangeInt31ToTaggedSigned();
206 } else if (output_type->Is(Type::Signed32())) {
207 if (SmiValuesAre32Bits()) {
208 op = simplified()->ChangeInt32ToTagged();
209 } else if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
210 op = simplified()->CheckedInt32ToTaggedSigned();
211 } else {
212 return TypeError(node, output_rep, output_type,
213 MachineRepresentation::kTaggedSigned);
214 }
215 } else if (output_type->Is(Type::Unsigned32()) &&
216 use_info.type_check() == TypeCheckKind::kSignedSmall) {
217 op = simplified()->CheckedUint32ToTaggedSigned();
218 } else {
219 return TypeError(node, output_rep, output_type,
220 MachineRepresentation::kTaggedSigned);
221 }
222 } else if (output_rep == MachineRepresentation::kFloat64) {
223 if (output_type->Is(Type::Signed31())) {
224 // float64 -> int32 -> tagged signed
225 node = InsertChangeFloat64ToInt32(node);
226 op = simplified()->ChangeInt31ToTaggedSigned();
227 } else if (output_type->Is(Type::Signed32())) {
228 // float64 -> int32 -> tagged signed
229 node = InsertChangeFloat64ToInt32(node);
230 if (SmiValuesAre32Bits()) {
231 op = simplified()->ChangeInt32ToTagged();
232 } else if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
233 op = simplified()->CheckedInt32ToTaggedSigned();
234 } else {
235 return TypeError(node, output_rep, output_type,
236 MachineRepresentation::kTaggedSigned);
237 }
238 } else if (output_type->Is(Type::Unsigned32()) &&
239 use_info.type_check() == TypeCheckKind::kSignedSmall) {
240 // float64 -> uint32 -> tagged signed
241 node = InsertChangeFloat64ToUint32(node);
242 op = simplified()->CheckedUint32ToTaggedSigned();
243 } else if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
244 op = simplified()->CheckedFloat64ToInt32(
245 output_type->Maybe(Type::MinusZero())
246 ? CheckForMinusZeroMode::kCheckForMinusZero
247 : CheckForMinusZeroMode::kDontCheckForMinusZero);
248 node = InsertConversion(node, op, use_node);
249 if (SmiValuesAre32Bits()) {
250 op = simplified()->ChangeInt32ToTagged();
251 } else {
252 op = simplified()->CheckedInt32ToTaggedSigned();
253 }
254 } else {
255 return TypeError(node, output_rep, output_type,
256 MachineRepresentation::kTaggedSigned);
257 }
258 } else if (CanBeTaggedPointer(output_rep) &&
259 use_info.type_check() == TypeCheckKind::kSignedSmall) {
260 op = simplified()->CheckedTaggedToTaggedSigned();
261 } else if (output_rep == MachineRepresentation::kBit &&
262 use_info.type_check() == TypeCheckKind::kSignedSmall) {
263 // TODO(turbofan): Consider adding a Bailout operator that just deopts.
264 // Also use that for MachineRepresentation::kPointer case above.
265 node = InsertChangeBitToTagged(node);
266 op = simplified()->CheckedTaggedToTaggedSigned();
267 } else {
268 return TypeError(node, output_rep, output_type,
269 MachineRepresentation::kTaggedSigned);
270 }
271 return InsertConversion(node, op, use_node);
272}
273
274Node* RepresentationChanger::GetTaggedPointerRepresentationFor(
Ben Murdoch014dc512016-03-22 12:00:34 +0000275 Node* node, MachineRepresentation output_rep, Type* output_type) {
276 // Eagerly fold representation changes for constants.
277 switch (node->opcode()) {
Ben Murdochf3b273f2017-01-17 12:11:28 +0000278 case IrOpcode::kHeapConstant:
279 return node; // No change necessary.
280 case IrOpcode::kInt32Constant:
281 if (output_type->Is(Type::Boolean())) {
282 return OpParameter<int32_t>(node) == 0 ? jsgraph()->FalseConstant()
283 : jsgraph()->TrueConstant();
284 } else {
285 return TypeError(node, output_rep, output_type,
286 MachineRepresentation::kTaggedPointer);
287 }
288 case IrOpcode::kFloat64Constant:
289 case IrOpcode::kFloat32Constant:
290 return TypeError(node, output_rep, output_type,
291 MachineRepresentation::kTaggedPointer);
292 default:
293 break;
294 }
295 // Select the correct X -> Tagged operator.
296 if (output_type->Is(Type::None())) {
297 // This is an impossible value; it should not be used at runtime.
298 // We just provide a dummy value here.
299 return jsgraph()->TheHoleConstant();
300 }
301 return TypeError(node, output_rep, output_type,
302 MachineRepresentation::kTaggedPointer);
303}
304
305Node* RepresentationChanger::GetTaggedRepresentationFor(
306 Node* node, MachineRepresentation output_rep, Type* output_type,
307 Truncation truncation) {
308 // Eagerly fold representation changes for constants.
309 switch (node->opcode()) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000310 case IrOpcode::kNumberConstant:
311 case IrOpcode::kHeapConstant:
312 return node; // No change necessary.
313 case IrOpcode::kInt32Constant:
314 if (output_type->Is(Type::Signed32())) {
315 int32_t value = OpParameter<int32_t>(node);
316 return jsgraph()->Constant(value);
317 } else if (output_type->Is(Type::Unsigned32())) {
318 uint32_t value = static_cast<uint32_t>(OpParameter<int32_t>(node));
319 return jsgraph()->Constant(static_cast<double>(value));
Ben Murdochf91f0612016-11-29 16:50:11 +0000320 } else if (output_type->Is(Type::Boolean())) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000321 return OpParameter<int32_t>(node) == 0 ? jsgraph()->FalseConstant()
322 : jsgraph()->TrueConstant();
323 } else {
324 return TypeError(node, output_rep, output_type,
325 MachineRepresentation::kTagged);
326 }
327 case IrOpcode::kFloat64Constant:
328 return jsgraph()->Constant(OpParameter<double>(node));
329 case IrOpcode::kFloat32Constant:
330 return jsgraph()->Constant(OpParameter<float>(node));
331 default:
332 break;
333 }
Ben Murdochf3b273f2017-01-17 12:11:28 +0000334 if (output_rep == MachineRepresentation::kTaggedSigned ||
335 output_rep == MachineRepresentation::kTaggedPointer) {
336 // this is a no-op.
337 return node;
338 }
Ben Murdoch014dc512016-03-22 12:00:34 +0000339 // Select the correct X -> Tagged operator.
340 const Operator* op;
Ben Murdochf3b273f2017-01-17 12:11:28 +0000341 if (output_type->Is(Type::None())) {
342 // This is an impossible value; it should not be used at runtime.
343 // We just provide a dummy value here.
344 return jsgraph()->TheHoleConstant();
Ben Murdochf91f0612016-11-29 16:50:11 +0000345 } else if (output_rep == MachineRepresentation::kBit) {
346 if (output_type->Is(Type::Boolean())) {
347 op = simplified()->ChangeBitToTagged();
348 } else {
349 return TypeError(node, output_rep, output_type,
350 MachineRepresentation::kTagged);
351 }
Ben Murdoch014dc512016-03-22 12:00:34 +0000352 } else if (IsWord(output_rep)) {
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100353 if (output_type->Is(Type::Signed31())) {
354 op = simplified()->ChangeInt31ToTaggedSigned();
Ben Murdoch014dc512016-03-22 12:00:34 +0000355 } else if (output_type->Is(Type::Signed32())) {
356 op = simplified()->ChangeInt32ToTagged();
Ben Murdochf3b273f2017-01-17 12:11:28 +0000357 } else if (output_type->Is(Type::Unsigned32()) ||
358 truncation.IsUsedAsWord32()) {
359 // Either the output is uint32 or the uses only care about the
360 // low 32 bits (so we can pick uint32 safely).
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100361 op = simplified()->ChangeUint32ToTagged();
Ben Murdoch014dc512016-03-22 12:00:34 +0000362 } else {
363 return TypeError(node, output_rep, output_type,
364 MachineRepresentation::kTagged);
365 }
366 } else if (output_rep ==
367 MachineRepresentation::kFloat32) { // float32 -> float64 -> tagged
368 node = InsertChangeFloat32ToFloat64(node);
Ben Murdochf3b273f2017-01-17 12:11:28 +0000369 op = simplified()->ChangeFloat64ToTagged();
Ben Murdoch014dc512016-03-22 12:00:34 +0000370 } else if (output_rep == MachineRepresentation::kFloat64) {
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100371 if (output_type->Is(Type::Signed31())) { // float64 -> int32 -> tagged
372 node = InsertChangeFloat64ToInt32(node);
373 op = simplified()->ChangeInt31ToTaggedSigned();
374 } else if (output_type->Is(
375 Type::Signed32())) { // float64 -> int32 -> tagged
376 node = InsertChangeFloat64ToInt32(node);
377 op = simplified()->ChangeInt32ToTagged();
378 } else if (output_type->Is(
379 Type::Unsigned32())) { // float64 -> uint32 -> tagged
380 node = InsertChangeFloat64ToUint32(node);
381 op = simplified()->ChangeUint32ToTagged();
382 } else {
Ben Murdochf3b273f2017-01-17 12:11:28 +0000383 op = simplified()->ChangeFloat64ToTagged();
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100384 }
Ben Murdoch014dc512016-03-22 12:00:34 +0000385 } else {
386 return TypeError(node, output_rep, output_type,
387 MachineRepresentation::kTagged);
388 }
389 return jsgraph()->graph()->NewNode(op, node);
390}
391
392
393Node* RepresentationChanger::GetFloat32RepresentationFor(
394 Node* node, MachineRepresentation output_rep, Type* output_type,
395 Truncation truncation) {
396 // Eagerly fold representation changes for constants.
397 switch (node->opcode()) {
398 case IrOpcode::kFloat64Constant:
399 case IrOpcode::kNumberConstant:
400 return jsgraph()->Float32Constant(
401 DoubleToFloat32(OpParameter<double>(node)));
402 case IrOpcode::kInt32Constant:
403 if (output_type->Is(Type::Unsigned32())) {
404 uint32_t value = static_cast<uint32_t>(OpParameter<int32_t>(node));
405 return jsgraph()->Float32Constant(static_cast<float>(value));
406 } else {
407 int32_t value = OpParameter<int32_t>(node);
408 return jsgraph()->Float32Constant(static_cast<float>(value));
409 }
410 case IrOpcode::kFloat32Constant:
411 return node; // No change necessary.
412 default:
413 break;
414 }
415 // Select the correct X -> Float32 operator.
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100416 const Operator* op = nullptr;
Ben Murdochf3b273f2017-01-17 12:11:28 +0000417 if (output_type->Is(Type::None())) {
418 // This is an impossible value; it should not be used at runtime.
419 // We just provide a dummy value here.
420 return jsgraph()->Float32Constant(0.0f);
Ben Murdochf91f0612016-11-29 16:50:11 +0000421 } else if (IsWord(output_rep)) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000422 if (output_type->Is(Type::Signed32())) {
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100423 // int32 -> float64 -> float32
Ben Murdoch014dc512016-03-22 12:00:34 +0000424 op = machine()->ChangeInt32ToFloat64();
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100425 node = jsgraph()->graph()->NewNode(op, node);
426 op = machine()->TruncateFloat64ToFloat32();
427 } else if (output_type->Is(Type::Unsigned32()) ||
Ben Murdochf91f0612016-11-29 16:50:11 +0000428 truncation.IsUsedAsWord32()) {
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100429 // Either the output is uint32 or the uses only care about the
430 // low 32 bits (so we can pick uint32 safely).
431
432 // uint32 -> float64 -> float32
Ben Murdoch014dc512016-03-22 12:00:34 +0000433 op = machine()->ChangeUint32ToFloat64();
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100434 node = jsgraph()->graph()->NewNode(op, node);
435 op = machine()->TruncateFloat64ToFloat32();
Ben Murdoch014dc512016-03-22 12:00:34 +0000436 }
Ben Murdochf3b273f2017-01-17 12:11:28 +0000437 } else if (output_rep == MachineRepresentation::kTagged ||
438 output_rep == MachineRepresentation::kTaggedPointer) {
Ben Murdochf91f0612016-11-29 16:50:11 +0000439 if (output_type->Is(Type::NumberOrOddball())) {
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100440 // tagged -> float64 -> float32
441 if (output_type->Is(Type::Number())) {
442 op = simplified()->ChangeTaggedToFloat64();
443 } else {
444 op = simplified()->TruncateTaggedToFloat64();
445 }
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100446 node = jsgraph()->graph()->NewNode(op, node);
447 op = machine()->TruncateFloat64ToFloat32();
448 }
Ben Murdoch014dc512016-03-22 12:00:34 +0000449 } else if (output_rep == MachineRepresentation::kFloat64) {
450 op = machine()->TruncateFloat64ToFloat32();
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100451 }
452 if (op == nullptr) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000453 return TypeError(node, output_rep, output_type,
454 MachineRepresentation::kFloat32);
455 }
456 return jsgraph()->graph()->NewNode(op, node);
457}
458
Ben Murdoch014dc512016-03-22 12:00:34 +0000459Node* RepresentationChanger::GetFloat64RepresentationFor(
460 Node* node, MachineRepresentation output_rep, Type* output_type,
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100461 Node* use_node, UseInfo use_info) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000462 // Eagerly fold representation changes for constants.
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100463 if ((use_info.type_check() == TypeCheckKind::kNone)) {
464 // TODO(jarin) Handle checked constant conversions.
465 switch (node->opcode()) {
466 case IrOpcode::kNumberConstant:
467 return jsgraph()->Float64Constant(OpParameter<double>(node));
468 case IrOpcode::kInt32Constant:
469 if (output_type->Is(Type::Signed32())) {
470 int32_t value = OpParameter<int32_t>(node);
471 return jsgraph()->Float64Constant(value);
472 } else {
473 DCHECK(output_type->Is(Type::Unsigned32()));
474 uint32_t value = static_cast<uint32_t>(OpParameter<int32_t>(node));
475 return jsgraph()->Float64Constant(static_cast<double>(value));
476 }
477 case IrOpcode::kFloat64Constant:
478 return node; // No change necessary.
479 case IrOpcode::kFloat32Constant:
480 return jsgraph()->Float64Constant(OpParameter<float>(node));
481 default:
482 break;
483 }
Ben Murdoch014dc512016-03-22 12:00:34 +0000484 }
485 // Select the correct X -> Float64 operator.
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100486 const Operator* op = nullptr;
Ben Murdochf3b273f2017-01-17 12:11:28 +0000487 if (output_type->Is(Type::None())) {
488 // This is an impossible value; it should not be used at runtime.
489 // We just provide a dummy value here.
490 return jsgraph()->Float64Constant(0.0);
Ben Murdochf91f0612016-11-29 16:50:11 +0000491 } else if (IsWord(output_rep)) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000492 if (output_type->Is(Type::Signed32())) {
493 op = machine()->ChangeInt32ToFloat64();
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100494 } else if (output_type->Is(Type::Unsigned32()) ||
Ben Murdochf91f0612016-11-29 16:50:11 +0000495 use_info.truncation().IsUsedAsWord32()) {
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100496 // Either the output is uint32 or the uses only care about the
497 // low 32 bits (so we can pick uint32 safely).
Ben Murdoch014dc512016-03-22 12:00:34 +0000498 op = machine()->ChangeUint32ToFloat64();
499 }
Ben Murdochf91f0612016-11-29 16:50:11 +0000500 } else if (output_rep == MachineRepresentation::kBit) {
501 op = machine()->ChangeUint32ToFloat64();
Ben Murdochf3b273f2017-01-17 12:11:28 +0000502 } else if (output_rep == MachineRepresentation::kTagged ||
503 output_rep == MachineRepresentation::kTaggedSigned ||
504 output_rep == MachineRepresentation::kTaggedPointer) {
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100505 if (output_type->Is(Type::Undefined())) {
506 return jsgraph()->Float64Constant(
507 std::numeric_limits<double>::quiet_NaN());
Ben Murdochf3b273f2017-01-17 12:11:28 +0000508
509 } else if (output_rep == MachineRepresentation::kTaggedSigned) {
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100510 node = InsertChangeTaggedSignedToInt32(node);
511 op = machine()->ChangeInt32ToFloat64();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100512 } else if (output_type->Is(Type::Number())) {
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100513 op = simplified()->ChangeTaggedToFloat64();
Ben Murdochf91f0612016-11-29 16:50:11 +0000514 } else if (output_type->Is(Type::NumberOrOddball())) {
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100515 // TODO(jarin) Here we should check that truncation is Number.
516 op = simplified()->TruncateTaggedToFloat64();
Ben Murdochf91f0612016-11-29 16:50:11 +0000517 } else if (use_info.type_check() == TypeCheckKind::kNumber ||
518 (use_info.type_check() == TypeCheckKind::kNumberOrOddball &&
519 !output_type->Maybe(Type::BooleanOrNullOrNumber()))) {
520 op = simplified()->CheckedTaggedToFloat64(CheckTaggedInputMode::kNumber);
521 } else if (use_info.type_check() == TypeCheckKind::kNumberOrOddball) {
522 op = simplified()->CheckedTaggedToFloat64(
523 CheckTaggedInputMode::kNumberOrOddball);
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100524 }
Ben Murdoch014dc512016-03-22 12:00:34 +0000525 } else if (output_rep == MachineRepresentation::kFloat32) {
526 op = machine()->ChangeFloat32ToFloat64();
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100527 }
528 if (op == nullptr) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000529 return TypeError(node, output_rep, output_type,
530 MachineRepresentation::kFloat64);
531 }
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100532 return InsertConversion(node, op, use_node);
Ben Murdoch014dc512016-03-22 12:00:34 +0000533}
534
Ben Murdoch014dc512016-03-22 12:00:34 +0000535Node* RepresentationChanger::MakeTruncatedInt32Constant(double value) {
536 return jsgraph()->Int32Constant(DoubleToInt32(value));
537}
538
Ben Murdoch014dc512016-03-22 12:00:34 +0000539Node* RepresentationChanger::GetWord32RepresentationFor(
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100540 Node* node, MachineRepresentation output_rep, Type* output_type,
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100541 Node* use_node, UseInfo use_info) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000542 // Eagerly fold representation changes for constants.
543 switch (node->opcode()) {
544 case IrOpcode::kInt32Constant:
545 return node; // No change necessary.
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100546 case IrOpcode::kFloat32Constant: {
547 float const fv = OpParameter<float>(node);
548 if (use_info.type_check() == TypeCheckKind::kNone ||
Ben Murdochf91f0612016-11-29 16:50:11 +0000549 ((use_info.type_check() == TypeCheckKind::kSignedSmall ||
550 use_info.type_check() == TypeCheckKind::kSigned32) &&
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100551 IsInt32Double(fv))) {
552 return MakeTruncatedInt32Constant(fv);
553 }
554 break;
555 }
Ben Murdoch014dc512016-03-22 12:00:34 +0000556 case IrOpcode::kNumberConstant:
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100557 case IrOpcode::kFloat64Constant: {
558 double const fv = OpParameter<double>(node);
559 if (use_info.type_check() == TypeCheckKind::kNone ||
Ben Murdochf91f0612016-11-29 16:50:11 +0000560 ((use_info.type_check() == TypeCheckKind::kSignedSmall ||
561 use_info.type_check() == TypeCheckKind::kSigned32) &&
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100562 IsInt32Double(fv))) {
563 return MakeTruncatedInt32Constant(fv);
564 }
565 break;
566 }
Ben Murdoch014dc512016-03-22 12:00:34 +0000567 default:
568 break;
569 }
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100570
Ben Murdoch014dc512016-03-22 12:00:34 +0000571 // Select the correct X -> Word32 operator.
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100572 const Operator* op = nullptr;
Ben Murdochf3b273f2017-01-17 12:11:28 +0000573 if (output_type->Is(Type::None())) {
574 // This is an impossible value; it should not be used at runtime.
575 // We just provide a dummy value here.
576 return jsgraph()->Int32Constant(0);
Ben Murdochf91f0612016-11-29 16:50:11 +0000577 } else if (output_rep == MachineRepresentation::kBit) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000578 return node; // Sloppy comparison -> word32
579 } else if (output_rep == MachineRepresentation::kFloat64) {
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100580 if (output_type->Is(Type::Unsigned32())) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000581 op = machine()->ChangeFloat64ToUint32();
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100582 } else if (output_type->Is(Type::Signed32())) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000583 op = machine()->ChangeFloat64ToInt32();
Ben Murdochf91f0612016-11-29 16:50:11 +0000584 } else if (use_info.truncation().IsUsedAsWord32()) {
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100585 op = machine()->TruncateFloat64ToWord32();
Ben Murdochf91f0612016-11-29 16:50:11 +0000586 } else if (use_info.type_check() == TypeCheckKind::kSignedSmall ||
587 use_info.type_check() == TypeCheckKind::kSigned32) {
588 op = simplified()->CheckedFloat64ToInt32(
589 output_type->Maybe(Type::MinusZero())
590 ? CheckForMinusZeroMode::kCheckForMinusZero
591 : CheckForMinusZeroMode::kDontCheckForMinusZero);
Ben Murdoch014dc512016-03-22 12:00:34 +0000592 }
593 } else if (output_rep == MachineRepresentation::kFloat32) {
594 node = InsertChangeFloat32ToFloat64(node); // float32 -> float64 -> int32
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100595 if (output_type->Is(Type::Unsigned32())) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000596 op = machine()->ChangeFloat64ToUint32();
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100597 } else if (output_type->Is(Type::Signed32())) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000598 op = machine()->ChangeFloat64ToInt32();
Ben Murdochf91f0612016-11-29 16:50:11 +0000599 } else if (use_info.truncation().IsUsedAsWord32()) {
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100600 op = machine()->TruncateFloat64ToWord32();
Ben Murdochf91f0612016-11-29 16:50:11 +0000601 } else if (use_info.type_check() == TypeCheckKind::kSignedSmall ||
602 use_info.type_check() == TypeCheckKind::kSigned32) {
603 op = simplified()->CheckedFloat64ToInt32(
604 output_type->Maybe(Type::MinusZero())
605 ? CheckForMinusZeroMode::kCheckForMinusZero
606 : CheckForMinusZeroMode::kDontCheckForMinusZero);
Ben Murdoch014dc512016-03-22 12:00:34 +0000607 }
Ben Murdochf3b273f2017-01-17 12:11:28 +0000608 } else if (output_rep == MachineRepresentation::kTaggedSigned) {
609 if (output_type->Is(Type::Signed32())) {
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100610 op = simplified()->ChangeTaggedSignedToInt32();
Ben Murdochf3b273f2017-01-17 12:11:28 +0000611 } else if (use_info.truncation().IsUsedAsWord32()) {
612 if (use_info.type_check() != TypeCheckKind::kNone) {
613 op = simplified()->CheckedTruncateTaggedToWord32();
614 } else {
615 op = simplified()->TruncateTaggedToWord32();
616 }
617 }
618 } else if (output_rep == MachineRepresentation::kTagged ||
619 output_rep == MachineRepresentation::kTaggedPointer) {
620 if (output_type->Is(Type::Unsigned32())) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000621 op = simplified()->ChangeTaggedToUint32();
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100622 } else if (output_type->Is(Type::Signed32())) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000623 op = simplified()->ChangeTaggedToInt32();
Ben Murdochf91f0612016-11-29 16:50:11 +0000624 } else if (use_info.truncation().IsUsedAsWord32()) {
625 if (use_info.type_check() != TypeCheckKind::kNone) {
626 op = simplified()->CheckedTruncateTaggedToWord32();
627 } else {
628 op = simplified()->TruncateTaggedToWord32();
629 }
630 } else if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
631 op = simplified()->CheckedTaggedSignedToInt32();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100632 } else if (use_info.type_check() == TypeCheckKind::kSigned32) {
Ben Murdochf91f0612016-11-29 16:50:11 +0000633 op = simplified()->CheckedTaggedToInt32(
634 output_type->Maybe(Type::MinusZero())
635 ? CheckForMinusZeroMode::kCheckForMinusZero
636 : CheckForMinusZeroMode::kDontCheckForMinusZero);
Ben Murdoch014dc512016-03-22 12:00:34 +0000637 }
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100638 } else if (output_rep == MachineRepresentation::kWord32) {
639 // Only the checked case should get here, the non-checked case is
640 // handled in GetRepresentationFor.
Ben Murdochf91f0612016-11-29 16:50:11 +0000641 if (use_info.type_check() == TypeCheckKind::kSignedSmall ||
642 use_info.type_check() == TypeCheckKind::kSigned32) {
643 if (output_type->Is(Type::Signed32())) {
644 return node;
645 } else if (output_type->Is(Type::Unsigned32())) {
646 op = simplified()->CheckedUint32ToInt32();
647 }
648 } else {
649 DCHECK_EQ(TypeCheckKind::kNumberOrOddball, use_info.type_check());
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100650 return node;
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100651 }
652 } else if (output_rep == MachineRepresentation::kWord8 ||
653 output_rep == MachineRepresentation::kWord16) {
654 DCHECK(use_info.representation() == MachineRepresentation::kWord32);
Ben Murdochf91f0612016-11-29 16:50:11 +0000655 DCHECK(use_info.type_check() == TypeCheckKind::kSignedSmall ||
656 use_info.type_check() == TypeCheckKind::kSigned32);
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100657 return node;
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100658 }
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100659
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100660 if (op == nullptr) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000661 return TypeError(node, output_rep, output_type,
662 MachineRepresentation::kWord32);
663 }
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100664 return InsertConversion(node, op, use_node);
665}
666
667Node* RepresentationChanger::InsertConversion(Node* node, const Operator* op,
668 Node* use_node) {
669 if (op->ControlInputCount() > 0) {
670 // If the operator can deoptimize (which means it has control
671 // input), we need to connect it to the effect and control chains.
672 Node* effect = NodeProperties::GetEffectInput(use_node);
673 Node* control = NodeProperties::GetControlInput(use_node);
674 Node* conversion = jsgraph()->graph()->NewNode(op, node, effect, control);
675 NodeProperties::ReplaceEffectInput(use_node, conversion);
676 return conversion;
677 }
Ben Murdoch014dc512016-03-22 12:00:34 +0000678 return jsgraph()->graph()->NewNode(op, node);
679}
680
681
682Node* RepresentationChanger::GetBitRepresentationFor(
683 Node* node, MachineRepresentation output_rep, Type* output_type) {
684 // Eagerly fold representation changes for constants.
685 switch (node->opcode()) {
686 case IrOpcode::kHeapConstant: {
687 Handle<HeapObject> value = OpParameter<Handle<HeapObject>>(node);
Ben Murdochf3b273f2017-01-17 12:11:28 +0000688 return jsgraph()->Int32Constant(value->BooleanValue() ? 1 : 0);
Ben Murdoch014dc512016-03-22 12:00:34 +0000689 }
690 default:
691 break;
692 }
693 // Select the correct X -> Bit operator.
694 const Operator* op;
Ben Murdochf3b273f2017-01-17 12:11:28 +0000695 if (output_type->Is(Type::None())) {
696 // This is an impossible value; it should not be used at runtime.
697 // We just provide a dummy value here.
698 return jsgraph()->Int32Constant(0);
699 } else if (output_rep == MachineRepresentation::kTagged ||
700 output_rep == MachineRepresentation::kTaggedPointer) {
701 if (output_type->Is(Type::BooleanOrNullOrUndefined())) {
702 // true is the only trueish Oddball.
703 op = simplified()->ChangeTaggedToBit();
704 } else {
705 op = simplified()->TruncateTaggedToBit();
706 }
707 } else if (output_rep == MachineRepresentation::kTaggedSigned) {
708 node = jsgraph()->graph()->NewNode(machine()->WordEqual(), node,
709 jsgraph()->ZeroConstant());
710 return jsgraph()->graph()->NewNode(machine()->Word32Equal(), node,
711 jsgraph()->Int32Constant(0));
712 } else if (IsWord(output_rep)) {
713 node = jsgraph()->graph()->NewNode(machine()->Word32Equal(), node,
714 jsgraph()->Int32Constant(0));
715 return jsgraph()->graph()->NewNode(machine()->Word32Equal(), node,
716 jsgraph()->Int32Constant(0));
717 } else if (output_rep == MachineRepresentation::kFloat32) {
718 node = jsgraph()->graph()->NewNode(machine()->Float32Abs(), node);
719 return jsgraph()->graph()->NewNode(machine()->Float32LessThan(),
720 jsgraph()->Float32Constant(0.0), node);
721 } else if (output_rep == MachineRepresentation::kFloat64) {
722 node = jsgraph()->graph()->NewNode(machine()->Float64Abs(), node);
723 return jsgraph()->graph()->NewNode(machine()->Float64LessThan(),
724 jsgraph()->Float64Constant(0.0), node);
Ben Murdoch014dc512016-03-22 12:00:34 +0000725 } else {
726 return TypeError(node, output_rep, output_type,
727 MachineRepresentation::kBit);
728 }
729 return jsgraph()->graph()->NewNode(op, node);
730}
731
Ben Murdoch014dc512016-03-22 12:00:34 +0000732Node* RepresentationChanger::GetWord64RepresentationFor(
733 Node* node, MachineRepresentation output_rep, Type* output_type) {
Ben Murdochf3b273f2017-01-17 12:11:28 +0000734 if (output_type->Is(Type::None())) {
735 // This is an impossible value; it should not be used at runtime.
736 // We just provide a dummy value here.
737 return jsgraph()->Int64Constant(0);
Ben Murdochf91f0612016-11-29 16:50:11 +0000738 } else if (output_rep == MachineRepresentation::kBit) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000739 return node; // Sloppy comparison -> word64
740 }
741 // Can't really convert Word64 to anything else. Purported to be internal.
742 return TypeError(node, output_rep, output_type,
743 MachineRepresentation::kWord64);
744}
745
Ben Murdoch014dc512016-03-22 12:00:34 +0000746const Operator* RepresentationChanger::Int32OperatorFor(
747 IrOpcode::Value opcode) {
748 switch (opcode) {
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100749 case IrOpcode::kSpeculativeNumberAdd: // Fall through.
Ben Murdoch014dc512016-03-22 12:00:34 +0000750 case IrOpcode::kNumberAdd:
751 return machine()->Int32Add();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100752 case IrOpcode::kSpeculativeNumberSubtract: // Fall through.
Ben Murdoch014dc512016-03-22 12:00:34 +0000753 case IrOpcode::kNumberSubtract:
754 return machine()->Int32Sub();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100755 case IrOpcode::kSpeculativeNumberMultiply:
Ben Murdoch014dc512016-03-22 12:00:34 +0000756 case IrOpcode::kNumberMultiply:
757 return machine()->Int32Mul();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100758 case IrOpcode::kSpeculativeNumberDivide:
Ben Murdoch014dc512016-03-22 12:00:34 +0000759 case IrOpcode::kNumberDivide:
760 return machine()->Int32Div();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100761 case IrOpcode::kSpeculativeNumberModulus:
Ben Murdoch014dc512016-03-22 12:00:34 +0000762 case IrOpcode::kNumberModulus:
763 return machine()->Int32Mod();
Ben Murdochf91f0612016-11-29 16:50:11 +0000764 case IrOpcode::kSpeculativeNumberBitwiseOr: // Fall through.
Ben Murdoch014dc512016-03-22 12:00:34 +0000765 case IrOpcode::kNumberBitwiseOr:
766 return machine()->Word32Or();
Ben Murdochf91f0612016-11-29 16:50:11 +0000767 case IrOpcode::kSpeculativeNumberBitwiseXor: // Fall through.
Ben Murdoch014dc512016-03-22 12:00:34 +0000768 case IrOpcode::kNumberBitwiseXor:
769 return machine()->Word32Xor();
Ben Murdochf91f0612016-11-29 16:50:11 +0000770 case IrOpcode::kSpeculativeNumberBitwiseAnd: // Fall through.
Ben Murdoch014dc512016-03-22 12:00:34 +0000771 case IrOpcode::kNumberBitwiseAnd:
772 return machine()->Word32And();
773 case IrOpcode::kNumberEqual:
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100774 case IrOpcode::kSpeculativeNumberEqual:
Ben Murdoch014dc512016-03-22 12:00:34 +0000775 return machine()->Word32Equal();
776 case IrOpcode::kNumberLessThan:
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100777 case IrOpcode::kSpeculativeNumberLessThan:
Ben Murdoch014dc512016-03-22 12:00:34 +0000778 return machine()->Int32LessThan();
779 case IrOpcode::kNumberLessThanOrEqual:
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100780 case IrOpcode::kSpeculativeNumberLessThanOrEqual:
Ben Murdoch014dc512016-03-22 12:00:34 +0000781 return machine()->Int32LessThanOrEqual();
782 default:
783 UNREACHABLE();
784 return nullptr;
785 }
786}
787
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100788const Operator* RepresentationChanger::Int32OverflowOperatorFor(
789 IrOpcode::Value opcode) {
790 switch (opcode) {
Ben Murdochf91f0612016-11-29 16:50:11 +0000791 case IrOpcode::kSpeculativeNumberAdd:
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100792 return simplified()->CheckedInt32Add();
Ben Murdochf91f0612016-11-29 16:50:11 +0000793 case IrOpcode::kSpeculativeNumberSubtract:
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100794 return simplified()->CheckedInt32Sub();
Ben Murdochf91f0612016-11-29 16:50:11 +0000795 case IrOpcode::kSpeculativeNumberDivide:
796 return simplified()->CheckedInt32Div();
797 case IrOpcode::kSpeculativeNumberModulus:
798 return simplified()->CheckedInt32Mod();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100799 default:
800 UNREACHABLE();
801 return nullptr;
802 }
803}
Ben Murdoch014dc512016-03-22 12:00:34 +0000804
805const Operator* RepresentationChanger::Uint32OperatorFor(
806 IrOpcode::Value opcode) {
807 switch (opcode) {
808 case IrOpcode::kNumberAdd:
809 return machine()->Int32Add();
810 case IrOpcode::kNumberSubtract:
811 return machine()->Int32Sub();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100812 case IrOpcode::kSpeculativeNumberMultiply:
Ben Murdoch014dc512016-03-22 12:00:34 +0000813 case IrOpcode::kNumberMultiply:
814 return machine()->Int32Mul();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100815 case IrOpcode::kSpeculativeNumberDivide:
Ben Murdoch014dc512016-03-22 12:00:34 +0000816 case IrOpcode::kNumberDivide:
817 return machine()->Uint32Div();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100818 case IrOpcode::kSpeculativeNumberModulus:
Ben Murdoch014dc512016-03-22 12:00:34 +0000819 case IrOpcode::kNumberModulus:
820 return machine()->Uint32Mod();
821 case IrOpcode::kNumberEqual:
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100822 case IrOpcode::kSpeculativeNumberEqual:
Ben Murdoch014dc512016-03-22 12:00:34 +0000823 return machine()->Word32Equal();
824 case IrOpcode::kNumberLessThan:
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100825 case IrOpcode::kSpeculativeNumberLessThan:
Ben Murdoch014dc512016-03-22 12:00:34 +0000826 return machine()->Uint32LessThan();
827 case IrOpcode::kNumberLessThanOrEqual:
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100828 case IrOpcode::kSpeculativeNumberLessThanOrEqual:
Ben Murdoch014dc512016-03-22 12:00:34 +0000829 return machine()->Uint32LessThanOrEqual();
Ben Murdoch3b9bc312016-06-02 14:46:10 +0100830 case IrOpcode::kNumberClz32:
831 return machine()->Word32Clz();
832 case IrOpcode::kNumberImul:
833 return machine()->Int32Mul();
Ben Murdoch014dc512016-03-22 12:00:34 +0000834 default:
835 UNREACHABLE();
836 return nullptr;
837 }
838}
839
Ben Murdochf91f0612016-11-29 16:50:11 +0000840const Operator* RepresentationChanger::Uint32OverflowOperatorFor(
841 IrOpcode::Value opcode) {
842 switch (opcode) {
843 case IrOpcode::kSpeculativeNumberDivide:
844 return simplified()->CheckedUint32Div();
845 case IrOpcode::kSpeculativeNumberModulus:
846 return simplified()->CheckedUint32Mod();
847 default:
848 UNREACHABLE();
849 return nullptr;
850 }
851}
Ben Murdoch014dc512016-03-22 12:00:34 +0000852
853const Operator* RepresentationChanger::Float64OperatorFor(
854 IrOpcode::Value opcode) {
855 switch (opcode) {
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100856 case IrOpcode::kSpeculativeNumberAdd:
Ben Murdoch014dc512016-03-22 12:00:34 +0000857 case IrOpcode::kNumberAdd:
858 return machine()->Float64Add();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100859 case IrOpcode::kSpeculativeNumberSubtract:
Ben Murdoch014dc512016-03-22 12:00:34 +0000860 case IrOpcode::kNumberSubtract:
861 return machine()->Float64Sub();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100862 case IrOpcode::kSpeculativeNumberMultiply:
Ben Murdoch014dc512016-03-22 12:00:34 +0000863 case IrOpcode::kNumberMultiply:
864 return machine()->Float64Mul();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100865 case IrOpcode::kSpeculativeNumberDivide:
Ben Murdoch014dc512016-03-22 12:00:34 +0000866 case IrOpcode::kNumberDivide:
867 return machine()->Float64Div();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100868 case IrOpcode::kSpeculativeNumberModulus:
Ben Murdoch014dc512016-03-22 12:00:34 +0000869 case IrOpcode::kNumberModulus:
870 return machine()->Float64Mod();
871 case IrOpcode::kNumberEqual:
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100872 case IrOpcode::kSpeculativeNumberEqual:
Ben Murdoch014dc512016-03-22 12:00:34 +0000873 return machine()->Float64Equal();
874 case IrOpcode::kNumberLessThan:
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100875 case IrOpcode::kSpeculativeNumberLessThan:
Ben Murdoch014dc512016-03-22 12:00:34 +0000876 return machine()->Float64LessThan();
877 case IrOpcode::kNumberLessThanOrEqual:
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100878 case IrOpcode::kSpeculativeNumberLessThanOrEqual:
Ben Murdoch014dc512016-03-22 12:00:34 +0000879 return machine()->Float64LessThanOrEqual();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100880 case IrOpcode::kNumberAbs:
881 return machine()->Float64Abs();
Ben Murdochf91f0612016-11-29 16:50:11 +0000882 case IrOpcode::kNumberAcos:
883 return machine()->Float64Acos();
884 case IrOpcode::kNumberAcosh:
885 return machine()->Float64Acosh();
886 case IrOpcode::kNumberAsin:
887 return machine()->Float64Asin();
888 case IrOpcode::kNumberAsinh:
889 return machine()->Float64Asinh();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100890 case IrOpcode::kNumberAtan:
891 return machine()->Float64Atan();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100892 case IrOpcode::kNumberAtanh:
893 return machine()->Float64Atanh();
Ben Murdochf91f0612016-11-29 16:50:11 +0000894 case IrOpcode::kNumberAtan2:
895 return machine()->Float64Atan2();
896 case IrOpcode::kNumberCbrt:
897 return machine()->Float64Cbrt();
898 case IrOpcode::kNumberCeil:
899 return machine()->Float64RoundUp().placeholder();
900 case IrOpcode::kNumberCos:
901 return machine()->Float64Cos();
902 case IrOpcode::kNumberCosh:
903 return machine()->Float64Cosh();
904 case IrOpcode::kNumberExp:
905 return machine()->Float64Exp();
906 case IrOpcode::kNumberExpm1:
907 return machine()->Float64Expm1();
908 case IrOpcode::kNumberFloor:
909 return machine()->Float64RoundDown().placeholder();
910 case IrOpcode::kNumberFround:
911 return machine()->TruncateFloat64ToFloat32();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100912 case IrOpcode::kNumberLog:
913 return machine()->Float64Log();
914 case IrOpcode::kNumberLog1p:
915 return machine()->Float64Log1p();
916 case IrOpcode::kNumberLog2:
917 return machine()->Float64Log2();
918 case IrOpcode::kNumberLog10:
919 return machine()->Float64Log10();
Ben Murdochf91f0612016-11-29 16:50:11 +0000920 case IrOpcode::kNumberMax:
921 return machine()->Float64Max();
922 case IrOpcode::kNumberMin:
923 return machine()->Float64Min();
924 case IrOpcode::kNumberPow:
925 return machine()->Float64Pow();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100926 case IrOpcode::kNumberSin:
927 return machine()->Float64Sin();
Ben Murdochf91f0612016-11-29 16:50:11 +0000928 case IrOpcode::kNumberSinh:
929 return machine()->Float64Sinh();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100930 case IrOpcode::kNumberSqrt:
931 return machine()->Float64Sqrt();
Ben Murdochf91f0612016-11-29 16:50:11 +0000932 case IrOpcode::kNumberTan:
933 return machine()->Float64Tan();
934 case IrOpcode::kNumberTanh:
935 return machine()->Float64Tanh();
936 case IrOpcode::kNumberTrunc:
937 return machine()->Float64RoundTruncate().placeholder();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100938 case IrOpcode::kNumberSilenceNaN:
939 return machine()->Float64SilenceNaN();
Ben Murdoch014dc512016-03-22 12:00:34 +0000940 default:
941 UNREACHABLE();
942 return nullptr;
943 }
944}
945
946
947Node* RepresentationChanger::TypeError(Node* node,
948 MachineRepresentation output_rep,
949 Type* output_type,
950 MachineRepresentation use) {
951 type_error_ = true;
952 if (!testing_type_errors_) {
953 std::ostringstream out_str;
954 out_str << output_rep << " (";
Ben Murdochf3b273f2017-01-17 12:11:28 +0000955 output_type->PrintTo(out_str);
Ben Murdoch014dc512016-03-22 12:00:34 +0000956 out_str << ")";
957
958 std::ostringstream use_str;
959 use_str << use;
960
961 V8_Fatal(__FILE__, __LINE__,
962 "RepresentationChangerError: node #%d:%s of "
963 "%s cannot be changed to %s",
964 node->id(), node->op()->mnemonic(), out_str.str().c_str(),
965 use_str.str().c_str());
966 }
967 return node;
968}
969
Ben Murdochf3b273f2017-01-17 12:11:28 +0000970Node* RepresentationChanger::InsertChangeBitToTagged(Node* node) {
971 return jsgraph()->graph()->NewNode(simplified()->ChangeBitToTagged(), node);
972}
Ben Murdoch014dc512016-03-22 12:00:34 +0000973
974Node* RepresentationChanger::InsertChangeFloat32ToFloat64(Node* node) {
975 return jsgraph()->graph()->NewNode(machine()->ChangeFloat32ToFloat64(), node);
976}
977
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100978Node* RepresentationChanger::InsertChangeFloat64ToUint32(Node* node) {
979 return jsgraph()->graph()->NewNode(machine()->ChangeFloat64ToUint32(), node);
980}
981
982Node* RepresentationChanger::InsertChangeFloat64ToInt32(Node* node) {
983 return jsgraph()->graph()->NewNode(machine()->ChangeFloat64ToInt32(), node);
984}
985
986Node* RepresentationChanger::InsertChangeTaggedSignedToInt32(Node* node) {
987 return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedSignedToInt32(),
988 node);
989}
Ben Murdoch014dc512016-03-22 12:00:34 +0000990
991Node* RepresentationChanger::InsertChangeTaggedToFloat64(Node* node) {
992 return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedToFloat64(),
993 node);
994}
995
996} // namespace compiler
997} // namespace internal
998} // namespace v8