Commit 861295bf authored by bmeurer's avatar bmeurer Committed by Commit bot

[turbofan] Optimize tagged conversion based on type.

If we have to convert a float64 value to tagged representation and we
already know that the value is either in Signed31/Signed32 or
Unsigned32 range, then we can just convert the float64 to word32 and
use the fast word32 to tagged conversion. Doing this in
ChangeLowering (or the effect linearization pass) would be unsound, as
the types on the nodes are no longer usable.

This removes all Type uses from effect linearization. There's still some
work to be done for ChangeLowering tho.

R=jarin@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#35713}
parent fa8bac65
...@@ -29,6 +29,8 @@ Reduction ChangeLowering::Reduce(Node* node) { ...@@ -29,6 +29,8 @@ Reduction ChangeLowering::Reduce(Node* node) {
return ChangeBoolToBit(node->InputAt(0)); return ChangeBoolToBit(node->InputAt(0));
case IrOpcode::kChangeFloat64ToTagged: case IrOpcode::kChangeFloat64ToTagged:
return ChangeFloat64ToTagged(node->InputAt(0), control); return ChangeFloat64ToTagged(node->InputAt(0), control);
case IrOpcode::kChangeInt31ToTagged:
return ChangeInt31ToTagged(node->InputAt(0), control);
case IrOpcode::kChangeInt32ToTagged: case IrOpcode::kChangeInt32ToTagged:
return ChangeInt32ToTagged(node->InputAt(0), control); return ChangeInt32ToTagged(node->InputAt(0), control);
case IrOpcode::kChangeSmiToInt32: case IrOpcode::kChangeSmiToInt32:
...@@ -177,15 +179,8 @@ Reduction ChangeLowering::ChangeBoolToBit(Node* value) { ...@@ -177,15 +179,8 @@ Reduction ChangeLowering::ChangeBoolToBit(Node* value) {
Reduction ChangeLowering::ChangeFloat64ToTagged(Node* value, Node* control) { Reduction ChangeLowering::ChangeFloat64ToTagged(Node* value, Node* control) {
Type* const value_type = NodeProperties::GetType(value); Node* value32 = graph()->NewNode(
Node* const value32 = graph()->NewNode(
machine()->TruncateFloat64ToInt32(TruncationMode::kRoundToZero), value); machine()->TruncateFloat64ToInt32(TruncationMode::kRoundToZero), value);
// TODO(bmeurer): This fast case must be disabled until we kill the asm.js
// support in the generic JavaScript pipeline, because LoadBuffer is lying
// about its result.
// if (value_type->Is(Type::Signed32())) {
// return ChangeInt32ToTagged(value32, control);
// }
Node* check_same = graph()->NewNode( Node* check_same = graph()->NewNode(
machine()->Float64Equal(), value, machine()->Float64Equal(), value,
graph()->NewNode(machine()->ChangeInt32ToFloat64(), value32)); graph()->NewNode(machine()->ChangeInt32ToFloat64(), value32));
...@@ -196,36 +191,33 @@ Reduction ChangeLowering::ChangeFloat64ToTagged(Node* value, Node* control) { ...@@ -196,36 +191,33 @@ Reduction ChangeLowering::ChangeFloat64ToTagged(Node* value, Node* control) {
Node* if_box = graph()->NewNode(common()->IfFalse(), branch_same); Node* if_box = graph()->NewNode(common()->IfFalse(), branch_same);
Node* vbox; Node* vbox;
// We only need to check for -0 if the {value} can potentially contain -0. // Check if {value} is -0.
if (value_type->Maybe(Type::MinusZero())) { Node* check_zero = graph()->NewNode(machine()->Word32Equal(), value32,
Node* check_zero = graph()->NewNode(machine()->Word32Equal(), value32, jsgraph()->Int32Constant(0));
jsgraph()->Int32Constant(0)); Node* branch_zero = graph()->NewNode(common()->Branch(BranchHint::kFalse),
Node* branch_zero = graph()->NewNode(common()->Branch(BranchHint::kFalse), check_zero, if_smi);
check_zero, if_smi);
Node* if_zero = graph()->NewNode(common()->IfTrue(), branch_zero);
Node* if_zero = graph()->NewNode(common()->IfTrue(), branch_zero); Node* if_notzero = graph()->NewNode(common()->IfFalse(), branch_zero);
Node* if_notzero = graph()->NewNode(common()->IfFalse(), branch_zero);
// In case of 0, we need to check the high bits for the IEEE -0 pattern.
// In case of 0, we need to check the high bits for the IEEE -0 pattern. Node* check_negative = graph()->NewNode(
Node* check_negative = graph()->NewNode( machine()->Int32LessThan(),
machine()->Int32LessThan(), graph()->NewNode(machine()->Float64ExtractHighWord32(), value),
graph()->NewNode(machine()->Float64ExtractHighWord32(), value), jsgraph()->Int32Constant(0));
jsgraph()->Int32Constant(0)); Node* branch_negative = graph()->NewNode(common()->Branch(BranchHint::kFalse),
Node* branch_negative = graph()->NewNode( check_negative, if_zero);
common()->Branch(BranchHint::kFalse), check_negative, if_zero);
Node* if_negative = graph()->NewNode(common()->IfTrue(), branch_negative);
Node* if_negative = graph()->NewNode(common()->IfTrue(), branch_negative); Node* if_notnegative = graph()->NewNode(common()->IfFalse(), branch_negative);
Node* if_notnegative =
graph()->NewNode(common()->IfFalse(), branch_negative); // We need to create a box for negative 0.
if_smi = graph()->NewNode(common()->Merge(2), if_notzero, if_notnegative);
// We need to create a box for negative 0. if_box = graph()->NewNode(common()->Merge(2), if_box, if_negative);
if_smi = graph()->NewNode(common()->Merge(2), if_notzero, if_notnegative);
if_box = graph()->NewNode(common()->Merge(2), if_box, if_negative);
}
// On 64-bit machines we can just wrap the 32-bit integer in a smi, for 32-bit // On 64-bit machines we can just wrap the 32-bit integer in a smi, for 32-bit
// machines we need to deal with potential overflow and fallback to boxing. // machines we need to deal with potential overflow and fallback to boxing.
if (machine()->Is64() || value_type->Is(Type::SignedSmall())) { if (machine()->Is64()) {
vsmi = ChangeInt32ToSmi(value32); vsmi = ChangeInt32ToSmi(value32);
} else { } else {
Node* smi_tag = Node* smi_tag =
...@@ -251,31 +243,33 @@ Reduction ChangeLowering::ChangeFloat64ToTagged(Node* value, Node* control) { ...@@ -251,31 +243,33 @@ Reduction ChangeLowering::ChangeFloat64ToTagged(Node* value, Node* control) {
return Replace(value); return Replace(value);
} }
Reduction ChangeLowering::ChangeInt31ToTagged(Node* value, Node* control) {
return Replace(ChangeInt32ToSmi(value));
}
Reduction ChangeLowering::ChangeInt32ToTagged(Node* value, Node* control) { Reduction ChangeLowering::ChangeInt32ToTagged(Node* value, Node* control) {
if (machine()->Is64() || if (machine()->Is64()) {
NodeProperties::GetType(value)->Is(Type::SignedSmall())) { value = ChangeInt32ToSmi(value);
return Replace(ChangeInt32ToSmi(value)); } else {
} Node* add =
graph()->NewNode(machine()->Int32AddWithOverflow(), value, value);
Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(), value, value);
Node* ovf = graph()->NewNode(common()->Projection(1), add);
Node* branch =
graph()->NewNode(common()->Branch(BranchHint::kFalse), ovf, control);
Node* if_true = graph()->NewNode(common()->IfTrue(), branch); Node* ovf = graph()->NewNode(common()->Projection(1), add);
Node* vtrue = Node* branch =
AllocateHeapNumberWithValue(ChangeInt32ToFloat64(value), if_true); graph()->NewNode(common()->Branch(BranchHint::kFalse), ovf, control);
Node* if_false = graph()->NewNode(common()->IfFalse(), branch); Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
Node* vfalse = graph()->NewNode(common()->Projection(0), add); Node* vtrue =
AllocateHeapNumberWithValue(ChangeInt32ToFloat64(value), if_true);
Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
Node* phi = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), Node* vfalse = graph()->NewNode(common()->Projection(0), add);
vtrue, vfalse, merge);
return Replace(phi); control = graph()->NewNode(common()->Merge(2), if_true, if_false);
value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
vtrue, vfalse, control);
}
return Replace(value);
} }
Reduction ChangeLowering::ChangeSmiToInt32(Node* value) { Reduction ChangeLowering::ChangeSmiToInt32(Node* value) {
...@@ -382,10 +376,6 @@ Reduction ChangeLowering::ChangeTaggedToFloat64(Node* value, Node* control) { ...@@ -382,10 +376,6 @@ Reduction ChangeLowering::ChangeTaggedToFloat64(Node* value, Node* control) {
Reduction ChangeLowering::ChangeUint32ToTagged(Node* value, Node* control) { Reduction ChangeLowering::ChangeUint32ToTagged(Node* value, Node* control) {
if (NodeProperties::GetType(value)->Is(Type::UnsignedSmall())) {
return Replace(ChangeUint32ToSmi(value));
}
Node* check = graph()->NewNode(machine()->Uint32LessThanOrEqual(), value, Node* check = graph()->NewNode(machine()->Uint32LessThanOrEqual(), value,
SmiMaxValueConstant()); SmiMaxValueConstant());
Node* branch = Node* branch =
......
...@@ -44,6 +44,7 @@ class ChangeLowering final : public Reducer { ...@@ -44,6 +44,7 @@ class ChangeLowering final : public Reducer {
Reduction ChangeBitToBool(Node* value, Node* control); Reduction ChangeBitToBool(Node* value, Node* control);
Reduction ChangeBoolToBit(Node* value); Reduction ChangeBoolToBit(Node* value);
Reduction ChangeFloat64ToTagged(Node* value, Node* control); Reduction ChangeFloat64ToTagged(Node* value, Node* control);
Reduction ChangeInt31ToTagged(Node* value, Node* control);
Reduction ChangeInt32ToTagged(Node* value, Node* control); Reduction ChangeInt32ToTagged(Node* value, Node* control);
Reduction ChangeSmiToInt32(Node* value); Reduction ChangeSmiToInt32(Node* value);
Reduction ChangeTaggedToFloat64(Node* value, Node* control); Reduction ChangeTaggedToFloat64(Node* value, Node* control);
......
...@@ -293,15 +293,8 @@ EffectControlLinearizer::LowerChangeFloat64ToTagged(Node* node, Node* effect, ...@@ -293,15 +293,8 @@ EffectControlLinearizer::LowerChangeFloat64ToTagged(Node* node, Node* effect,
Node* control) { Node* control) {
Node* value = node->InputAt(0); Node* value = node->InputAt(0);
Type* const value_type = NodeProperties::GetType(value); Node* value32 = graph()->NewNode(
Node* const value32 = graph()->NewNode(
machine()->TruncateFloat64ToInt32(TruncationMode::kRoundToZero), value); machine()->TruncateFloat64ToInt32(TruncationMode::kRoundToZero), value);
// TODO(bmeurer): This fast case must be disabled until we kill the asm.js
// support in the generic JavaScript pipeline, because LoadBuffer is lying
// about its result.
// if (value_type->Is(Type::Signed32())) {
// return ChangeInt32ToTagged(value32, control);
// }
Node* check_same = graph()->NewNode( Node* check_same = graph()->NewNode(
machine()->Float64Equal(), value, machine()->Float64Equal(), value,
graph()->NewNode(machine()->ChangeInt32ToFloat64(), value32)); graph()->NewNode(machine()->ChangeInt32ToFloat64(), value32));
...@@ -311,36 +304,33 @@ EffectControlLinearizer::LowerChangeFloat64ToTagged(Node* node, Node* effect, ...@@ -311,36 +304,33 @@ EffectControlLinearizer::LowerChangeFloat64ToTagged(Node* node, Node* effect,
Node* vsmi; Node* vsmi;
Node* if_box = graph()->NewNode(common()->IfFalse(), branch_same); Node* if_box = graph()->NewNode(common()->IfFalse(), branch_same);
// We only need to check for -0 if the {value} can potentially contain -0. // Check if {value} is -0.
if (value_type->Maybe(Type::MinusZero())) { Node* check_zero = graph()->NewNode(machine()->Word32Equal(), value32,
Node* check_zero = graph()->NewNode(machine()->Word32Equal(), value32, jsgraph()->Int32Constant(0));
jsgraph()->Int32Constant(0)); Node* branch_zero = graph()->NewNode(common()->Branch(BranchHint::kFalse),
Node* branch_zero = graph()->NewNode(common()->Branch(BranchHint::kFalse), check_zero, if_smi);
check_zero, if_smi);
Node* if_zero = graph()->NewNode(common()->IfTrue(), branch_zero);
Node* if_zero = graph()->NewNode(common()->IfTrue(), branch_zero); Node* if_notzero = graph()->NewNode(common()->IfFalse(), branch_zero);
Node* if_notzero = graph()->NewNode(common()->IfFalse(), branch_zero);
// In case of 0, we need to check the high bits for the IEEE -0 pattern.
// In case of 0, we need to check the high bits for the IEEE -0 pattern. Node* check_negative = graph()->NewNode(
Node* check_negative = graph()->NewNode( machine()->Int32LessThan(),
machine()->Int32LessThan(), graph()->NewNode(machine()->Float64ExtractHighWord32(), value),
graph()->NewNode(machine()->Float64ExtractHighWord32(), value), jsgraph()->Int32Constant(0));
jsgraph()->Int32Constant(0)); Node* branch_negative = graph()->NewNode(common()->Branch(BranchHint::kFalse),
Node* branch_negative = graph()->NewNode( check_negative, if_zero);
common()->Branch(BranchHint::kFalse), check_negative, if_zero);
Node* if_negative = graph()->NewNode(common()->IfTrue(), branch_negative);
Node* if_negative = graph()->NewNode(common()->IfTrue(), branch_negative); Node* if_notnegative = graph()->NewNode(common()->IfFalse(), branch_negative);
Node* if_notnegative =
graph()->NewNode(common()->IfFalse(), branch_negative); // We need to create a box for negative 0.
if_smi = graph()->NewNode(common()->Merge(2), if_notzero, if_notnegative);
// We need to create a box for negative 0. if_box = graph()->NewNode(common()->Merge(2), if_box, if_negative);
if_smi = graph()->NewNode(common()->Merge(2), if_notzero, if_notnegative);
if_box = graph()->NewNode(common()->Merge(2), if_box, if_negative);
}
// On 64-bit machines we can just wrap the 32-bit integer in a smi, for 32-bit // On 64-bit machines we can just wrap the 32-bit integer in a smi, for 32-bit
// machines we need to deal with potential overflow and fallback to boxing. // machines we need to deal with potential overflow and fallback to boxing.
if (machine()->Is64() || value_type->Is(Type::SignedSmall())) { if (machine()->Is64()) {
vsmi = ChangeInt32ToSmi(value32); vsmi = ChangeInt32ToSmi(value32);
} else { } else {
Node* smi_tag = Node* smi_tag =
...@@ -373,8 +363,7 @@ EffectControlLinearizer::LowerChangeInt32ToTagged(Node* node, Node* effect, ...@@ -373,8 +363,7 @@ EffectControlLinearizer::LowerChangeInt32ToTagged(Node* node, Node* effect,
Node* control) { Node* control) {
Node* value = node->InputAt(0); Node* value = node->InputAt(0);
if (machine()->Is64() || if (machine()->Is64()) {
NodeProperties::GetType(value)->Is(Type::SignedSmall())) {
return ValueEffectControl(ChangeInt32ToSmi(value), effect, control); return ValueEffectControl(ChangeInt32ToSmi(value), effect, control);
} }
...@@ -405,10 +394,6 @@ EffectControlLinearizer::LowerChangeUint32ToTagged(Node* node, Node* effect, ...@@ -405,10 +394,6 @@ EffectControlLinearizer::LowerChangeUint32ToTagged(Node* node, Node* effect,
Node* control) { Node* control) {
Node* value = node->InputAt(0); Node* value = node->InputAt(0);
if (NodeProperties::GetType(value)->Is(Type::UnsignedSmall())) {
return ValueEffectControl(ChangeUint32ToSmi(value), effect, control);
}
Node* check = graph()->NewNode(machine()->Uint32LessThanOrEqual(), value, Node* check = graph()->NewNode(machine()->Uint32LessThanOrEqual(), value,
SmiMaxValueConstant()); SmiMaxValueConstant());
Node* branch = Node* branch =
......
...@@ -200,6 +200,7 @@ ...@@ -200,6 +200,7 @@
V(ChangeTaggedToInt32) \ V(ChangeTaggedToInt32) \
V(ChangeTaggedToUint32) \ V(ChangeTaggedToUint32) \
V(ChangeTaggedToFloat64) \ V(ChangeTaggedToFloat64) \
V(ChangeInt31ToTagged) \
V(ChangeInt32ToTagged) \ V(ChangeInt32ToTagged) \
V(ChangeUint32ToTagged) \ V(ChangeUint32ToTagged) \
V(ChangeFloat64ToTagged) \ V(ChangeFloat64ToTagged) \
......
...@@ -1281,7 +1281,6 @@ Handle<Code> Pipeline::GenerateCode() { ...@@ -1281,7 +1281,6 @@ Handle<Code> Pipeline::GenerateCode() {
RunPrintAndVerify("Early optimized"); RunPrintAndVerify("Early optimized");
if (info()->is_effect_scheduling_enabled()) { if (info()->is_effect_scheduling_enabled()) {
// TODO(jarin) Run value numbering for the representation changes.
Run<EffectControlLinearizationPhase>(); Run<EffectControlLinearizationPhase>();
RunPrintAndVerify("Effect and control linearized"); RunPrintAndVerify("Effect and control linearized");
} }
......
...@@ -190,10 +190,12 @@ Node* RepresentationChanger::GetTaggedRepresentationFor( ...@@ -190,10 +190,12 @@ Node* RepresentationChanger::GetTaggedRepresentationFor(
if (output_rep == MachineRepresentation::kBit) { if (output_rep == MachineRepresentation::kBit) {
op = simplified()->ChangeBitToBool(); op = simplified()->ChangeBitToBool();
} else if (IsWord(output_rep)) { } else if (IsWord(output_rep)) {
if (output_type->Is(Type::Unsigned32())) { if (output_type->Is(Type::Signed31())) {
op = simplified()->ChangeUint32ToTagged(); op = simplified()->ChangeInt31ToTagged();
} else if (output_type->Is(Type::Signed32())) { } else if (output_type->Is(Type::Signed32())) {
op = simplified()->ChangeInt32ToTagged(); op = simplified()->ChangeInt32ToTagged();
} else if (output_type->Is(Type::Unsigned32())) {
op = simplified()->ChangeUint32ToTagged();
} else { } else {
return TypeError(node, output_rep, output_type, return TypeError(node, output_rep, output_type,
MachineRepresentation::kTagged); MachineRepresentation::kTagged);
...@@ -201,9 +203,24 @@ Node* RepresentationChanger::GetTaggedRepresentationFor( ...@@ -201,9 +203,24 @@ Node* RepresentationChanger::GetTaggedRepresentationFor(
} else if (output_rep == } else if (output_rep ==
MachineRepresentation::kFloat32) { // float32 -> float64 -> tagged MachineRepresentation::kFloat32) { // float32 -> float64 -> tagged
node = InsertChangeFloat32ToFloat64(node); node = InsertChangeFloat32ToFloat64(node);
// TODO(bmeurer): Pass -0 hint to ChangeFloat64ToTagged.
op = simplified()->ChangeFloat64ToTagged(); op = simplified()->ChangeFloat64ToTagged();
} else if (output_rep == MachineRepresentation::kFloat64) { } else if (output_rep == MachineRepresentation::kFloat64) {
op = simplified()->ChangeFloat64ToTagged(); if (output_type->Is(Type::Signed31())) { // float64 -> int32 -> tagged
node = InsertChangeFloat64ToInt32(node);
op = simplified()->ChangeInt31ToTagged();
} else if (output_type->Is(
Type::Signed32())) { // float64 -> int32 -> tagged
node = InsertChangeFloat64ToInt32(node);
op = simplified()->ChangeInt32ToTagged();
} else if (output_type->Is(
Type::Unsigned32())) { // float64 -> uint32 -> tagged
node = InsertChangeFloat64ToUint32(node);
op = simplified()->ChangeUint32ToTagged();
} else {
// TODO(bmeurer): Pass -0 hint to ChangeFloat64ToTagged.
op = simplified()->ChangeFloat64ToTagged();
}
} else { } else {
return TypeError(node, output_rep, output_type, return TypeError(node, output_rep, output_type,
MachineRepresentation::kTagged); MachineRepresentation::kTagged);
...@@ -528,6 +545,13 @@ Node* RepresentationChanger::InsertChangeFloat32ToFloat64(Node* node) { ...@@ -528,6 +545,13 @@ Node* RepresentationChanger::InsertChangeFloat32ToFloat64(Node* node) {
return jsgraph()->graph()->NewNode(machine()->ChangeFloat32ToFloat64(), node); return jsgraph()->graph()->NewNode(machine()->ChangeFloat32ToFloat64(), node);
} }
Node* RepresentationChanger::InsertChangeFloat64ToUint32(Node* node) {
return jsgraph()->graph()->NewNode(machine()->ChangeFloat64ToUint32(), node);
}
Node* RepresentationChanger::InsertChangeFloat64ToInt32(Node* node) {
return jsgraph()->graph()->NewNode(machine()->ChangeFloat64ToInt32(), node);
}
Node* RepresentationChanger::InsertChangeTaggedToFloat64(Node* node) { Node* RepresentationChanger::InsertChangeTaggedToFloat64(Node* node) {
return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedToFloat64(), return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedToFloat64(),
......
...@@ -133,6 +133,8 @@ class RepresentationChanger final { ...@@ -133,6 +133,8 @@ class RepresentationChanger final {
Type* output_type, MachineRepresentation use); Type* output_type, MachineRepresentation use);
Node* MakeTruncatedInt32Constant(double value); Node* MakeTruncatedInt32Constant(double value);
Node* InsertChangeFloat32ToFloat64(Node* node); Node* InsertChangeFloat32ToFloat64(Node* node);
Node* InsertChangeFloat64ToInt32(Node* node);
Node* InsertChangeFloat64ToUint32(Node* node);
Node* InsertChangeTaggedToFloat64(Node* node); Node* InsertChangeTaggedToFloat64(Node* node);
JSGraph* jsgraph() const { return jsgraph_; } JSGraph* jsgraph() const { return jsgraph_; }
......
...@@ -50,6 +50,7 @@ Reduction SimplifiedOperatorReducer::Reduce(Node* node) { ...@@ -50,6 +50,7 @@ Reduction SimplifiedOperatorReducer::Reduce(Node* node) {
if (m.IsChangeTaggedToFloat64()) return Replace(m.node()->InputAt(0)); if (m.IsChangeTaggedToFloat64()) return Replace(m.node()->InputAt(0));
break; break;
} }
case IrOpcode::kChangeInt31ToTagged:
case IrOpcode::kChangeInt32ToTagged: { case IrOpcode::kChangeInt32ToTagged: {
Int32Matcher m(node->InputAt(0)); Int32Matcher m(node->InputAt(0));
if (m.HasValue()) return ReplaceNumber(m.Value()); if (m.HasValue()) return ReplaceNumber(m.Value());
...@@ -59,7 +60,7 @@ Reduction SimplifiedOperatorReducer::Reduce(Node* node) { ...@@ -59,7 +60,7 @@ Reduction SimplifiedOperatorReducer::Reduce(Node* node) {
NumberMatcher m(node->InputAt(0)); NumberMatcher m(node->InputAt(0));
if (m.HasValue()) return ReplaceFloat64(m.Value()); if (m.HasValue()) return ReplaceFloat64(m.Value());
if (m.IsChangeFloat64ToTagged()) return Replace(m.node()->InputAt(0)); if (m.IsChangeFloat64ToTagged()) return Replace(m.node()->InputAt(0));
if (m.IsChangeInt32ToTagged()) { if (m.IsChangeInt31ToTagged() || m.IsChangeInt32ToTagged()) {
return Change(node, machine()->ChangeInt32ToFloat64(), m.InputAt(0)); return Change(node, machine()->ChangeInt32ToFloat64(), m.InputAt(0));
} }
if (m.IsChangeUint32ToTagged()) { if (m.IsChangeUint32ToTagged()) {
...@@ -73,7 +74,9 @@ Reduction SimplifiedOperatorReducer::Reduce(Node* node) { ...@@ -73,7 +74,9 @@ Reduction SimplifiedOperatorReducer::Reduce(Node* node) {
if (m.IsChangeFloat64ToTagged()) { if (m.IsChangeFloat64ToTagged()) {
return Change(node, machine()->ChangeFloat64ToInt32(), m.InputAt(0)); return Change(node, machine()->ChangeFloat64ToInt32(), m.InputAt(0));
} }
if (m.IsChangeInt32ToTagged()) return Replace(m.InputAt(0)); if (m.IsChangeInt31ToTagged() || m.IsChangeInt32ToTagged()) {
return Replace(m.InputAt(0));
}
break; break;
} }
case IrOpcode::kChangeTaggedToUint32: { case IrOpcode::kChangeTaggedToUint32: {
......
...@@ -186,6 +186,7 @@ const ElementAccess& ElementAccessOf(const Operator* op) { ...@@ -186,6 +186,7 @@ const ElementAccess& ElementAccessOf(const Operator* op) {
V(ChangeTaggedToInt32, Operator::kNoProperties, 1) \ V(ChangeTaggedToInt32, Operator::kNoProperties, 1) \
V(ChangeTaggedToUint32, Operator::kNoProperties, 1) \ V(ChangeTaggedToUint32, Operator::kNoProperties, 1) \
V(ChangeTaggedToFloat64, Operator::kNoProperties, 1) \ V(ChangeTaggedToFloat64, Operator::kNoProperties, 1) \
V(ChangeInt31ToTagged, Operator::kNoProperties, 1) \
V(ChangeInt32ToTagged, Operator::kNoProperties, 1) \ V(ChangeInt32ToTagged, Operator::kNoProperties, 1) \
V(ChangeUint32ToTagged, Operator::kNoProperties, 1) \ V(ChangeUint32ToTagged, Operator::kNoProperties, 1) \
V(ChangeFloat64ToTagged, Operator::kNoProperties, 1) \ V(ChangeFloat64ToTagged, Operator::kNoProperties, 1) \
......
...@@ -163,6 +163,7 @@ class SimplifiedOperatorBuilder final : public ZoneObject { ...@@ -163,6 +163,7 @@ class SimplifiedOperatorBuilder final : public ZoneObject {
const Operator* ChangeTaggedToInt32(); const Operator* ChangeTaggedToInt32();
const Operator* ChangeTaggedToUint32(); const Operator* ChangeTaggedToUint32();
const Operator* ChangeTaggedToFloat64(); const Operator* ChangeTaggedToFloat64();
const Operator* ChangeInt31ToTagged();
const Operator* ChangeInt32ToTagged(); const Operator* ChangeInt32ToTagged();
const Operator* ChangeUint32ToTagged(); const Operator* ChangeUint32ToTagged();
const Operator* ChangeFloat64ToTagged(); const Operator* ChangeFloat64ToTagged();
......
...@@ -1871,6 +1871,13 @@ Type* Typer::Visitor::TypeChangeTaggedToFloat64(Node* node) { ...@@ -1871,6 +1871,13 @@ Type* Typer::Visitor::TypeChangeTaggedToFloat64(Node* node) {
return ChangeRepresentation(arg, Type::UntaggedFloat64(), zone()); return ChangeRepresentation(arg, Type::UntaggedFloat64(), zone());
} }
Type* Typer::Visitor::TypeChangeInt31ToTagged(Node* node) {
Type* arg = Operand(node, 0);
// TODO(neis): DCHECK(arg->Is(Type::Signed31()));
Type* rep =
arg->Is(Type::SignedSmall()) ? Type::TaggedSigned() : Type::Tagged();
return ChangeRepresentation(arg, rep, zone());
}
Type* Typer::Visitor::TypeChangeInt32ToTagged(Node* node) { Type* Typer::Visitor::TypeChangeInt32ToTagged(Node* node) {
Type* arg = Operand(node, 0); Type* arg = Operand(node, 0);
......
...@@ -796,6 +796,15 @@ void Verifier::Visitor::Check(Node* node) { ...@@ -796,6 +796,15 @@ void Verifier::Visitor::Check(Node* node) {
// CheckUpperIs(node, to)); // CheckUpperIs(node, to));
break; break;
} }
case IrOpcode::kChangeInt31ToTagged: {
// Signed31 /\ UntaggedInt32 -> Signed31 /\ Tagged
// TODO(neis): Activate once ChangeRepresentation works in typer.
// Type* from =Type::Intersect(Type::Signed31(), Type::UntaggedInt32());
// Type* to = Type::Intersect(Type::Signed31(), Type::Tagged());
// CheckValueInputIs(node, 0, from));
// CheckUpperIs(node, to));
break;
}
case IrOpcode::kChangeInt32ToTagged: { case IrOpcode::kChangeInt32ToTagged: {
// Signed32 /\ UntaggedInt32 -> Signed32 /\ Tagged // Signed32 /\ UntaggedInt32 -> Signed32 /\ Tagged
// TODO(neis): Activate once ChangeRepresentation works in typer. // TODO(neis): Activate once ChangeRepresentation works in typer.
......
...@@ -444,12 +444,26 @@ TEST(SingleChanges) { ...@@ -444,12 +444,26 @@ TEST(SingleChanges) {
CheckChange(IrOpcode::kChangeBitToBool, MachineRepresentation::kBit, CheckChange(IrOpcode::kChangeBitToBool, MachineRepresentation::kBit,
Type::None(), MachineRepresentation::kTagged); Type::None(), MachineRepresentation::kTagged);
CheckChange(IrOpcode::kChangeInt31ToTagged, MachineRepresentation::kWord32,
Type::Signed31(), MachineRepresentation::kTagged);
CheckChange(IrOpcode::kChangeInt32ToTagged, MachineRepresentation::kWord32, CheckChange(IrOpcode::kChangeInt32ToTagged, MachineRepresentation::kWord32,
Type::Signed32(), MachineRepresentation::kTagged); Type::Signed32(), MachineRepresentation::kTagged);
CheckChange(IrOpcode::kChangeUint32ToTagged, MachineRepresentation::kWord32, CheckChange(IrOpcode::kChangeUint32ToTagged, MachineRepresentation::kWord32,
Type::Unsigned32(), MachineRepresentation::kTagged); Type::Unsigned32(), MachineRepresentation::kTagged);
CheckChange(IrOpcode::kChangeFloat64ToTagged, MachineRepresentation::kFloat64, CheckChange(IrOpcode::kChangeFloat64ToTagged, MachineRepresentation::kFloat64,
Type::None(), MachineRepresentation::kTagged); Type::Number(), MachineRepresentation::kTagged);
CheckTwoChanges(IrOpcode::kChangeFloat64ToInt32,
IrOpcode::kChangeInt31ToTagged,
MachineRepresentation::kFloat64, Type::Signed31(),
MachineRepresentation::kTagged);
CheckTwoChanges(IrOpcode::kChangeFloat64ToInt32,
IrOpcode::kChangeInt32ToTagged,
MachineRepresentation::kFloat64, Type::Signed32(),
MachineRepresentation::kTagged);
CheckTwoChanges(IrOpcode::kChangeFloat64ToUint32,
IrOpcode::kChangeUint32ToTagged,
MachineRepresentation::kFloat64, Type::Unsigned32(),
MachineRepresentation::kTagged);
CheckChange(IrOpcode::kChangeTaggedToInt32, MachineRepresentation::kTagged, CheckChange(IrOpcode::kChangeTaggedToInt32, MachineRepresentation::kTagged,
Type::Signed32(), MachineRepresentation::kWord32); Type::Signed32(), MachineRepresentation::kWord32);
......
...@@ -908,7 +908,7 @@ TEST(LowerBooleanToNumber_bit_tagged) { ...@@ -908,7 +908,7 @@ TEST(LowerBooleanToNumber_bit_tagged) {
t.Return(use); t.Return(use);
t.Lower(); t.Lower();
CHECK_EQ(b, use->InputAt(0)->InputAt(0)); CHECK_EQ(b, use->InputAt(0)->InputAt(0));
CHECK_EQ(IrOpcode::kChangeUint32ToTagged, use->InputAt(0)->opcode()); CHECK_EQ(IrOpcode::kChangeInt31ToTagged, use->InputAt(0)->opcode());
} }
...@@ -921,7 +921,7 @@ TEST(LowerBooleanToNumber_tagged_tagged) { ...@@ -921,7 +921,7 @@ TEST(LowerBooleanToNumber_tagged_tagged) {
t.Return(use); t.Return(use);
t.Lower(); t.Lower();
CHECK_EQ(cnv, use->InputAt(0)->InputAt(0)); CHECK_EQ(cnv, use->InputAt(0)->InputAt(0));
CHECK_EQ(IrOpcode::kChangeUint32ToTagged, use->InputAt(0)->opcode()); CHECK_EQ(IrOpcode::kChangeInt31ToTagged, use->InputAt(0)->opcode());
CHECK_EQ(t.machine()->WordEqual()->opcode(), cnv->opcode()); CHECK_EQ(t.machine()->WordEqual()->opcode(), cnv->opcode());
CHECK(b == cnv->InputAt(0) || b == cnv->InputAt(1)); CHECK(b == cnv->InputAt(0) || b == cnv->InputAt(1));
Node* c = t.jsgraph.TrueConstant(); Node* c = t.jsgraph.TrueConstant();
......
...@@ -124,25 +124,14 @@ TARGET_TEST_P(ChangeLoweringCommonTest, ChangeBoolToBit) { ...@@ -124,25 +124,14 @@ TARGET_TEST_P(ChangeLoweringCommonTest, ChangeBoolToBit) {
EXPECT_THAT(r.replacement(), IsWordEqual(value, IsTrueConstant())); EXPECT_THAT(r.replacement(), IsWordEqual(value, IsTrueConstant()));
} }
TARGET_TEST_P(ChangeLoweringCommonTest, ChangeInt31ToTagged) {
TARGET_TEST_P(ChangeLoweringCommonTest, ChangeInt32ToTaggedWithSignedSmall) {
Node* value = Parameter(Type::SignedSmall()); Node* value = Parameter(Type::SignedSmall());
Reduction r = Reduction r =
Reduce(graph()->NewNode(simplified()->ChangeInt32ToTagged(), value)); Reduce(graph()->NewNode(simplified()->ChangeInt31ToTagged(), value));
ASSERT_TRUE(r.Changed()); ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsChangeInt32ToSmi(value)); EXPECT_THAT(r.replacement(), IsChangeInt32ToSmi(value));
} }
TARGET_TEST_P(ChangeLoweringCommonTest, ChangeUint32ToTaggedWithUnsignedSmall) {
Node* value = Parameter(Type::UnsignedSmall());
Reduction r =
Reduce(graph()->NewNode(simplified()->ChangeUint32ToTagged(), value));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsChangeUint32ToSmi(value));
}
TARGET_TEST_P(ChangeLoweringCommonTest, ChangeTaggedToInt32WithTaggedSigned) { TARGET_TEST_P(ChangeLoweringCommonTest, ChangeTaggedToInt32WithTaggedSigned) {
Node* value = Parameter(Type::TaggedSigned()); Node* value = Parameter(Type::TaggedSigned());
Reduction r = Reduction r =
......
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