Commit c605a8c1 authored by titzer@chromium.org's avatar titzer@chromium.org

Smarter representation selection for phis.

R=jarin@chromium.org
BUG=

Review URL: https://codereview.chromium.org/641713002

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24474 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 8659e507
...@@ -273,62 +273,62 @@ class RepresentationSelector { ...@@ -273,62 +273,62 @@ class RepresentationSelector {
// Helper for handling phis. // Helper for handling phis.
void VisitPhi(Node* node, MachineTypeUnion use, void VisitPhi(Node* node, MachineTypeUnion use,
SimplifiedLowering* lowering) { SimplifiedLowering* lowering) {
// First, propagate the usage information to inputs of the phi. // Phis adapt to the output representation their uses demand, pushing
if (!lower()) { // representation changes to their inputs.
int values = OperatorProperties::GetValueInputCount(node->op());
// Propagate {use} of the phi to value inputs, and 0 to control.
Node::Inputs inputs = node->inputs();
for (Node::Inputs::iterator iter(inputs.begin()); iter != inputs.end();
++iter, --values) {
// TODO(titzer): it'd be nice to have distinguished edge kinds here.
ProcessInput(node, iter.index(), values > 0 ? use : 0);
}
}
// Phis adapt to whatever output representation their uses demand,
// pushing representation changes to their inputs.
MachineTypeUnion use_rep = GetUseInfo(node) & kRepMask;
Type* upper = NodeProperties::GetBounds(node).upper; Type* upper = NodeProperties::GetBounds(node).upper;
MachineTypeUnion phi_type = changer_->TypeFromUpperBound(upper); MachineType output = kMachNone;
MachineTypeUnion rep = 0; MachineType propagate = kMachNone;
if (use_rep & kRepTagged) {
rep = kRepTagged; // Tagged overrides everything. if (upper->Is(Type::Signed32()) || upper->Is(Type::Unsigned32())) {
} else if (use_rep & kRepFloat32) { // legal = kRepTagged | kRepFloat64 | kRepWord32;
rep = kRepFloat32; if ((use & kRepMask) == kRepTagged) {
} else if (use_rep & kRepFloat64) { // only tagged uses.
rep = kRepFloat64; output = kRepTagged;
} else if (use_rep & kRepWord64) { propagate = kRepTagged;
rep = kRepWord64; } else if ((use & kRepMask) == kRepFloat64) {
} else if (use_rep & kRepWord32) { // only float64 uses.
if (phi_type & kTypeNumber) { output = kRepFloat64;
rep = kRepFloat64; propagate = kRepFloat64;
} else { } else {
rep = kRepWord32; // multiple uses.
output = kRepWord32;
propagate = kRepWord32;
} }
} else if (use_rep & kRepBit) { } else if (upper->Is(Type::Boolean())) {
rep = kRepBit; // legal = kRepTagged | kRepBit;
} else { if ((use & kRepMask) == kRepTagged) {
// There was no representation associated with any of the uses. // only tagged uses.
if (phi_type & kTypeAny) { output = kRepTagged;
rep = kRepTagged; propagate = kRepTagged;
} else if (phi_type & kTypeNumber) {
rep = kRepFloat64;
} else if (phi_type & kTypeInt64 || phi_type & kTypeUint64) {
rep = kRepWord64;
} else if (phi_type & kTypeInt32 || phi_type & kTypeUint32) {
rep = kRepWord32;
} else if (phi_type & kTypeBool) {
rep = kRepBit;
} else { } else {
UNREACHABLE(); // should have at least a usage type! // multiple uses.
output = kRepBit;
propagate = kRepBit;
} }
} else if (upper->Is(Type::Number())) {
// legal = kRepTagged | kRepFloat64;
if ((use & kRepMask) == kRepTagged) {
// only tagged uses.
output = kRepTagged;
propagate = kRepTagged;
} else {
// multiple uses.
output = kRepFloat64;
propagate = kRepFloat64;
}
} else {
// legal = kRepTagged;
output = kRepTagged;
propagate = kRepTagged;
} }
// Preserve the usage type, but set the representation.
MachineTypeUnion output_type = rep | phi_type; MachineType output_type =
static_cast<MachineType>(changer_->TypeFromUpperBound(upper) | output);
SetOutput(node, output_type); SetOutput(node, output_type);
if (lower()) { int values = OperatorProperties::GetValueInputCount(node->op());
int values = OperatorProperties::GetValueInputCount(node->op());
if (lower()) {
// Update the phi operator. // Update the phi operator.
MachineType type = static_cast<MachineType>(output_type); MachineType type = static_cast<MachineType>(output_type);
if (type != OpParameter<MachineType>(node)) { if (type != OpParameter<MachineType>(node)) {
...@@ -342,6 +342,16 @@ class RepresentationSelector { ...@@ -342,6 +342,16 @@ class RepresentationSelector {
// TODO(titzer): it'd be nice to have distinguished edge kinds here. // TODO(titzer): it'd be nice to have distinguished edge kinds here.
ProcessInput(node, iter.index(), values > 0 ? output_type : 0); ProcessInput(node, iter.index(), values > 0 ? output_type : 0);
} }
} else {
// Propagate {use} of the phi to value inputs, and 0 to control.
Node::Inputs inputs = node->inputs();
MachineType use_type =
static_cast<MachineType>((use & kTypeMask) | propagate);
for (Node::Inputs::iterator iter(inputs.begin()); iter != inputs.end();
++iter, --values) {
// TODO(titzer): it'd be nice to have distinguished edge kinds here.
ProcessInput(node, iter.index(), values > 0 ? use_type : 0);
}
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment