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

Side by Side Diff: src/compiler/simplified-lowering.cc

Issue 1462503005: [turbofan] Simplified lowering - introduce the concept of UseInfo. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 1 month 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/representation-change.h ('k') | no next file » | 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 #include "src/compiler/simplified-lowering.h" 5 #include "src/compiler/simplified-lowering.h"
6 6
7 #include <limits> 7 #include <limits>
8 8
9 #include "src/base/bits.h" 9 #include "src/base/bits.h"
10 #include "src/code-factory.h" 10 #include "src/code-factory.h"
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 // 2.) LOWER: perform lowering for all {Simplified} nodes by replacing some 49 // 2.) LOWER: perform lowering for all {Simplified} nodes by replacing some
50 // operators for some nodes, expanding some nodes to multiple nodes, or 50 // operators for some nodes, expanding some nodes to multiple nodes, or
51 // removing some (redundant) nodes. 51 // removing some (redundant) nodes.
52 // During this phase, use the {RepresentationChanger} to insert 52 // During this phase, use the {RepresentationChanger} to insert
53 // representation changes between uses that demand a particular 53 // representation changes between uses that demand a particular
54 // representation and nodes that produce a different representation. 54 // representation and nodes that produce a different representation.
55 LOWER 55 LOWER
56 }; 56 };
57 57
58 58
59 namespace {
60
61 // The {UseInfo} class is used to describe a use of an input of a node.
62 //
63 // This information is used in two different ways, based on the phase:
64 //
65 // 1. During propagation, the use info is used to inform the input node
66 // about what part of the input is used (we call this truncation) and what
67 // is the preferred representation.
68 //
69 // 2. During lowering, the use info is used to properly convert the input
70 // to the preferred representation. The preferred representation might be
71 // insufficient to do the conversion (e.g. word32->float64 conv), so we also
72 // need the signedness information to produce the correct value.
73 struct UseInfo {
Benedikt Meurer 2015/11/19 10:38:31 Nit: class please
Jarin 2015/11/19 10:44:59 Done.
74 // Constructors
75 // ================================================================
76
77 // Uses truncating to the preferred representation.
78 static UseInfo TruncatingWord32() {
79 return UseInfo(kTypeInt32 | kTypeUint32 | kRepWord32);
80 }
81 static UseInfo TruncatingWord64() {
82 return UseInfo(kTypeInt64 | kTypeUint64 | kRepWord64);
83 }
84 static UseInfo Bool() { return UseInfo(kMachBool); }
85 static UseInfo Float32() { return UseInfo(kMachFloat32); }
86 static UseInfo Float64() { return UseInfo(kMachFloat64); }
87 static UseInfo PointerInt() {
88 return kPointerSize == 4 ? TruncatingWord32() : TruncatingWord64();
89 }
90
91 // Non-truncating uses.
92 static UseInfo AnyTagged() { return UseInfo(kMachAnyTagged); }
93 static UseInfo Any() { return UseInfo(kTypeAny); }
94
95 // Ignored-value 'use'.
96 static UseInfo None() { return UseInfo(kMachNone); }
97
98 // Truncating to a representation that is smaller than the preferred
99 // one.
100 static UseInfo Float64TruncatingToWord32() {
101 return UseInfo(kRepFloat64 | kTypeInt32 | kTypeUint32);
102 }
103 static UseInfo Word64TruncatingToWord32() {
104 return UseInfo(kRepWord64 | kTypeInt32 | kTypeUint32);
105 }
106 static UseInfo AnyTruncatingToBool() { return UseInfo(kTypeBool); }
107
108 UseInfo(MachineTypeUnion representation, MachineTypeUnion truncation)
109 : type_(representation | truncation) {
110 DCHECK(base::bits::CountPopulation32(representation & kRepMask) == 1);
111 DCHECK((representation & kTypeMask) == 0);
112 DCHECK((truncation & kRepMask) == 0);
113 // TODO(jarin) Check/normalize truncation?
114 }
115
116 // Queries
117 // ================================================================
118 MachineType GetRepresentation() const {
119 return static_cast<MachineType>(type_ & kRepMask);
120 }
121
122 // This should only be used by the Enqueue method.
123 MachineTypeUnion machine_type() const { return type_; }
124
125 private:
126 explicit UseInfo(MachineTypeUnion type) : type_(type) {}
127
128 MachineTypeUnion type_;
129 };
130
131
132 UseInfo UseInfoFromRepresentation(MachineTypeUnion rep) {
133 DCHECK((rep & kTypeMask) == 0);
134 if (rep & kRepTagged) return UseInfo::AnyTagged();
135 if (rep & kRepFloat64) {
136 DCHECK((rep & kRepWord64) == 0);
137 return UseInfo::Float64();
138 }
139 if (rep & kRepFloat32) {
140 if (rep == kRepFloat32) return UseInfo::Float32();
141 return UseInfo::AnyTagged();
142 }
143 if (rep & kRepWord64) {
144 return UseInfo::TruncatingWord64();
145 }
146 if (rep & (kRepWord32 | kRepWord16 | kRepWord8)) {
147 CHECK(!(rep & kRepBit));
148 return UseInfo::TruncatingWord32();
149 }
150 DCHECK(rep & kRepBit);
151 return UseInfo::Bool();
152 }
153
154
155 UseInfo UseInfoFromMachineType(MachineType type) {
156 return UseInfoFromRepresentation(RepresentationOf(type));
157 }
158
159
160 UseInfo UseInfoForBasePointer(const FieldAccess& access) {
161 return access.tag() != 0 ? UseInfo::AnyTagged() : UseInfo::PointerInt();
162 }
163
164
165 UseInfo UseInfoForBasePointer(const ElementAccess& access) {
166 return access.tag() != 0 ? UseInfo::AnyTagged() : UseInfo::PointerInt();
167 }
168
169 } // namespace
170
171
59 class RepresentationSelector { 172 class RepresentationSelector {
60 public: 173 public:
61 // Information for each node tracked during the fixpoint. 174 // Information for each node tracked during the fixpoint.
62 struct NodeInfo { 175 struct NodeInfo {
63 MachineTypeUnion use : 15; // Union of all usages for the node. 176 MachineTypeUnion use : 15; // Union of all usages for the node.
64 bool queued : 1; // Bookkeeping for the traversal. 177 bool queued : 1; // Bookkeeping for the traversal.
65 bool visited : 1; // Bookkeeping for the traversal. 178 bool visited : 1; // Bookkeeping for the traversal.
66 MachineTypeUnion output : 15; // Output type of the node. 179 MachineTypeUnion output : 15; // Output type of the node.
67 }; 180 };
68 181
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 // We also need to replace the node in the rest of the vector. 237 // We also need to replace the node in the rest of the vector.
125 for (NodeVector::iterator j = i + 1; j != replacements_.end(); ++j) { 238 for (NodeVector::iterator j = i + 1; j != replacements_.end(); ++j) {
126 ++j; 239 ++j;
127 if (*j == node) *j = replacement; 240 if (*j == node) *j = replacement;
128 } 241 }
129 } 242 }
130 } 243 }
131 244
132 // Enqueue {node} if the {use} contains new information for that node. 245 // Enqueue {node} if the {use} contains new information for that node.
133 // Add {node} to {nodes_} if this is the first time it's been visited. 246 // Add {node} to {nodes_} if this is the first time it's been visited.
134 void Enqueue(Node* node, MachineTypeUnion use = 0) { 247 void Enqueue(Node* node, UseInfo use_info = UseInfo::None()) {
248 MachineTypeUnion use = use_info.machine_type();
249
135 if (phase_ != PROPAGATE) return; 250 if (phase_ != PROPAGATE) return;
136 NodeInfo* info = GetInfo(node); 251 NodeInfo* info = GetInfo(node);
137 if (!info->visited) { 252 if (!info->visited) {
138 // First visit of this node. 253 // First visit of this node.
139 info->visited = true; 254 info->visited = true;
140 info->queued = true; 255 info->queued = true;
141 nodes_.push_back(node); 256 nodes_.push_back(node);
142 queue_.push(node); 257 queue_.push(node);
143 TRACE(" initial: "); 258 TRACE(" initial: ");
144 info->use |= use; 259 info->use |= use;
(...skipping 11 matching lines...) Expand all
156 } else { 271 } else {
157 TRACE(" inqueue: "); 272 TRACE(" inqueue: ");
158 } 273 }
159 info->use |= use; 274 info->use |= use;
160 PrintUseInfo(node); 275 PrintUseInfo(node);
161 } 276 }
162 } 277 }
163 278
164 bool lower() { return phase_ == LOWER; } 279 bool lower() { return phase_ == LOWER; }
165 280
166 void Enqueue(Node* node, MachineType use) {
167 Enqueue(node, static_cast<MachineTypeUnion>(use));
168 }
169
170 void SetOutput(Node* node, MachineTypeUnion output) { 281 void SetOutput(Node* node, MachineTypeUnion output) {
171 // Every node should have at most one output representation. Note that 282 // Every node should have at most one output representation. Note that
172 // phis can have 0, if they have not been used in a representation-inducing 283 // phis can have 0, if they have not been used in a representation-inducing
173 // instruction. 284 // instruction.
174 DCHECK((output & kRepMask) == 0 || 285 DCHECK((output & kRepMask) == 0 ||
175 base::bits::IsPowerOfTwo32(output & kRepMask)); 286 base::bits::IsPowerOfTwo32(output & kRepMask));
176 GetInfo(node)->output = output; 287 GetInfo(node)->output = output;
177 } 288 }
178 289
179 bool BothInputsAre(Node* node, Type* type) { 290 bool BothInputsAre(Node* node, Type* type) {
180 DCHECK_EQ(2, node->InputCount()); 291 DCHECK_EQ(2, node->InputCount());
181 return NodeProperties::GetType(node->InputAt(0))->Is(type) && 292 return NodeProperties::GetType(node->InputAt(0))->Is(type) &&
182 NodeProperties::GetType(node->InputAt(1))->Is(type); 293 NodeProperties::GetType(node->InputAt(1))->Is(type);
183 } 294 }
184 295
185 void ProcessTruncateWord32Input(Node* node, int index, MachineTypeUnion use) { 296 void ProcessTruncateWord32Input(Node* node, int index) {
186 Node* input = node->InputAt(index); 297 Node* input = node->InputAt(index);
187 if (phase_ == PROPAGATE) { 298 if (phase_ == PROPAGATE) {
188 // In the propagate phase, propagate the usage information backward. 299 // In the propagate phase, propagate the usage information backward.
189 Enqueue(input, use); 300 Enqueue(input, UseInfo::TruncatingWord32());
190 } else { 301 } else {
191 // In the change phase, insert a change before the use if necessary. 302 // In the change phase, insert a change before the use if necessary.
192 MachineTypeUnion output = GetInfo(input)->output; 303 MachineTypeUnion output = GetInfo(input)->output;
193 if ((output & (kRepBit | kRepWord8 | kRepWord16 | kRepWord32)) == 0) { 304 if ((output & (kRepBit | kRepWord8 | kRepWord16 | kRepWord32)) == 0) {
194 // Output representation doesn't match usage. 305 // Output representation doesn't match usage.
195 TRACE(" truncate-to-int32: #%d:%s(@%d #%d:%s) ", node->id(), 306 TRACE(" truncate-to-int32: #%d:%s(@%d #%d:%s) ", node->id(),
196 node->op()->mnemonic(), index, input->id(), 307 node->op()->mnemonic(), index, input->id(),
197 input->op()->mnemonic()); 308 input->op()->mnemonic());
198 TRACE(" from "); 309 TRACE(" from ");
199 PrintInfo(output); 310 PrintInfo(output);
200 TRACE(" to ");
201 PrintInfo(use);
202 TRACE("\n"); 311 TRACE("\n");
203 Node* n = changer_->GetTruncatedWord32For(input, output); 312 Node* n = changer_->GetTruncatedWord32For(input, output);
204 node->ReplaceInput(index, n); 313 node->ReplaceInput(index, n);
205 } 314 }
206 } 315 }
207 } 316 }
208 317
209 void ProcessInput(Node* node, int index, MachineTypeUnion use) { 318 void EnqueueInputUse(Node* node, int index, UseInfo use) {
319 Enqueue(node->InputAt(index), use);
320 }
321
322 void ConvertInput(Node* node, int index, UseInfo use) {
210 Node* input = node->InputAt(index); 323 Node* input = node->InputAt(index);
211 if (phase_ == PROPAGATE) { 324 // In the change phase, insert a change before the use if necessary.
212 // In the propagate phase, propagate the usage information backward. 325 if (use.GetRepresentation() == kMachNone)
213 Enqueue(input, use); 326 return; // No input requirement on the use.
214 } else { 327 MachineTypeUnion output = GetInfo(input)->output;
215 // In the change phase, insert a change before the use if necessary. 328 if ((output & kRepMask) != use.GetRepresentation()) {
216 if ((use & kRepMask) == 0) return; // No input requirement on the use. 329 // Output representation doesn't match usage.
217 MachineTypeUnion output = GetInfo(input)->output; 330 TRACE(" change: #%d:%s(@%d #%d:%s) ", node->id(), node->op()->mnemonic(),
218 if ((output & kRepMask & use) == 0) { 331 index, input->id(), input->op()->mnemonic());
219 // Output representation doesn't match usage. 332 TRACE(" from ");
220 TRACE(" change: #%d:%s(@%d #%d:%s) ", node->id(), 333 PrintInfo(output);
221 node->op()->mnemonic(), index, input->id(), 334 TRACE(" to ");
222 input->op()->mnemonic()); 335 PrintUseInfo(use);
223 TRACE(" from "); 336 TRACE("\n");
224 PrintInfo(output); 337 Node* n =
225 TRACE(" to "); 338 changer_->GetRepresentationFor(input, output, use.machine_type());
226 PrintInfo(use); 339 node->ReplaceInput(index, n);
227 TRACE("\n");
228 Node* n = changer_->GetRepresentationFor(input, output, use);
229 node->ReplaceInput(index, n);
230 }
231 } 340 }
232 } 341 }
233 342
343 void ProcessInput(Node* node, int index, UseInfo use) {
344 if (phase_ == PROPAGATE) {
345 EnqueueInputUse(node, index, use);
346 } else {
347 ConvertInput(node, index, use);
348 }
349 }
350
234 void ProcessRemainingInputs(Node* node, int index) { 351 void ProcessRemainingInputs(Node* node, int index) {
235 DCHECK_GE(index, NodeProperties::PastValueIndex(node)); 352 DCHECK_GE(index, NodeProperties::PastValueIndex(node));
236 DCHECK_GE(index, NodeProperties::PastContextIndex(node)); 353 DCHECK_GE(index, NodeProperties::PastContextIndex(node));
237 for (int i = std::max(index, NodeProperties::FirstEffectIndex(node)); 354 for (int i = std::max(index, NodeProperties::FirstEffectIndex(node));
238 i < NodeProperties::PastEffectIndex(node); ++i) { 355 i < NodeProperties::PastEffectIndex(node); ++i) {
239 Enqueue(node->InputAt(i)); // Effect inputs: just visit 356 Enqueue(node->InputAt(i)); // Effect inputs: just visit
240 } 357 }
241 for (int i = std::max(index, NodeProperties::FirstControlIndex(node)); 358 for (int i = std::max(index, NodeProperties::FirstControlIndex(node));
242 i < NodeProperties::PastControlIndex(node); ++i) { 359 i < NodeProperties::PastControlIndex(node); ++i) {
243 Enqueue(node->InputAt(i)); // Control inputs: just visit 360 Enqueue(node->InputAt(i)); // Control inputs: just visit
244 } 361 }
245 } 362 }
246 363
247 // The default, most general visitation case. For {node}, process all value, 364 // The default, most general visitation case. For {node}, process all value,
248 // context, frame state, effect, and control inputs, assuming that value 365 // context, frame state, effect, and control inputs, assuming that value
249 // inputs should have {kRepTagged} representation and can observe all output 366 // inputs should have {kRepTagged} representation and can observe all output
250 // values {kTypeAny}. 367 // values {kTypeAny}.
251 void VisitInputs(Node* node) { 368 void VisitInputs(Node* node) {
252 int tagged_count = node->op()->ValueInputCount() + 369 int tagged_count = node->op()->ValueInputCount() +
253 OperatorProperties::GetContextInputCount(node->op()); 370 OperatorProperties::GetContextInputCount(node->op());
254 // Visit value and context inputs as tagged. 371 // Visit value and context inputs as tagged.
255 for (int i = 0; i < tagged_count; i++) { 372 for (int i = 0; i < tagged_count; i++) {
256 ProcessInput(node, i, kMachAnyTagged); 373 ProcessInput(node, i, UseInfo::AnyTagged());
257 } 374 }
258 // Only enqueue other inputs (framestates, effects, control). 375 // Only enqueue other inputs (framestates, effects, control).
259 for (int i = tagged_count; i < node->InputCount(); i++) { 376 for (int i = tagged_count; i < node->InputCount(); i++) {
260 Enqueue(node->InputAt(i)); 377 Enqueue(node->InputAt(i));
261 } 378 }
262 // Assume the output is tagged. 379 // Assume the output is tagged.
263 SetOutput(node, kMachAnyTagged); 380 SetOutput(node, kMachAnyTagged);
264 } 381 }
265 382
266 // Helper for binops of the R x L -> O variety. 383 // Helper for binops of the R x L -> O variety.
267 void VisitBinop(Node* node, MachineTypeUnion left_use, 384 void VisitBinop(Node* node, UseInfo left_use, UseInfo right_use,
268 MachineTypeUnion right_use, MachineTypeUnion output) { 385 MachineTypeUnion output) {
269 DCHECK_EQ(2, node->op()->ValueInputCount()); 386 DCHECK_EQ(2, node->op()->ValueInputCount());
270 ProcessInput(node, 0, left_use); 387 ProcessInput(node, 0, left_use);
271 ProcessInput(node, 1, right_use); 388 ProcessInput(node, 1, right_use);
272 for (int i = 2; i < node->InputCount(); i++) { 389 for (int i = 2; i < node->InputCount(); i++) {
273 Enqueue(node->InputAt(i)); 390 Enqueue(node->InputAt(i));
274 } 391 }
275 SetOutput(node, output); 392 SetOutput(node, output);
276 } 393 }
277 394
278 // Helper for binops of the I x I -> O variety. 395 // Helper for binops of the I x I -> O variety.
279 void VisitBinop(Node* node, MachineTypeUnion input_use, 396 void VisitBinop(Node* node, UseInfo input_use, MachineTypeUnion output) {
280 MachineTypeUnion output) {
281 VisitBinop(node, input_use, input_use, output); 397 VisitBinop(node, input_use, input_use, output);
282 } 398 }
283 399
284 // Helper for unops of the I -> O variety. 400 // Helper for unops of the I -> O variety.
285 void VisitUnop(Node* node, MachineTypeUnion input_use, 401 void VisitUnop(Node* node, UseInfo input_use, MachineTypeUnion output) {
286 MachineTypeUnion output) {
287 DCHECK_EQ(1, node->InputCount()); 402 DCHECK_EQ(1, node->InputCount());
288 ProcessInput(node, 0, input_use); 403 ProcessInput(node, 0, input_use);
289 SetOutput(node, output); 404 SetOutput(node, output);
290 } 405 }
291 406
292 // Helper for leaf nodes. 407 // Helper for leaf nodes.
293 void VisitLeaf(Node* node, MachineTypeUnion output) { 408 void VisitLeaf(Node* node, MachineTypeUnion output) {
294 DCHECK_EQ(0, node->InputCount()); 409 DCHECK_EQ(0, node->InputCount());
295 SetOutput(node, output); 410 SetOutput(node, output);
296 } 411 }
297 412
298 // Helpers for specific types of binops. 413 // Helpers for specific types of binops.
299 void VisitFloat64Binop(Node* node) { 414 void VisitFloat64Binop(Node* node) {
300 VisitBinop(node, kMachFloat64, kMachFloat64); 415 VisitBinop(node, UseInfo::Float64(), kMachFloat64);
301 } 416 }
302 void VisitInt32Binop(Node* node) { VisitBinop(node, kMachInt32, kMachInt32); } 417 void VisitInt32Binop(Node* node) {
418 VisitBinop(node, UseInfo::TruncatingWord32(), kMachInt32);
419 }
303 void VisitUint32Binop(Node* node) { 420 void VisitUint32Binop(Node* node) {
304 VisitBinop(node, kMachUint32, kMachUint32); 421 VisitBinop(node, UseInfo::TruncatingWord32(), kMachUint32);
305 } 422 }
306 void VisitInt64Binop(Node* node) { VisitBinop(node, kMachInt64, kMachInt64); } 423 void VisitInt64Binop(Node* node) {
424 VisitBinop(node, UseInfo::TruncatingWord64(), kMachInt64);
425 }
307 void VisitUint64Binop(Node* node) { 426 void VisitUint64Binop(Node* node) {
308 VisitBinop(node, kMachUint64, kMachUint64); 427 VisitBinop(node, UseInfo::TruncatingWord64(), kMachUint64);
309 } 428 }
310 void VisitFloat64Cmp(Node* node) { VisitBinop(node, kMachFloat64, kRepBit); } 429 void VisitFloat64Cmp(Node* node) {
311 void VisitInt32Cmp(Node* node) { VisitBinop(node, kMachInt32, kRepBit); } 430 VisitBinop(node, UseInfo::Float64(), kMachBool);
312 void VisitUint32Cmp(Node* node) { VisitBinop(node, kMachUint32, kRepBit); } 431 }
313 void VisitInt64Cmp(Node* node) { VisitBinop(node, kMachInt64, kRepBit); } 432 void VisitInt32Cmp(Node* node) {
314 void VisitUint64Cmp(Node* node) { VisitBinop(node, kMachUint64, kRepBit); } 433 VisitBinop(node, UseInfo::TruncatingWord32(), kMachBool);
434 }
435 void VisitUint32Cmp(Node* node) {
436 VisitBinop(node, UseInfo::TruncatingWord32(), kMachBool);
437 }
438 void VisitInt64Cmp(Node* node) {
439 VisitBinop(node, UseInfo::TruncatingWord64(), kMachBool);
440 }
441 void VisitUint64Cmp(Node* node) {
442 VisitBinop(node, UseInfo::TruncatingWord64(), kMachBool);
443 }
315 444
316 // Infer representation for phi-like nodes. 445 // Infer representation for phi-like nodes.
317 MachineType GetRepresentationForPhi(Node* node, MachineTypeUnion use) { 446 static MachineType GetRepresentationForPhi(Node* node, MachineTypeUnion use) {
318 // Phis adapt to the output representation their uses demand. 447 // Phis adapt to the output representation their uses demand.
319 Type* upper = NodeProperties::GetType(node); 448 Type* upper = NodeProperties::GetType(node);
320 if ((use & kRepMask) == kRepFloat32) { 449 if ((use & kRepMask) == kRepFloat32) {
321 // only float32 uses. 450 // only float32 uses.
322 return kRepFloat32; 451 return kRepFloat32;
323 } else if ((use & kRepMask) == kRepFloat64) { 452 } else if ((use & kRepMask) == kRepFloat64) {
324 // only float64 uses. 453 // only float64 uses.
325 return kRepFloat64; 454 return kRepFloat64;
326 } else if ((use & kRepMask) == kRepTagged) { 455 } else if ((use & kRepMask) == kRepTagged) {
327 // only tagged uses. 456 // only tagged uses.
328 return kRepTagged; 457 return kRepTagged;
329 } else if (upper->Is(Type::Integral32())) { 458 } else if (upper->Is(Type::Integral32())) {
330 // Integer within [-2^31, 2^32[ range. 459 // Integer within [-2^31, 2^32[ range.
331 if (upper->Is(Type::Signed32()) || upper->Is(Type::Unsigned32())) { 460 if (upper->Is(Type::Signed32()) || upper->Is(Type::Unsigned32())) {
332 // multiple uses, but we are within 32 bits range => pick kRepWord32. 461 // multiple uses, but we are within 32 bits range => pick kRepWord32.
333 return kRepWord32; 462 return kRepWord32;
334 } else if ((use & kTypeMask) == kTypeInt32 || 463 } else if (!CanObserveNonWord32(use)) {
335 (use & kTypeMask) == kTypeUint32) { 464 // We only use 32 bits.
336 // We only use 32 bits or we use the result consistently.
337 return kRepWord32; 465 return kRepWord32;
338 } else { 466 } else {
339 return kRepFloat64; 467 return kRepFloat64;
340 } 468 }
341 } else if (upper->Is(Type::Boolean())) { 469 } else if (upper->Is(Type::Boolean())) {
342 // multiple uses => pick kRepBit. 470 // multiple uses => pick kRepBit.
343 return kRepBit; 471 return kRepBit;
344 } else if (upper->Is(Type::Number())) { 472 } else if (upper->Is(Type::Number())) {
345 // multiple uses => pick kRepFloat64. 473 // multiple uses => pick kRepFloat64.
346 return kRepFloat64; 474 return kRepFloat64;
347 } else if (upper->Is(Type::Internal())) { 475 } else if (upper->Is(Type::Internal())) {
348 return kMachPtr; 476 return kMachPtr;
349 } 477 }
350 return kRepTagged; 478 return kRepTagged;
351 } 479 }
352 480
353 // Helper for handling selects. 481 // Helper for handling selects.
354 void VisitSelect(Node* node, MachineTypeUnion use, 482 void VisitSelect(Node* node, MachineTypeUnion use,
355 SimplifiedLowering* lowering) { 483 SimplifiedLowering* lowering) {
356 ProcessInput(node, 0, kRepBit); 484 ProcessInput(node, 0, UseInfo::Bool());
357 MachineType output = GetRepresentationForPhi(node, use); 485 MachineType output = GetRepresentationForPhi(node, use);
358 486
359 Type* upper = NodeProperties::GetType(node); 487 Type* upper = NodeProperties::GetType(node);
360 MachineType output_type = 488 MachineType output_type =
361 static_cast<MachineType>(changer_->TypeFromUpperBound(upper) | output); 489 static_cast<MachineType>(changer_->TypeFromUpperBound(upper) | output);
362 SetOutput(node, output_type); 490 SetOutput(node, output_type);
363 491
364 if (lower()) { 492 if (lower()) {
365 // Update the select operator. 493 // Update the select operator.
366 SelectParameters p = SelectParametersOf(node->op()); 494 SelectParameters p = SelectParametersOf(node->op());
367 MachineType type = static_cast<MachineType>(output_type); 495 MachineType type = static_cast<MachineType>(output_type);
368 if (type != p.type()) { 496 if (type != p.type()) {
369 NodeProperties::ChangeOp(node, 497 NodeProperties::ChangeOp(node,
370 lowering->common()->Select(type, p.hint())); 498 lowering->common()->Select(type, p.hint()));
371 } 499 }
372
373 // Convert inputs to the output representation of this select.
374 ProcessInput(node, 1, output_type);
375 ProcessInput(node, 2, output_type);
376 } else {
377 // Propagate {use} of the select to value inputs.
378 MachineType use_type =
379 static_cast<MachineType>((use & kTypeMask) | output);
380 ProcessInput(node, 1, use_type);
381 ProcessInput(node, 2, use_type);
382 } 500 }
501 // Convert inputs to the output representation of this phi, pass the
502 // use truncation along.
503 UseInfo input_use(output, use & kTypeMask);
504 ProcessInput(node, 1, input_use);
505 ProcessInput(node, 2, input_use);
383 } 506 }
384 507
385 // Helper for handling phis. 508 // Helper for handling phis.
386 void VisitPhi(Node* node, MachineTypeUnion use, 509 void VisitPhi(Node* node, MachineTypeUnion use,
387 SimplifiedLowering* lowering) { 510 SimplifiedLowering* lowering) {
388 MachineType output = GetRepresentationForPhi(node, use); 511 MachineType output = GetRepresentationForPhi(node, use);
389 512
390 Type* upper = NodeProperties::GetType(node); 513 Type* upper = NodeProperties::GetType(node);
391 MachineType output_type = 514 MachineType output_type =
392 static_cast<MachineType>(changer_->TypeFromUpperBound(upper) | output); 515 static_cast<MachineType>(changer_->TypeFromUpperBound(upper) | output);
393 SetOutput(node, output_type); 516 SetOutput(node, output_type);
394 517
395 int values = node->op()->ValueInputCount(); 518 int values = node->op()->ValueInputCount();
396 519
397 if (lower()) { 520 if (lower()) {
398 // Update the phi operator. 521 // Update the phi operator.
399 MachineType type = static_cast<MachineType>(output_type); 522 MachineType type = static_cast<MachineType>(output_type);
400 if (type != OpParameter<MachineType>(node)) { 523 if (type != OpParameter<MachineType>(node)) {
401 NodeProperties::ChangeOp(node, lowering->common()->Phi(type, values)); 524 NodeProperties::ChangeOp(node, lowering->common()->Phi(type, values));
402 } 525 }
403 } 526 }
404 527
405 // Convert inputs to the output representation of this phi, pass the 528 // Convert inputs to the output representation of this phi, pass the
406 // use truncation along. 529 // use truncation along.
407 MachineType use_type = static_cast<MachineType>((use & kTypeMask) | output); 530 UseInfo input_use(output, use & kTypeMask);
408 for (int i = 0; i < node->InputCount(); i++) { 531 for (int i = 0; i < node->InputCount(); i++) {
409 ProcessInput(node, i, i < values ? use_type : 0); 532 ProcessInput(node, i, i < values ? input_use : UseInfo::None());
410 } 533 }
411 } 534 }
412 535
413 void VisitCall(Node* node, SimplifiedLowering* lowering) { 536 void VisitCall(Node* node, SimplifiedLowering* lowering) {
414 const CallDescriptor* desc = OpParameter<const CallDescriptor*>(node->op()); 537 const CallDescriptor* desc = OpParameter<const CallDescriptor*>(node->op());
415 const MachineSignature* sig = desc->GetMachineSignature(); 538 const MachineSignature* sig = desc->GetMachineSignature();
416 int params = static_cast<int>(sig->parameter_count()); 539 int params = static_cast<int>(sig->parameter_count());
417 // Propagate representation information from call descriptor. 540 // Propagate representation information from call descriptor.
418 for (int i = 0; i < node->InputCount(); i++) { 541 for (int i = 0; i < node->InputCount(); i++) {
419 if (i == 0) { 542 if (i == 0) {
420 // The target of the call. 543 // The target of the call.
421 ProcessInput(node, i, 0); 544 ProcessInput(node, i, UseInfo::None());
422 } else if ((i - 1) < params) { 545 } else if ((i - 1) < params) {
423 ProcessInput(node, i, sig->GetParam(i - 1)); 546 ProcessInput(node, i, UseInfoFromMachineType(sig->GetParam(i - 1)));
424 } else { 547 } else {
425 ProcessInput(node, i, 0); 548 ProcessInput(node, i, UseInfo::None());
426 } 549 }
427 } 550 }
428 551
429 if (sig->return_count() > 0) { 552 if (sig->return_count() > 0) {
430 SetOutput(node, desc->GetMachineSignature()->GetReturn()); 553 SetOutput(node, desc->GetMachineSignature()->GetReturn());
431 } else { 554 } else {
432 SetOutput(node, kMachAnyTagged); 555 SetOutput(node, kMachAnyTagged);
433 } 556 }
434 } 557 }
435 558
436 void VisitStateValues(Node* node) { 559 void VisitStateValues(Node* node) {
437 if (phase_ == PROPAGATE) { 560 if (phase_ == PROPAGATE) {
438 for (int i = 0; i < node->InputCount(); i++) { 561 for (int i = 0; i < node->InputCount(); i++) {
439 Enqueue(node->InputAt(i), kTypeAny); 562 Enqueue(node->InputAt(i), UseInfo::Any());
440 } 563 }
441 } else { 564 } else {
442 Zone* zone = jsgraph_->zone(); 565 Zone* zone = jsgraph_->zone();
443 ZoneVector<MachineType>* types = 566 ZoneVector<MachineType>* types =
444 new (zone->New(sizeof(ZoneVector<MachineType>))) 567 new (zone->New(sizeof(ZoneVector<MachineType>)))
445 ZoneVector<MachineType>(node->InputCount(), zone); 568 ZoneVector<MachineType>(node->InputCount(), zone);
446 for (int i = 0; i < node->InputCount(); i++) { 569 for (int i = 0; i < node->InputCount(); i++) {
447 MachineTypeUnion input_type = GetInfo(node->InputAt(i))->output; 570 MachineTypeUnion input_type = GetInfo(node->InputAt(i))->output;
448 (*types)[i] = static_cast<MachineType>(input_type); 571 (*types)[i] = static_cast<MachineType>(input_type);
449 } 572 }
(...skipping 25 matching lines...) Expand all
475 return BothInputsAre(node, safe_int_additive_range_) && 598 return BothInputsAre(node, safe_int_additive_range_) &&
476 !CanObserveNonWord32(use); 599 !CanObserveNonWord32(use);
477 } 600 }
478 601
479 bool CanLowerToUint32Binop(Node* node, MachineTypeUnion use) { 602 bool CanLowerToUint32Binop(Node* node, MachineTypeUnion use) {
480 return BothInputsAre(node, Type::Unsigned32()) && 603 return BothInputsAre(node, Type::Unsigned32()) &&
481 (!CanObserveNonWord32(use) || 604 (!CanObserveNonWord32(use) ||
482 NodeProperties::GetType(node)->Is(Type::Unsigned32())); 605 NodeProperties::GetType(node)->Is(Type::Unsigned32()));
483 } 606 }
484 607
485 bool CanObserveNonWord32(MachineTypeUnion use) { 608 static bool CanObserveNonWord32(MachineTypeUnion use) {
486 return (use & kTypeMask & ~(kTypeInt32 | kTypeUint32)) != 0; 609 return (use & kTypeMask & ~(kTypeInt32 | kTypeUint32)) != 0;
487 } 610 }
488 611
489 bool CanObserveNaN(MachineTypeUnion use) { 612 static bool CanObserveNaN(MachineTypeUnion use) {
490 return (use & (kTypeNumber | kTypeAny)) != 0; 613 return (use & (kTypeNumber | kTypeAny)) != 0;
491 } 614 }
492 615
493 // Dispatching routine for visiting the node {node} with the usage {use}. 616 // Dispatching routine for visiting the node {node} with the usage {use}.
494 // Depending on the operator, propagate new usage info to the inputs. 617 // Depending on the operator, propagate new usage info to the inputs.
495 void VisitNode(Node* node, MachineTypeUnion use, 618 void VisitNode(Node* node, MachineTypeUnion use,
496 SimplifiedLowering* lowering) { 619 SimplifiedLowering* lowering) {
497 switch (node->opcode()) { 620 switch (node->opcode()) {
498 //------------------------------------------------------------------ 621 //------------------------------------------------------------------
499 // Common operators. 622 // Common operators.
500 //------------------------------------------------------------------ 623 //------------------------------------------------------------------
501 case IrOpcode::kStart: 624 case IrOpcode::kStart:
502 case IrOpcode::kDead: 625 case IrOpcode::kDead:
503 return VisitLeaf(node, 0); 626 return VisitLeaf(node, 0);
504 case IrOpcode::kParameter: { 627 case IrOpcode::kParameter: {
505 // TODO(titzer): use representation from linkage. 628 // TODO(titzer): use representation from linkage.
506 Type* upper = NodeProperties::GetType(node); 629 Type* upper = NodeProperties::GetType(node);
507 ProcessInput(node, 0, 0); 630 ProcessInput(node, 0, UseInfo::None());
508 SetOutput(node, kRepTagged | changer_->TypeFromUpperBound(upper)); 631 SetOutput(node, kRepTagged | changer_->TypeFromUpperBound(upper));
509 return; 632 return;
510 } 633 }
511 case IrOpcode::kInt32Constant: 634 case IrOpcode::kInt32Constant:
512 return VisitLeaf(node, kRepWord32); 635 return VisitLeaf(node, kRepWord32);
513 case IrOpcode::kInt64Constant: 636 case IrOpcode::kInt64Constant:
514 return VisitLeaf(node, kRepWord64); 637 return VisitLeaf(node, kRepWord64);
515 case IrOpcode::kFloat32Constant: 638 case IrOpcode::kFloat32Constant:
516 return VisitLeaf(node, kRepFloat32); 639 return VisitLeaf(node, kRepFloat32);
517 case IrOpcode::kFloat64Constant: 640 case IrOpcode::kFloat64Constant:
518 return VisitLeaf(node, kRepFloat64); 641 return VisitLeaf(node, kRepFloat64);
519 case IrOpcode::kExternalConstant: 642 case IrOpcode::kExternalConstant:
520 return VisitLeaf(node, kMachPtr); 643 return VisitLeaf(node, kMachPtr);
521 case IrOpcode::kNumberConstant: 644 case IrOpcode::kNumberConstant:
522 return VisitLeaf(node, kRepTagged); 645 return VisitLeaf(node, kRepTagged);
523 case IrOpcode::kHeapConstant: 646 case IrOpcode::kHeapConstant:
524 return VisitLeaf(node, kRepTagged); 647 return VisitLeaf(node, kRepTagged);
525 648
526 case IrOpcode::kBranch: 649 case IrOpcode::kBranch:
527 ProcessInput(node, 0, kRepBit); 650 ProcessInput(node, 0, UseInfo::Bool());
528 Enqueue(NodeProperties::GetControlInput(node, 0)); 651 Enqueue(NodeProperties::GetControlInput(node, 0));
529 break; 652 break;
530 case IrOpcode::kSwitch: 653 case IrOpcode::kSwitch:
531 ProcessInput(node, 0, kRepWord32); 654 ProcessInput(node, 0, UseInfo::TruncatingWord32());
532 Enqueue(NodeProperties::GetControlInput(node, 0)); 655 Enqueue(NodeProperties::GetControlInput(node, 0));
533 break; 656 break;
534 case IrOpcode::kSelect: 657 case IrOpcode::kSelect:
535 return VisitSelect(node, use, lowering); 658 return VisitSelect(node, use, lowering);
536 case IrOpcode::kPhi: 659 case IrOpcode::kPhi:
537 return VisitPhi(node, use, lowering); 660 return VisitPhi(node, use, lowering);
538 case IrOpcode::kCall: 661 case IrOpcode::kCall:
539 return VisitCall(node, lowering); 662 return VisitCall(node, lowering);
540 663
541 //------------------------------------------------------------------ 664 //------------------------------------------------------------------
(...skipping 20 matching lines...) Expand all
562 // BooleanNot(x: kRepBit) => Word32Equal(x, #0) 685 // BooleanNot(x: kRepBit) => Word32Equal(x, #0)
563 node->AppendInput(jsgraph_->zone(), jsgraph_->Int32Constant(0)); 686 node->AppendInput(jsgraph_->zone(), jsgraph_->Int32Constant(0));
564 NodeProperties::ChangeOp(node, lowering->machine()->Word32Equal()); 687 NodeProperties::ChangeOp(node, lowering->machine()->Word32Equal());
565 } else { 688 } else {
566 // BooleanNot(x: kRepTagged) => WordEqual(x, #false) 689 // BooleanNot(x: kRepTagged) => WordEqual(x, #false)
567 node->AppendInput(jsgraph_->zone(), jsgraph_->FalseConstant()); 690 node->AppendInput(jsgraph_->zone(), jsgraph_->FalseConstant());
568 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual()); 691 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual());
569 } 692 }
570 } else { 693 } else {
571 // No input representation requirement; adapt during lowering. 694 // No input representation requirement; adapt during lowering.
572 ProcessInput(node, 0, kTypeBool); 695 ProcessInput(node, 0, UseInfo::AnyTruncatingToBool());
573 SetOutput(node, kRepBit); 696 SetOutput(node, kRepBit);
574 } 697 }
575 break; 698 break;
576 } 699 }
577 case IrOpcode::kBooleanToNumber: { 700 case IrOpcode::kBooleanToNumber: {
578 if (lower()) { 701 if (lower()) {
579 MachineTypeUnion input = GetInfo(node->InputAt(0))->output; 702 MachineTypeUnion input = GetInfo(node->InputAt(0))->output;
580 if (input & kRepBit) { 703 if (input & kRepBit) {
581 // BooleanToNumber(x: kRepBit) => x 704 // BooleanToNumber(x: kRepBit) => x
582 DeferReplacement(node, node->InputAt(0)); 705 DeferReplacement(node, node->InputAt(0));
583 } else { 706 } else {
584 // BooleanToNumber(x: kRepTagged) => WordEqual(x, #true) 707 // BooleanToNumber(x: kRepTagged) => WordEqual(x, #true)
585 node->AppendInput(jsgraph_->zone(), jsgraph_->TrueConstant()); 708 node->AppendInput(jsgraph_->zone(), jsgraph_->TrueConstant());
586 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual()); 709 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual());
587 } 710 }
588 } else { 711 } else {
589 // No input representation requirement; adapt during lowering. 712 // No input representation requirement; adapt during lowering.
590 ProcessInput(node, 0, kTypeBool); 713 ProcessInput(node, 0, UseInfo::AnyTruncatingToBool());
591 SetOutput(node, kMachInt32); 714 SetOutput(node, kMachInt32);
592 } 715 }
593 break; 716 break;
594 } 717 }
595 case IrOpcode::kNumberEqual: 718 case IrOpcode::kNumberEqual:
596 case IrOpcode::kNumberLessThan: 719 case IrOpcode::kNumberLessThan:
597 case IrOpcode::kNumberLessThanOrEqual: { 720 case IrOpcode::kNumberLessThanOrEqual: {
598 // Number comparisons reduce to integer comparisons for integer inputs. 721 // Number comparisons reduce to integer comparisons for integer inputs.
599 if (BothInputsAre(node, Type::Signed32())) { 722 if (BothInputsAre(node, Type::Signed32())) {
600 // => signed Int32Cmp 723 // => signed Int32Cmp
(...skipping 17 matching lines...) Expand all
618 if (CanLowerToInt32Binop(node, use)) { 741 if (CanLowerToInt32Binop(node, use)) {
619 // => signed Int32Add/Sub 742 // => signed Int32Add/Sub
620 VisitInt32Binop(node); 743 VisitInt32Binop(node);
621 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); 744 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
622 } else if (CanLowerToUint32Binop(node, use)) { 745 } else if (CanLowerToUint32Binop(node, use)) {
623 // => unsigned Int32Add/Sub 746 // => unsigned Int32Add/Sub
624 VisitUint32Binop(node); 747 VisitUint32Binop(node);
625 if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node)); 748 if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node));
626 } else if (CanLowerToWord32AdditiveBinop(node, use)) { 749 } else if (CanLowerToWord32AdditiveBinop(node, use)) {
627 // => signed Int32Add/Sub, truncating inputs 750 // => signed Int32Add/Sub, truncating inputs
628 ProcessTruncateWord32Input(node, 0, kTypeInt32); 751 ProcessTruncateWord32Input(node, 0);
629 ProcessTruncateWord32Input(node, 1, kTypeInt32); 752 ProcessTruncateWord32Input(node, 1);
630 SetOutput(node, kMachInt32); 753 SetOutput(node, kMachInt32);
631 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); 754 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
632 } else { 755 } else {
633 // => Float64Add/Sub 756 // => Float64Add/Sub
634 VisitFloat64Binop(node); 757 VisitFloat64Binop(node);
635 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); 758 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
636 } 759 }
637 break; 760 break;
638 } 761 }
639 case IrOpcode::kNumberMultiply: { 762 case IrOpcode::kNumberMultiply: {
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
688 break; 811 break;
689 } 812 }
690 case IrOpcode::kNumberBitwiseOr: 813 case IrOpcode::kNumberBitwiseOr:
691 case IrOpcode::kNumberBitwiseXor: 814 case IrOpcode::kNumberBitwiseXor:
692 case IrOpcode::kNumberBitwiseAnd: { 815 case IrOpcode::kNumberBitwiseAnd: {
693 VisitInt32Binop(node); 816 VisitInt32Binop(node);
694 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); 817 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
695 break; 818 break;
696 } 819 }
697 case IrOpcode::kNumberShiftLeft: { 820 case IrOpcode::kNumberShiftLeft: {
698 VisitBinop(node, kMachInt32, kMachUint32, kMachInt32); 821 VisitBinop(node, UseInfo::TruncatingWord32(),
822 UseInfo::TruncatingWord32(), kMachInt32);
699 if (lower()) lowering->DoShift(node, lowering->machine()->Word32Shl()); 823 if (lower()) lowering->DoShift(node, lowering->machine()->Word32Shl());
700 break; 824 break;
701 } 825 }
702 case IrOpcode::kNumberShiftRight: { 826 case IrOpcode::kNumberShiftRight: {
703 VisitBinop(node, kMachInt32, kMachUint32, kMachInt32); 827 VisitBinop(node, UseInfo::TruncatingWord32(),
828 UseInfo::TruncatingWord32(), kMachInt32);
704 if (lower()) lowering->DoShift(node, lowering->machine()->Word32Sar()); 829 if (lower()) lowering->DoShift(node, lowering->machine()->Word32Sar());
705 break; 830 break;
706 } 831 }
707 case IrOpcode::kNumberShiftRightLogical: { 832 case IrOpcode::kNumberShiftRightLogical: {
708 VisitBinop(node, kMachUint32, kMachUint32, kMachUint32); 833 VisitBinop(node, UseInfo::TruncatingWord32(),
834 UseInfo::TruncatingWord32(), kMachUint32);
709 if (lower()) lowering->DoShift(node, lowering->machine()->Word32Shr()); 835 if (lower()) lowering->DoShift(node, lowering->machine()->Word32Shr());
710 break; 836 break;
711 } 837 }
712 case IrOpcode::kNumberToInt32: { 838 case IrOpcode::kNumberToInt32: {
713 MachineTypeUnion use_rep = use & kRepMask; 839 MachineTypeUnion use_rep = use & kRepMask;
714 Node* input = node->InputAt(0); 840 Node* input = node->InputAt(0);
715 Type* in_upper = NodeProperties::GetType(input); 841 Type* in_upper = NodeProperties::GetType(input);
716 MachineTypeUnion in = GetInfo(input)->output; 842 MachineTypeUnion in = GetInfo(input)->output;
717 if (in_upper->Is(Type::Signed32())) { 843 if (in_upper->Is(Type::Signed32())) {
718 // If the input has type int32, pass through representation. 844 // If the input has type int32, pass through representation.
719 VisitUnop(node, kTypeInt32 | use_rep, kTypeInt32 | use_rep); 845 VisitUnop(node, UseInfoFromRepresentation(use_rep),
846 kTypeInt32 | use_rep);
720 if (lower()) DeferReplacement(node, node->InputAt(0)); 847 if (lower()) DeferReplacement(node, node->InputAt(0));
721 } else if ((in & kTypeMask) == kTypeUint32 || 848 } else if ((in & kTypeMask) == kTypeUint32 ||
722 in_upper->Is(Type::Unsigned32())) { 849 in_upper->Is(Type::Unsigned32())) {
723 // Just change representation if necessary. 850 // Just change representation if necessary.
724 VisitUnop(node, kTypeUint32 | kRepWord32, kTypeInt32 | kRepWord32); 851 VisitUnop(node, UseInfo::TruncatingWord32(), kTypeInt32 | kRepWord32);
725 if (lower()) DeferReplacement(node, node->InputAt(0)); 852 if (lower()) DeferReplacement(node, node->InputAt(0));
726 } else if ((in & kTypeMask) == kTypeInt32 || 853 } else if ((in & kTypeMask) == kTypeInt32 ||
727 (in & kRepMask) == kRepWord32) { 854 (in & kRepMask) == kRepWord32) {
728 // Just change representation if necessary. 855 // Just change representation if necessary.
729 VisitUnop(node, kTypeInt32 | kRepWord32, kTypeInt32 | kRepWord32); 856 VisitUnop(node, UseInfo::TruncatingWord32(), kTypeInt32 | kRepWord32);
730 if (lower()) DeferReplacement(node, node->InputAt(0)); 857 if (lower()) DeferReplacement(node, node->InputAt(0));
731 } else { 858 } else {
732 // Require the input in float64 format and perform truncation. 859 // Require the input in float64 format and perform truncation.
733 // TODO(turbofan): avoid a truncation with a smi check. 860 // TODO(turbofan): avoid a truncation with a smi check.
734 VisitUnop(node, kTypeInt32 | kRepFloat64, kTypeInt32 | kRepWord32); 861 VisitUnop(node, UseInfo::Float64TruncatingToWord32(),
862 kTypeInt32 | kRepWord32);
735 if (lower()) { 863 if (lower()) {
736 NodeProperties::ChangeOp( 864 NodeProperties::ChangeOp(
737 node, lowering->machine()->TruncateFloat64ToInt32( 865 node, lowering->machine()->TruncateFloat64ToInt32(
738 TruncationMode::kJavaScript)); 866 TruncationMode::kJavaScript));
739 } 867 }
740 } 868 }
741 break; 869 break;
742 } 870 }
743 case IrOpcode::kNumberToUint32: { 871 case IrOpcode::kNumberToUint32: {
744 MachineTypeUnion use_rep = use & kRepMask; 872 MachineTypeUnion use_rep = use & kRepMask;
745 Node* input = node->InputAt(0); 873 Node* input = node->InputAt(0);
746 Type* in_upper = NodeProperties::GetType(input); 874 Type* in_upper = NodeProperties::GetType(input);
747 MachineTypeUnion in = GetInfo(input)->output; 875 MachineTypeUnion in = GetInfo(input)->output;
748 if (in_upper->Is(Type::Unsigned32())) { 876 if (in_upper->Is(Type::Unsigned32())) {
749 // If the input has type uint32, pass through representation. 877 // If the input has type uint32, pass through representation.
750 VisitUnop(node, kTypeUint32 | use_rep, kTypeUint32 | use_rep); 878 VisitUnop(node, UseInfoFromRepresentation(use_rep),
879 kTypeUint32 | use_rep);
751 if (lower()) DeferReplacement(node, node->InputAt(0)); 880 if (lower()) DeferReplacement(node, node->InputAt(0));
752 } else if ((in & kTypeMask) == kTypeInt32 || 881 } else if ((in & kTypeMask) == kTypeInt32 ||
753 in_upper->Is(Type::Signed32())) { 882 in_upper->Is(Type::Signed32())) {
754 // Just change representation if necessary. 883 // Just change representation if necessary.
755 VisitUnop(node, kTypeInt32 | kRepWord32, kTypeUint32 | kRepWord32); 884 VisitUnop(node, UseInfo::TruncatingWord32(),
885 kTypeUint32 | kRepWord32);
756 if (lower()) DeferReplacement(node, node->InputAt(0)); 886 if (lower()) DeferReplacement(node, node->InputAt(0));
757 } else if ((in & kTypeMask) == kTypeUint32 || 887 } else if ((in & kTypeMask) == kTypeUint32 ||
758 (in & kRepMask) == kRepWord32) { 888 (in & kRepMask) == kRepWord32) {
759 // Just change representation if necessary. 889 // Just change representation if necessary.
760 VisitUnop(node, kTypeUint32 | kRepWord32, kTypeUint32 | kRepWord32); 890 VisitUnop(node, UseInfo::TruncatingWord32(),
891 kTypeUint32 | kRepWord32);
761 if (lower()) DeferReplacement(node, node->InputAt(0)); 892 if (lower()) DeferReplacement(node, node->InputAt(0));
762 } else { 893 } else {
763 // Require the input in float64 format and perform truncation. 894 // Require the input in float64 format and perform truncation.
764 // TODO(turbofan): avoid a truncation with a smi check. 895 // TODO(turbofan): avoid a truncation with a smi check.
765 VisitUnop(node, kTypeUint32 | kRepFloat64, kTypeUint32 | kRepWord32); 896 VisitUnop(node, UseInfo::Float64TruncatingToWord32(),
897 kTypeUint32 | kRepWord32);
766 if (lower()) { 898 if (lower()) {
767 NodeProperties::ChangeOp( 899 NodeProperties::ChangeOp(
768 node, lowering->machine()->TruncateFloat64ToInt32( 900 node, lowering->machine()->TruncateFloat64ToInt32(
769 TruncationMode::kJavaScript)); 901 TruncationMode::kJavaScript));
770 } 902 }
771 } 903 }
772 break; 904 break;
773 } 905 }
774 case IrOpcode::kNumberIsHoleNaN: { 906 case IrOpcode::kNumberIsHoleNaN: {
775 VisitUnop(node, kMachFloat64, kMachBool); 907 VisitUnop(node, UseInfo::Float64(), kMachBool);
776 if (lower()) { 908 if (lower()) {
777 // NumberIsHoleNaN(x) => Word32Equal(Float64ExtractLowWord32(x), 909 // NumberIsHoleNaN(x) => Word32Equal(Float64ExtractLowWord32(x),
778 // #HoleNaNLower32) 910 // #HoleNaNLower32)
779 node->ReplaceInput(0, 911 node->ReplaceInput(0,
780 jsgraph_->graph()->NewNode( 912 jsgraph_->graph()->NewNode(
781 lowering->machine()->Float64ExtractLowWord32(), 913 lowering->machine()->Float64ExtractLowWord32(),
782 node->InputAt(0))); 914 node->InputAt(0)));
783 node->AppendInput(jsgraph_->zone(), 915 node->AppendInput(jsgraph_->zone(),
784 jsgraph_->Int32Constant(kHoleNanLower32)); 916 jsgraph_->Int32Constant(kHoleNanLower32));
785 NodeProperties::ChangeOp(node, jsgraph_->machine()->Word32Equal()); 917 NodeProperties::ChangeOp(node, jsgraph_->machine()->Word32Equal());
786 } 918 }
787 break; 919 break;
788 } 920 }
789 case IrOpcode::kPlainPrimitiveToNumber: { 921 case IrOpcode::kPlainPrimitiveToNumber: {
790 VisitUnop(node, kMachAnyTagged, kTypeNumber | kRepTagged); 922 VisitUnop(node, UseInfo::AnyTagged(), kTypeNumber | kRepTagged);
791 if (lower()) { 923 if (lower()) {
792 // PlainPrimitiveToNumber(x) => Call(ToNumberStub, x, no-context) 924 // PlainPrimitiveToNumber(x) => Call(ToNumberStub, x, no-context)
793 Operator::Properties properties = node->op()->properties(); 925 Operator::Properties properties = node->op()->properties();
794 Callable callable = CodeFactory::ToNumber(jsgraph_->isolate()); 926 Callable callable = CodeFactory::ToNumber(jsgraph_->isolate());
795 CallDescriptor::Flags flags = CallDescriptor::kNoFlags; 927 CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
796 CallDescriptor* desc = Linkage::GetStubCallDescriptor( 928 CallDescriptor* desc = Linkage::GetStubCallDescriptor(
797 jsgraph_->isolate(), jsgraph_->zone(), callable.descriptor(), 0, 929 jsgraph_->isolate(), jsgraph_->zone(), callable.descriptor(), 0,
798 flags, properties); 930 flags, properties);
799 node->InsertInput(jsgraph_->zone(), 0, 931 node->InsertInput(jsgraph_->zone(), 0,
800 jsgraph_->HeapConstant(callable.code())); 932 jsgraph_->HeapConstant(callable.code()));
801 node->AppendInput(jsgraph_->zone(), jsgraph_->NoContextConstant()); 933 node->AppendInput(jsgraph_->zone(), jsgraph_->NoContextConstant());
802 NodeProperties::ChangeOp(node, jsgraph_->common()->Call(desc)); 934 NodeProperties::ChangeOp(node, jsgraph_->common()->Call(desc));
803 } 935 }
804 break; 936 break;
805 } 937 }
806 case IrOpcode::kReferenceEqual: { 938 case IrOpcode::kReferenceEqual: {
807 VisitBinop(node, kMachAnyTagged, kRepBit); 939 VisitBinop(node, UseInfo::AnyTagged(), kMachBool);
808 if (lower()) { 940 if (lower()) {
809 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual()); 941 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual());
810 } 942 }
811 break; 943 break;
812 } 944 }
813 case IrOpcode::kStringEqual: { 945 case IrOpcode::kStringEqual: {
814 VisitBinop(node, kMachAnyTagged, kRepBit); 946 VisitBinop(node, UseInfo::AnyTagged(), kMachBool);
815 if (lower()) lowering->DoStringEqual(node); 947 if (lower()) lowering->DoStringEqual(node);
816 break; 948 break;
817 } 949 }
818 case IrOpcode::kStringLessThan: { 950 case IrOpcode::kStringLessThan: {
819 VisitBinop(node, kMachAnyTagged, kRepBit); 951 VisitBinop(node, UseInfo::AnyTagged(), kMachBool);
820 if (lower()) lowering->DoStringLessThan(node); 952 if (lower()) lowering->DoStringLessThan(node);
821 break; 953 break;
822 } 954 }
823 case IrOpcode::kStringLessThanOrEqual: { 955 case IrOpcode::kStringLessThanOrEqual: {
824 VisitBinop(node, kMachAnyTagged, kRepBit); 956 VisitBinop(node, UseInfo::AnyTagged(), kMachBool);
825 if (lower()) lowering->DoStringLessThanOrEqual(node); 957 if (lower()) lowering->DoStringLessThanOrEqual(node);
826 break; 958 break;
827 } 959 }
828 case IrOpcode::kAllocate: { 960 case IrOpcode::kAllocate: {
829 ProcessInput(node, 0, kMachAnyTagged); 961 ProcessInput(node, 0, UseInfo::AnyTagged());
830 ProcessRemainingInputs(node, 1); 962 ProcessRemainingInputs(node, 1);
831 SetOutput(node, kMachAnyTagged); 963 SetOutput(node, kMachAnyTagged);
832 break; 964 break;
833 } 965 }
834 case IrOpcode::kLoadField: { 966 case IrOpcode::kLoadField: {
835 FieldAccess access = FieldAccessOf(node->op()); 967 FieldAccess access = FieldAccessOf(node->op());
836 ProcessInput(node, 0, changer_->TypeForBasePointer(access)); 968 ProcessInput(node, 0, UseInfoForBasePointer(access));
837 ProcessRemainingInputs(node, 1); 969 ProcessRemainingInputs(node, 1);
838 SetOutput(node, access.machine_type); 970 SetOutput(node, access.machine_type);
839 break; 971 break;
840 } 972 }
841 case IrOpcode::kStoreField: { 973 case IrOpcode::kStoreField: {
842 FieldAccess access = FieldAccessOf(node->op()); 974 FieldAccess access = FieldAccessOf(node->op());
843 ProcessInput(node, 0, changer_->TypeForBasePointer(access)); 975 ProcessInput(node, 0, UseInfoForBasePointer(access));
844 ProcessInput(node, 1, access.machine_type); 976 ProcessInput(node, 1, UseInfoFromMachineType(access.machine_type));
845 ProcessRemainingInputs(node, 2); 977 ProcessRemainingInputs(node, 2);
846 SetOutput(node, 0); 978 SetOutput(node, 0);
847 break; 979 break;
848 } 980 }
849 case IrOpcode::kLoadBuffer: { 981 case IrOpcode::kLoadBuffer: {
850 BufferAccess access = BufferAccessOf(node->op()); 982 BufferAccess access = BufferAccessOf(node->op());
851 ProcessInput(node, 0, kMachPtr); // buffer 983 ProcessInput(node, 0, UseInfo::PointerInt()); // buffer
852 ProcessInput(node, 1, kMachInt32); // offset 984 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // offset
853 ProcessInput(node, 2, kMachInt32); // length 985 ProcessInput(node, 2, UseInfo::TruncatingWord32()); // length
854 ProcessRemainingInputs(node, 3); 986 ProcessRemainingInputs(node, 3);
855 // Tagged overrides everything if we have to do a typed array bounds 987 // Tagged overrides everything if we have to do a typed array bounds
856 // check, because we may need to return undefined then. 988 // check, because we may need to return undefined then.
857 MachineType output_type; 989 MachineType output_type;
858 if (use & kRepTagged) { 990 if (use & kRepTagged) {
859 output_type = kMachAnyTagged; 991 output_type = kMachAnyTagged;
860 } else if (use & kRepFloat64) { 992 } else if (use & kRepFloat64) {
861 if (access.machine_type() & kRepFloat32) { 993 if (access.machine_type() & kRepFloat32) {
862 output_type = access.machine_type(); 994 output_type = access.machine_type();
863 } else { 995 } else {
864 output_type = kMachFloat64; 996 output_type = kMachFloat64;
865 } 997 }
866 } else if (use & kRepFloat32) { 998 } else if (use & kRepFloat32) {
867 output_type = kMachFloat32; 999 output_type = kMachFloat32;
868 } else { 1000 } else {
869 output_type = access.machine_type(); 1001 output_type = access.machine_type();
870 } 1002 }
871 SetOutput(node, output_type); 1003 SetOutput(node, output_type);
872 if (lower()) lowering->DoLoadBuffer(node, output_type, changer_); 1004 if (lower()) lowering->DoLoadBuffer(node, output_type, changer_);
873 break; 1005 break;
874 } 1006 }
875 case IrOpcode::kStoreBuffer: { 1007 case IrOpcode::kStoreBuffer: {
876 BufferAccess access = BufferAccessOf(node->op()); 1008 BufferAccess access = BufferAccessOf(node->op());
877 ProcessInput(node, 0, kMachPtr); // buffer 1009 ProcessInput(node, 0, UseInfo::PointerInt()); // buffer
878 ProcessInput(node, 1, kMachInt32); // offset 1010 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // offset
879 ProcessInput(node, 2, kMachInt32); // length 1011 ProcessInput(node, 2, UseInfo::TruncatingWord32()); // length
880 ProcessInput(node, 3, access.machine_type()); // value 1012 ProcessInput(node, 3,
1013 UseInfoFromMachineType(access.machine_type())); // value
881 ProcessRemainingInputs(node, 4); 1014 ProcessRemainingInputs(node, 4);
882 SetOutput(node, 0); 1015 SetOutput(node, 0);
883 if (lower()) lowering->DoStoreBuffer(node); 1016 if (lower()) lowering->DoStoreBuffer(node);
884 break; 1017 break;
885 } 1018 }
886 case IrOpcode::kLoadElement: { 1019 case IrOpcode::kLoadElement: {
887 ElementAccess access = ElementAccessOf(node->op()); 1020 ElementAccess access = ElementAccessOf(node->op());
888 ProcessInput(node, 0, changer_->TypeForBasePointer(access)); // base 1021 ProcessInput(node, 0, UseInfoForBasePointer(access)); // base
889 ProcessInput(node, 1, kMachInt32); // index 1022 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // index
890 ProcessRemainingInputs(node, 2); 1023 ProcessRemainingInputs(node, 2);
891 SetOutput(node, access.machine_type); 1024 SetOutput(node, access.machine_type);
892 break; 1025 break;
893 } 1026 }
894 case IrOpcode::kStoreElement: { 1027 case IrOpcode::kStoreElement: {
895 ElementAccess access = ElementAccessOf(node->op()); 1028 ElementAccess access = ElementAccessOf(node->op());
896 ProcessInput(node, 0, changer_->TypeForBasePointer(access)); // base 1029 ProcessInput(node, 0, UseInfoForBasePointer(access)); // base
897 ProcessInput(node, 1, kMachInt32); // index 1030 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // index
898 ProcessInput(node, 2, access.machine_type); // value 1031 ProcessInput(node, 2,
1032 UseInfoFromMachineType(access.machine_type)); // value
899 ProcessRemainingInputs(node, 3); 1033 ProcessRemainingInputs(node, 3);
900 SetOutput(node, 0); 1034 SetOutput(node, 0);
901 break; 1035 break;
902 } 1036 }
903 case IrOpcode::kObjectIsNumber: { 1037 case IrOpcode::kObjectIsNumber: {
904 ProcessInput(node, 0, kMachAnyTagged); 1038 ProcessInput(node, 0, UseInfo::AnyTagged());
905 SetOutput(node, kRepBit | kTypeBool); 1039 SetOutput(node, kMachBool);
906 if (lower()) lowering->DoObjectIsNumber(node); 1040 if (lower()) lowering->DoObjectIsNumber(node);
907 break; 1041 break;
908 } 1042 }
909 case IrOpcode::kObjectIsSmi: { 1043 case IrOpcode::kObjectIsSmi: {
910 ProcessInput(node, 0, kMachAnyTagged); 1044 ProcessInput(node, 0, UseInfo::AnyTagged());
911 SetOutput(node, kRepBit | kTypeBool); 1045 SetOutput(node, kMachBool);
912 if (lower()) lowering->DoObjectIsSmi(node); 1046 if (lower()) lowering->DoObjectIsSmi(node);
913 break; 1047 break;
914 } 1048 }
915 1049
916 //------------------------------------------------------------------ 1050 //------------------------------------------------------------------
917 // Machine-level operators. 1051 // Machine-level operators.
918 //------------------------------------------------------------------ 1052 //------------------------------------------------------------------
919 case IrOpcode::kLoad: { 1053 case IrOpcode::kLoad: {
920 // TODO(titzer): machine loads/stores need to know BaseTaggedness!? 1054 // TODO(jarin) Eventually, we should get rid of all machine stores
921 MachineTypeUnion tBase = kRepTagged | kMachPtr; 1055 // from the high-level phases, then this becomes UNREACHABLE.
922 LoadRepresentation rep = OpParameter<LoadRepresentation>(node); 1056 LoadRepresentation rep = OpParameter<LoadRepresentation>(node);
923 ProcessInput(node, 0, tBase); // pointer or object 1057 ProcessInput(node, 0, UseInfo::AnyTagged()); // tagged pointer
924 ProcessInput(node, 1, kMachIntPtr); // index 1058 ProcessInput(node, 1, UseInfo::PointerInt()); // index
925 ProcessRemainingInputs(node, 2); 1059 ProcessRemainingInputs(node, 2);
926 SetOutput(node, rep); 1060 SetOutput(node, rep);
927 break; 1061 break;
928 } 1062 }
929 case IrOpcode::kStore: { 1063 case IrOpcode::kStore: {
930 // TODO(titzer): machine loads/stores need to know BaseTaggedness!? 1064 // TODO(jarin) Eventually, we should get rid of all machine stores
931 MachineTypeUnion tBase = kRepTagged | kMachPtr; 1065 // from the high-level phases, then this becomes UNREACHABLE.
932 StoreRepresentation rep = OpParameter<StoreRepresentation>(node); 1066 StoreRepresentation rep = OpParameter<StoreRepresentation>(node);
933 ProcessInput(node, 0, tBase); // pointer or object 1067 ProcessInput(node, 0, UseInfo::AnyTagged()); // tagged pointer
934 ProcessInput(node, 1, kMachIntPtr); // index 1068 ProcessInput(node, 1, UseInfo::PointerInt()); // index
935 ProcessInput(node, 2, rep.machine_type()); 1069 ProcessInput(node, 2, UseInfoFromMachineType(rep.machine_type()));
936 ProcessRemainingInputs(node, 3); 1070 ProcessRemainingInputs(node, 3);
937 SetOutput(node, 0); 1071 SetOutput(node, 0);
938 break; 1072 break;
939 } 1073 }
940 case IrOpcode::kWord32Shr: 1074 case IrOpcode::kWord32Shr:
941 // We output unsigned int32 for shift right because JavaScript. 1075 // We output unsigned int32 for shift right because JavaScript.
942 return VisitBinop(node, kMachUint32, kMachUint32); 1076 return VisitBinop(node, UseInfo::TruncatingWord32(), kMachUint32);
943 case IrOpcode::kWord32And: 1077 case IrOpcode::kWord32And:
944 case IrOpcode::kWord32Or: 1078 case IrOpcode::kWord32Or:
945 case IrOpcode::kWord32Xor: 1079 case IrOpcode::kWord32Xor:
946 case IrOpcode::kWord32Shl: 1080 case IrOpcode::kWord32Shl:
947 case IrOpcode::kWord32Sar: 1081 case IrOpcode::kWord32Sar:
948 // We use signed int32 as the output type for these word32 operations, 1082 // We use signed int32 as the output type for these word32 operations,
949 // though the machine bits are the same for either signed or unsigned, 1083 // though the machine bits are the same for either signed or unsigned,
950 // because JavaScript considers the result from these operations signed. 1084 // because JavaScript considers the result from these operations signed.
951 return VisitBinop(node, kRepWord32, kRepWord32 | kTypeInt32); 1085 return VisitBinop(node, UseInfo::TruncatingWord32(),
1086 kRepWord32 | kTypeInt32);
952 case IrOpcode::kWord32Equal: 1087 case IrOpcode::kWord32Equal:
953 return VisitBinop(node, kRepWord32, kRepBit); 1088 return VisitBinop(node, UseInfo::TruncatingWord32(), kMachBool);
954 1089
955 case IrOpcode::kWord32Clz: 1090 case IrOpcode::kWord32Clz:
956 return VisitUnop(node, kMachUint32, kMachUint32); 1091 return VisitUnop(node, UseInfo::TruncatingWord32(), kMachUint32);
957 1092
958 case IrOpcode::kInt32Add: 1093 case IrOpcode::kInt32Add:
959 case IrOpcode::kInt32Sub: 1094 case IrOpcode::kInt32Sub:
960 case IrOpcode::kInt32Mul: 1095 case IrOpcode::kInt32Mul:
961 case IrOpcode::kInt32MulHigh: 1096 case IrOpcode::kInt32MulHigh:
962 case IrOpcode::kInt32Div: 1097 case IrOpcode::kInt32Div:
963 case IrOpcode::kInt32Mod: 1098 case IrOpcode::kInt32Mod:
964 return VisitInt32Binop(node); 1099 return VisitInt32Binop(node);
965 case IrOpcode::kUint32Div: 1100 case IrOpcode::kUint32Div:
966 case IrOpcode::kUint32Mod: 1101 case IrOpcode::kUint32Mod:
(...skipping 23 matching lines...) Expand all
990 case IrOpcode::kUint64Div: 1125 case IrOpcode::kUint64Div:
991 case IrOpcode::kUint64Mod: 1126 case IrOpcode::kUint64Mod:
992 return VisitUint64Binop(node); 1127 return VisitUint64Binop(node);
993 1128
994 case IrOpcode::kWord64And: 1129 case IrOpcode::kWord64And:
995 case IrOpcode::kWord64Or: 1130 case IrOpcode::kWord64Or:
996 case IrOpcode::kWord64Xor: 1131 case IrOpcode::kWord64Xor:
997 case IrOpcode::kWord64Shl: 1132 case IrOpcode::kWord64Shl:
998 case IrOpcode::kWord64Shr: 1133 case IrOpcode::kWord64Shr:
999 case IrOpcode::kWord64Sar: 1134 case IrOpcode::kWord64Sar:
1000 return VisitBinop(node, kRepWord64, kRepWord64); 1135 return VisitBinop(node, UseInfo::TruncatingWord64(), kRepWord64);
1001 case IrOpcode::kWord64Equal: 1136 case IrOpcode::kWord64Equal:
1002 return VisitBinop(node, kRepWord64, kRepBit); 1137 return VisitBinop(node, UseInfo::TruncatingWord64(), kMachBool);
1003 1138
1004 case IrOpcode::kChangeInt32ToInt64: 1139 case IrOpcode::kChangeInt32ToInt64:
1005 return VisitUnop(node, kTypeInt32 | kRepWord32, 1140 return VisitUnop(node, UseInfo::TruncatingWord32(),
1006 kTypeInt32 | kRepWord64); 1141 kTypeInt32 | kRepWord64);
1007 case IrOpcode::kChangeUint32ToUint64: 1142 case IrOpcode::kChangeUint32ToUint64:
1008 return VisitUnop(node, kTypeUint32 | kRepWord32, 1143 return VisitUnop(node, UseInfo::TruncatingWord32(),
1009 kTypeUint32 | kRepWord64); 1144 kTypeUint32 | kRepWord64);
1010 case IrOpcode::kTruncateFloat64ToFloat32: 1145 case IrOpcode::kTruncateFloat64ToFloat32:
1011 return VisitUnop(node, kTypeNumber | kRepFloat64, 1146 return VisitUnop(node, UseInfo::Float64(), kTypeNumber | kRepFloat32);
1012 kTypeNumber | kRepFloat32);
1013 case IrOpcode::kTruncateFloat64ToInt32: 1147 case IrOpcode::kTruncateFloat64ToInt32:
1014 return VisitUnop(node, kTypeNumber | kRepFloat64, 1148 return VisitUnop(node, UseInfo::Float64(), kTypeInt32 | kRepWord32);
1015 kTypeInt32 | kRepWord32);
1016 case IrOpcode::kTruncateInt64ToInt32: 1149 case IrOpcode::kTruncateInt64ToInt32:
1017 // TODO(titzer): Is kTypeInt32 correct here? 1150 // TODO(titzer): Is kTypeInt32 correct here?
1018 return VisitUnop(node, kTypeInt32 | kRepWord64, 1151 return VisitUnop(node, UseInfo::Word64TruncatingToWord32(),
1019 kTypeInt32 | kRepWord32); 1152 kTypeInt32 | kRepWord32);
1020 1153
1021 case IrOpcode::kChangeFloat32ToFloat64: 1154 case IrOpcode::kChangeFloat32ToFloat64:
1022 return VisitUnop(node, kTypeNumber | kRepFloat32, 1155 return VisitUnop(node, UseInfo::Float32(), kTypeNumber | kRepFloat64);
1023 kTypeNumber | kRepFloat64);
1024 case IrOpcode::kChangeInt32ToFloat64: 1156 case IrOpcode::kChangeInt32ToFloat64:
1025 return VisitUnop(node, kTypeInt32 | kRepWord32, 1157 return VisitUnop(node, UseInfo::TruncatingWord32(),
1026 kTypeInt32 | kRepFloat64); 1158 kTypeInt32 | kRepFloat64);
1027 case IrOpcode::kChangeUint32ToFloat64: 1159 case IrOpcode::kChangeUint32ToFloat64:
1028 return VisitUnop(node, kTypeUint32 | kRepWord32, 1160 return VisitUnop(node, UseInfo::TruncatingWord32(),
1029 kTypeUint32 | kRepFloat64); 1161 kTypeUint32 | kRepFloat64);
1030 case IrOpcode::kChangeFloat64ToInt32: 1162 case IrOpcode::kChangeFloat64ToInt32:
1031 return VisitUnop(node, kTypeInt32 | kRepFloat64, 1163 return VisitUnop(node, UseInfo::Float64TruncatingToWord32(),
1032 kTypeInt32 | kRepWord32); 1164 kTypeInt32 | kRepWord32);
1033 case IrOpcode::kChangeFloat64ToUint32: 1165 case IrOpcode::kChangeFloat64ToUint32:
1034 return VisitUnop(node, kTypeUint32 | kRepFloat64, 1166 return VisitUnop(node, UseInfo::Float64TruncatingToWord32(),
1035 kTypeUint32 | kRepWord32); 1167 kTypeUint32 | kRepWord32);
1036 1168
1037 case IrOpcode::kFloat64Add: 1169 case IrOpcode::kFloat64Add:
1038 case IrOpcode::kFloat64Sub: 1170 case IrOpcode::kFloat64Sub:
1039 case IrOpcode::kFloat64Mul: 1171 case IrOpcode::kFloat64Mul:
1040 case IrOpcode::kFloat64Div: 1172 case IrOpcode::kFloat64Div:
1041 case IrOpcode::kFloat64Mod: 1173 case IrOpcode::kFloat64Mod:
1042 case IrOpcode::kFloat64Min: 1174 case IrOpcode::kFloat64Min:
1043 return VisitFloat64Binop(node); 1175 return VisitFloat64Binop(node);
1044 case IrOpcode::kFloat64Abs: 1176 case IrOpcode::kFloat64Abs:
1045 case IrOpcode::kFloat64Sqrt: 1177 case IrOpcode::kFloat64Sqrt:
1046 case IrOpcode::kFloat64RoundDown: 1178 case IrOpcode::kFloat64RoundDown:
1047 case IrOpcode::kFloat64RoundTruncate: 1179 case IrOpcode::kFloat64RoundTruncate:
1048 case IrOpcode::kFloat64RoundTiesAway: 1180 case IrOpcode::kFloat64RoundTiesAway:
1049 return VisitUnop(node, kMachFloat64, kMachFloat64); 1181 return VisitUnop(node, UseInfo::Float64(), kMachFloat64);
1050 case IrOpcode::kFloat64Equal: 1182 case IrOpcode::kFloat64Equal:
1051 case IrOpcode::kFloat64LessThan: 1183 case IrOpcode::kFloat64LessThan:
1052 case IrOpcode::kFloat64LessThanOrEqual: 1184 case IrOpcode::kFloat64LessThanOrEqual:
1053 return VisitFloat64Cmp(node); 1185 return VisitFloat64Cmp(node);
1054 case IrOpcode::kFloat64ExtractLowWord32: 1186 case IrOpcode::kFloat64ExtractLowWord32:
1055 case IrOpcode::kFloat64ExtractHighWord32: 1187 case IrOpcode::kFloat64ExtractHighWord32:
1056 return VisitUnop(node, kMachFloat64, kMachInt32); 1188 return VisitUnop(node, UseInfo::Float64(), kMachInt32);
1057 case IrOpcode::kFloat64InsertLowWord32: 1189 case IrOpcode::kFloat64InsertLowWord32:
1058 case IrOpcode::kFloat64InsertHighWord32: 1190 case IrOpcode::kFloat64InsertHighWord32:
1059 return VisitBinop(node, kMachFloat64, kMachInt32, kMachFloat64); 1191 return VisitBinop(node, UseInfo::Float64(), UseInfo::TruncatingWord32(),
1192 kMachFloat64);
1060 case IrOpcode::kLoadStackPointer: 1193 case IrOpcode::kLoadStackPointer:
1061 case IrOpcode::kLoadFramePointer: 1194 case IrOpcode::kLoadFramePointer:
1062 return VisitLeaf(node, kMachPtr); 1195 return VisitLeaf(node, kMachPtr);
1063 case IrOpcode::kStateValues: 1196 case IrOpcode::kStateValues:
1064 VisitStateValues(node); 1197 VisitStateValues(node);
1065 break; 1198 break;
1066 default: 1199 default:
1067 VisitInputs(node); 1200 VisitInputs(node);
1068 break; 1201 break;
1069 } 1202 }
(...skipping 26 matching lines...) Expand all
1096 TRACE("\n"); 1229 TRACE("\n");
1097 } 1230 }
1098 1231
1099 void PrintInfo(MachineTypeUnion info) { 1232 void PrintInfo(MachineTypeUnion info) {
1100 if (FLAG_trace_representation) { 1233 if (FLAG_trace_representation) {
1101 OFStream os(stdout); 1234 OFStream os(stdout);
1102 os << static_cast<MachineType>(info); 1235 os << static_cast<MachineType>(info);
1103 } 1236 }
1104 } 1237 }
1105 1238
1239 void PrintUseInfo(UseInfo info) {
1240 if (FLAG_trace_representation) {
1241 OFStream os(stdout);
1242 os << static_cast<MachineType>(info.machine_type());
1243 }
1244 }
1245
1106 private: 1246 private:
1107 JSGraph* jsgraph_; 1247 JSGraph* jsgraph_;
1108 size_t const count_; // number of nodes in the graph 1248 size_t const count_; // number of nodes in the graph
1109 NodeInfo* info_; // node id -> usage information 1249 NodeInfo* info_; // node id -> usage information
1110 NodeVector nodes_; // collected nodes 1250 NodeVector nodes_; // collected nodes
1111 NodeVector replacements_; // replacements to be done after lowering 1251 NodeVector replacements_; // replacements to be done after lowering
1112 Phase phase_; // current phase of algorithm 1252 Phase phase_; // current phase of algorithm
1113 RepresentationChanger* changer_; // for inserting representation changes 1253 RepresentationChanger* changer_; // for inserting representation changes
1114 ZoneQueue<Node*> queue_; // queue for traversing the graph 1254 ZoneQueue<Node*> queue_; // queue for traversing the graph
1115 // TODO(danno): RepresentationSelector shouldn't know anything about the 1255 // TODO(danno): RepresentationSelector shouldn't know anything about the
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after
1564 ReplaceEffectUses(node, comparison); 1704 ReplaceEffectUses(node, comparison);
1565 node->ReplaceInput(0, comparison); 1705 node->ReplaceInput(0, comparison);
1566 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); 1706 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL));
1567 node->TrimInputCount(2); 1707 node->TrimInputCount(2);
1568 NodeProperties::ChangeOp(node, machine()->IntLessThanOrEqual()); 1708 NodeProperties::ChangeOp(node, machine()->IntLessThanOrEqual());
1569 } 1709 }
1570 1710
1571 } // namespace compiler 1711 } // namespace compiler
1572 } // namespace internal 1712 } // namespace internal
1573 } // namespace v8 1713 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/representation-change.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698