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
This commit is contained in:
titzer@chromium.org 2014-10-08 16:01:18 +00:00
parent 8659e50723
commit c605a8c1da

View File

@ -273,62 +273,62 @@ class RepresentationSelector {
// Helper for handling phis.
void VisitPhi(Node* node, MachineTypeUnion use,
SimplifiedLowering* lowering) {
// First, propagate the usage information to inputs of the phi.
if (!lower()) {
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;
// Phis adapt to the output representation their uses demand, pushing
// representation changes to their inputs.
Type* upper = NodeProperties::GetBounds(node).upper;
MachineTypeUnion phi_type = changer_->TypeFromUpperBound(upper);
MachineTypeUnion rep = 0;
if (use_rep & kRepTagged) {
rep = kRepTagged; // Tagged overrides everything.
} else if (use_rep & kRepFloat32) {
rep = kRepFloat32;
} else if (use_rep & kRepFloat64) {
rep = kRepFloat64;
} else if (use_rep & kRepWord64) {
rep = kRepWord64;
} else if (use_rep & kRepWord32) {
if (phi_type & kTypeNumber) {
rep = kRepFloat64;
MachineType output = kMachNone;
MachineType propagate = kMachNone;
if (upper->Is(Type::Signed32()) || upper->Is(Type::Unsigned32())) {
// legal = kRepTagged | kRepFloat64 | kRepWord32;
if ((use & kRepMask) == kRepTagged) {
// only tagged uses.
output = kRepTagged;
propagate = kRepTagged;
} else if ((use & kRepMask) == kRepFloat64) {
// only float64 uses.
output = kRepFloat64;
propagate = kRepFloat64;
} else {
rep = kRepWord32;
// multiple uses.
output = kRepWord32;
propagate = kRepWord32;
}
} else if (upper->Is(Type::Boolean())) {
// legal = kRepTagged | kRepBit;
if ((use & kRepMask) == kRepTagged) {
// only tagged uses.
output = kRepTagged;
propagate = kRepTagged;
} else {
// 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 if (use_rep & kRepBit) {
rep = kRepBit;
} else {
// There was no representation associated with any of the uses.
if (phi_type & kTypeAny) {
rep = 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 {
UNREACHABLE(); // should have at least a usage type!
}
// 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);
if (lower()) {
int values = OperatorProperties::GetValueInputCount(node->op());
int values = OperatorProperties::GetValueInputCount(node->op());
if (lower()) {
// Update the phi operator.
MachineType type = static_cast<MachineType>(output_type);
if (type != OpParameter<MachineType>(node)) {
@ -342,6 +342,16 @@ class RepresentationSelector {
// TODO(titzer): it'd be nice to have distinguished edge kinds here.
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);
}
}
}