Commit 6322bf41 authored by bmeurer's avatar bmeurer Committed by Commit bot

[turbofan] Improve representation selection for HeapObject checking.

For lowering CheckHeapObject, always report TaggedPointer representation
and let the RepresentationChanger come up with a reasonable conversion from
whatever input representation to TaggedPointer. This way we no longer insert
the useless ChangeSomethingToTagged and then check the result for HeapObject,
i.e. mostly reduces the amount of useless code being generated.

Note there are now two operators ChangeFloat64ToTaggedPointer and the old
ChangeFloat64ToTagged, because their semantics different wrt. the strength
reduction in the SimplifiedOperatorReducer.

Also set the output MachineRepresentation::kTaggedPointer properly in
SimplifiedLowering whenever we know that we produce a HeapObject.

R=jarin@chromium.org
BUG=v8:5267

Review-Url: https://codereview.chromium.org/2476593002
Cr-Commit-Position: refs/heads/master@{#40725}
parent 5bbc5e8e
...@@ -600,6 +600,9 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node, ...@@ -600,6 +600,9 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node,
case IrOpcode::kChangeFloat64ToTagged: case IrOpcode::kChangeFloat64ToTagged:
state = LowerChangeFloat64ToTagged(node, *effect, *control); state = LowerChangeFloat64ToTagged(node, *effect, *control);
break; break;
case IrOpcode::kChangeFloat64ToTaggedPointer:
state = LowerChangeFloat64ToTaggedPointer(node, *effect, *control);
break;
case IrOpcode::kChangeTaggedSignedToInt32: case IrOpcode::kChangeTaggedSignedToInt32:
state = LowerChangeTaggedSignedToInt32(node, *effect, *control); state = LowerChangeTaggedSignedToInt32(node, *effect, *control);
break; break;
...@@ -636,9 +639,6 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node, ...@@ -636,9 +639,6 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node,
case IrOpcode::kCheckIf: case IrOpcode::kCheckIf:
state = LowerCheckIf(node, frame_state, *effect, *control); state = LowerCheckIf(node, frame_state, *effect, *control);
break; break;
case IrOpcode::kCheckHeapObject:
state = LowerCheckHeapObject(node, frame_state, *effect, *control);
break;
case IrOpcode::kCheckedInt32Add: case IrOpcode::kCheckedInt32Add:
state = LowerCheckedInt32Add(node, frame_state, *effect, *control); state = LowerCheckedInt32Add(node, frame_state, *effect, *control);
break; break;
...@@ -688,6 +688,10 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node, ...@@ -688,6 +688,10 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node,
state = LowerCheckedTaggedToTaggedSigned(node, frame_state, *effect, state = LowerCheckedTaggedToTaggedSigned(node, frame_state, *effect,
*control); *control);
break; break;
case IrOpcode::kCheckedTaggedToTaggedPointer:
state = LowerCheckedTaggedToTaggedPointer(node, frame_state, *effect,
*control);
break;
case IrOpcode::kTruncateTaggedToWord32: case IrOpcode::kTruncateTaggedToWord32:
state = LowerTruncateTaggedToWord32(node, *effect, *control); state = LowerTruncateTaggedToWord32(node, *effect, *control);
break; break;
...@@ -792,6 +796,14 @@ EffectControlLinearizer::LowerChangeFloat64ToTagged(Node* node, Node* effect, ...@@ -792,6 +796,14 @@ EffectControlLinearizer::LowerChangeFloat64ToTagged(Node* node, Node* effect,
return AllocateHeapNumberWithValue(value, effect, control); return AllocateHeapNumberWithValue(value, effect, control);
} }
EffectControlLinearizer::ValueEffectControl
EffectControlLinearizer::LowerChangeFloat64ToTaggedPointer(Node* node,
Node* effect,
Node* control) {
Node* value = node->InputAt(0);
return AllocateHeapNumberWithValue(value, effect, control);
}
EffectControlLinearizer::ValueEffectControl EffectControlLinearizer::ValueEffectControl
EffectControlLinearizer::LowerChangeBitToTagged(Node* node, Node* effect, EffectControlLinearizer::LowerChangeBitToTagged(Node* node, Node* effect,
Node* control) { Node* control) {
...@@ -1273,19 +1285,6 @@ EffectControlLinearizer::LowerCheckIf(Node* node, Node* frame_state, ...@@ -1273,19 +1285,6 @@ EffectControlLinearizer::LowerCheckIf(Node* node, Node* frame_state,
return ValueEffectControl(value, effect, control); return ValueEffectControl(value, effect, control);
} }
EffectControlLinearizer::ValueEffectControl
EffectControlLinearizer::LowerCheckHeapObject(Node* node, Node* frame_state,
Node* effect, Node* control) {
Node* value = node->InputAt(0);
Node* check = ObjectIsSmi(value);
control = effect =
graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kSmi), check,
frame_state, effect, control);
return ValueEffectControl(value, effect, control);
}
EffectControlLinearizer::ValueEffectControl EffectControlLinearizer::ValueEffectControl
EffectControlLinearizer::LowerCheckedInt32Add(Node* node, Node* frame_state, EffectControlLinearizer::LowerCheckedInt32Add(Node* node, Node* frame_state,
Node* effect, Node* control) { Node* effect, Node* control) {
...@@ -1882,6 +1881,21 @@ EffectControlLinearizer::LowerCheckedTaggedToTaggedSigned(Node* node, ...@@ -1882,6 +1881,21 @@ EffectControlLinearizer::LowerCheckedTaggedToTaggedSigned(Node* node,
return ValueEffectControl(value, effect, control); return ValueEffectControl(value, effect, control);
} }
EffectControlLinearizer::ValueEffectControl
EffectControlLinearizer::LowerCheckedTaggedToTaggedPointer(Node* node,
Node* frame_state,
Node* effect,
Node* control) {
Node* value = node->InputAt(0);
Node* check = ObjectIsSmi(value);
control = effect =
graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kSmi), check,
frame_state, effect, control);
return ValueEffectControl(value, effect, control);
}
EffectControlLinearizer::ValueEffectControl EffectControlLinearizer::ValueEffectControl
EffectControlLinearizer::LowerTruncateTaggedToWord32(Node* node, Node* effect, EffectControlLinearizer::LowerTruncateTaggedToWord32(Node* node, Node* effect,
Node* control) { Node* control) {
......
...@@ -56,6 +56,8 @@ class V8_EXPORT_PRIVATE EffectControlLinearizer { ...@@ -56,6 +56,8 @@ class V8_EXPORT_PRIVATE EffectControlLinearizer {
Node* control); Node* control);
ValueEffectControl LowerChangeFloat64ToTagged(Node* node, Node* effect, ValueEffectControl LowerChangeFloat64ToTagged(Node* node, Node* effect,
Node* control); Node* control);
ValueEffectControl LowerChangeFloat64ToTaggedPointer(Node* node, Node* effect,
Node* control);
ValueEffectControl LowerChangeTaggedSignedToInt32(Node* node, Node* effect, ValueEffectControl LowerChangeTaggedSignedToInt32(Node* node, Node* effect,
Node* control); Node* control);
ValueEffectControl LowerChangeTaggedToBit(Node* node, Node* effect, ValueEffectControl LowerChangeTaggedToBit(Node* node, Node* effect,
...@@ -74,8 +76,6 @@ class V8_EXPORT_PRIVATE EffectControlLinearizer { ...@@ -74,8 +76,6 @@ class V8_EXPORT_PRIVATE EffectControlLinearizer {
Node* effect, Node* control); Node* effect, Node* control);
ValueEffectControl LowerCheckIf(Node* node, Node* frame_state, Node* effect, ValueEffectControl LowerCheckIf(Node* node, Node* frame_state, Node* effect,
Node* control); Node* control);
ValueEffectControl LowerCheckHeapObject(Node* node, Node* frame_state,
Node* effect, Node* control);
ValueEffectControl LowerCheckedInt32Add(Node* node, Node* frame_state, ValueEffectControl LowerCheckedInt32Add(Node* node, Node* frame_state,
Node* effect, Node* control); Node* effect, Node* control);
ValueEffectControl LowerCheckedInt32Sub(Node* node, Node* frame_state, ValueEffectControl LowerCheckedInt32Sub(Node* node, Node* frame_state,
...@@ -114,6 +114,10 @@ class V8_EXPORT_PRIVATE EffectControlLinearizer { ...@@ -114,6 +114,10 @@ class V8_EXPORT_PRIVATE EffectControlLinearizer {
Node* frame_state, Node* frame_state,
Node* effect, Node* effect,
Node* control); Node* control);
ValueEffectControl LowerCheckedTaggedToTaggedPointer(Node* node,
Node* frame_state,
Node* effect,
Node* control);
ValueEffectControl LowerChangeTaggedToFloat64(Node* node, Node* effect, ValueEffectControl LowerChangeTaggedToFloat64(Node* node, Node* effect,
Node* control); Node* control);
ValueEffectControl LowerTruncateTaggedToBit(Node* node, Node* effect, ValueEffectControl LowerTruncateTaggedToBit(Node* node, Node* effect,
......
...@@ -179,6 +179,7 @@ ...@@ -179,6 +179,7 @@
V(ChangeInt32ToTagged) \ V(ChangeInt32ToTagged) \
V(ChangeUint32ToTagged) \ V(ChangeUint32ToTagged) \
V(ChangeFloat64ToTagged) \ V(ChangeFloat64ToTagged) \
V(ChangeFloat64ToTaggedPointer) \
V(ChangeTaggedToBit) \ V(ChangeTaggedToBit) \
V(ChangeBitToTagged) \ V(ChangeBitToTagged) \
V(TruncateTaggedToWord32) \ V(TruncateTaggedToWord32) \
...@@ -201,7 +202,8 @@ ...@@ -201,7 +202,8 @@
V(CheckedTaggedToInt32) \ V(CheckedTaggedToInt32) \
V(CheckedTruncateTaggedToWord32) \ V(CheckedTruncateTaggedToWord32) \
V(CheckedTaggedToFloat64) \ V(CheckedTaggedToFloat64) \
V(CheckedTaggedToTaggedSigned) V(CheckedTaggedToTaggedSigned) \
V(CheckedTaggedToTaggedPointer)
#define SIMPLIFIED_COMPARE_BINOP_LIST(V) \ #define SIMPLIFIED_COMPARE_BINOP_LIST(V) \
V(NumberEqual) \ V(NumberEqual) \
......
...@@ -142,8 +142,10 @@ Node* RepresentationChanger::GetRepresentationFor( ...@@ -142,8 +142,10 @@ Node* RepresentationChanger::GetRepresentationFor(
return GetTaggedSignedRepresentationFor(node, output_rep, output_type, return GetTaggedSignedRepresentationFor(node, output_rep, output_type,
use_node, use_info); use_node, use_info);
case MachineRepresentation::kTaggedPointer: case MachineRepresentation::kTaggedPointer:
DCHECK(use_info.type_check() == TypeCheckKind::kNone); DCHECK(use_info.type_check() == TypeCheckKind::kNone ||
return GetTaggedPointerRepresentationFor(node, output_rep, output_type); use_info.type_check() == TypeCheckKind::kHeapObject);
return GetTaggedPointerRepresentationFor(node, output_rep, output_type,
use_node, use_info);
case MachineRepresentation::kTagged: case MachineRepresentation::kTagged:
DCHECK(use_info.type_check() == TypeCheckKind::kNone); DCHECK(use_info.type_check() == TypeCheckKind::kNone);
return GetTaggedRepresentationFor(node, output_rep, output_type, return GetTaggedRepresentationFor(node, output_rep, output_type,
...@@ -285,7 +287,8 @@ Node* RepresentationChanger::GetTaggedSignedRepresentationFor( ...@@ -285,7 +287,8 @@ Node* RepresentationChanger::GetTaggedSignedRepresentationFor(
} }
Node* RepresentationChanger::GetTaggedPointerRepresentationFor( Node* RepresentationChanger::GetTaggedPointerRepresentationFor(
Node* node, MachineRepresentation output_rep, Type* output_type) { Node* node, MachineRepresentation output_rep, Type* output_type,
Node* use_node, UseInfo use_info) {
// Eagerly fold representation changes for constants. // Eagerly fold representation changes for constants.
switch (node->opcode()) { switch (node->opcode()) {
case IrOpcode::kHeapConstant: case IrOpcode::kHeapConstant:
...@@ -297,14 +300,46 @@ Node* RepresentationChanger::GetTaggedPointerRepresentationFor( ...@@ -297,14 +300,46 @@ Node* RepresentationChanger::GetTaggedPointerRepresentationFor(
default: default:
break; break;
} }
// Select the correct X -> Tagged operator. // Select the correct X -> TaggedPointer operator.
Operator const* op;
if (output_type->Is(Type::None())) { if (output_type->Is(Type::None())) {
// This is an impossible value; it should not be used at runtime. // This is an impossible value; it should not be used at runtime.
// We just provide a dummy value here. // We just provide a dummy value here.
return jsgraph()->TheHoleConstant(); return jsgraph()->TheHoleConstant();
} else if (output_rep == MachineRepresentation::kBit) {
return node;
} else if (IsWord(output_rep)) {
if (output_type->Is(Type::Unsigned32())) {
// uint32 -> float64 -> tagged
node = InsertChangeUint32ToFloat64(node);
} else if (output_type->Is(Type::Signed32())) {
// int32 -> float64 -> tagged
node = InsertChangeInt32ToFloat64(node);
} else {
return TypeError(node, output_rep, output_type,
MachineRepresentation::kTaggedPointer);
}
op = simplified()->ChangeFloat64ToTaggedPointer();
} else if (output_rep == MachineRepresentation::kFloat32) {
// float32 -> float64 -> tagged
node = InsertChangeFloat32ToFloat64(node);
op = simplified()->ChangeFloat64ToTaggedPointer();
} else if (output_rep == MachineRepresentation::kFloat64) {
// float64 -> tagged
op = simplified()->ChangeFloat64ToTaggedPointer();
} else if (CanBeTaggedSigned(output_rep) &&
use_info.type_check() == TypeCheckKind::kHeapObject) {
if (!output_type->Maybe(Type::SignedSmall())) {
return node;
}
// TODO(turbofan): Consider adding a Bailout operator that just deopts
// for TaggedSigned output representation.
op = simplified()->CheckedTaggedToTaggedPointer();
} else {
return TypeError(node, output_rep, output_type,
MachineRepresentation::kTaggedPointer);
} }
return TypeError(node, output_rep, output_type, return InsertConversion(node, op, use_node);
MachineRepresentation::kTaggedPointer);
} }
Node* RepresentationChanger::GetTaggedRepresentationFor( Node* RepresentationChanger::GetTaggedRepresentationFor(
...@@ -953,6 +988,10 @@ Node* RepresentationChanger::InsertChangeFloat64ToInt32(Node* node) { ...@@ -953,6 +988,10 @@ Node* RepresentationChanger::InsertChangeFloat64ToInt32(Node* node) {
return jsgraph()->graph()->NewNode(machine()->ChangeFloat64ToInt32(), node); return jsgraph()->graph()->NewNode(machine()->ChangeFloat64ToInt32(), node);
} }
Node* RepresentationChanger::InsertChangeInt32ToFloat64(Node* node) {
return jsgraph()->graph()->NewNode(machine()->ChangeInt32ToFloat64(), node);
}
Node* RepresentationChanger::InsertChangeTaggedSignedToInt32(Node* node) { Node* RepresentationChanger::InsertChangeTaggedSignedToInt32(Node* node) {
return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedSignedToInt32(), return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedSignedToInt32(),
node); node);
...@@ -963,6 +1002,10 @@ Node* RepresentationChanger::InsertChangeTaggedToFloat64(Node* node) { ...@@ -963,6 +1002,10 @@ Node* RepresentationChanger::InsertChangeTaggedToFloat64(Node* node) {
node); node);
} }
Node* RepresentationChanger::InsertChangeUint32ToFloat64(Node* node) {
return jsgraph()->graph()->NewNode(machine()->ChangeUint32ToFloat64(), node);
}
} // namespace compiler } // namespace compiler
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -80,7 +80,8 @@ enum class TypeCheckKind : uint8_t { ...@@ -80,7 +80,8 @@ enum class TypeCheckKind : uint8_t {
kSignedSmall, kSignedSmall,
kSigned32, kSigned32,
kNumber, kNumber,
kNumberOrOddball kNumberOrOddball,
kHeapObject
}; };
inline std::ostream& operator<<(std::ostream& os, TypeCheckKind type_check) { inline std::ostream& operator<<(std::ostream& os, TypeCheckKind type_check) {
...@@ -95,6 +96,8 @@ inline std::ostream& operator<<(std::ostream& os, TypeCheckKind type_check) { ...@@ -95,6 +96,8 @@ inline std::ostream& operator<<(std::ostream& os, TypeCheckKind type_check) {
return os << "Number"; return os << "Number";
case TypeCheckKind::kNumberOrOddball: case TypeCheckKind::kNumberOrOddball:
return os << "NumberOrOddball"; return os << "NumberOrOddball";
case TypeCheckKind::kHeapObject:
return os << "HeapObject";
} }
UNREACHABLE(); UNREACHABLE();
return os; return os;
...@@ -152,6 +155,10 @@ class UseInfo { ...@@ -152,6 +155,10 @@ class UseInfo {
} }
// Possibly deoptimizing conversions. // Possibly deoptimizing conversions.
static UseInfo CheckedHeapObjectAsTaggedPointer() {
return UseInfo(MachineRepresentation::kTaggedPointer, Truncation::Any(),
TypeCheckKind::kHeapObject);
}
static UseInfo CheckedSignedSmallAsTaggedSigned() { static UseInfo CheckedSignedSmallAsTaggedSigned() {
return UseInfo(MachineRepresentation::kTaggedSigned, Truncation::Any(), return UseInfo(MachineRepresentation::kTaggedSigned, Truncation::Any(),
TypeCheckKind::kSignedSmall); TypeCheckKind::kSignedSmall);
...@@ -260,7 +267,8 @@ class RepresentationChanger final { ...@@ -260,7 +267,8 @@ class RepresentationChanger final {
UseInfo use_info); UseInfo use_info);
Node* GetTaggedPointerRepresentationFor(Node* node, Node* GetTaggedPointerRepresentationFor(Node* node,
MachineRepresentation output_rep, MachineRepresentation output_rep,
Type* output_type); Type* output_type, Node* use_node,
UseInfo use_info);
Node* GetTaggedRepresentationFor(Node* node, MachineRepresentation output_rep, Node* GetTaggedRepresentationFor(Node* node, MachineRepresentation output_rep,
Type* output_type, Truncation truncation); Type* output_type, Truncation truncation);
Node* GetFloat32RepresentationFor(Node* node, Node* GetFloat32RepresentationFor(Node* node,
...@@ -284,8 +292,10 @@ class RepresentationChanger final { ...@@ -284,8 +292,10 @@ class RepresentationChanger final {
Node* InsertChangeFloat32ToFloat64(Node* node); Node* InsertChangeFloat32ToFloat64(Node* node);
Node* InsertChangeFloat64ToInt32(Node* node); Node* InsertChangeFloat64ToInt32(Node* node);
Node* InsertChangeFloat64ToUint32(Node* node); Node* InsertChangeFloat64ToUint32(Node* node);
Node* InsertChangeInt32ToFloat64(Node* node);
Node* InsertChangeTaggedSignedToInt32(Node* node); Node* InsertChangeTaggedSignedToInt32(Node* node);
Node* InsertChangeTaggedToFloat64(Node* node); Node* InsertChangeTaggedToFloat64(Node* node);
Node* InsertChangeUint32ToFloat64(Node* node);
Node* InsertConversion(Node* node, const Operator* op, Node* use_node); Node* InsertConversion(Node* node, const Operator* op, Node* use_node);
......
...@@ -1353,7 +1353,7 @@ class RepresentationSelector { ...@@ -1353,7 +1353,7 @@ class RepresentationSelector {
case IrOpcode::kNumberConstant: case IrOpcode::kNumberConstant:
return VisitLeaf(node, MachineRepresentation::kTagged); return VisitLeaf(node, MachineRepresentation::kTagged);
case IrOpcode::kHeapConstant: case IrOpcode::kHeapConstant:
return VisitLeaf(node, MachineRepresentation::kTagged); return VisitLeaf(node, MachineRepresentation::kTaggedPointer);
case IrOpcode::kBranch: case IrOpcode::kBranch:
ProcessInput(node, 0, UseInfo::Bool()); ProcessInput(node, 0, UseInfo::Bool());
...@@ -1381,7 +1381,7 @@ class RepresentationSelector { ...@@ -1381,7 +1381,7 @@ class RepresentationSelector {
if (lower()) DeferReplacement(node, node->InputAt(0)); if (lower()) DeferReplacement(node, node->InputAt(0));
} else { } else {
VisitInputs(node); VisitInputs(node);
SetOutput(node, MachineRepresentation::kTagged); SetOutput(node, MachineRepresentation::kTaggedPointer);
} }
return; return;
} }
...@@ -2092,7 +2092,7 @@ class RepresentationSelector { ...@@ -2092,7 +2092,7 @@ class RepresentationSelector {
case IrOpcode::kStringLessThan: case IrOpcode::kStringLessThan:
case IrOpcode::kStringLessThanOrEqual: { case IrOpcode::kStringLessThanOrEqual: {
return VisitBinop(node, UseInfo::AnyTagged(), return VisitBinop(node, UseInfo::AnyTagged(),
MachineRepresentation::kTagged); MachineRepresentation::kTaggedPointer);
} }
case IrOpcode::kStringCharCodeAt: { case IrOpcode::kStringCharCodeAt: {
VisitBinop(node, UseInfo::AnyTagged(), UseInfo::TruncatingWord32(), VisitBinop(node, UseInfo::AnyTagged(), UseInfo::TruncatingWord32(),
...@@ -2101,12 +2101,12 @@ class RepresentationSelector { ...@@ -2101,12 +2101,12 @@ class RepresentationSelector {
} }
case IrOpcode::kStringFromCharCode: { case IrOpcode::kStringFromCharCode: {
VisitUnop(node, UseInfo::TruncatingWord32(), VisitUnop(node, UseInfo::TruncatingWord32(),
MachineRepresentation::kTagged); MachineRepresentation::kTaggedPointer);
return; return;
} }
case IrOpcode::kStringFromCodePoint: { case IrOpcode::kStringFromCodePoint: {
VisitUnop(node, UseInfo::TruncatingWord32(), VisitUnop(node, UseInfo::TruncatingWord32(),
MachineRepresentation::kTagged); MachineRepresentation::kTaggedPointer);
return; return;
} }
...@@ -2130,11 +2130,13 @@ class RepresentationSelector { ...@@ -2130,11 +2130,13 @@ class RepresentationSelector {
} }
case IrOpcode::kCheckHeapObject: { case IrOpcode::kCheckHeapObject: {
if (InputCannotBe(node, Type::SignedSmall())) { if (InputCannotBe(node, Type::SignedSmall())) {
VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged); VisitUnop(node, UseInfo::AnyTagged(),
if (lower()) DeferReplacement(node, node->InputAt(0)); MachineRepresentation::kTaggedPointer);
} else { } else {
VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged); VisitUnop(node, UseInfo::CheckedHeapObjectAsTaggedPointer(),
MachineRepresentation::kTaggedPointer);
} }
if (lower()) DeferReplacement(node, node->InputAt(0));
return; return;
} }
case IrOpcode::kCheckIf: { case IrOpcode::kCheckIf: {
...@@ -2175,10 +2177,12 @@ class RepresentationSelector { ...@@ -2175,10 +2177,12 @@ class RepresentationSelector {
} }
case IrOpcode::kCheckString: { case IrOpcode::kCheckString: {
if (InputIs(node, Type::String())) { if (InputIs(node, Type::String())) {
VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged); VisitUnop(node, UseInfo::AnyTagged(),
MachineRepresentation::kTaggedPointer);
if (lower()) DeferReplacement(node, node->InputAt(0)); if (lower()) DeferReplacement(node, node->InputAt(0));
} else { } else {
VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged); VisitUnop(node, UseInfo::AnyTagged(),
MachineRepresentation::kTaggedPointer);
} }
return; return;
} }
...@@ -2186,7 +2190,7 @@ class RepresentationSelector { ...@@ -2186,7 +2190,7 @@ class RepresentationSelector {
case IrOpcode::kAllocate: { case IrOpcode::kAllocate: {
ProcessInput(node, 0, UseInfo::TruncatingWord32()); ProcessInput(node, 0, UseInfo::TruncatingWord32());
ProcessRemainingInputs(node, 1); ProcessRemainingInputs(node, 1);
SetOutput(node, MachineRepresentation::kTagged); SetOutput(node, MachineRepresentation::kTaggedPointer);
return; return;
} }
case IrOpcode::kLoadField: { case IrOpcode::kLoadField: {
...@@ -2400,7 +2404,8 @@ class RepresentationSelector { ...@@ -2400,7 +2404,8 @@ class RepresentationSelector {
return; return;
} }
case IrOpcode::kCheckTaggedHole: { case IrOpcode::kCheckTaggedHole: {
VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged); VisitUnop(node, UseInfo::AnyTagged(),
MachineRepresentation::kTaggedPointer);
return; return;
} }
case IrOpcode::kConvertTaggedHoleToUndefined: { case IrOpcode::kConvertTaggedHoleToUndefined: {
...@@ -2433,14 +2438,14 @@ class RepresentationSelector { ...@@ -2433,14 +2438,14 @@ class RepresentationSelector {
} }
case IrOpcode::kEnsureWritableFastElements: case IrOpcode::kEnsureWritableFastElements:
return VisitBinop(node, UseInfo::AnyTagged(), return VisitBinop(node, UseInfo::AnyTagged(),
MachineRepresentation::kTagged); MachineRepresentation::kTaggedPointer);
case IrOpcode::kMaybeGrowFastElements: { case IrOpcode::kMaybeGrowFastElements: {
ProcessInput(node, 0, UseInfo::AnyTagged()); // object ProcessInput(node, 0, UseInfo::AnyTagged()); // object
ProcessInput(node, 1, UseInfo::AnyTagged()); // elements ProcessInput(node, 1, UseInfo::AnyTagged()); // elements
ProcessInput(node, 2, UseInfo::TruncatingWord32()); // index ProcessInput(node, 2, UseInfo::TruncatingWord32()); // index
ProcessInput(node, 3, UseInfo::TruncatingWord32()); // length ProcessInput(node, 3, UseInfo::TruncatingWord32()); // length
ProcessRemainingInputs(node, 4); ProcessRemainingInputs(node, 4);
SetOutput(node, MachineRepresentation::kTagged); SetOutput(node, MachineRepresentation::kTaggedPointer);
return; return;
} }
...@@ -2465,6 +2470,11 @@ class RepresentationSelector { ...@@ -2465,6 +2470,11 @@ class RepresentationSelector {
case IrOpcode::kOsrGuard: case IrOpcode::kOsrGuard:
return VisitOsrGuard(node); return VisitOsrGuard(node);
case IrOpcode::kFinishRegion:
VisitInputs(node);
// Assume the output is tagged pointer.
return SetOutput(node, MachineRepresentation::kTaggedPointer);
case IrOpcode::kReturn: case IrOpcode::kReturn:
VisitReturn(node); VisitReturn(node);
// Assume the output is tagged. // Assume the output is tagged.
...@@ -2486,7 +2496,6 @@ class RepresentationSelector { ...@@ -2486,7 +2496,6 @@ class RepresentationSelector {
case IrOpcode::kMerge: case IrOpcode::kMerge:
case IrOpcode::kThrow: case IrOpcode::kThrow:
case IrOpcode::kBeginRegion: case IrOpcode::kBeginRegion:
case IrOpcode::kFinishRegion:
case IrOpcode::kProjection: case IrOpcode::kProjection:
case IrOpcode::kObjectState: case IrOpcode::kObjectState:
case IrOpcode::kOsrValue: case IrOpcode::kOsrValue:
......
...@@ -80,7 +80,9 @@ Reduction SimplifiedOperatorReducer::Reduce(Node* node) { ...@@ -80,7 +80,9 @@ Reduction SimplifiedOperatorReducer::Reduce(Node* node) {
case IrOpcode::kTruncateTaggedToFloat64: { case IrOpcode::kTruncateTaggedToFloat64: {
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() || m.IsChangeFloat64ToTaggedPointer()) {
return Replace(m.node()->InputAt(0));
}
if (m.IsChangeInt31ToTaggedSigned() || m.IsChangeInt32ToTagged()) { if (m.IsChangeInt31ToTaggedSigned() || m.IsChangeInt32ToTagged()) {
return Change(node, machine()->ChangeInt32ToFloat64(), m.InputAt(0)); return Change(node, machine()->ChangeInt32ToFloat64(), m.InputAt(0));
} }
...@@ -93,7 +95,7 @@ Reduction SimplifiedOperatorReducer::Reduce(Node* node) { ...@@ -93,7 +95,7 @@ Reduction SimplifiedOperatorReducer::Reduce(Node* node) {
case IrOpcode::kChangeTaggedToInt32: { case IrOpcode::kChangeTaggedToInt32: {
NumberMatcher m(node->InputAt(0)); NumberMatcher m(node->InputAt(0));
if (m.HasValue()) return ReplaceInt32(DoubleToInt32(m.Value())); if (m.HasValue()) return ReplaceInt32(DoubleToInt32(m.Value()));
if (m.IsChangeFloat64ToTagged()) { if (m.IsChangeFloat64ToTagged() || m.IsChangeFloat64ToTaggedPointer()) {
return Change(node, machine()->ChangeFloat64ToInt32(), m.InputAt(0)); return Change(node, machine()->ChangeFloat64ToInt32(), m.InputAt(0));
} }
if (m.IsChangeInt31ToTaggedSigned() || m.IsChangeInt32ToTagged()) { if (m.IsChangeInt31ToTaggedSigned() || m.IsChangeInt32ToTagged()) {
...@@ -104,7 +106,7 @@ Reduction SimplifiedOperatorReducer::Reduce(Node* node) { ...@@ -104,7 +106,7 @@ Reduction SimplifiedOperatorReducer::Reduce(Node* node) {
case IrOpcode::kChangeTaggedToUint32: { case IrOpcode::kChangeTaggedToUint32: {
NumberMatcher m(node->InputAt(0)); NumberMatcher m(node->InputAt(0));
if (m.HasValue()) return ReplaceUint32(DoubleToUint32(m.Value())); if (m.HasValue()) return ReplaceUint32(DoubleToUint32(m.Value()));
if (m.IsChangeFloat64ToTagged()) { if (m.IsChangeFloat64ToTagged() || m.IsChangeFloat64ToTaggedPointer()) {
return Change(node, machine()->ChangeFloat64ToUint32(), m.InputAt(0)); return Change(node, machine()->ChangeFloat64ToUint32(), m.InputAt(0));
} }
if (m.IsChangeUint32ToTagged()) return Replace(m.InputAt(0)); if (m.IsChangeUint32ToTagged()) return Replace(m.InputAt(0));
...@@ -122,7 +124,7 @@ Reduction SimplifiedOperatorReducer::Reduce(Node* node) { ...@@ -122,7 +124,7 @@ Reduction SimplifiedOperatorReducer::Reduce(Node* node) {
m.IsChangeUint32ToTagged()) { m.IsChangeUint32ToTagged()) {
return Replace(m.InputAt(0)); return Replace(m.InputAt(0));
} }
if (m.IsChangeFloat64ToTagged()) { if (m.IsChangeFloat64ToTagged() || m.IsChangeFloat64ToTaggedPointer()) {
return Change(node, machine()->TruncateFloat64ToWord32(), m.InputAt(0)); return Change(node, machine()->TruncateFloat64ToWord32(), m.InputAt(0));
} }
break; break;
......
...@@ -404,6 +404,7 @@ UnicodeEncoding UnicodeEncodingOf(const Operator* op) { ...@@ -404,6 +404,7 @@ UnicodeEncoding UnicodeEncodingOf(const Operator* op) {
V(ChangeTaggedToUint32, Operator::kNoProperties, 1, 0) \ V(ChangeTaggedToUint32, Operator::kNoProperties, 1, 0) \
V(ChangeTaggedToFloat64, Operator::kNoProperties, 1, 0) \ V(ChangeTaggedToFloat64, Operator::kNoProperties, 1, 0) \
V(ChangeFloat64ToTagged, Operator::kNoProperties, 1, 0) \ V(ChangeFloat64ToTagged, Operator::kNoProperties, 1, 0) \
V(ChangeFloat64ToTaggedPointer, Operator::kNoProperties, 1, 0) \
V(ChangeInt31ToTaggedSigned, Operator::kNoProperties, 1, 0) \ V(ChangeInt31ToTaggedSigned, Operator::kNoProperties, 1, 0) \
V(ChangeInt32ToTagged, Operator::kNoProperties, 1, 0) \ V(ChangeInt32ToTagged, Operator::kNoProperties, 1, 0) \
V(ChangeUint32ToTagged, Operator::kNoProperties, 1, 0) \ V(ChangeUint32ToTagged, Operator::kNoProperties, 1, 0) \
...@@ -430,25 +431,26 @@ UnicodeEncoding UnicodeEncodingOf(const Operator* op) { ...@@ -430,25 +431,26 @@ UnicodeEncoding UnicodeEncodingOf(const Operator* op) {
V(SpeculativeNumberLessThan) \ V(SpeculativeNumberLessThan) \
V(SpeculativeNumberLessThanOrEqual) V(SpeculativeNumberLessThanOrEqual)
#define CHECKED_OP_LIST(V) \ #define CHECKED_OP_LIST(V) \
V(CheckBounds, 2, 1) \ V(CheckBounds, 2, 1) \
V(CheckHeapObject, 1, 1) \ V(CheckHeapObject, 1, 1) \
V(CheckIf, 1, 0) \ V(CheckIf, 1, 0) \
V(CheckNumber, 1, 1) \ V(CheckNumber, 1, 1) \
V(CheckSmi, 1, 1) \ V(CheckSmi, 1, 1) \
V(CheckString, 1, 1) \ V(CheckString, 1, 1) \
V(CheckTaggedHole, 1, 1) \ V(CheckTaggedHole, 1, 1) \
V(CheckedInt32Add, 2, 1) \ V(CheckedInt32Add, 2, 1) \
V(CheckedInt32Sub, 2, 1) \ V(CheckedInt32Sub, 2, 1) \
V(CheckedInt32Div, 2, 1) \ V(CheckedInt32Div, 2, 1) \
V(CheckedInt32Mod, 2, 1) \ V(CheckedInt32Mod, 2, 1) \
V(CheckedUint32Div, 2, 1) \ V(CheckedUint32Div, 2, 1) \
V(CheckedUint32Mod, 2, 1) \ V(CheckedUint32Mod, 2, 1) \
V(CheckedUint32ToInt32, 1, 1) \ V(CheckedUint32ToInt32, 1, 1) \
V(CheckedUint32ToTaggedSigned, 1, 1) \ V(CheckedUint32ToTaggedSigned, 1, 1) \
V(CheckedInt32ToTaggedSigned, 1, 1) \ V(CheckedInt32ToTaggedSigned, 1, 1) \
V(CheckedTaggedSignedToInt32, 1, 1) \ V(CheckedTaggedSignedToInt32, 1, 1) \
V(CheckedTaggedToTaggedSigned, 1, 1) \ V(CheckedTaggedToTaggedSigned, 1, 1) \
V(CheckedTaggedToTaggedPointer, 1, 1) \
V(CheckedTruncateTaggedToWord32, 1, 1) V(CheckedTruncateTaggedToWord32, 1, 1)
struct SimplifiedOperatorGlobalCache final { struct SimplifiedOperatorGlobalCache final {
......
...@@ -309,6 +309,7 @@ class V8_EXPORT_PRIVATE SimplifiedOperatorBuilder final ...@@ -309,6 +309,7 @@ class V8_EXPORT_PRIVATE SimplifiedOperatorBuilder final
const Operator* ChangeInt32ToTagged(); const Operator* ChangeInt32ToTagged();
const Operator* ChangeUint32ToTagged(); const Operator* ChangeUint32ToTagged();
const Operator* ChangeFloat64ToTagged(); const Operator* ChangeFloat64ToTagged();
const Operator* ChangeFloat64ToTaggedPointer();
const Operator* ChangeTaggedToBit(); const Operator* ChangeTaggedToBit();
const Operator* ChangeBitToTagged(); const Operator* ChangeBitToTagged();
const Operator* TruncateTaggedToWord32(); const Operator* TruncateTaggedToWord32();
...@@ -339,6 +340,7 @@ class V8_EXPORT_PRIVATE SimplifiedOperatorBuilder final ...@@ -339,6 +340,7 @@ class V8_EXPORT_PRIVATE SimplifiedOperatorBuilder final
const Operator* CheckedTaggedToInt32(CheckForMinusZeroMode); const Operator* CheckedTaggedToInt32(CheckForMinusZeroMode);
const Operator* CheckedTaggedToFloat64(CheckTaggedInputMode); const Operator* CheckedTaggedToFloat64(CheckTaggedInputMode);
const Operator* CheckedTaggedToTaggedSigned(); const Operator* CheckedTaggedToTaggedSigned();
const Operator* CheckedTaggedToTaggedPointer();
const Operator* CheckedTruncateTaggedToWord32(); const Operator* CheckedTruncateTaggedToWord32();
const Operator* CheckFloat64Hole(CheckFloat64HoleMode); const Operator* CheckFloat64Hole(CheckFloat64HoleMode);
......
...@@ -988,6 +988,8 @@ void Verifier::Visitor::Check(Node* node) { ...@@ -988,6 +988,8 @@ void Verifier::Visitor::Check(Node* node) {
// CheckTypeIs(node, to)); // CheckTypeIs(node, to));
break; break;
} }
case IrOpcode::kChangeFloat64ToTaggedPointer:
break;
case IrOpcode::kChangeTaggedToBit: { case IrOpcode::kChangeTaggedToBit: {
// Boolean /\ TaggedPtr -> Boolean /\ UntaggedInt1 // Boolean /\ TaggedPtr -> Boolean /\ UntaggedInt1
// TODO(neis): Activate once ChangeRepresentation works in typer. // TODO(neis): Activate once ChangeRepresentation works in typer.
...@@ -1065,6 +1067,7 @@ void Verifier::Visitor::Check(Node* node) { ...@@ -1065,6 +1067,7 @@ void Verifier::Visitor::Check(Node* node) {
case IrOpcode::kCheckedTaggedToInt32: case IrOpcode::kCheckedTaggedToInt32:
case IrOpcode::kCheckedTaggedToFloat64: case IrOpcode::kCheckedTaggedToFloat64:
case IrOpcode::kCheckedTaggedToTaggedSigned: case IrOpcode::kCheckedTaggedToTaggedSigned:
case IrOpcode::kCheckedTaggedToTaggedPointer:
case IrOpcode::kCheckedTruncateTaggedToWord32: case IrOpcode::kCheckedTruncateTaggedToWord32:
break; break;
......
...@@ -234,6 +234,11 @@ inline bool CanBeTaggedPointer(MachineRepresentation rep) { ...@@ -234,6 +234,11 @@ inline bool CanBeTaggedPointer(MachineRepresentation rep) {
rep == MachineRepresentation::kTaggedPointer; rep == MachineRepresentation::kTaggedPointer;
} }
inline bool CanBeTaggedSigned(MachineRepresentation rep) {
return rep == MachineRepresentation::kTagged ||
rep == MachineRepresentation::kTaggedSigned;
}
inline bool IsAnyTagged(MachineRepresentation rep) { inline bool IsAnyTagged(MachineRepresentation rep) {
return CanBeTaggedPointer(rep) || rep == MachineRepresentation::kTaggedSigned; return CanBeTaggedPointer(rep) || rep == MachineRepresentation::kTaggedSigned;
} }
......
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