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

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

Issue 641713002: Smarter representation selection for phis. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | 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 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 } 266 }
267 void VisitFloat64Cmp(Node* node) { VisitBinop(node, kMachFloat64, kRepBit); } 267 void VisitFloat64Cmp(Node* node) { VisitBinop(node, kMachFloat64, kRepBit); }
268 void VisitInt32Cmp(Node* node) { VisitBinop(node, kMachInt32, kRepBit); } 268 void VisitInt32Cmp(Node* node) { VisitBinop(node, kMachInt32, kRepBit); }
269 void VisitUint32Cmp(Node* node) { VisitBinop(node, kMachUint32, kRepBit); } 269 void VisitUint32Cmp(Node* node) { VisitBinop(node, kMachUint32, kRepBit); }
270 void VisitInt64Cmp(Node* node) { VisitBinop(node, kMachInt64, kRepBit); } 270 void VisitInt64Cmp(Node* node) { VisitBinop(node, kMachInt64, kRepBit); }
271 void VisitUint64Cmp(Node* node) { VisitBinop(node, kMachUint64, kRepBit); } 271 void VisitUint64Cmp(Node* node) { VisitBinop(node, kMachUint64, kRepBit); }
272 272
273 // Helper for handling phis. 273 // Helper for handling phis.
274 void VisitPhi(Node* node, MachineTypeUnion use, 274 void VisitPhi(Node* node, MachineTypeUnion use,
275 SimplifiedLowering* lowering) { 275 SimplifiedLowering* lowering) {
276 // First, propagate the usage information to inputs of the phi. 276 // Phis adapt to the output representation their uses demand, pushing
277 if (!lower()) { 277 // representation changes to their inputs.
278 int values = OperatorProperties::GetValueInputCount(node->op()); 278 Type* upper = NodeProperties::GetBounds(node).upper;
279 // Propagate {use} of the phi to value inputs, and 0 to control. 279 MachineType output = kMachNone;
280 Node::Inputs inputs = node->inputs(); 280 MachineType prop = kMachNone;
Jarin 2014/10/08 15:12:03 How about expanding to {propagate}?
titzer 2014/10/15 11:51:49 Done.
281 for (Node::Inputs::iterator iter(inputs.begin()); iter != inputs.end(); 281
282 ++iter, --values) { 282 if (upper->Is(Type::Signed32()) || upper->Is(Type::Unsigned32())) {
283 // TODO(titzer): it'd be nice to have distinguished edge kinds here. 283 // legal = kRepTagged | kRepFloat64 | kRepWord32;
284 ProcessInput(node, iter.index(), values > 0 ? use : 0); 284 if ((use & kRepMask) == kRepTagged) {
285 // only tagged uses.
286 output = kRepTagged;
287 prop = kRepTagged;
288 } else if ((use & kRepMask) == kRepFloat64) {
289 // only float64 uses.
290 output = kRepFloat64;
291 prop = kRepFloat64;
292 } else {
293 // multiple uses.
294 output = kRepWord32;
295 prop = kRepWord32;
285 } 296 }
297 } else if (upper->Is(Type::Boolean())) {
298 // legal = kRepTagged | kRepBit;
299 if ((use & kRepMask) == kRepTagged) {
300 // only tagged uses.
301 output = kRepTagged;
302 prop = kRepTagged;
303 } else {
304 // multiple uses.
305 output = kRepBit;
306 prop = kRepBit;
307 }
308 } else if (upper->Is(Type::Number())) {
309 // legal = kRepTagged | kRepFloat64;
310 if ((use & kRepMask) == kRepTagged) {
311 // only tagged uses.
312 output = kRepTagged;
313 prop = kRepTagged;
314 } else {
315 // multiple uses.
316 output = kRepFloat64;
317 prop = kRepFloat64;
318 }
319 } else {
320 // legal = kRepTagged;
321 output = kRepTagged;
322 prop = kRepTagged;
286 } 323 }
287 // Phis adapt to whatever output representation their uses demand, 324
288 // pushing representation changes to their inputs. 325 MachineType output_type =
289 MachineTypeUnion use_rep = GetUseInfo(node) & kRepMask; 326 static_cast<MachineType>(changer_->TypeFromUpperBound(upper) | output);
290 Type* upper = NodeProperties::GetBounds(node).upper;
291 MachineTypeUnion phi_type = changer_->TypeFromUpperBound(upper);
292 MachineTypeUnion rep = 0;
293 if (use_rep & kRepTagged) {
294 rep = kRepTagged; // Tagged overrides everything.
295 } else if (use_rep & kRepFloat32) {
296 rep = kRepFloat32;
297 } else if (use_rep & kRepFloat64) {
298 rep = kRepFloat64;
299 } else if (use_rep & kRepWord64) {
300 rep = kRepWord64;
301 } else if (use_rep & kRepWord32) {
302 if (phi_type & kTypeNumber) {
303 rep = kRepFloat64;
304 } else {
305 rep = kRepWord32;
306 }
307 } else if (use_rep & kRepBit) {
308 rep = kRepBit;
309 } else {
310 // There was no representation associated with any of the uses.
311 if (phi_type & kTypeAny) {
312 rep = kRepTagged;
313 } else if (phi_type & kTypeNumber) {
314 rep = kRepFloat64;
315 } else if (phi_type & kTypeInt64 || phi_type & kTypeUint64) {
316 rep = kRepWord64;
317 } else if (phi_type & kTypeInt32 || phi_type & kTypeUint32) {
318 rep = kRepWord32;
319 } else if (phi_type & kTypeBool) {
320 rep = kRepBit;
321 } else {
322 UNREACHABLE(); // should have at least a usage type!
323 }
324 }
325 // Preserve the usage type, but set the representation.
326 MachineTypeUnion output_type = rep | phi_type;
327 SetOutput(node, output_type); 327 SetOutput(node, output_type);
328 328
329 int values = OperatorProperties::GetValueInputCount(node->op());
330
329 if (lower()) { 331 if (lower()) {
330 int values = OperatorProperties::GetValueInputCount(node->op());
331
332 // Update the phi operator. 332 // Update the phi operator.
333 MachineType type = static_cast<MachineType>(output_type); 333 MachineType type = static_cast<MachineType>(output_type);
334 if (type != OpParameter<MachineType>(node)) { 334 if (type != OpParameter<MachineType>(node)) {
335 node->set_op(lowering->common()->Phi(type, values)); 335 node->set_op(lowering->common()->Phi(type, values));
336 } 336 }
337 337
338 // Convert inputs to the output representation of this phi. 338 // Convert inputs to the output representation of this phi.
339 Node::Inputs inputs = node->inputs(); 339 Node::Inputs inputs = node->inputs();
340 for (Node::Inputs::iterator iter(inputs.begin()); iter != inputs.end(); 340 for (Node::Inputs::iterator iter(inputs.begin()); iter != inputs.end();
341 ++iter, --values) { 341 ++iter, --values) {
342 // TODO(titzer): it'd be nice to have distinguished edge kinds here. 342 // TODO(titzer): it'd be nice to have distinguished edge kinds here.
343 ProcessInput(node, iter.index(), values > 0 ? output_type : 0); 343 ProcessInput(node, iter.index(), values > 0 ? output_type : 0);
344 } 344 }
345 } else {
346 // Propagate {use} of the phi to value inputs, and 0 to control.
347 Node::Inputs inputs = node->inputs();
348 MachineType use_type = static_cast<MachineType>((use & kTypeMask) | prop);
349 for (Node::Inputs::iterator iter(inputs.begin()); iter != inputs.end();
350 ++iter, --values) {
351 // TODO(titzer): it'd be nice to have distinguished edge kinds here.
352 ProcessInput(node, iter.index(), values > 0 ? use_type : 0);
353 }
345 } 354 }
346 } 355 }
347 356
348 const Operator* Int32Op(Node* node) { 357 const Operator* Int32Op(Node* node) {
349 return changer_->Int32OperatorFor(node->opcode()); 358 return changer_->Int32OperatorFor(node->opcode());
350 } 359 }
351 360
352 const Operator* Uint32Op(Node* node) { 361 const Operator* Uint32Op(Node* node) {
353 return changer_->Uint32OperatorFor(node->opcode()); 362 return changer_->Uint32OperatorFor(node->opcode());
354 } 363 }
(...skipping 769 matching lines...) Expand 10 before | Expand all | Expand 10 after
1124 void SimplifiedLowering::DoStringLessThanOrEqual(Node* node) { 1133 void SimplifiedLowering::DoStringLessThanOrEqual(Node* node) {
1125 node->set_op(machine()->IntLessThanOrEqual()); 1134 node->set_op(machine()->IntLessThanOrEqual());
1126 node->ReplaceInput(0, StringComparison(node, true)); 1135 node->ReplaceInput(0, StringComparison(node, true));
1127 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); 1136 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL));
1128 } 1137 }
1129 1138
1130 1139
1131 } // namespace compiler 1140 } // namespace compiler
1132 } // namespace internal 1141 } // namespace internal
1133 } // namespace v8 1142 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698