Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(118)

Side by Side Diff: src/compiler/representation-change.h

Issue 840953003: [turbofan] Correctify representation changes to bit. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: std::isnan Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/opcodes.h ('k') | src/compiler/simplified-operator.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_COMPILER_REPRESENTATION_CHANGE_H_ 5 #ifndef V8_COMPILER_REPRESENTATION_CHANGE_H_
6 #define V8_COMPILER_REPRESENTATION_CHANGE_H_ 6 #define V8_COMPILER_REPRESENTATION_CHANGE_H_
7 7
8 #include <sstream> 8 #include <sstream>
9 9
10 #include "src/base/bits.h" 10 #include "src/base/bits.h"
11 #include "src/compiler/js-graph.h" 11 #include "src/compiler/js-graph.h"
12 #include "src/compiler/machine-operator.h" 12 #include "src/compiler/machine-operator.h"
13 #include "src/compiler/node-properties-inl.h" 13 #include "src/compiler/node-properties-inl.h"
14 #include "src/compiler/simplified-operator.h" 14 #include "src/compiler/simplified-operator.h"
15 15
16 namespace v8 { 16 namespace v8 {
17 namespace internal { 17 namespace internal {
18 namespace compiler { 18 namespace compiler {
19 19
20 // Contains logic related to changing the representation of values for constants 20 // Contains logic related to changing the representation of values for constants
21 // and other nodes, as well as lowering Simplified->Machine operators. 21 // and other nodes, as well as lowering Simplified->Machine operators.
22 // Eagerly folds any representation changes for constants. 22 // Eagerly folds any representation changes for constants.
23 class RepresentationChanger { 23 class RepresentationChanger {
24 public: 24 public:
25 RepresentationChanger(JSGraph* jsgraph, SimplifiedOperatorBuilder* simplified, 25 RepresentationChanger(JSGraph* jsgraph, SimplifiedOperatorBuilder* simplified,
26 Isolate* isolate) 26 Isolate* isolate)
27 : jsgraph_(jsgraph), 27 : jsgraph_(jsgraph),
28 simplified_(simplified), 28 simplified_(simplified),
29 isolate_(isolate), 29 isolate_(isolate),
30 bit_range_(Type::Range(isolate->factory()->NewNumber(0),
31 isolate->factory()->NewNumber(1),
32 jsgraph->zone())),
30 testing_type_errors_(false), 33 testing_type_errors_(false),
31 type_error_(false) {} 34 type_error_(false) {}
32 35
33 // TODO(titzer): should Word64 also be implicitly convertable to others? 36 // TODO(titzer): should Word64 also be implicitly convertable to others?
34 static const MachineTypeUnion rWord = 37 static const MachineTypeUnion rWord = kRepWord8 | kRepWord16 | kRepWord32;
35 kRepBit | kRepWord8 | kRepWord16 | kRepWord32;
36 38
37 Node* GetRepresentationFor(Node* node, MachineTypeUnion output_type, 39 Node* GetRepresentationFor(Node* node, MachineTypeUnion output_type,
38 MachineTypeUnion use_type) { 40 MachineTypeUnion use_type) {
39 if (!base::bits::IsPowerOfTwo32(output_type & kRepMask)) { 41 if (!base::bits::IsPowerOfTwo32(output_type & kRepMask)) {
40 // There should be only one output representation. 42 // There should be only one output representation.
41 return TypeError(node, output_type, use_type); 43 return TypeError(node, output_type, use_type);
42 } 44 }
43 if ((use_type & kRepMask) == (output_type & kRepMask)) { 45 if ((use_type & kRepMask) == (output_type & kRepMask)) {
44 // Representations are the same. That's a no-op. 46 // Representations are the same. That's a no-op.
45 return node; 47 return node;
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
255 return node; // No change necessary. 257 return node; // No change necessary.
256 case IrOpcode::kFloat32Constant: 258 case IrOpcode::kFloat32Constant:
257 return MakeInt32Constant(OpParameter<float>(node)); 259 return MakeInt32Constant(OpParameter<float>(node));
258 case IrOpcode::kNumberConstant: 260 case IrOpcode::kNumberConstant:
259 case IrOpcode::kFloat64Constant: 261 case IrOpcode::kFloat64Constant:
260 return MakeInt32Constant(OpParameter<double>(node)); 262 return MakeInt32Constant(OpParameter<double>(node));
261 default: 263 default:
262 break; 264 break;
263 } 265 }
264 // Select the correct X -> Word32 operator. 266 // Select the correct X -> Word32 operator.
265 const Operator* op = NULL; 267 const Operator* op;
266 if (output_type & kRepFloat64) { 268 if (output_type & kRepBit) {
269 return node; // No change necessary.
270 } else if (output_type & kRepFloat64) {
267 if (output_type & kTypeUint32 || use_unsigned) { 271 if (output_type & kTypeUint32 || use_unsigned) {
268 op = machine()->ChangeFloat64ToUint32(); 272 op = machine()->ChangeFloat64ToUint32();
269 } else { 273 } else {
270 op = machine()->ChangeFloat64ToInt32(); 274 op = machine()->ChangeFloat64ToInt32();
271 } 275 }
272 } else if (output_type & kRepFloat32) { 276 } else if (output_type & kRepFloat32) {
273 node = InsertChangeFloat32ToFloat64(node); // float32 -> float64 -> int32 277 node = InsertChangeFloat32ToFloat64(node); // float32 -> float64 -> int32
274 if (output_type & kTypeUint32 || use_unsigned) { 278 if (output_type & kTypeUint32 || use_unsigned) {
275 op = machine()->ChangeFloat64ToUint32(); 279 op = machine()->ChangeFloat64ToUint32();
276 } else { 280 } else {
(...skipping 14 matching lines...) Expand all
291 Node* GetBitRepresentationFor(Node* node, MachineTypeUnion output_type) { 295 Node* GetBitRepresentationFor(Node* node, MachineTypeUnion output_type) {
292 // Eagerly fold representation changes for constants. 296 // Eagerly fold representation changes for constants.
293 switch (node->opcode()) { 297 switch (node->opcode()) {
294 case IrOpcode::kInt32Constant: { 298 case IrOpcode::kInt32Constant: {
295 int32_t value = OpParameter<int32_t>(node); 299 int32_t value = OpParameter<int32_t>(node);
296 if (value == 0 || value == 1) return node; 300 if (value == 0 || value == 1) return node;
297 return jsgraph()->Int32Constant(1); // value != 0 301 return jsgraph()->Int32Constant(1); // value != 0
298 } 302 }
299 case IrOpcode::kNumberConstant: { 303 case IrOpcode::kNumberConstant: {
300 double value = OpParameter<double>(node); 304 double value = OpParameter<double>(node);
301 if (std::isnan(value) || value == 0.0) { 305 if (value == 0 || std::isnan(value)) return jsgraph()->Int32Constant(0);
302 return jsgraph()->Int32Constant(0); 306 return jsgraph()->Int32Constant(1); // value != +0.0, -0.0, NaN
303 }
304 return jsgraph()->Int32Constant(1);
305 } 307 }
306 case IrOpcode::kHeapConstant: { 308 case IrOpcode::kHeapConstant: {
307 Handle<Object> handle = OpParameter<Unique<Object> >(node).handle(); 309 Handle<Object> object = OpParameter<Unique<Object>>(node).handle();
308 DCHECK(*handle == isolate()->heap()->true_value() || 310 return jsgraph()->Int32Constant(object->BooleanValue() ? 1 : 0);
309 *handle == isolate()->heap()->false_value());
310 return jsgraph()->Int32Constant(
311 *handle == isolate()->heap()->true_value() ? 1 : 0);
312 } 311 }
313 default: 312 default:
314 break; 313 break;
315 } 314 }
316 // Select the correct X -> Bit operator. 315 // Select the correct X -> Bit operator.
317 const Operator* op; 316 const Operator* op;
318 if (output_type & rWord) { 317 if (output_type & rWord) {
319 return node; // No change necessary. 318 op = simplified()->ChangeWord32ToBit();
320 } else if (output_type & kRepWord64) { 319 } else if (output_type & kRepWord64) {
321 return node; // TODO(titzer): No change necessary, on 64-bit. 320 op = simplified()->ChangeWord64ToBit();
322 } else if (output_type & kRepTagged) { 321 } else if (output_type & kRepTagged) {
323 op = simplified()->ChangeBoolToBit(); 322 Type* upper = NodeProperties::GetBounds(node).upper;
323 if (upper->Is(Type::Boolean())) {
324 op = simplified()->ChangeBoolToBit();
325 } else if (upper->Is(Type::Signed32())) {
326 // Tagged -> Int32 -> Bit
327 node = InsertChangeTaggedToInt32(node);
328 op = simplified()->ChangeWord32ToBit();
329 } else if (upper->Is(Type::Unsigned32())) {
330 // Tagged -> Uint32 -> Bit
331 node = InsertChangeTaggedToUint32(node);
332 op = simplified()->ChangeWord32ToBit();
333 } else {
334 return TypeError(node, output_type, kRepBit);
335 }
324 } else { 336 } else {
325 return TypeError(node, output_type, kRepBit); 337 return TypeError(node, output_type, kRepBit);
326 } 338 }
327 return jsgraph()->graph()->NewNode(op, node); 339 return graph()->NewNode(op, node);
328 } 340 }
329 341
330 Node* GetWord64RepresentationFor(Node* node, MachineTypeUnion output_type) { 342 Node* GetWord64RepresentationFor(Node* node, MachineTypeUnion output_type) {
331 if (output_type & kRepBit) { 343 if (output_type & kRepBit) {
332 return node; // Sloppy comparison -> word64 344 return node; // Sloppy comparison -> word64
333 } 345 }
334 // Can't really convert Word64 to anything else. Purported to be internal. 346 // Can't really convert Word64 to anything else. Purported to be internal.
335 return TypeError(node, output_type, kRepWord64); 347 return TypeError(node, output_type, kRepWord64);
336 } 348 }
337 349
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 if (type->Is(Type::Unsigned32())) return kTypeUint32; 434 if (type->Is(Type::Unsigned32())) return kTypeUint32;
423 if (type->Is(Type::Number())) return kTypeNumber; 435 if (type->Is(Type::Number())) return kTypeNumber;
424 if (type->Is(Type::Boolean())) return kTypeBool; 436 if (type->Is(Type::Boolean())) return kTypeBool;
425 return kTypeAny; 437 return kTypeAny;
426 } 438 }
427 439
428 private: 440 private:
429 JSGraph* jsgraph_; 441 JSGraph* jsgraph_;
430 SimplifiedOperatorBuilder* simplified_; 442 SimplifiedOperatorBuilder* simplified_;
431 Isolate* isolate_; 443 Isolate* isolate_;
444 Type* bit_range_;
432 445
433 friend class RepresentationChangerTester; // accesses the below fields. 446 friend class RepresentationChangerTester; // accesses the below fields.
434 447
435 bool testing_type_errors_; // If {true}, don't abort on a type error. 448 bool testing_type_errors_; // If {true}, don't abort on a type error.
436 bool type_error_; // Set when a type error is detected. 449 bool type_error_; // Set when a type error is detected.
437 450
438 Node* TypeError(Node* node, MachineTypeUnion output_type, 451 Node* TypeError(Node* node, MachineTypeUnion output_type,
439 MachineTypeUnion use) { 452 MachineTypeUnion use) {
440 type_error_ = true; 453 type_error_ = true;
441 if (!testing_type_errors_) { 454 if (!testing_type_errors_) {
442 std::ostringstream out_str; 455 std::ostringstream out_str;
443 out_str << static_cast<MachineType>(output_type); 456 out_str << static_cast<MachineType>(output_type);
444 457
445 std::ostringstream use_str; 458 std::ostringstream use_str;
446 use_str << static_cast<MachineType>(use); 459 use_str << static_cast<MachineType>(use);
447 460
448 V8_Fatal(__FILE__, __LINE__, 461 V8_Fatal(__FILE__, __LINE__,
449 "RepresentationChangerError: node #%d:%s of " 462 "RepresentationChangerError: node #%d:%s of "
450 "%s cannot be changed to %s", 463 "%s cannot be changed to %s",
451 node->id(), node->op()->mnemonic(), out_str.str().c_str(), 464 node->id(), node->op()->mnemonic(), out_str.str().c_str(),
452 use_str.str().c_str()); 465 use_str.str().c_str());
453 } 466 }
454 return node; 467 return node;
455 } 468 }
456 469
457 Node* InsertChangeFloat32ToFloat64(Node* node) { 470 Node* InsertChangeFloat32ToFloat64(Node* node) {
458 return jsgraph()->graph()->NewNode(machine()->ChangeFloat32ToFloat64(), 471 return graph()->NewNode(machine()->ChangeFloat32ToFloat64(), node);
459 node);
460 } 472 }
461 473
462 Node* InsertChangeTaggedToFloat64(Node* node) { 474 Node* InsertChangeTaggedToFloat64(Node* node) {
463 return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedToFloat64(), 475 return graph()->NewNode(simplified()->ChangeTaggedToFloat64(), node);
464 node);
465 } 476 }
466 477
467 JSGraph* jsgraph() { return jsgraph_; } 478 Node* InsertChangeTaggedToInt32(Node* node) {
468 Isolate* isolate() { return isolate_; } 479 return graph()->NewNode(simplified()->ChangeTaggedToInt32(), node);
469 SimplifiedOperatorBuilder* simplified() { return simplified_; } 480 }
470 MachineOperatorBuilder* machine() { return jsgraph()->machine(); } 481
482 Node* InsertChangeTaggedToUint32(Node* node) {
483 return graph()->NewNode(simplified()->ChangeTaggedToUint32(), node);
484 }
485
486 Graph* graph() const { return jsgraph()->graph(); }
487 JSGraph* jsgraph() const { return jsgraph_; }
488 Isolate* isolate() const { return isolate_; }
489 SimplifiedOperatorBuilder* simplified() const { return simplified_; }
490 MachineOperatorBuilder* machine() const { return jsgraph()->machine(); }
471 }; 491 };
472 492
473 } // namespace compiler 493 } // namespace compiler
474 } // namespace internal 494 } // namespace internal
475 } // namespace v8 495 } // namespace v8
476 496
477 #endif // V8_COMPILER_REPRESENTATION_CHANGE_H_ 497 #endif // V8_COMPILER_REPRESENTATION_CHANGE_H_
OLDNEW
« no previous file with comments | « src/compiler/opcodes.h ('k') | src/compiler/simplified-operator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698