Commit 02e31851 authored by Jaroslav Sevcik's avatar Jaroslav Sevcik

[turbofan] Add an extra frame state for deoptimization before binary op.

BUG=
R=bmeurer@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#27060}
parent 25895aee
......@@ -1177,7 +1177,9 @@ void AstGraphBuilder::VisitForInBody(ForInStatement* stmt) {
Node* index_inc =
NewNode(javascript()->Add(), index, jsgraph()->OneConstant());
// TODO(jarin): provide real bailout id.
PrepareFrameState(index_inc, BailoutId::None());
PrepareFrameStateAfterAndBefore(index_inc, BailoutId::None(),
OutputFrameStateCombine::Ignore(),
jsgraph()->EmptyFrameState());
environment()->Poke(0, index_inc);
for_loop.Continue();
is_property_missing.Else();
......@@ -1197,7 +1199,9 @@ void AstGraphBuilder::VisitForInBody(ForInStatement* stmt) {
Node* index_inc =
NewNode(javascript()->Add(), index, jsgraph()->OneConstant());
// TODO(jarin): provide real bailout id.
PrepareFrameState(index_inc, BailoutId::None());
PrepareFrameStateAfterAndBefore(index_inc, BailoutId::None(),
OutputFrameStateCombine::Ignore(),
jsgraph()->EmptyFrameState());
environment()->Poke(0, index_inc);
for_loop.EndLoop();
environment()->Drop(5);
......@@ -1831,11 +1835,13 @@ void AstGraphBuilder::VisitAssignment(Assignment* expr) {
}
environment()->Push(old_value);
VisitForValue(expr->value());
Node* frame_state_before = environment()->Checkpoint(expr->value()->id());
Node* right = environment()->Pop();
Node* left = environment()->Pop();
Node* value = BuildBinaryOp(left, right, expr->binary_op());
PrepareFrameState(value, expr->binary_operation()->id(),
OutputFrameStateCombine::Push());
PrepareFrameStateAfterAndBefore(value, expr->binary_operation()->id(),
OutputFrameStateCombine::Push(),
frame_state_before);
environment()->Push(value);
} else {
VisitForValue(expr->value());
......@@ -2173,9 +2179,11 @@ void AstGraphBuilder::VisitCountOperation(CountOperation* expr) {
// Create node to perform +1/-1 operation.
Node* value =
BuildBinaryOp(old_value, jsgraph()->OneConstant(), expr->binary_op());
// TODO(jarin) Insert proper bailout id here (will need to change
// full code generator).
PrepareFrameState(value, BailoutId::None());
// This should never deoptimize because we have converted to number
// before.
PrepareFrameStateAfterAndBefore(value, BailoutId::None(),
OutputFrameStateCombine::Ignore(),
jsgraph()->EmptyFrameState());
// Store the value.
switch (assign_type) {
......@@ -2227,10 +2235,13 @@ void AstGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) {
default: {
VisitForValue(expr->left());
VisitForValue(expr->right());
Node* frame_state_before = environment()->Checkpoint(expr->right()->id());
Node* right = environment()->Pop();
Node* left = environment()->Pop();
Node* value = BuildBinaryOp(left, right, expr->op());
PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
PrepareFrameStateAfterAndBefore(value, expr->id(),
ast_context()->GetStateCombine(),
frame_state_before);
ast_context()->ProduceValue(value);
}
}
......@@ -2979,11 +2990,31 @@ bool AstGraphBuilder::CheckOsrEntry(IterationStatement* stmt) {
void AstGraphBuilder::PrepareFrameState(Node* node, BailoutId ast_id,
OutputFrameStateCombine combine) {
if (OperatorProperties::HasFrameStateInput(node->op())) {
DCHECK(NodeProperties::GetFrameStateInput(node)->opcode() ==
IrOpcode::kDead);
if (OperatorProperties::GetFrameStateInputCount(node->op()) > 0) {
DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
DCHECK_EQ(IrOpcode::kDead,
NodeProperties::GetFrameStateInput(node, 0)->opcode());
NodeProperties::ReplaceFrameStateInput(
node, 0, environment()->Checkpoint(ast_id, combine));
}
}
void AstGraphBuilder::PrepareFrameStateAfterAndBefore(
Node* node, BailoutId ast_id, OutputFrameStateCombine combine,
Node* frame_state_before) {
if (OperatorProperties::GetFrameStateInputCount(node->op()) > 0) {
DCHECK_EQ(2, OperatorProperties::GetFrameStateInputCount(node->op()));
DCHECK_EQ(IrOpcode::kDead,
NodeProperties::GetFrameStateInput(node, 0)->opcode());
NodeProperties::ReplaceFrameStateInput(
node, environment()->Checkpoint(ast_id, combine));
node, 0, environment()->Checkpoint(ast_id, combine));
DCHECK_EQ(IrOpcode::kDead,
NodeProperties::GetFrameStateInput(node, 1)->opcode());
NodeProperties::ReplaceFrameStateInput(node, 1, frame_state_before);
}
}
......@@ -3010,7 +3041,7 @@ Node* AstGraphBuilder::MakeNode(const Operator* op, int value_input_count,
DCHECK(op->ValueInputCount() == value_input_count);
bool has_context = OperatorProperties::HasContextInput(op);
bool has_framestate = OperatorProperties::HasFrameStateInput(op);
int frame_state_count = OperatorProperties::GetFrameStateInputCount(op);
bool has_control = op->ControlInputCount() == 1;
bool has_effect = op->EffectInputCount() == 1;
......@@ -3018,13 +3049,13 @@ Node* AstGraphBuilder::MakeNode(const Operator* op, int value_input_count,
DCHECK(op->EffectInputCount() < 2);
Node* result = NULL;
if (!has_context && !has_framestate && !has_control && !has_effect) {
if (!has_context && frame_state_count == 0 && !has_control && !has_effect) {
result = graph()->NewNode(op, value_input_count, value_inputs, incomplete);
} else {
bool inside_try_scope = try_nesting_level_ > 0;
int input_count_with_deps = value_input_count;
if (has_context) ++input_count_with_deps;
if (has_framestate) ++input_count_with_deps;
input_count_with_deps += frame_state_count;
if (has_control) ++input_count_with_deps;
if (has_effect) ++input_count_with_deps;
Node** buffer = EnsureInputBufferSize(input_count_with_deps);
......@@ -3033,7 +3064,7 @@ Node* AstGraphBuilder::MakeNode(const Operator* op, int value_input_count,
if (has_context) {
*current_input++ = current_context();
}
if (has_framestate) {
for (int i = 0; i < frame_state_count; i++) {
// The frame state will be inserted later. Here we misuse
// the {DeadControl} node as a sentinel to be later overwritten
// with the real frame state.
......
......@@ -320,6 +320,9 @@ class AstGraphBuilder : public AstVisitor {
void PrepareFrameState(
Node* node, BailoutId ast_id,
OutputFrameStateCombine combine = OutputFrameStateCombine::Ignore());
void PrepareFrameStateAfterAndBefore(Node* node, BailoutId ast_id,
OutputFrameStateCombine combine,
Node* frame_state_before);
BitVector* GetVariablesAssignedInLoop(IterationStatement* stmt);
......@@ -410,7 +413,8 @@ class AstGraphBuilder::Environment : public ZoneObject {
// Preserve a checkpoint of the environment for the IR graph. Any
// further mutation of the environment will not affect checkpoints.
Node* Checkpoint(BailoutId ast_id, OutputFrameStateCombine combine);
Node* Checkpoint(BailoutId ast_id, OutputFrameStateCombine combine =
OutputFrameStateCombine::Ignore());
// Control dependency tracked by this environment.
Node* GetControlDependency() { return control_dependency_; }
......
......@@ -229,10 +229,12 @@ Reduction ChangeLowering::ChangeTaggedToFloat64(Node* value, Node* control) {
Diamond d1(graph(), common(), TestNotSmi(object), BranchHint::kFalse);
d1.Chain(control);
DCHECK_EQ(FLAG_turbo_deoptimization,
OperatorProperties::GetFrameStateInputCount(value->op()) == 1);
Node* number =
OperatorProperties::HasFrameStateInput(value->op())
FLAG_turbo_deoptimization
? graph()->NewNode(value->op(), object, context,
NodeProperties::GetFrameStateInput(value),
NodeProperties::GetFrameStateInput(value, 0),
effect, d1.if_true)
: graph()->NewNode(value->op(), object, context, effect,
d1.if_true);
......
......@@ -107,7 +107,7 @@ REPLACE_UNIMPLEMENTED(JSDebugger)
static CallDescriptor::Flags FlagsForNode(Node* node) {
CallDescriptor::Flags result = CallDescriptor::kNoFlags;
if (OperatorProperties::HasFrameStateInput(node->op())) {
if (OperatorProperties::GetFrameStateInputCount(node->op()) > 0) {
result |= CallDescriptor::kNeedsFrameState;
}
return result;
......@@ -130,14 +130,14 @@ void JSGenericLowering::ReplaceWithCompareIC(Node* node, Token::Value token) {
if (node->op()->HasProperty(Operator::kPure)) {
// A pure (strict) comparison doesn't have an effect, control or frame
// state. But for the graph, we need to add control and effect inputs.
DCHECK(!OperatorProperties::HasFrameStateInput(node->op()));
DCHECK(OperatorProperties::GetFrameStateInputCount(node->op()) == 0);
inputs.push_back(graph()->start());
inputs.push_back(graph()->start());
} else {
DCHECK(OperatorProperties::HasFrameStateInput(node->op()) ==
DCHECK((OperatorProperties::GetFrameStateInputCount(node->op()) == 1) ==
FLAG_turbo_deoptimization);
if (FLAG_turbo_deoptimization) {
inputs.push_back(NodeProperties::GetFrameStateInput(node));
inputs.push_back(NodeProperties::GetFrameStateInput(node, 0));
}
inputs.push_back(NodeProperties::GetEffectInput(node));
inputs.push_back(NodeProperties::GetControlInput(node));
......@@ -198,12 +198,26 @@ void JSGenericLowering::ReplaceWithCompareIC(Node* node, Token::Value token) {
void JSGenericLowering::ReplaceWithStubCall(Node* node, Callable callable,
CallDescriptor::Flags flags) {
Operator::Properties properties = node->op()->properties();
CallDescriptor* desc =
Linkage::GetStubCallDescriptor(isolate(), zone(), callable.descriptor(),
0, flags | FlagsForNode(node), properties);
flags |= FlagsForNode(node);
CallDescriptor* desc = Linkage::GetStubCallDescriptor(
isolate(), zone(), callable.descriptor(), 0, flags, properties);
const Operator* new_op = common()->Call(desc);
// Take care of frame states.
int old_frame_state_count =
OperatorProperties::GetFrameStateInputCount(node->op());
int new_frame_state_count =
(flags & CallDescriptor::kNeedsFrameState) ? 1 : 0;
DCHECK_GE(old_frame_state_count, new_frame_state_count);
// If there are extra frame states, get rid of them.
for (int i = new_frame_state_count; i < old_frame_state_count; i++) {
node->RemoveInput(NodeProperties::FirstFrameStateIndex(node) +
new_frame_state_count);
}
Node* stub_code = jsgraph()->HeapConstant(callable.code());
node->InsertInput(zone(), 0, stub_code);
node->set_op(common()->Call(desc));
node->set_op(new_op);
}
......
......@@ -14,6 +14,7 @@
#include "src/compiler/js-operator.h"
#include "src/compiler/node-matchers.h"
#include "src/compiler/node-properties.h"
#include "src/compiler/operator-properties.h"
#include "src/compiler/simplified-operator.h"
#include "src/compiler/typer.h"
#include "src/full-codegen.h"
......@@ -49,7 +50,7 @@ class JSCallFunctionAccessor {
return value_inputs - 2;
}
Node* frame_state() { return NodeProperties::GetFrameStateInput(call_); }
Node* frame_state() { return NodeProperties::GetFrameStateInput(call_, 0); }
private:
Node* call_;
......@@ -379,8 +380,9 @@ Reduction JSInliner::Reduce(Node* node) {
for (Node* node : visitor.copies()) {
if (node && node->opcode() == IrOpcode::kFrameState) {
DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
AddClosureToFrameState(node, function);
NodeProperties::ReplaceFrameStateInput(node, outer_frame_state);
NodeProperties::ReplaceFrameStateInput(node, 0, outer_frame_state);
}
}
}
......
......@@ -51,7 +51,7 @@ Reduction JSIntrinsicLowering::Reduce(Node* node) {
Reduction JSIntrinsicLowering::ReduceDeoptimizeNow(Node* node) {
if (!FLAG_turbo_deoptimization) return NoChange();
Node* frame_state = NodeProperties::GetFrameStateInput(node);
Node* frame_state = NodeProperties::GetFrameStateInput(node, 0);
DCHECK_EQ(frame_state->opcode(), IrOpcode::kFrameState);
Node* effect = NodeProperties::GetEffectInput(node);
......
......@@ -646,8 +646,9 @@ Reduction JSTypedLowering::ReduceJSToNumber(Node* node) {
NodeProperties::ReplaceContextInput(node, jsgraph()->NoContextConstant());
NodeProperties::ReplaceControlInput(node, graph()->start());
NodeProperties::ReplaceEffectInput(node, graph()->start());
if (OperatorProperties::HasFrameStateInput(node->op())) {
NodeProperties::ReplaceFrameStateInput(node,
if (FLAG_turbo_deoptimization) {
DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
NodeProperties::ReplaceFrameStateInput(node, 0,
jsgraph()->EmptyFrameState());
}
return Changed(node);
......@@ -769,8 +770,10 @@ Reduction JSTypedLowering::ReduceJSStoreProperty(Node* node) {
if (number_reduction.Changed()) {
value = number_reduction.replacement();
} else {
if (OperatorProperties::HasFrameStateInput(
javascript()->ToNumber())) {
DCHECK(FLAG_turbo_deoptimization ==
(OperatorProperties::GetFrameStateInputCount(
javascript()->ToNumber()) == 1));
if (FLAG_turbo_deoptimization) {
value = effect =
graph()->NewNode(javascript()->ToNumber(), value, context,
jsgraph()->EmptyFrameState(), effect, control);
......
......@@ -58,9 +58,9 @@ Node* NodeProperties::GetContextInput(Node* node) {
// static
Node* NodeProperties::GetFrameStateInput(Node* node) {
DCHECK(OperatorProperties::HasFrameStateInput(node->op()));
return node->InputAt(FirstFrameStateIndex(node));
Node* NodeProperties::GetFrameStateInput(Node* node, int index) {
DCHECK_LT(index, OperatorProperties::GetFrameStateInputCount(node->op()));
return node->InputAt(FirstFrameStateIndex(node) + index);
}
......@@ -138,9 +138,10 @@ void NodeProperties::ReplaceEffectInput(Node* node, Node* effect, int index) {
// static
void NodeProperties::ReplaceFrameStateInput(Node* node, Node* frame_state) {
DCHECK(OperatorProperties::HasFrameStateInput(node->op()));
node->ReplaceInput(FirstFrameStateIndex(node), frame_state);
void NodeProperties::ReplaceFrameStateInput(Node* node, int index,
Node* frame_state) {
DCHECK_LT(index, OperatorProperties::GetFrameStateInputCount(node->op()));
node->ReplaceInput(FirstFrameStateIndex(node) + index, frame_state);
}
......
......@@ -39,7 +39,7 @@ class NodeProperties FINAL {
static Node* GetValueInput(Node* node, int index);
static Node* GetContextInput(Node* node);
static Node* GetFrameStateInput(Node* node);
static Node* GetFrameStateInput(Node* node, int index);
static Node* GetEffectInput(Node* node, int index = 0);
static Node* GetControlInput(Node* node, int index = 0);
......@@ -77,7 +77,7 @@ class NodeProperties FINAL {
static void ReplaceContextInput(Node* node, Node* context);
static void ReplaceControlInput(Node* node, Node* control);
static void ReplaceEffectInput(Node* node, Node* effect, int index = 0);
static void ReplaceFrameStateInput(Node* node, Node* frame_state);
static void ReplaceFrameStateInput(Node* node, int index, Node* frame_state);
static void RemoveNonValueInputs(Node* node);
// Replace value uses of {node} with {value} and effect uses of {node} with
......
......@@ -20,13 +20,13 @@ bool OperatorProperties::HasContextInput(const Operator* op) {
// static
bool OperatorProperties::HasFrameStateInput(const Operator* op) {
int OperatorProperties::GetFrameStateInputCount(const Operator* op) {
if (!FLAG_turbo_deoptimization) {
return false;
return 0;
}
switch (op->opcode()) {
case IrOpcode::kFrameState:
return true;
return 1;
case IrOpcode::kJSCallRuntime: {
const CallRuntimeParameters& p = CallRuntimeParametersOf(op);
return Linkage::NeedsFrameState(p.id());
......@@ -35,7 +35,7 @@ bool OperatorProperties::HasFrameStateInput(const Operator* op) {
// Strict equality cannot lazily deoptimize.
case IrOpcode::kJSStrictEqual:
case IrOpcode::kJSStrictNotEqual:
return false;
return 0;
// Calls
case IrOpcode::kJSCallFunction:
......@@ -51,19 +51,6 @@ bool OperatorProperties::HasFrameStateInput(const Operator* op) {
case IrOpcode::kJSLessThanOrEqual:
case IrOpcode::kJSNotEqual:
// Binary operations
case IrOpcode::kJSAdd:
case IrOpcode::kJSBitwiseAnd:
case IrOpcode::kJSBitwiseOr:
case IrOpcode::kJSBitwiseXor:
case IrOpcode::kJSDivide:
case IrOpcode::kJSModulus:
case IrOpcode::kJSMultiply:
case IrOpcode::kJSShiftLeft:
case IrOpcode::kJSShiftRight:
case IrOpcode::kJSShiftRightLogical:
case IrOpcode::kJSSubtract:
// Context operations
case IrOpcode::kJSCreateWithContext:
......@@ -81,10 +68,26 @@ bool OperatorProperties::HasFrameStateInput(const Operator* op) {
case IrOpcode::kJSStoreNamed:
case IrOpcode::kJSStoreProperty:
case IrOpcode::kJSDeleteProperty:
return true;
return 1;
// Binary operators that can deopt in the middle the operation (e.g.,
// as a result of lazy deopt in ToNumber conversion) need a second frame
// state so that we can resume before the operation.
case IrOpcode::kJSMultiply:
case IrOpcode::kJSAdd:
case IrOpcode::kJSBitwiseAnd:
case IrOpcode::kJSBitwiseOr:
case IrOpcode::kJSBitwiseXor:
case IrOpcode::kJSDivide:
case IrOpcode::kJSModulus:
case IrOpcode::kJSShiftLeft:
case IrOpcode::kJSShiftRight:
case IrOpcode::kJSShiftRightLogical:
case IrOpcode::kJSSubtract:
return 2;
default:
return false;
return 0;
}
}
......
......@@ -18,14 +18,11 @@ class Operator;
class OperatorProperties FINAL {
public:
static bool HasContextInput(const Operator* op);
static bool HasFrameStateInput(const Operator* op);
static int GetContextInputCount(const Operator* op) {
return HasContextInput(op) ? 1 : 0;
}
static int GetFrameStateInputCount(const Operator* op) {
return HasFrameStateInput(op) ? 1 : 0;
}
static int GetFrameStateInputCount(const Operator* op);
static int GetTotalInputCount(const Operator* op);
static bool IsBasicBlockBegin(const Operator* op);
......
......@@ -125,8 +125,8 @@ void Verifier::Visitor::Check(Node* node) {
CHECK_EQ(input_count, node->InputCount());
// Verify that frame state has been inserted for the nodes that need it.
if (OperatorProperties::HasFrameStateInput(node->op())) {
Node* frame_state = NodeProperties::GetFrameStateInput(node);
for (int i = 0; i < frame_state_count; i++) {
Node* frame_state = NodeProperties::GetFrameStateInput(node, i);
CHECK(frame_state->opcode() == IrOpcode::kFrameState ||
// kFrameState uses undefined as a sentinel.
(node->opcode() == IrOpcode::kFrameState &&
......
......@@ -48,7 +48,7 @@ Node* SimplifiedGraphBuilder::MakeNode(const Operator* op,
DCHECK(op->ValueInputCount() == value_input_count);
DCHECK(!OperatorProperties::HasContextInput(op));
DCHECK(!OperatorProperties::HasFrameStateInput(op));
DCHECK_EQ(0, OperatorProperties::GetFrameStateInputCount(op));
bool has_control = op->ControlInputCount() == 1;
bool has_effect = op->EffectInputCount() == 1;
......
......@@ -113,9 +113,13 @@ class JSTypedLoweringTester : public HandleAndZoneScope {
Node* Binop(const Operator* op, Node* left, Node* right) {
// JS binops also require context, effect, and control
if (OperatorProperties::HasFrameStateInput(op)) {
if (OperatorProperties::GetFrameStateInputCount(op) == 1) {
return graph.NewNode(op, left, right, context(),
EmptyFrameState(context()), start(), control());
} else if (OperatorProperties::GetFrameStateInputCount(op) == 2) {
return graph.NewNode(op, left, right, context(),
EmptyFrameState(context()),
EmptyFrameState(context()), start(), control());
} else {
return graph.NewNode(op, left, right, context(), start(), control());
}
......@@ -123,7 +127,8 @@ class JSTypedLoweringTester : public HandleAndZoneScope {
Node* Unop(const Operator* op, Node* input) {
// JS unops also require context, effect, and control
if (OperatorProperties::HasFrameStateInput(op)) {
if (OperatorProperties::GetFrameStateInputCount(op) > 0) {
DCHECK(OperatorProperties::GetFrameStateInputCount(op) == 1);
return graph.NewNode(op, input, context(), EmptyFrameState(context()),
start(), control());
} else {
......@@ -133,7 +138,10 @@ class JSTypedLoweringTester : public HandleAndZoneScope {
Node* UseForEffect(Node* node) {
// TODO(titzer): use EffectPhi after fixing EffectCount
if (OperatorProperties::HasFrameStateInput(javascript.ToNumber())) {
if (OperatorProperties::GetFrameStateInputCount(javascript.ToNumber()) >
0) {
DCHECK(OperatorProperties::GetFrameStateInputCount(
javascript.ToNumber()) == 1);
return graph.NewNode(javascript.ToNumber(), node, context(),
EmptyFrameState(context()), node, control());
} else {
......@@ -748,8 +756,9 @@ TEST(RemoveToNumberEffects) {
switch (i) {
case 0:
// TODO(jarin) Replace with a query of FLAG_turbo_deoptimization.
if (OperatorProperties::HasFrameStateInput(R.javascript.ToNumber())) {
if (FLAG_turbo_deoptimization) {
DCHECK(OperatorProperties::GetFrameStateInputCount(
R.javascript.ToNumber()) == 1);
effect_use = R.graph.NewNode(R.javascript.ToNumber(), p0, R.context(),
frame_state, ton, R.start());
} else {
......@@ -758,8 +767,9 @@ TEST(RemoveToNumberEffects) {
}
break;
case 1:
// TODO(jarin) Replace with a query of FLAG_turbo_deoptimization.
if (OperatorProperties::HasFrameStateInput(R.javascript.ToNumber())) {
if (FLAG_turbo_deoptimization) {
DCHECK(OperatorProperties::GetFrameStateInputCount(
R.javascript.ToNumber()) == 1);
effect_use =
R.graph.NewNode(R.javascript.ToNumber(), ton, R.context(),
frame_state, ton, R.start());
......@@ -772,11 +782,11 @@ TEST(RemoveToNumberEffects) {
effect_use = R.graph.NewNode(R.common.EffectPhi(1), ton, R.start());
case 3:
effect_use = R.graph.NewNode(R.javascript.Add(), ton, ton, R.context(),
frame_state, ton, R.start());
frame_state, frame_state, ton, R.start());
break;
case 4:
effect_use = R.graph.NewNode(R.javascript.Add(), p0, p0, R.context(),
frame_state, ton, R.start());
frame_state, frame_state, ton, R.start());
break;
case 5:
effect_use = R.graph.NewNode(R.common.Return(), p0, ton, R.start());
......
......@@ -55,17 +55,17 @@ const SharedOperator kSharedOperators[] = {
SHARED(GreaterThan, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2),
SHARED(LessThanOrEqual, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2),
SHARED(GreaterThanOrEqual, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2),
SHARED(BitwiseOr, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2),
SHARED(BitwiseXor, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2),
SHARED(BitwiseAnd, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2),
SHARED(ShiftLeft, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2),
SHARED(ShiftRight, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2),
SHARED(ShiftRightLogical, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2),
SHARED(Add, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2),
SHARED(Subtract, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2),
SHARED(Multiply, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2),
SHARED(Divide, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2),
SHARED(Modulus, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2),
SHARED(BitwiseOr, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2),
SHARED(BitwiseXor, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2),
SHARED(BitwiseAnd, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2),
SHARED(ShiftLeft, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2),
SHARED(ShiftRight, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2),
SHARED(ShiftRightLogical, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2),
SHARED(Add, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2),
SHARED(Subtract, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2),
SHARED(Multiply, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2),
SHARED(Divide, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2),
SHARED(Modulus, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2),
SHARED(UnaryNot, Operator::kPure, 1, 0, 0, 0, 1, 0, 0),
SHARED(ToBoolean, Operator::kPure, 1, 0, 0, 0, 1, 0, 0),
SHARED(ToNumber, Operator::kNoProperties, 1, 1, 1, 1, 1, 1, 2),
......
......@@ -673,6 +673,8 @@ TEST_F(SchedulerTest, BuildScheduleIfSplit) {
TEST_F(SchedulerTest, BuildScheduleIfSplitWithEffects) {
FLAG_turbo_deoptimization = false;
const Operator* op;
// Manually transcripted code for:
......@@ -809,6 +811,8 @@ TEST_F(SchedulerTest, BuildScheduleIfSplitWithEffects) {
TEST_F(SchedulerTest, BuildScheduleSimpleLoop) {
FLAG_turbo_deoptimization = false;
const Operator* op;
// Manually transcripted code for:
......@@ -912,6 +916,8 @@ TEST_F(SchedulerTest, BuildScheduleSimpleLoop) {
TEST_F(SchedulerTest, BuildScheduleComplexLoops) {
FLAG_turbo_deoptimization = false;
const Operator* op;
// Manually transcripted code for:
......@@ -1150,6 +1156,8 @@ TEST_F(SchedulerTest, BuildScheduleComplexLoops) {
TEST_F(SchedulerTest, BuildScheduleBreakAndContinue) {
FLAG_turbo_deoptimization = false;
const Operator* op;
// Manually transcripted code for:
......@@ -1470,6 +1478,8 @@ TEST_F(SchedulerTest, BuildScheduleBreakAndContinue) {
TEST_F(SchedulerTest, BuildScheduleSimpleLoopWithCodeMotion) {
FLAG_turbo_deoptimization = false;
const Operator* op;
// Manually transcripted code for:
......
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