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

[turbofan] Remember types for deoptimization during simplified lowering.

With this change, we remember the types of frame state inputs (in a new
operator, called TypedStateValues). Instead of inferring the value types
when building translations, we used the recorded types.

The original approach was not reliable because the passes after
simplified lowering can change node types, and this in turn confuses
the translation builder.

BUG=chromium:468727
LOG=n
R=bmeurer@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#27310}
parent 87af6018
......@@ -509,8 +509,10 @@ void CodeGenerator::AddTranslationForOperand(Translation* translation,
InstructionOperand* op,
MachineType type) {
if (op->IsStackSlot()) {
if (type == kMachBool || type == kMachInt32 || type == kMachInt8 ||
type == kMachInt16) {
// TODO(jarin) kMachBool and kRepBit should materialize true and false
// rather than creating an int value.
if (type == kMachBool || type == kRepBit || type == kMachInt32 ||
type == kMachInt8 || type == kMachInt16) {
translation->StoreInt32StackSlot(op->index());
} else if (type == kMachUint32 || type == kMachUint16 ||
type == kMachUint8) {
......@@ -525,8 +527,10 @@ void CodeGenerator::AddTranslationForOperand(Translation* translation,
translation->StoreDoubleStackSlot(op->index());
} else if (op->IsRegister()) {
InstructionOperandConverter converter(this, instr);
if (type == kMachBool || type == kMachInt32 || type == kMachInt8 ||
type == kMachInt16) {
// TODO(jarin) kMachBool and kRepBit should materialize true and false
// rather than creating an int value.
if (type == kMachBool || type == kRepBit || type == kMachInt32 ||
type == kMachInt8 || type == kMachInt16) {
translation->StoreInt32Register(converter.ToRegister(op));
} else if (type == kMachUint32 || type == kMachUint16 ||
type == kMachUint8) {
......@@ -546,12 +550,14 @@ void CodeGenerator::AddTranslationForOperand(Translation* translation,
Handle<Object> constant_object;
switch (constant.type()) {
case Constant::kInt32:
DCHECK(type == kMachInt32 || type == kMachUint32);
DCHECK(type == kMachInt32 || type == kMachUint32 || type == kRepBit);
constant_object =
isolate()->factory()->NewNumberFromInt(constant.ToInt32());
break;
case Constant::kFloat64:
DCHECK(type == kMachFloat64 || type == kMachAnyTagged);
DCHECK(type == kMachFloat64 || type == kMachAnyTagged ||
type == kRepTagged || type == (kTypeInt32 | kRepTagged) ||
type == (kTypeUint32 | kRepTagged));
constant_object = isolate()->factory()->NewNumber(constant.ToFloat64());
break;
case Constant::kHeapObject:
......
......@@ -604,6 +604,15 @@ const Operator* CommonOperatorBuilder::StateValues(int arguments) {
}
const Operator* CommonOperatorBuilder::TypedStateValues(
const ZoneVector<MachineType>* types) {
return new (zone()) Operator1<const ZoneVector<MachineType>*>( // --
IrOpcode::kTypedStateValues, Operator::kPure, // opcode
"TypedStateValues", // name
static_cast<int>(types->size()), 0, 0, 1, 0, 0, types); // counts
}
const Operator* CommonOperatorBuilder::FrameState(
FrameStateType type, BailoutId bailout_id,
OutputFrameStateCombine state_combine, MaybeHandle<JSFunction> jsfunction) {
......
......@@ -205,6 +205,7 @@ class CommonOperatorBuilder FINAL : public ZoneObject {
const Operator* ValueEffect(int arguments);
const Operator* Finish(int arguments);
const Operator* StateValues(int arguments);
const Operator* TypedStateValues(const ZoneVector<MachineType>* types);
const Operator* FrameState(
FrameStateType type, BailoutId bailout_id,
OutputFrameStateCombine state_combine,
......
......@@ -574,147 +574,6 @@ void InstructionSelector::VisitControl(BasicBlock* block) {
}
MachineType InstructionSelector::GetMachineType(Node* node) {
DCHECK_NOT_NULL(schedule()->block(node)); // should only use scheduled nodes.
switch (node->opcode()) {
case IrOpcode::kStart:
case IrOpcode::kLoop:
case IrOpcode::kEnd:
case IrOpcode::kBranch:
case IrOpcode::kIfTrue:
case IrOpcode::kIfFalse:
case IrOpcode::kSwitch:
case IrOpcode::kIfValue:
case IrOpcode::kIfDefault:
case IrOpcode::kEffectPhi:
case IrOpcode::kEffectSet:
case IrOpcode::kMerge:
// No code needed for these graph artifacts.
return kMachNone;
case IrOpcode::kFinish:
return kMachAnyTagged;
case IrOpcode::kParameter:
return linkage()->GetParameterType(OpParameter<int>(node));
case IrOpcode::kOsrValue:
return kMachAnyTagged;
case IrOpcode::kPhi:
return OpParameter<MachineType>(node);
case IrOpcode::kProjection:
// TODO(jarin) Really project from outputs.
return kMachAnyTagged;
case IrOpcode::kInt32Constant:
return kMachInt32;
case IrOpcode::kInt64Constant:
return kMachInt64;
case IrOpcode::kExternalConstant:
return kMachPtr;
case IrOpcode::kFloat64Constant:
return kMachFloat64;
case IrOpcode::kHeapConstant:
case IrOpcode::kNumberConstant:
return kMachAnyTagged;
case IrOpcode::kCall:
return kMachAnyTagged;
case IrOpcode::kFrameState:
case IrOpcode::kStateValues:
return kMachNone;
case IrOpcode::kLoad:
return OpParameter<LoadRepresentation>(node);
case IrOpcode::kStore:
return kMachNone;
case IrOpcode::kCheckedLoad:
return OpParameter<MachineType>(node);
case IrOpcode::kCheckedStore:
return kMachNone;
case IrOpcode::kWord32And:
case IrOpcode::kWord32Or:
case IrOpcode::kWord32Xor:
case IrOpcode::kWord32Shl:
case IrOpcode::kWord32Shr:
case IrOpcode::kWord32Sar:
case IrOpcode::kWord32Ror:
return kMachInt32;
case IrOpcode::kWord32Equal:
return kMachBool;
case IrOpcode::kWord64And:
case IrOpcode::kWord64Or:
case IrOpcode::kWord64Xor:
case IrOpcode::kWord64Shl:
case IrOpcode::kWord64Shr:
case IrOpcode::kWord64Sar:
case IrOpcode::kWord64Ror:
return kMachInt64;
case IrOpcode::kWord64Equal:
return kMachBool;
case IrOpcode::kInt32Add:
case IrOpcode::kInt32AddWithOverflow:
case IrOpcode::kInt32Sub:
case IrOpcode::kInt32SubWithOverflow:
case IrOpcode::kInt32Mul:
case IrOpcode::kInt32Div:
case IrOpcode::kInt32Mod:
return kMachInt32;
case IrOpcode::kInt32LessThan:
case IrOpcode::kInt32LessThanOrEqual:
case IrOpcode::kUint32LessThan:
case IrOpcode::kUint32LessThanOrEqual:
return kMachBool;
case IrOpcode::kInt64Add:
case IrOpcode::kInt64Sub:
case IrOpcode::kInt64Mul:
case IrOpcode::kInt64Div:
case IrOpcode::kInt64Mod:
return kMachInt64;
case IrOpcode::kInt64LessThan:
case IrOpcode::kInt64LessThanOrEqual:
return kMachBool;
case IrOpcode::kChangeFloat32ToFloat64:
case IrOpcode::kChangeInt32ToFloat64:
case IrOpcode::kChangeUint32ToFloat64:
return kMachFloat64;
case IrOpcode::kChangeFloat64ToInt32:
return kMachInt32;
case IrOpcode::kChangeFloat64ToUint32:
return kMachUint32;
case IrOpcode::kChangeInt32ToInt64:
return kMachInt64;
case IrOpcode::kChangeUint32ToUint64:
return kMachUint64;
case IrOpcode::kTruncateFloat64ToFloat32:
return kMachFloat32;
case IrOpcode::kTruncateFloat64ToInt32:
case IrOpcode::kTruncateInt64ToInt32:
return kMachInt32;
case IrOpcode::kFloat64Add:
case IrOpcode::kFloat64Sub:
case IrOpcode::kFloat64Mul:
case IrOpcode::kFloat64Div:
case IrOpcode::kFloat64Mod:
case IrOpcode::kFloat64Max:
case IrOpcode::kFloat64Min:
case IrOpcode::kFloat64Sqrt:
case IrOpcode::kFloat64RoundDown:
case IrOpcode::kFloat64RoundTruncate:
case IrOpcode::kFloat64RoundTiesAway:
return kMachFloat64;
case IrOpcode::kFloat64Equal:
case IrOpcode::kFloat64LessThan:
case IrOpcode::kFloat64LessThanOrEqual:
return kMachBool;
case IrOpcode::kFloat64ExtractLowWord32:
case IrOpcode::kFloat64ExtractHighWord32:
return kMachInt32;
case IrOpcode::kFloat64InsertLowWord32:
case IrOpcode::kFloat64InsertHighWord32:
return kMachFloat64;
default:
V8_Fatal(__FILE__, __LINE__, "Unexpected operator #%d:%s @ node #%d",
node->opcode(), node->op()->mnemonic(), node->id());
}
return kMachNone;
}
void InstructionSelector::VisitNode(Node* node) {
DCHECK_NOT_NULL(schedule()->block(node)); // should only use scheduled nodes.
SourcePosition source_position = source_positions_->GetSourcePosition(node);
......@@ -1149,9 +1008,9 @@ FrameStateDescriptor* InstructionSelector::GetFrameStateDescriptor(
Node* state) {
DCHECK(state->opcode() == IrOpcode::kFrameState);
DCHECK_EQ(5, state->InputCount());
DCHECK_EQ(IrOpcode::kStateValues, state->InputAt(0)->opcode());
DCHECK_EQ(IrOpcode::kStateValues, state->InputAt(1)->opcode());
DCHECK_EQ(IrOpcode::kStateValues, state->InputAt(2)->opcode());
DCHECK_EQ(IrOpcode::kTypedStateValues, state->InputAt(0)->opcode());
DCHECK_EQ(IrOpcode::kTypedStateValues, state->InputAt(1)->opcode());
DCHECK_EQ(IrOpcode::kTypedStateValues, state->InputAt(2)->opcode());
FrameStateCallInfo state_info = OpParameter<FrameStateCallInfo>(state);
int parameters =
......@@ -1197,9 +1056,9 @@ void InstructionSelector::AddFrameStateInputs(
Node* stack = state->InputAt(2);
Node* context = state->InputAt(3);
DCHECK_EQ(IrOpcode::kStateValues, parameters->op()->opcode());
DCHECK_EQ(IrOpcode::kStateValues, locals->op()->opcode());
DCHECK_EQ(IrOpcode::kStateValues, stack->op()->opcode());
DCHECK_EQ(IrOpcode::kTypedStateValues, parameters->op()->opcode());
DCHECK_EQ(IrOpcode::kTypedStateValues, locals->op()->opcode());
DCHECK_EQ(IrOpcode::kTypedStateValues, stack->op()->opcode());
DCHECK_EQ(descriptor->parameters_count(),
StateValuesAccess(parameters).size());
......@@ -1211,21 +1070,22 @@ void InstructionSelector::AddFrameStateInputs(
OperandGenerator g(this);
size_t value_index = 0;
for (Node* input_node : StateValuesAccess(parameters)) {
inputs->push_back(UseOrImmediate(&g, input_node));
descriptor->SetType(value_index++, GetMachineType(input_node));
for (StateValuesAccess::TypedNode input_node :
StateValuesAccess(parameters)) {
inputs->push_back(UseOrImmediate(&g, input_node.node));
descriptor->SetType(value_index++, input_node.type);
}
if (descriptor->HasContext()) {
inputs->push_back(UseOrImmediate(&g, context));
descriptor->SetType(value_index++, kMachAnyTagged);
}
for (Node* input_node : StateValuesAccess(locals)) {
inputs->push_back(UseOrImmediate(&g, input_node));
descriptor->SetType(value_index++, GetMachineType(input_node));
for (StateValuesAccess::TypedNode input_node : StateValuesAccess(locals)) {
inputs->push_back(UseOrImmediate(&g, input_node.node));
descriptor->SetType(value_index++, input_node.type);
}
for (Node* input_node : StateValuesAccess(stack)) {
inputs->push_back(UseOrImmediate(&g, input_node));
descriptor->SetType(value_index++, GetMachineType(input_node));
for (StateValuesAccess::TypedNode input_node : StateValuesAccess(stack)) {
inputs->push_back(UseOrImmediate(&g, input_node.node));
descriptor->SetType(value_index++, input_node.type);
}
DCHECK(value_index == descriptor->GetSize());
}
......
......@@ -173,7 +173,6 @@ class InstructionSelector FINAL {
FrameStateDescriptor* GetFrameStateDescriptor(Node* node);
void AddFrameStateInputs(Node* state, InstructionOperandVector* inputs,
FrameStateDescriptor* descriptor);
MachineType GetMachineType(Node* node);
// ===========================================================================
// ============= Architecture-specific graph covering methods. ===============
......
......@@ -142,12 +142,12 @@ void NonLiveFrameStateSlotReplacer::ClearNonLiveFrameStateSlots(
Node* NonLiveFrameStateSlotReplacer::ClearNonLiveStateValues(
Node* values, BitVector* liveness) {
DCHECK(inputs_buffer_.empty());
for (Node* node : StateValuesAccess(values)) {
for (StateValuesAccess::TypedNode node : StateValuesAccess(values)) {
// Index of the next variable is its furure index in the inputs buffer,
// i.e., the buffer's size.
int var = static_cast<int>(inputs_buffer_.size());
bool live = liveness->Contains(var) || permanently_live_.Contains(var);
inputs_buffer_.push_back(live ? node : replacement_node_);
inputs_buffer_.push_back(live ? node.node : replacement_node_);
}
Node* result = state_values_cache()->GetNodeForValues(
inputs_buffer_.empty() ? nullptr : &(inputs_buffer_.front()),
......
......@@ -48,6 +48,7 @@
V(Finish) \
V(FrameState) \
V(StateValues) \
V(TypedStateValues) \
V(Call) \
V(Parameter) \
V(OsrValue) \
......
......@@ -424,6 +424,25 @@ class RepresentationSelector {
}
}
void VisitStateValues(Node* node) {
if (phase_ == PROPAGATE) {
for (int i = 0; i < node->InputCount(); i++) {
Enqueue(node->InputAt(i), kTypeAny);
}
} else {
Zone* zone = jsgraph_->zone();
ZoneVector<MachineType>* types =
new (zone->New(sizeof(ZoneVector<MachineType>)))
ZoneVector<MachineType>(node->InputCount(), zone);
for (int i = 0; i < node->InputCount(); i++) {
MachineTypeUnion input_type = GetInfo(node->InputAt(i))->output;
(*types)[i] = static_cast<MachineType>(input_type);
}
node->set_op(jsgraph_->common()->TypedStateValues(types));
}
SetOutput(node, kMachAnyTagged);
}
const Operator* Int32Op(Node* node) {
return changer_->Int32OperatorFor(node->opcode());
}
......@@ -1021,10 +1040,7 @@ class RepresentationSelector {
case IrOpcode::kLoadStackPointer:
return VisitLeaf(node, kMachPtr);
case IrOpcode::kStateValues:
for (int i = 0; i < node->InputCount(); i++) {
ProcessInput(node, i, kTypeAny);
}
SetOutput(node, kMachAnyTagged);
VisitStateValues(node);
break;
default:
VisitInputs(node);
......
......@@ -173,6 +173,7 @@ Node* StateValuesCache::GetNodeForValues(Node** values, size_t count) {
#if DEBUG
for (size_t i = 0; i < count; i++) {
DCHECK_NE(values[i]->opcode(), IrOpcode::kStateValues);
DCHECK_NE(values[i]->opcode(), IrOpcode::kTypedStateValues);
}
#endif
if (count == 0) {
......@@ -190,7 +191,8 @@ Node* StateValuesCache::GetNodeForValues(Node** values, size_t count) {
Node* tree = BuildTree(&it, height);
// If the 'tree' is a single node, equip it with a StateValues wrapper.
if (tree->opcode() != IrOpcode::kStateValues) {
if (tree->opcode() != IrOpcode::kStateValues &&
tree->opcode() != IrOpcode::kTypedStateValues) {
tree = GetValuesNodeFromCache(&tree, 1);
}
......@@ -249,7 +251,8 @@ void StateValuesAccess::iterator::Advance() {
return;
}
Top()->index++;
} else if (node->InputAt(index)->opcode() == IrOpcode::kStateValues) {
} else if (node->InputAt(index)->opcode() == IrOpcode::kStateValues ||
node->InputAt(index)->opcode() == IrOpcode::kTypedStateValues) {
// Nested state, we need to push to the stack.
Push(node->InputAt(index));
} else {
......@@ -265,6 +268,19 @@ Node* StateValuesAccess::iterator::node() {
}
MachineType StateValuesAccess::iterator::type() {
Node* state = Top()->node;
if (state->opcode() == IrOpcode::kStateValues) {
return kMachAnyTagged;
} else {
DCHECK_EQ(IrOpcode::kTypedStateValues, state->opcode());
const ZoneVector<MachineType>* types =
OpParameter<const ZoneVector<MachineType>*>(state);
return (*types)[Top()->index];
}
}
bool StateValuesAccess::iterator::operator!=(iterator& other) {
// We only allow comparison with end().
CHECK(other.done());
......@@ -278,13 +294,16 @@ StateValuesAccess::iterator& StateValuesAccess::iterator::operator++() {
}
Node* StateValuesAccess::iterator::operator*() { return node(); }
StateValuesAccess::TypedNode StateValuesAccess::iterator::operator*() {
return TypedNode(node(), type());
}
size_t StateValuesAccess::size() {
size_t count = 0;
for (int i = 0; i < node_->InputCount(); i++) {
if (node_->InputAt(i)->opcode() == IrOpcode::kStateValues) {
if (node_->InputAt(i)->opcode() == IrOpcode::kStateValues ||
node_->InputAt(i)->opcode() == IrOpcode::kTypedStateValues) {
count += StateValuesAccess(node_->InputAt(i)).size();
} else {
count++;
......
......@@ -62,12 +62,18 @@ class StateValuesCache {
class StateValuesAccess {
public:
struct TypedNode {
Node* node;
MachineType type;
TypedNode(Node* node, MachineType type) : node(node), type(type) {}
};
class iterator {
public:
// Bare minimum of operators needed for range iteration.
bool operator!=(iterator& other);
iterator& operator++();
Node* operator*();
TypedNode operator*();
private:
friend class StateValuesAccess;
......@@ -76,6 +82,7 @@ class StateValuesAccess {
explicit iterator(Node* node);
Node* node();
MachineType type();
bool done();
void Advance();
......
......@@ -716,6 +716,11 @@ Bounds Typer::Visitor::TypeStateValues(Node* node) {
}
Bounds Typer::Visitor::TypeTypedStateValues(Node* node) {
return Bounds(Type::None(zone()), Type::Internal(zone()));
}
Bounds Typer::Visitor::TypeCall(Node* node) {
return Bounds::Unbounded(zone());
}
......
......@@ -427,6 +427,7 @@ void Verifier::Visitor::Check(Node* node) {
// TODO(jarin): what are the constraints on these?
break;
case IrOpcode::kStateValues:
case IrOpcode::kTypedStateValues:
// TODO(jarin): what are the constraints on these?
break;
case IrOpcode::kCall:
......
......@@ -46,7 +46,9 @@ class DeoptCodegenTester {
function(NewFunction(src)),
parse_info(scope->main_zone(), function),
info(&parse_info),
bailout_id(-1) {
bailout_id(-1),
tagged_type(1, kMachAnyTagged, zone()),
empty_types(zone()) {
CHECK(Parser::ParseStatic(&parse_info));
info.SetOptimizing(BailoutId::None(), Handle<Code>(function->code()));
CHECK(Compiler::Analyze(&parse_info));
......@@ -83,6 +85,8 @@ class DeoptCodegenTester {
Handle<Code> result_code;
TestInstrSeq* code;
Graph* graph;
ZoneVector<MachineType> tagged_type;
ZoneVector<MachineType> empty_types;
};
......@@ -120,9 +124,10 @@ class TrivialDeoptCodegenTester : public DeoptCodegenTester {
m.NewNode(common.HeapConstant(caller_context_constant));
bailout_id = GetCallBailoutId();
Node* parameters = m.NewNode(common.StateValues(1), m.UndefinedConstant());
Node* locals = m.NewNode(common.StateValues(0));
Node* stack = m.NewNode(common.StateValues(0));
Node* parameters =
m.NewNode(common.TypedStateValues(&tagged_type), m.UndefinedConstant());
Node* locals = m.NewNode(common.TypedStateValues(&empty_types));
Node* stack = m.NewNode(common.TypedStateValues(&empty_types));
Node* state_node = m.NewNode(
common.FrameState(JS_FRAME, bailout_id,
......@@ -235,9 +240,10 @@ class TrivialRuntimeDeoptCodegenTester : public DeoptCodegenTester {
Node* context_node = m.NewNode(common.HeapConstant(context_constant));
bailout_id = GetCallBailoutId();
Node* parameters = m.NewNode(common.StateValues(1), m.UndefinedConstant());
Node* locals = m.NewNode(common.StateValues(0));
Node* stack = m.NewNode(common.StateValues(0));
Node* parameters =
m.NewNode(common.TypedStateValues(&tagged_type), m.UndefinedConstant());
Node* locals = m.NewNode(common.TypedStateValues(&empty_types));
Node* stack = m.NewNode(common.TypedStateValues(&empty_types));
Node* state_node = m.NewNode(
common.FrameState(JS_FRAME, bailout_id,
......
// Copyright 2015 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: --noanalyze-environment-liveness
function f() {
var __v_7 = -126 - __v_3;
var __v_17 = ((__v_15 & __v_14) != 4) | 16;
if (__v_17) {
var __v_11 = 1 << __v_7;
}
__v_12 >>= __v_3;
}
assertThrows(f);
......@@ -347,9 +347,13 @@ TARGET_TEST_F(InstructionSelectorTest, CallJSFunctionWithDeopt) {
Node* receiver = m.Parameter(1);
Node* context = m.Parameter(2);
Node* parameters = m.NewNode(m.common()->StateValues(1), m.Int32Constant(1));
Node* locals = m.NewNode(m.common()->StateValues(0));
Node* stack = m.NewNode(m.common()->StateValues(0));
ZoneVector<MachineType> int32_type(1, kMachInt32, zone());
ZoneVector<MachineType> empty_types(zone());
Node* parameters =
m.NewNode(m.common()->TypedStateValues(&int32_type), m.Int32Constant(1));
Node* locals = m.NewNode(m.common()->TypedStateValues(&empty_types));
Node* stack = m.NewNode(m.common()->TypedStateValues(&empty_types));
Node* context_dummy = m.Int32Constant(0);
Node* state_node = m.NewNode(
......@@ -387,10 +391,17 @@ TARGET_TEST_F(InstructionSelectorTest, CallFunctionStubWithDeopt) {
Node* receiver = m.Parameter(1);
Node* context = m.Int32Constant(1); // Context is ignored.
ZoneVector<MachineType> int32_type(1, kMachInt32, zone());
ZoneVector<MachineType> float64_type(1, kMachFloat64, zone());
ZoneVector<MachineType> tagged_type(1, kMachAnyTagged, zone());
// Build frame state for the state before the call.
Node* parameters = m.NewNode(m.common()->StateValues(1), m.Int32Constant(43));
Node* locals = m.NewNode(m.common()->StateValues(1), m.Float64Constant(0.5));
Node* stack = m.NewNode(m.common()->StateValues(1), m.UndefinedConstant());
Node* parameters =
m.NewNode(m.common()->TypedStateValues(&int32_type), m.Int32Constant(43));
Node* locals = m.NewNode(m.common()->TypedStateValues(&float64_type),
m.Float64Constant(0.5));
Node* stack = m.NewNode(m.common()->TypedStateValues(&tagged_type),
m.UndefinedConstant());
Node* context_sentinel = m.Int32Constant(0);
Node* frame_state_before = m.NewNode(
......@@ -473,10 +484,17 @@ TARGET_TEST_F(InstructionSelectorTest,
Node* receiver = m.Parameter(1);
Node* context = m.Int32Constant(66);
ZoneVector<MachineType> int32_type(1, kMachInt32, zone());
ZoneVector<MachineType> int32x2_type(2, kMachInt32, zone());
ZoneVector<MachineType> float64_type(1, kMachFloat64, zone());
// Build frame state for the state before the call.
Node* parameters = m.NewNode(m.common()->StateValues(1), m.Int32Constant(63));
Node* locals = m.NewNode(m.common()->StateValues(1), m.Int32Constant(64));
Node* stack = m.NewNode(m.common()->StateValues(1), m.Int32Constant(65));
Node* parameters =
m.NewNode(m.common()->TypedStateValues(&int32_type), m.Int32Constant(63));
Node* locals =
m.NewNode(m.common()->TypedStateValues(&int32_type), m.Int32Constant(64));
Node* stack =
m.NewNode(m.common()->TypedStateValues(&int32_type), m.Int32Constant(65));
Node* frame_state_parent =
m.NewNode(m.common()->FrameState(JS_FRAME, bailout_id_parent,
OutputFrameStateCombine::Ignore()),
......@@ -484,11 +502,11 @@ TARGET_TEST_F(InstructionSelectorTest,
Node* context2 = m.Int32Constant(46);
Node* parameters2 =
m.NewNode(m.common()->StateValues(1), m.Int32Constant(43));
Node* locals2 =
m.NewNode(m.common()->StateValues(1), m.Float64Constant(0.25));
Node* stack2 = m.NewNode(m.common()->StateValues(2), m.Int32Constant(44),
m.Int32Constant(45));
m.NewNode(m.common()->TypedStateValues(&int32_type), m.Int32Constant(43));
Node* locals2 = m.NewNode(m.common()->TypedStateValues(&float64_type),
m.Float64Constant(0.25));
Node* stack2 = m.NewNode(m.common()->TypedStateValues(&int32x2_type),
m.Int32Constant(44), m.Int32Constant(45));
Node* frame_state_before =
m.NewNode(m.common()->FrameState(JS_FRAME, bailout_id_before,
OutputFrameStateCombine::Push()),
......
......@@ -115,15 +115,15 @@ class LivenessAnalysisTest : public GraphTest {
return false;
}
int i = 0;
for (Node* value : locals) {
for (StateValuesAccess::TypedNode value : locals) {
if (liveness_[i] == 'L') {
StringMatchResultListener value_listener;
if (value == replacement_) {
*listener << "whose local #" << i << " was " << value->opcode()
if (value.node == replacement_) {
*listener << "whose local #" << i << " was " << value.node->opcode()
<< " but should have been 'undefined'";
return false;
} else if (!IsInt32Constant(first_const + i)
.MatchAndExplain(value, &value_listener)) {
.MatchAndExplain(value.node, &value_listener)) {
*listener << "whose local #" << i << " does not match";
if (value_listener.str() != "") {
*listener << ", " << value_listener.str();
......@@ -131,8 +131,8 @@ class LivenessAnalysisTest : public GraphTest {
return false;
}
} else if (liveness_[i] == '.') {
if (value != replacement_) {
*listener << "whose local #" << i << " is " << value
if (value.node != replacement_) {
*listener << "whose local #" << i << " is " << value.node
<< " but should have been " << replacement_
<< " (undefined)";
return false;
......
......@@ -32,8 +32,8 @@ TEST_F(StateValuesIteratorTest, SimpleIteration) {
}
Node* state_values = StateValuesFromVector(&inputs);
int i = 0;
for (Node* node : StateValuesAccess(state_values)) {
EXPECT_THAT(node, IsInt32Constant(i));
for (StateValuesAccess::TypedNode node : StateValuesAccess(state_values)) {
EXPECT_THAT(node.node, IsInt32Constant(i));
i++;
}
EXPECT_EQ(count, i);
......@@ -43,7 +43,7 @@ TEST_F(StateValuesIteratorTest, SimpleIteration) {
TEST_F(StateValuesIteratorTest, EmptyIteration) {
NodeVector inputs(zone());
Node* state_values = StateValuesFromVector(&inputs);
for (Node* node : StateValuesAccess(state_values)) {
for (auto node : StateValuesAccess(state_values)) {
USE(node);
FAIL();
}
......@@ -82,8 +82,8 @@ TEST_F(StateValuesIteratorTest, NestedIteration) {
}
Node* state_values = StateValuesFromVector(&inputs);
int i = 0;
for (Node* node : StateValuesAccess(state_values)) {
EXPECT_THAT(node, IsInt32Constant(i));
for (StateValuesAccess::TypedNode node : StateValuesAccess(state_values)) {
EXPECT_THAT(node.node, IsInt32Constant(i));
i++;
}
EXPECT_EQ(count, i);
......@@ -110,8 +110,8 @@ TEST_F(StateValuesIteratorTest, TreeFromVector) {
// Check the tree contents with vector.
int i = 0;
for (Node* node : StateValuesAccess(values_node)) {
EXPECT_THAT(node, IsInt32Constant(i));
for (StateValuesAccess::TypedNode node : StateValuesAccess(values_node)) {
EXPECT_THAT(node.node, IsInt32Constant(i));
i++;
}
EXPECT_EQ(inputs.size(), static_cast<size_t>(i));
......
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