blob: 839335d1fce847da03801d807e0659b5b04b36fb [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#ifndef V8_COMPILER_REPRESENTATION_CHANGE_H_
6#define V8_COMPILER_REPRESENTATION_CHANGE_H_
7
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008#include "src/compiler/js-graph.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009#include "src/compiler/simplified-operator.h"
10
11namespace v8 {
12namespace internal {
13namespace compiler {
14
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000015class Truncation final {
16 public:
17 // Constructors.
18 static Truncation None() { return Truncation(TruncationKind::kNone); }
19 static Truncation Bool() { return Truncation(TruncationKind::kBool); }
20 static Truncation Word32() { return Truncation(TruncationKind::kWord32); }
21 static Truncation Word64() { return Truncation(TruncationKind::kWord64); }
22 static Truncation Float32() { return Truncation(TruncationKind::kFloat32); }
23 static Truncation Float64() { return Truncation(TruncationKind::kFloat64); }
24 static Truncation Any() { return Truncation(TruncationKind::kAny); }
25
26 static Truncation Generalize(Truncation t1, Truncation t2) {
27 return Truncation(Generalize(t1.kind(), t2.kind()));
28 }
29
30 // Queries.
31 bool TruncatesToWord32() const {
32 return LessGeneral(kind_, TruncationKind::kWord32);
33 }
Ben Murdochc5610432016-08-08 18:44:38 +010034 bool TruncatesToFloat64() const {
35 return LessGeneral(kind_, TruncationKind::kFloat64);
36 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000037 bool TruncatesNaNToZero() {
38 return LessGeneral(kind_, TruncationKind::kWord32) ||
39 LessGeneral(kind_, TruncationKind::kBool);
40 }
41 bool TruncatesUndefinedToZeroOrNaN() {
42 return LessGeneral(kind_, TruncationKind::kFloat64) ||
43 LessGeneral(kind_, TruncationKind::kWord64);
44 }
45
46 // Operators.
47 bool operator==(Truncation other) const { return kind() == other.kind(); }
48 bool operator!=(Truncation other) const { return !(*this == other); }
49
50 // Debug utilities.
51 const char* description() const;
52 bool IsLessGeneralThan(Truncation other) {
53 return LessGeneral(kind(), other.kind());
54 }
55
56 private:
57 enum class TruncationKind : uint8_t {
58 kNone,
59 kBool,
60 kWord32,
61 kWord64,
62 kFloat32,
63 kFloat64,
64 kAny
65 };
66
67 explicit Truncation(TruncationKind kind) : kind_(kind) {}
68 TruncationKind kind() const { return kind_; }
69
70 TruncationKind kind_;
71
72 static TruncationKind Generalize(TruncationKind rep1, TruncationKind rep2);
73 static bool LessGeneral(TruncationKind rep1, TruncationKind rep2);
74};
75
76
Ben Murdochb8a8cc12014-11-26 15:28:44 +000077// Contains logic related to changing the representation of values for constants
78// and other nodes, as well as lowering Simplified->Machine operators.
79// Eagerly folds any representation changes for constants.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000080class RepresentationChanger final {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000081 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000082 RepresentationChanger(JSGraph* jsgraph, Isolate* isolate)
Ben Murdochb8a8cc12014-11-26 15:28:44 +000083 : jsgraph_(jsgraph),
Ben Murdochb8a8cc12014-11-26 15:28:44 +000084 isolate_(isolate),
85 testing_type_errors_(false),
86 type_error_(false) {}
87
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000088 // Changes representation from {output_type} to {use_rep}. The {truncation}
89 // parameter is only used for sanity checking - if the changer cannot figure
90 // out signedness for the word32->float64 conversion, then we check that the
91 // uses truncate to word32 (so they do not care about signedness).
92 Node* GetRepresentationFor(Node* node, MachineRepresentation output_rep,
93 Type* output_type, MachineRepresentation use_rep,
94 Truncation truncation = Truncation::None());
95 const Operator* Int32OperatorFor(IrOpcode::Value opcode);
96 const Operator* Uint32OperatorFor(IrOpcode::Value opcode);
97 const Operator* Float64OperatorFor(IrOpcode::Value opcode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000098
99 MachineType TypeForBasePointer(const FieldAccess& access) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000100 return access.tag() != 0 ? MachineType::AnyTagged()
101 : MachineType::Pointer();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000102 }
103
104 MachineType TypeForBasePointer(const ElementAccess& access) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000105 return access.tag() != 0 ? MachineType::AnyTagged()
106 : MachineType::Pointer();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000107 }
108
109 private:
110 JSGraph* jsgraph_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000111 Isolate* isolate_;
112
113 friend class RepresentationChangerTester; // accesses the below fields.
114
115 bool testing_type_errors_; // If {true}, don't abort on a type error.
116 bool type_error_; // Set when a type error is detected.
117
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000118 Node* GetTaggedRepresentationFor(Node* node, MachineRepresentation output_rep,
119 Type* output_type);
120 Node* GetFloat32RepresentationFor(Node* node,
121 MachineRepresentation output_rep,
122 Type* output_type, Truncation truncation);
123 Node* GetFloat64RepresentationFor(Node* node,
124 MachineRepresentation output_rep,
125 Type* output_type, Truncation truncation);
126 Node* GetWord32RepresentationFor(Node* node, MachineRepresentation output_rep,
Ben Murdochda12d292016-06-02 14:46:10 +0100127 Type* output_type, Truncation truncation);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000128 Node* GetBitRepresentationFor(Node* node, MachineRepresentation output_rep,
129 Type* output_type);
130 Node* GetWord64RepresentationFor(Node* node, MachineRepresentation output_rep,
131 Type* output_type);
132 Node* TypeError(Node* node, MachineRepresentation output_rep,
133 Type* output_type, MachineRepresentation use);
134 Node* MakeTruncatedInt32Constant(double value);
135 Node* InsertChangeFloat32ToFloat64(Node* node);
Ben Murdochc5610432016-08-08 18:44:38 +0100136 Node* InsertChangeFloat64ToInt32(Node* node);
137 Node* InsertChangeFloat64ToUint32(Node* node);
138 Node* InsertChangeTaggedSignedToInt32(Node* node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000139 Node* InsertChangeTaggedToFloat64(Node* node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000140
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000141 JSGraph* jsgraph() const { return jsgraph_; }
142 Isolate* isolate() const { return isolate_; }
143 Factory* factory() const { return isolate()->factory(); }
144 SimplifiedOperatorBuilder* simplified() { return jsgraph()->simplified(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000145 MachineOperatorBuilder* machine() { return jsgraph()->machine(); }
146};
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400147
148} // namespace compiler
149} // namespace internal
150} // namespace v8
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000151
152#endif // V8_COMPILER_REPRESENTATION_CHANGE_H_