Index: src/compiler/simplified-lowering.cc |
diff --git a/src/compiler/simplified-lowering.cc b/src/compiler/simplified-lowering.cc |
index ff48d34ef80ba182da5aa4c4d66b518114275f37..0f784c650e1d22b689c4d3e649341f0ac5d8ac19 100644 |
--- a/src/compiler/simplified-lowering.cc |
+++ b/src/compiler/simplified-lowering.cc |
@@ -296,61 +296,46 @@ class RepresentationSelector { |
void VisitInt64Cmp(Node* node) { VisitBinop(node, kMachInt64, kRepBit); } |
void VisitUint64Cmp(Node* node) { VisitBinop(node, kMachUint64, kRepBit); } |
- // Helper for handling selects. |
- // TODO(turbofan): Share some code with VisitPhi() below? |
- void VisitSelect(Node* node, MachineTypeUnion use, |
- SimplifiedLowering* lowering) { |
- ProcessInput(node, 0, kRepBit); |
- |
- // Selects adapt to the output representation their uses demand, pushing |
- // representation changes to their inputs. |
+ // Infer representation for phi-like nodes. |
+ MachineType GetRepresentationForPhi(Node* node, MachineTypeUnion use) { |
+ // Phis adapt to the output representation their uses demand. |
Type* upper = NodeProperties::GetBounds(node).upper; |
- 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) { |
+ if ((use & kRepMask) == kRepTagged) { |
+ // only tagged uses. |
+ return kRepTagged; |
+ } else if (IsSafeIntAdditiveOperand(node)) { |
+ // Integer within [-2^52, 2^52] range. |
+ if ((use & kRepMask) == kRepFloat64) { |
// only float64 uses. |
- output = kRepFloat64; |
- propagate = kRepFloat64; |
+ return kRepFloat64; |
+ } else if (upper->Is(Type::Signed32()) || upper->Is(Type::Unsigned32())) { |
+ // multiple uses, but we are within 32 bits range => pick kRepWord32. |
+ return kRepWord32; |
+ } else if ((use & kRepMask) == kRepWord32 || |
+ (use & kTypeMask) == kTypeInt32 || |
+ (use & kTypeMask) == kTypeUint32) { |
+ // The type is a safe integer, but we only use 32 bits. |
+ return kRepWord32; |
} else { |
- // multiple uses. |
- output = kRepWord32; |
- propagate = kRepWord32; |
+ return kRepFloat64; |
} |
} 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; |
- } |
+ // multiple uses => pick kRepBit. |
+ return 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; |
+ // multiple uses => pick kRepFloat64. |
+ return kRepFloat64; |
} |
+ return kRepTagged; |
+ } |
+ |
+ // Helper for handling selects. |
+ void VisitSelect(Node* node, MachineTypeUnion use, |
+ SimplifiedLowering* lowering) { |
+ ProcessInput(node, 0, kRepBit); |
+ MachineType output = GetRepresentationForPhi(node, use); |
+ Type* upper = NodeProperties::GetBounds(node).upper; |
MachineType output_type = |
static_cast<MachineType>(changer_->TypeFromUpperBound(upper) | output); |
SetOutput(node, output_type); |
@@ -369,7 +354,7 @@ class RepresentationSelector { |
} else { |
// Propagate {use} of the select to value inputs. |
MachineType use_type = |
- static_cast<MachineType>((use & kTypeMask) | propagate); |
+ static_cast<MachineType>((use & kTypeMask) | output); |
ProcessInput(node, 1, use_type); |
ProcessInput(node, 2, use_type); |
} |
@@ -378,55 +363,9 @@ class RepresentationSelector { |
// Helper for handling phis. |
void VisitPhi(Node* node, MachineTypeUnion use, |
SimplifiedLowering* lowering) { |
- // Phis adapt to the output representation their uses demand, pushing |
- // representation changes to their inputs. |
- Type* upper = NodeProperties::GetBounds(node).upper; |
- 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 { |
- // 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 { |
- // legal = kRepTagged; |
- output = kRepTagged; |
- propagate = kRepTagged; |
- } |
+ MachineType output = GetRepresentationForPhi(node, use); |
+ Type* upper = NodeProperties::GetBounds(node).upper; |
MachineType output_type = |
static_cast<MachineType>(changer_->TypeFromUpperBound(upper) | output); |
SetOutput(node, output_type); |
@@ -451,7 +390,7 @@ class RepresentationSelector { |
// 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); |
+ static_cast<MachineType>((use & kTypeMask) | output); |
for (Node::Inputs::iterator iter(inputs.begin()); iter != inputs.end(); |
++iter, --values) { |
// TODO(titzer): it'd be nice to have distinguished edge kinds here. |
@@ -725,13 +664,15 @@ class RepresentationSelector { |
case IrOpcode::kNumberToInt32: { |
MachineTypeUnion use_rep = use & kRepMask; |
Node* input = node->InputAt(0); |
+ Type* in_upper = NodeProperties::GetBounds(input).upper; |
MachineTypeUnion in = GetInfo(input)->output; |
- if (NodeProperties::GetBounds(input).upper->Is(Type::Signed32())) { |
+ if (in_upper->Is(Type::Signed32())) { |
// If the input has type int32, pass through representation. |
VisitUnop(node, kTypeInt32 | use_rep, kTypeInt32 | use_rep); |
if (lower()) DeferReplacement(node, node->InputAt(0)); |
} else if ((in & kTypeMask) == kTypeUint32 || |
(in & kTypeMask) == kTypeInt32 || |
+ in_upper->Is(Type::Unsigned32()) || |
(in & kRepMask) == kRepWord32) { |
// Just change representation if necessary. |
VisitUnop(node, kTypeInt32 | kRepWord32, kTypeInt32 | kRepWord32); |
@@ -748,13 +689,15 @@ class RepresentationSelector { |
case IrOpcode::kNumberToUint32: { |
MachineTypeUnion use_rep = use & kRepMask; |
Node* input = node->InputAt(0); |
+ Type* in_upper = NodeProperties::GetBounds(input).upper; |
MachineTypeUnion in = GetInfo(input)->output; |
- if (NodeProperties::GetBounds(input).upper->Is(Type::Unsigned32())) { |
+ if (in_upper->Is(Type::Unsigned32())) { |
// If the input has type uint32, pass through representation. |
VisitUnop(node, kTypeUint32 | use_rep, kTypeUint32 | use_rep); |
if (lower()) DeferReplacement(node, node->InputAt(0)); |
} else if ((in & kTypeMask) == kTypeUint32 || |
(in & kTypeMask) == kTypeInt32 || |
+ in_upper->Is(Type::Signed32()) || |
(in & kRepMask) == kRepWord32) { |
// Just change representation if necessary. |
VisitUnop(node, kTypeUint32 | kRepWord32, kTypeUint32 | kRepWord32); |