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

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