Commit c83b21ab authored by jarin's avatar jarin Committed by Commit bot

[turbofan] Insert dummy values when changing from None type.

Currently we choose the MachineRepresentation::kNone representation for
values of Type::None, and when converting values from the kNone representation
we use "impossible" conversions that will crash at runtime. This
assumes that the impossible conversions should never be hit (the only
way to produce the impossible values is to perform an always-failing
runtime check on a value, such as Smi-checking a string). Note that
this assumes that the runtime check is executed before the impossible
convesrion.

Introducing BitwiseOr type feedback broke this in two ways:

- we always pick Word32 representation for bitwise-or, so the
  impossible conversion does not trigger (it only triggers with
  None representation), and we could end up with unsupported
  conversions from Word32.

- even if we inserted impossible conversions, they are pure conversions.
  Since untagging, bitwise-or operations are also pure, we could hoist
  all these before the smi check of the inputs and we could hit the
  impossible conversions before we get to the smi check.

This CL addresses this by just providing dummy values for conversions
from the Type::None type. It also removes the impossible-to-* conversions.

BUG=chromium:638132

Review-Url: https://codereview.chromium.org/2266823002
Cr-Commit-Position: refs/heads/master@{#38883}
parent 052ba98d
...@@ -267,9 +267,7 @@ namespace internal { ...@@ -267,9 +267,7 @@ namespace internal {
V(kWrongArgumentCountForInvokeIntrinsic, \ V(kWrongArgumentCountForInvokeIntrinsic, \
"Wrong number of arguments for intrinsic") \ "Wrong number of arguments for intrinsic") \
V(kShouldNotDirectlyEnterOsrFunction, \ V(kShouldNotDirectlyEnterOsrFunction, \
"Should not directly enter OSR-compiled function") \ "Should not directly enter OSR-compiled function")
V(kConversionFromImpossibleValue, \
"Reached conversion from value with empty type (i.e., impossible type)")
#define ERROR_MESSAGES_CONSTANTS(C, T) C, #define ERROR_MESSAGES_CONSTANTS(C, T) C,
enum BailoutReason { enum BailoutReason {
......
...@@ -707,9 +707,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -707,9 +707,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kArchDebugBreak: case kArchDebugBreak:
__ stop("kArchDebugBreak"); __ stop("kArchDebugBreak");
break; break;
case kArchImpossible:
__ Abort(kConversionFromImpossibleValue);
break;
case kArchComment: { case kArchComment: {
Address comment_string = i.InputExternalReference(0).address(); Address comment_string = i.InputExternalReference(0).address();
__ RecordComment(reinterpret_cast<const char*>(comment_string)); __ RecordComment(reinterpret_cast<const char*>(comment_string));
......
...@@ -766,9 +766,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -766,9 +766,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kArchDebugBreak: case kArchDebugBreak:
__ Debug("kArchDebugBreak", 0, BREAK); __ Debug("kArchDebugBreak", 0, BREAK);
break; break;
case kArchImpossible:
__ Abort(kConversionFromImpossibleValue);
break;
case kArchComment: { case kArchComment: {
Address comment_string = i.InputExternalReference(0).address(); Address comment_string = i.InputExternalReference(0).address();
__ RecordComment(reinterpret_cast<const char*>(comment_string)); __ RecordComment(reinterpret_cast<const char*>(comment_string));
......
...@@ -637,9 +637,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -637,9 +637,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kArchDebugBreak: case kArchDebugBreak:
__ int3(); __ int3();
break; break;
case kArchImpossible:
__ Abort(kConversionFromImpossibleValue);
break;
case kArchNop: case kArchNop:
case kArchThrowTerminator: case kArchThrowTerminator:
// don't emit code for nops. // don't emit code for nops.
......
...@@ -57,7 +57,6 @@ enum class RecordWriteMode { kValueIsMap, kValueIsPointer, kValueIsAny }; ...@@ -57,7 +57,6 @@ enum class RecordWriteMode { kValueIsMap, kValueIsPointer, kValueIsAny };
V(ArchTableSwitch) \ V(ArchTableSwitch) \
V(ArchNop) \ V(ArchNop) \
V(ArchDebugBreak) \ V(ArchDebugBreak) \
V(ArchImpossible) \
V(ArchComment) \ V(ArchComment) \
V(ArchThrowTerminator) \ V(ArchThrowTerminator) \
V(ArchDeoptimize) \ V(ArchDeoptimize) \
......
...@@ -242,7 +242,6 @@ int InstructionScheduler::GetInstructionFlags(const Instruction* instr) const { ...@@ -242,7 +242,6 @@ int InstructionScheduler::GetInstructionFlags(const Instruction* instr) const {
case kArchTruncateDoubleToI: case kArchTruncateDoubleToI:
case kArchStackSlot: case kArchStackSlot:
case kArchDebugBreak: case kArchDebugBreak:
case kArchImpossible:
case kArchComment: case kArchComment:
case kIeee754Float64Acos: case kIeee754Float64Acos:
case kIeee754Float64Acosh: case kIeee754Float64Acosh:
......
...@@ -350,6 +350,10 @@ enum class FrameStateInputKind { kAny, kStackSlot }; ...@@ -350,6 +350,10 @@ enum class FrameStateInputKind { kAny, kStackSlot };
InstructionOperand OperandForDeopt(OperandGenerator* g, Node* input, InstructionOperand OperandForDeopt(OperandGenerator* g, Node* input,
FrameStateInputKind kind, FrameStateInputKind kind,
MachineRepresentation rep) { MachineRepresentation rep) {
if (rep == MachineRepresentation::kNone) {
return g->TempImmediate(FrameStateDescriptor::kImpossibleValue);
}
switch (input->opcode()) { switch (input->opcode()) {
case IrOpcode::kInt32Constant: case IrOpcode::kInt32Constant:
case IrOpcode::kInt64Constant: case IrOpcode::kInt64Constant:
...@@ -362,17 +366,13 @@ InstructionOperand OperandForDeopt(OperandGenerator* g, Node* input, ...@@ -362,17 +366,13 @@ InstructionOperand OperandForDeopt(OperandGenerator* g, Node* input,
UNREACHABLE(); UNREACHABLE();
break; break;
default: default:
if (rep == MachineRepresentation::kNone) { switch (kind) {
return g->TempImmediate(FrameStateDescriptor::kImpossibleValue); case FrameStateInputKind::kStackSlot:
} else { return g->UseUniqueSlot(input);
switch (kind) { case FrameStateInputKind::kAny:
case FrameStateInputKind::kStackSlot: // Currently deopts "wrap" other operations, so the deopt's inputs
return g->UseUniqueSlot(input); // are potentially needed untill the end of the deoptimising code.
case FrameStateInputKind::kAny: return g->UseAnyAtEnd(input);
// Currently deopts "wrap" other operations, so the deopt's inputs
// are potentially needed untill the end of the deoptimising code.
return g->UseAnyAtEnd(input);
}
} }
} }
UNREACHABLE(); UNREACHABLE();
...@@ -1067,19 +1067,6 @@ void InstructionSelector::VisitNode(Node* node) { ...@@ -1067,19 +1067,6 @@ void InstructionSelector::VisitNode(Node* node) {
return MarkAsWord32(node), VisitChangeFloat64ToInt32(node); return MarkAsWord32(node), VisitChangeFloat64ToInt32(node);
case IrOpcode::kChangeFloat64ToUint32: case IrOpcode::kChangeFloat64ToUint32:
return MarkAsWord32(node), VisitChangeFloat64ToUint32(node); return MarkAsWord32(node), VisitChangeFloat64ToUint32(node);
case IrOpcode::kImpossibleToWord32:
return MarkAsWord32(node), VisitImpossibleToWord32(node);
case IrOpcode::kImpossibleToWord64:
return MarkAsWord64(node), VisitImpossibleToWord64(node);
case IrOpcode::kImpossibleToFloat32:
return MarkAsFloat32(node), VisitImpossibleToFloat32(node);
case IrOpcode::kImpossibleToFloat64:
return MarkAsFloat64(node), VisitImpossibleToFloat64(node);
case IrOpcode::kImpossibleToTagged:
MarkAsRepresentation(MachineType::PointerRepresentation(), node);
return VisitImpossibleToTagged(node);
case IrOpcode::kImpossibleToBit:
return MarkAsWord32(node), VisitImpossibleToBit(node);
case IrOpcode::kFloat64SilenceNaN: case IrOpcode::kFloat64SilenceNaN:
MarkAsFloat64(node); MarkAsFloat64(node);
if (CanProduceSignalingNaN(node->InputAt(0))) { if (CanProduceSignalingNaN(node->InputAt(0))) {
...@@ -1320,42 +1307,6 @@ void InstructionSelector::VisitNode(Node* node) { ...@@ -1320,42 +1307,6 @@ void InstructionSelector::VisitNode(Node* node) {
} }
} }
void InstructionSelector::VisitImpossibleToWord32(Node* node) {
OperandGenerator g(this);
Emit(kArchImpossible, g.DefineAsConstant(node, Constant(0)));
}
void InstructionSelector::VisitImpossibleToWord64(Node* node) {
OperandGenerator g(this);
Emit(kArchImpossible,
g.DefineAsConstant(node, Constant(static_cast<int64_t>(0))));
}
void InstructionSelector::VisitImpossibleToFloat32(Node* node) {
OperandGenerator g(this);
Emit(kArchImpossible, g.DefineAsConstant(node, Constant(0.0f)));
}
void InstructionSelector::VisitImpossibleToFloat64(Node* node) {
OperandGenerator g(this);
Emit(kArchImpossible, g.DefineAsConstant(node, Constant(0.0)));
}
void InstructionSelector::VisitImpossibleToBit(Node* node) {
OperandGenerator g(this);
Emit(kArchImpossible, g.DefineAsConstant(node, Constant(0)));
}
void InstructionSelector::VisitImpossibleToTagged(Node* node) {
OperandGenerator g(this);
#if V8_TARGET_ARCH_64_BIT
Emit(kArchImpossible,
g.DefineAsConstant(node, Constant(static_cast<int64_t>(0))));
#else // V8_TARGET_ARCH_64_BIT
Emit(kArchImpossible, g.DefineAsConstant(node, Constant(0)));
#endif // V8_TARGET_ARCH_64_BIT
}
void InstructionSelector::VisitLoadStackPointer(Node* node) { void InstructionSelector::VisitLoadStackPointer(Node* node) {
OperandGenerator g(this); OperandGenerator g(this);
Emit(kArchStackPointer, g.DefineAsRegister(node)); Emit(kArchStackPointer, g.DefineAsRegister(node));
......
...@@ -145,12 +145,6 @@ MachineRepresentation AtomicStoreRepresentationOf(Operator const* op) { ...@@ -145,12 +145,6 @@ MachineRepresentation AtomicStoreRepresentationOf(Operator const* op) {
V(ChangeInt32ToInt64, Operator::kNoProperties, 1, 0, 1) \ V(ChangeInt32ToInt64, Operator::kNoProperties, 1, 0, 1) \
V(ChangeUint32ToFloat64, Operator::kNoProperties, 1, 0, 1) \ V(ChangeUint32ToFloat64, Operator::kNoProperties, 1, 0, 1) \
V(ChangeUint32ToUint64, Operator::kNoProperties, 1, 0, 1) \ V(ChangeUint32ToUint64, Operator::kNoProperties, 1, 0, 1) \
V(ImpossibleToWord32, Operator::kNoProperties, 1, 0, 1) \
V(ImpossibleToWord64, Operator::kNoProperties, 1, 0, 1) \
V(ImpossibleToFloat32, Operator::kNoProperties, 1, 0, 1) \
V(ImpossibleToFloat64, Operator::kNoProperties, 1, 0, 1) \
V(ImpossibleToTagged, Operator::kNoProperties, 1, 0, 1) \
V(ImpossibleToBit, Operator::kNoProperties, 1, 0, 1) \
V(TruncateFloat64ToFloat32, Operator::kNoProperties, 1, 0, 1) \ V(TruncateFloat64ToFloat32, Operator::kNoProperties, 1, 0, 1) \
V(TruncateInt64ToInt32, Operator::kNoProperties, 1, 0, 1) \ V(TruncateInt64ToInt32, Operator::kNoProperties, 1, 0, 1) \
V(BitcastFloat32ToInt32, Operator::kNoProperties, 1, 0, 1) \ V(BitcastFloat32ToInt32, Operator::kNoProperties, 1, 0, 1) \
......
...@@ -302,16 +302,6 @@ class MachineOperatorBuilder final : public ZoneObject { ...@@ -302,16 +302,6 @@ class MachineOperatorBuilder final : public ZoneObject {
const Operator* ChangeUint32ToFloat64(); const Operator* ChangeUint32ToFloat64();
const Operator* ChangeUint32ToUint64(); const Operator* ChangeUint32ToUint64();
// These are changes from impossible values (for example a smi-checked
// string). They can safely emit an abort instruction, which should
// never be reached.
const Operator* ImpossibleToWord32();
const Operator* ImpossibleToWord64();
const Operator* ImpossibleToFloat32();
const Operator* ImpossibleToFloat64();
const Operator* ImpossibleToTagged();
const Operator* ImpossibleToBit();
// These operators truncate or round numbers, both changing the representation // These operators truncate or round numbers, both changing the representation
// of the number and mapping multiple input values onto the same output value. // of the number and mapping multiple input values onto the same output value.
const Operator* TruncateFloat64ToFloat32(); const Operator* TruncateFloat64ToFloat32();
......
...@@ -693,9 +693,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -693,9 +693,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kArchDebugBreak: case kArchDebugBreak:
__ stop("kArchDebugBreak"); __ stop("kArchDebugBreak");
break; break;
case kArchImpossible:
__ Abort(kConversionFromImpossibleValue);
break;
case kArchComment: { case kArchComment: {
Address comment_string = i.InputExternalReference(0).address(); Address comment_string = i.InputExternalReference(0).address();
__ RecordComment(reinterpret_cast<const char*>(comment_string)); __ RecordComment(reinterpret_cast<const char*>(comment_string));
......
...@@ -702,9 +702,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -702,9 +702,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kArchDebugBreak: case kArchDebugBreak:
__ stop("kArchDebugBreak"); __ stop("kArchDebugBreak");
break; break;
case kArchImpossible:
__ Abort(kConversionFromImpossibleValue);
break;
case kArchComment: { case kArchComment: {
Address comment_string = i.InputExternalReference(0).address(); Address comment_string = i.InputExternalReference(0).address();
__ RecordComment(reinterpret_cast<const char*>(comment_string)); __ RecordComment(reinterpret_cast<const char*>(comment_string));
......
...@@ -407,12 +407,6 @@ ...@@ -407,12 +407,6 @@
V(ChangeInt32ToInt64) \ V(ChangeInt32ToInt64) \
V(ChangeUint32ToFloat64) \ V(ChangeUint32ToFloat64) \
V(ChangeUint32ToUint64) \ V(ChangeUint32ToUint64) \
V(ImpossibleToBit) \
V(ImpossibleToWord32) \
V(ImpossibleToWord64) \
V(ImpossibleToFloat32) \
V(ImpossibleToFloat64) \
V(ImpossibleToTagged) \
V(TruncateFloat64ToFloat32) \ V(TruncateFloat64ToFloat32) \
V(TruncateInt64ToInt32) \ V(TruncateInt64ToInt32) \
V(RoundFloat64ToInt32) \ V(RoundFloat64ToInt32) \
......
...@@ -1077,9 +1077,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -1077,9 +1077,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kArchDebugBreak: case kArchDebugBreak:
__ stop("kArchDebugBreak"); __ stop("kArchDebugBreak");
break; break;
case kArchImpossible:
__ Abort(kConversionFromImpossibleValue);
break;
case kArchNop: case kArchNop:
case kArchThrowTerminator: case kArchThrowTerminator:
// don't emit code for nops. // don't emit code for nops.
......
...@@ -204,10 +204,10 @@ Node* RepresentationChanger::GetTaggedRepresentationFor( ...@@ -204,10 +204,10 @@ Node* RepresentationChanger::GetTaggedRepresentationFor(
} }
// Select the correct X -> Tagged operator. // Select the correct X -> Tagged operator.
const Operator* op; const Operator* op;
if (output_rep == MachineRepresentation::kNone) { if (!output_type->IsInhabited()) {
// We should only asisgn this representation if the type is empty. // This is an impossible value; it should not be used at runtime.
CHECK(!output_type->IsInhabited()); // We just provide a dummy value here.
op = machine()->ImpossibleToTagged(); return jsgraph()->TheHoleConstant();
} else if (output_rep == MachineRepresentation::kBit) { } else if (output_rep == MachineRepresentation::kBit) {
if (output_type->Is(Type::Boolean())) { if (output_type->Is(Type::Boolean())) {
op = simplified()->ChangeBitToTagged(); op = simplified()->ChangeBitToTagged();
...@@ -283,10 +283,10 @@ Node* RepresentationChanger::GetFloat32RepresentationFor( ...@@ -283,10 +283,10 @@ Node* RepresentationChanger::GetFloat32RepresentationFor(
} }
// Select the correct X -> Float32 operator. // Select the correct X -> Float32 operator.
const Operator* op = nullptr; const Operator* op = nullptr;
if (output_rep == MachineRepresentation::kNone) { if (!output_type->IsInhabited()) {
// We should only use kNone representation if the type is empty. // This is an impossible value; it should not be used at runtime.
CHECK(!output_type->IsInhabited()); // We just provide a dummy value here.
op = machine()->ImpossibleToFloat32(); return jsgraph()->Float32Constant(0.0f);
} else if (IsWord(output_rep)) { } else if (IsWord(output_rep)) {
if (output_type->Is(Type::Signed32())) { if (output_type->Is(Type::Signed32())) {
// int32 -> float64 -> float32 // int32 -> float64 -> float32
...@@ -352,10 +352,10 @@ Node* RepresentationChanger::GetFloat64RepresentationFor( ...@@ -352,10 +352,10 @@ Node* RepresentationChanger::GetFloat64RepresentationFor(
} }
// Select the correct X -> Float64 operator. // Select the correct X -> Float64 operator.
const Operator* op = nullptr; const Operator* op = nullptr;
if (output_rep == MachineRepresentation::kNone) { if (!output_type->IsInhabited()) {
// We should only use kNone representation if the type is empty. // This is an impossible value; it should not be used at runtime.
CHECK(!output_type->IsInhabited()); // We just provide a dummy value here.
op = machine()->ImpossibleToFloat64(); return jsgraph()->Float64Constant(0.0);
} else if (IsWord(output_rep)) { } else if (IsWord(output_rep)) {
if (output_type->Is(Type::Signed32())) { if (output_type->Is(Type::Signed32())) {
op = machine()->ChangeInt32ToFloat64(); op = machine()->ChangeInt32ToFloat64();
...@@ -435,10 +435,10 @@ Node* RepresentationChanger::GetWord32RepresentationFor( ...@@ -435,10 +435,10 @@ Node* RepresentationChanger::GetWord32RepresentationFor(
// Select the correct X -> Word32 operator. // Select the correct X -> Word32 operator.
const Operator* op = nullptr; const Operator* op = nullptr;
if (output_rep == MachineRepresentation::kNone) { if (!output_type->IsInhabited()) {
// We should only use kNone representation if the type is empty. // This is an impossible value; it should not be used at runtime.
CHECK(!output_type->IsInhabited()); // We just provide a dummy value here.
op = machine()->ImpossibleToWord32(); return jsgraph()->Int32Constant(0);
} else if (output_rep == MachineRepresentation::kBit) { } else if (output_rep == MachineRepresentation::kBit) {
return node; // Sloppy comparison -> word32 return node; // Sloppy comparison -> word32
} else if (output_rep == MachineRepresentation::kFloat64) { } else if (output_rep == MachineRepresentation::kFloat64) {
...@@ -551,10 +551,10 @@ Node* RepresentationChanger::GetBitRepresentationFor( ...@@ -551,10 +551,10 @@ Node* RepresentationChanger::GetBitRepresentationFor(
} }
// Select the correct X -> Bit operator. // Select the correct X -> Bit operator.
const Operator* op; const Operator* op;
if (output_rep == MachineRepresentation::kNone) { if (!output_type->IsInhabited()) {
// We should only use kNone representation if the type is empty. // This is an impossible value; it should not be used at runtime.
CHECK(!output_type->IsInhabited()); // We just provide a dummy value here.
op = machine()->ImpossibleToBit(); return jsgraph()->Int32Constant(0);
} else if (output_rep == MachineRepresentation::kTagged) { } else if (output_rep == MachineRepresentation::kTagged) {
op = simplified()->ChangeTaggedToBit(); op = simplified()->ChangeTaggedToBit();
} else { } else {
...@@ -566,10 +566,10 @@ Node* RepresentationChanger::GetBitRepresentationFor( ...@@ -566,10 +566,10 @@ Node* RepresentationChanger::GetBitRepresentationFor(
Node* RepresentationChanger::GetWord64RepresentationFor( Node* RepresentationChanger::GetWord64RepresentationFor(
Node* node, MachineRepresentation output_rep, Type* output_type) { Node* node, MachineRepresentation output_rep, Type* output_type) {
if (output_rep == MachineRepresentation::kNone) { if (!output_type->IsInhabited()) {
// We should only use kNone representation if the type is empty. // This is an impossible value; it should not be used at runtime.
CHECK(!output_type->IsInhabited()); // We just provide a dummy value here.
return jsgraph()->graph()->NewNode(machine()->ImpossibleToFloat64(), node); return jsgraph()->Int64Constant(0);
} else if (output_rep == MachineRepresentation::kBit) { } else if (output_rep == MachineRepresentation::kBit) {
return node; // Sloppy comparison -> word64 return node; // Sloppy comparison -> word64
} }
......
...@@ -980,9 +980,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -980,9 +980,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kArchDebugBreak: case kArchDebugBreak:
__ stop("kArchDebugBreak"); __ stop("kArchDebugBreak");
break; break;
case kArchImpossible:
__ Abort(kConversionFromImpossibleValue);
break;
case kArchNop: case kArchNop:
case kArchThrowTerminator: case kArchThrowTerminator:
// don't emit code for nops. // don't emit code for nops.
......
...@@ -311,6 +311,9 @@ class RepresentationSelector { ...@@ -311,6 +311,9 @@ class RepresentationSelector {
bool updated = UpdateFeedbackType(node); bool updated = UpdateFeedbackType(node);
TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic()); TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic());
VisitNode(node, info->truncation(), nullptr); VisitNode(node, info->truncation(), nullptr);
TRACE(" ==> output ");
PrintOutputInfo(info);
TRACE("\n");
if (updated) { if (updated) {
for (Node* const user : node->uses()) { for (Node* const user : node->uses()) {
if (GetInfo(user)->visited()) { if (GetInfo(user)->visited()) {
...@@ -330,6 +333,9 @@ class RepresentationSelector { ...@@ -330,6 +333,9 @@ class RepresentationSelector {
bool updated = UpdateFeedbackType(node); bool updated = UpdateFeedbackType(node);
TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic()); TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic());
VisitNode(node, info->truncation(), nullptr); VisitNode(node, info->truncation(), nullptr);
TRACE(" ==> output ");
PrintOutputInfo(info);
TRACE("\n");
if (updated) { if (updated) {
for (Node* const user : node->uses()) { for (Node* const user : node->uses()) {
if (GetInfo(user)->visited()) { if (GetInfo(user)->visited()) {
...@@ -534,9 +540,6 @@ class RepresentationSelector { ...@@ -534,9 +540,6 @@ class RepresentationSelector {
TRACE(" visit #%d: %s (trunc: %s)\n", node->id(), node->op()->mnemonic(), TRACE(" visit #%d: %s (trunc: %s)\n", node->id(), node->op()->mnemonic(),
info->truncation().description()); info->truncation().description());
VisitNode(node, info->truncation(), nullptr); VisitNode(node, info->truncation(), nullptr);
TRACE(" ==> output ");
PrintOutputInfo(info);
TRACE("\n");
} }
} }
...@@ -986,8 +989,11 @@ class RepresentationSelector { ...@@ -986,8 +989,11 @@ class RepresentationSelector {
for (int i = 0; i < node->InputCount(); i++) { for (int i = 0; i < node->InputCount(); i++) {
Node* input = node->InputAt(i); Node* input = node->InputAt(i);
NodeInfo* input_info = GetInfo(input); NodeInfo* input_info = GetInfo(input);
MachineType machine_type(input_info->representation(), Type* input_type = TypeOf(input);
DeoptValueSemanticOf(TypeOf(input))); MachineRepresentation rep = input_type->IsInhabited()
? input_info->representation()
: MachineRepresentation::kNone;
MachineType machine_type(rep, DeoptValueSemanticOf(input_type));
DCHECK(machine_type.representation() != DCHECK(machine_type.representation() !=
MachineRepresentation::kWord32 || MachineRepresentation::kWord32 ||
machine_type.semantic() == MachineSemantic::kInt32 || machine_type.semantic() == MachineSemantic::kInt32 ||
......
...@@ -1980,28 +1980,6 @@ Type* Typer::Visitor::TypeChangeUint32ToUint64(Node* node) { ...@@ -1980,28 +1980,6 @@ Type* Typer::Visitor::TypeChangeUint32ToUint64(Node* node) {
return Type::Internal(); return Type::Internal();
} }
Type* Typer::Visitor::TypeImpossibleToWord32(Node* node) {
return Type::None();
}
Type* Typer::Visitor::TypeImpossibleToWord64(Node* node) {
return Type::None();
}
Type* Typer::Visitor::TypeImpossibleToFloat32(Node* node) {
return Type::None();
}
Type* Typer::Visitor::TypeImpossibleToFloat64(Node* node) {
return Type::None();
}
Type* Typer::Visitor::TypeImpossibleToTagged(Node* node) {
return Type::None();
}
Type* Typer::Visitor::TypeImpossibleToBit(Node* node) { return Type::None(); }
Type* Typer::Visitor::TypeTruncateFloat64ToFloat32(Node* node) { Type* Typer::Visitor::TypeTruncateFloat64ToFloat32(Node* node) {
return Type::Intersect(Type::Number(), Type::UntaggedFloat32(), zone()); return Type::Intersect(Type::Number(), Type::UntaggedFloat32(), zone());
} }
......
...@@ -1003,14 +1003,6 @@ void Verifier::Visitor::Check(Node* node) { ...@@ -1003,14 +1003,6 @@ void Verifier::Visitor::Check(Node* node) {
// CheckUpperIs(node, to)); // CheckUpperIs(node, to));
break; break;
} }
case IrOpcode::kImpossibleToWord32:
case IrOpcode::kImpossibleToWord64:
case IrOpcode::kImpossibleToFloat32:
case IrOpcode::kImpossibleToFloat64:
case IrOpcode::kImpossibleToTagged:
case IrOpcode::kImpossibleToBit:
break;
case IrOpcode::kCheckBounds: case IrOpcode::kCheckBounds:
CheckValueInputIs(node, 0, Type::Any()); CheckValueInputIs(node, 0, Type::Any());
CheckValueInputIs(node, 1, Type::Unsigned31()); CheckValueInputIs(node, 1, Type::Unsigned31());
......
...@@ -866,9 +866,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -866,9 +866,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kArchDebugBreak: case kArchDebugBreak:
__ int3(); __ int3();
break; break;
case kArchImpossible:
__ Abort(kConversionFromImpossibleValue);
break;
case kArchNop: case kArchNop:
case kArchThrowTerminator: case kArchThrowTerminator:
// don't emit code for nops. // don't emit code for nops.
......
...@@ -715,9 +715,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -715,9 +715,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kArchDebugBreak: case kArchDebugBreak:
__ int3(); __ int3();
break; break;
case kArchImpossible:
__ Abort(kConversionFromImpossibleValue);
break;
case kArchNop: case kArchNop:
case kArchThrowTerminator: case kArchThrowTerminator:
// don't emit code for nops. // don't emit code for nops.
......
...@@ -493,9 +493,9 @@ static void CheckChange(IrOpcode::Value expected, MachineRepresentation from, ...@@ -493,9 +493,9 @@ static void CheckChange(IrOpcode::Value expected, MachineRepresentation from,
TEST(SingleChanges) { TEST(SingleChanges) {
CheckChange(IrOpcode::kChangeTaggedToBit, MachineRepresentation::kTagged, CheckChange(IrOpcode::kChangeTaggedToBit, MachineRepresentation::kTagged,
Type::None(), MachineRepresentation::kBit); Type::Boolean(), MachineRepresentation::kBit);
CheckChange(IrOpcode::kChangeBitToTagged, MachineRepresentation::kBit, CheckChange(IrOpcode::kChangeBitToTagged, MachineRepresentation::kBit,
Type::None(), MachineRepresentation::kTagged); Type::Boolean(), MachineRepresentation::kTagged);
CheckChange(IrOpcode::kChangeInt31ToTaggedSigned, CheckChange(IrOpcode::kChangeInt31ToTaggedSigned,
MachineRepresentation::kWord32, Type::Signed31(), MachineRepresentation::kWord32, Type::Signed31(),
...@@ -546,7 +546,7 @@ TEST(SingleChanges) { ...@@ -546,7 +546,7 @@ TEST(SingleChanges) {
Type::Unsigned32(), MachineRepresentation::kWord32); Type::Unsigned32(), MachineRepresentation::kWord32);
CheckChange(IrOpcode::kTruncateFloat64ToFloat32, CheckChange(IrOpcode::kTruncateFloat64ToFloat32,
MachineRepresentation::kFloat64, Type::None(), MachineRepresentation::kFloat64, Type::Number(),
MachineRepresentation::kFloat32); MachineRepresentation::kFloat32);
// Int32,Uint32 <-> Float32 require two changes. // Int32,Uint32 <-> Float32 require two changes.
...@@ -570,11 +570,11 @@ TEST(SingleChanges) { ...@@ -570,11 +570,11 @@ TEST(SingleChanges) {
// Float32 <-> Tagged require two changes. // Float32 <-> Tagged require two changes.
CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64, CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64,
IrOpcode::kChangeFloat64ToTagged, IrOpcode::kChangeFloat64ToTagged,
MachineRepresentation::kFloat32, Type::None(), MachineRepresentation::kFloat32, Type::Number(),
MachineRepresentation::kTagged); MachineRepresentation::kTagged);
CheckTwoChanges(IrOpcode::kChangeTaggedToFloat64, CheckTwoChanges(IrOpcode::kChangeTaggedToFloat64,
IrOpcode::kTruncateFloat64ToFloat32, IrOpcode::kTruncateFloat64ToFloat32,
MachineRepresentation::kTagged, Type::None(), MachineRepresentation::kTagged, Type::Number(),
MachineRepresentation::kFloat32); MachineRepresentation::kFloat32);
} }
...@@ -587,7 +587,7 @@ TEST(SignednessInWord32) { ...@@ -587,7 +587,7 @@ TEST(SignednessInWord32) {
CheckChange(IrOpcode::kChangeTaggedToUint32, MachineRepresentation::kTagged, CheckChange(IrOpcode::kChangeTaggedToUint32, MachineRepresentation::kTagged,
Type::Unsigned32(), MachineRepresentation::kWord32); Type::Unsigned32(), MachineRepresentation::kWord32);
CheckChange(IrOpcode::kChangeInt32ToFloat64, MachineRepresentation::kWord32, CheckChange(IrOpcode::kChangeInt32ToFloat64, MachineRepresentation::kWord32,
Type::None(), MachineRepresentation::kFloat64); Type::Signed32(), MachineRepresentation::kFloat64);
CheckChange(IrOpcode::kChangeFloat64ToInt32, MachineRepresentation::kFloat64, CheckChange(IrOpcode::kChangeFloat64ToInt32, MachineRepresentation::kFloat64,
Type::Signed32(), MachineRepresentation::kWord32); Type::Signed32(), MachineRepresentation::kWord32);
CheckChange(IrOpcode::kTruncateFloat64ToWord32, CheckChange(IrOpcode::kTruncateFloat64ToWord32,
...@@ -600,7 +600,7 @@ TEST(SignednessInWord32) { ...@@ -600,7 +600,7 @@ TEST(SignednessInWord32) {
CheckTwoChanges(IrOpcode::kChangeInt32ToFloat64, CheckTwoChanges(IrOpcode::kChangeInt32ToFloat64,
IrOpcode::kTruncateFloat64ToFloat32, IrOpcode::kTruncateFloat64ToFloat32,
MachineRepresentation::kWord32, Type::None(), MachineRepresentation::kWord32, Type::Signed32(),
MachineRepresentation::kFloat32); MachineRepresentation::kFloat32);
CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64, CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64,
IrOpcode::kTruncateFloat64ToWord32, IrOpcode::kTruncateFloat64ToWord32,
...@@ -614,13 +614,11 @@ TEST(Nops) { ...@@ -614,13 +614,11 @@ TEST(Nops) {
// X -> X is always a nop for any single representation X. // X -> X is always a nop for any single representation X.
for (size_t i = 0; i < arraysize(kMachineTypes); i++) { for (size_t i = 0; i < arraysize(kMachineTypes); i++) {
r.CheckNop(kMachineTypes[i].representation(), Type::None(), r.CheckNop(kMachineTypes[i].representation(), Type::Number(),
kMachineTypes[i].representation()); kMachineTypes[i].representation());
} }
// 32-bit floats. // 32-bit floats.
r.CheckNop(MachineRepresentation::kFloat32, Type::None(),
MachineRepresentation::kFloat32);
r.CheckNop(MachineRepresentation::kFloat32, Type::Number(), r.CheckNop(MachineRepresentation::kFloat32, Type::Number(),
MachineRepresentation::kFloat32); MachineRepresentation::kFloat32);
...@@ -639,14 +637,6 @@ TEST(Nops) { ...@@ -639,14 +637,6 @@ TEST(Nops) {
MachineRepresentation::kWord32); MachineRepresentation::kWord32);
// kRepBit (result of comparison) is implicitly a wordish thing. // kRepBit (result of comparison) is implicitly a wordish thing.
r.CheckNop(MachineRepresentation::kBit, Type::None(),
MachineRepresentation::kWord8);
r.CheckNop(MachineRepresentation::kBit, Type::None(),
MachineRepresentation::kWord16);
r.CheckNop(MachineRepresentation::kBit, Type::None(),
MachineRepresentation::kWord32);
r.CheckNop(MachineRepresentation::kBit, Type::None(),
MachineRepresentation::kWord64);
r.CheckNop(MachineRepresentation::kBit, Type::Boolean(), r.CheckNop(MachineRepresentation::kBit, Type::Boolean(),
MachineRepresentation::kWord8); MachineRepresentation::kWord8);
r.CheckNop(MachineRepresentation::kBit, Type::Boolean(), r.CheckNop(MachineRepresentation::kBit, Type::Boolean(),
...@@ -662,39 +652,39 @@ TEST(TypeErrors) { ...@@ -662,39 +652,39 @@ TEST(TypeErrors) {
RepresentationChangerTester r; RepresentationChangerTester r;
// Wordish cannot be implicitly converted to/from comparison conditions. // Wordish cannot be implicitly converted to/from comparison conditions.
r.CheckTypeError(MachineRepresentation::kWord8, Type::None(), r.CheckTypeError(MachineRepresentation::kWord8, Type::Number(),
MachineRepresentation::kBit); MachineRepresentation::kBit);
r.CheckTypeError(MachineRepresentation::kWord16, Type::None(), r.CheckTypeError(MachineRepresentation::kWord16, Type::Number(),
MachineRepresentation::kBit); MachineRepresentation::kBit);
r.CheckTypeError(MachineRepresentation::kWord32, Type::None(), r.CheckTypeError(MachineRepresentation::kWord32, Type::Number(),
MachineRepresentation::kBit); MachineRepresentation::kBit);
r.CheckTypeError(MachineRepresentation::kWord64, Type::None(), r.CheckTypeError(MachineRepresentation::kWord64, Type::Number(),
MachineRepresentation::kBit); MachineRepresentation::kBit);
// Floats cannot be implicitly converted to/from comparison conditions. // Floats cannot be implicitly converted to/from comparison conditions.
r.CheckTypeError(MachineRepresentation::kFloat64, Type::None(), r.CheckTypeError(MachineRepresentation::kFloat64, Type::Number(),
MachineRepresentation::kBit); MachineRepresentation::kBit);
// Floats cannot be implicitly converted to/from comparison conditions. // Floats cannot be implicitly converted to/from comparison conditions.
r.CheckTypeError(MachineRepresentation::kFloat32, Type::None(), r.CheckTypeError(MachineRepresentation::kFloat32, Type::Number(),
MachineRepresentation::kBit); MachineRepresentation::kBit);
r.CheckTypeError(MachineRepresentation::kBit, Type::None(), r.CheckTypeError(MachineRepresentation::kBit, Type::Number(),
MachineRepresentation::kFloat32); MachineRepresentation::kFloat32);
r.CheckTypeError(MachineRepresentation::kBit, Type::Boolean(), r.CheckTypeError(MachineRepresentation::kBit, Type::Boolean(),
MachineRepresentation::kFloat32); MachineRepresentation::kFloat32);
// Word64 is internal and shouldn't be implicitly converted. // Word64 is internal and shouldn't be implicitly converted.
r.CheckTypeError(MachineRepresentation::kWord64, Type::None(), r.CheckTypeError(MachineRepresentation::kWord64, Type::Internal(),
MachineRepresentation::kTagged); MachineRepresentation::kTagged);
r.CheckTypeError(MachineRepresentation::kTagged, Type::None(), r.CheckTypeError(MachineRepresentation::kTagged, Type::Number(),
MachineRepresentation::kWord64); MachineRepresentation::kWord64);
r.CheckTypeError(MachineRepresentation::kTagged, Type::Boolean(), r.CheckTypeError(MachineRepresentation::kTagged, Type::Boolean(),
MachineRepresentation::kWord64); MachineRepresentation::kWord64);
// Word64 / Word32 shouldn't be implicitly converted. // Word64 / Word32 shouldn't be implicitly converted.
r.CheckTypeError(MachineRepresentation::kWord64, Type::None(), r.CheckTypeError(MachineRepresentation::kWord64, Type::Internal(),
MachineRepresentation::kWord32); MachineRepresentation::kWord32);
r.CheckTypeError(MachineRepresentation::kWord32, Type::None(), r.CheckTypeError(MachineRepresentation::kWord32, Type::Number(),
MachineRepresentation::kWord64); MachineRepresentation::kWord64);
r.CheckTypeError(MachineRepresentation::kWord32, Type::Signed32(), r.CheckTypeError(MachineRepresentation::kWord32, Type::Signed32(),
MachineRepresentation::kWord64); MachineRepresentation::kWord64);
......
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
function g(x, y) {
return x | y;
}
function f(b) {
if (b) {
var s = g("a", "b") && true;
return s;
}
}
// Prime function g with Smi feedback.
g(1, 2);
g(1, 2);
f(0);
f(0);
%OptimizeFunctionOnNextCall(f);
// Compile inlined function g with string inputs but Smi feedback.
f(1);
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