From 2111d18dbad8ce14124d69488aa3568dd4604768 Mon Sep 17 00:00:00 2001 From: bmeurer Date: Wed, 13 May 2015 00:38:42 -0700 Subject: [PATCH] [turbofan] Add frame state before JavaScript comparisons. Use these check points to optimize comparisons where we already know that one side cannot be a String (or turn into a string via ToPrimitive). Also remove bunch of useless DoNotCrash tests for the scheduler that are painful to maintain and add almost no value. R=jarin@chromium.org Review URL: https://codereview.chromium.org/1140583004 Cr-Commit-Position: refs/heads/master@{#28383} --- src/compiler/ast-graph-builder.cc | 7 +- src/compiler/js-typed-lowering.cc | 63 +- src/compiler/js-typed-lowering.h | 2 - src/compiler/operator-properties.cc | 15 +- test/mjsunit/compiler/deopt-tonumber-compare.js | 44 + test/unittests/compiler/js-operator-unittest.cc | 8 +- test/unittests/compiler/scheduler-unittest.cc | 1332 +---------------------- 7 files changed, 87 insertions(+), 1384 deletions(-) create mode 100644 test/mjsunit/compiler/deopt-tonumber-compare.js diff --git a/src/compiler/ast-graph-builder.cc b/src/compiler/ast-graph-builder.cc index 8bf9312..629ea18 100644 --- a/src/compiler/ast-graph-builder.cc +++ b/src/compiler/ast-graph-builder.cc @@ -1311,10 +1311,12 @@ void AstGraphBuilder::VisitForInBody(ForInStatement* stmt) { Node* obj = environment()->Peek(4); // Check loop termination condition. + FrameStateBeforeAndAfter states(this, BailoutId::None()); Node* exit_cond = NewNode(javascript()->LessThan(LanguageMode::SLOPPY), index, cache_length); // TODO(jarin): provide real bailout id. - PrepareFrameState(exit_cond, BailoutId::None()); + states.AddToNode(exit_cond, BailoutId::None(), + OutputFrameStateCombine::Ignore()); for_loop.BreakUnless(exit_cond); Node* pair = NewNode(javascript()->CallRuntime(Runtime::kForInNext, 4), obj, cache_array, cache_type, index); @@ -2531,10 +2533,11 @@ void AstGraphBuilder::VisitCompareOperation(CompareOperation* expr) { } VisitForValue(expr->left()); VisitForValue(expr->right()); + FrameStateBeforeAndAfter states(this, expr->right()->id()); Node* right = environment()->Pop(); Node* left = environment()->Pop(); Node* value = NewNode(op, left, right); - PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); + states.AddToNode(value, expr->id(), ast_context()->GetStateCombine()); ast_context()->ProduceValue(value); } diff --git a/src/compiler/js-typed-lowering.cc b/src/compiler/js-typed-lowering.cc index 6df7652..9b1d678 100644 --- a/src/compiler/js-typed-lowering.cc +++ b/src/compiler/js-typed-lowering.cc @@ -121,11 +121,6 @@ class JSBinopReduction final { JSBinopReduction(JSTypedLowering* lowering, Node* node) : lowering_(lowering), node_(node) {} - void ConvertPrimitiveInputsToNumber() { - node_->ReplaceInput(0, ConvertPrimitiveToNumber(left())); - node_->ReplaceInput(1, ConvertPrimitiveToNumber(right())); - } - void ConvertInputsToNumber(Node* frame_state) { // To convert the inputs to numbers, we have to provide frame states // for lazy bailouts in the ToNumber conversions. @@ -137,13 +132,13 @@ class JSBinopReduction final { Node* left_input = left_type()->Is(Type::PlainPrimitive()) - ? ConvertPrimitiveToNumber(left()) + ? ConvertPlainPrimitiveToNumber(left()) : ConvertToNumber(left(), CreateFrameStateForLeftInput(frame_state)); Node* right_input = right_type()->Is(Type::PlainPrimitive()) - ? ConvertPrimitiveToNumber(right()) + ? ConvertPlainPrimitiveToNumber(right()) : ConvertToNumber(right(), CreateFrameStateForRightInput( frame_state, left_input)); @@ -164,9 +159,10 @@ class JSBinopReduction final { // Convert inputs for bitwise shift operation (ES5 spec 11.7). void ConvertInputsForShift(Signedness left_signedness) { - node_->ReplaceInput( - 0, ConvertToUI32(ConvertPrimitiveToNumber(left()), left_signedness)); - Node* rnum = ConvertToUI32(ConvertPrimitiveToNumber(right()), kUnsigned); + node_->ReplaceInput(0, ConvertToUI32(ConvertPlainPrimitiveToNumber(left()), + left_signedness)); + Node* rnum = + ConvertToUI32(ConvertPlainPrimitiveToNumber(right()), kUnsigned); Type* rnum_type = NodeProperties::GetBounds(rnum).upper; if (!rnum_type->Is(lowering_->zero_thirtyone_range_)) { rnum = graph()->NewNode(machine()->Word32And(), rnum, @@ -333,13 +329,20 @@ class JSBinopReduction final { frame_state->InputAt(3), frame_state->InputAt(4)); } - Node* ConvertPrimitiveToNumber(Node* node) { - return lowering_->ConvertPrimitiveToNumber(node); + Node* ConvertPlainPrimitiveToNumber(Node* node) { + DCHECK(NodeProperties::GetBounds(node).upper->Is(Type::PlainPrimitive())); + // Avoid inserting too many eager ToNumber() operations. + Reduction const reduction = lowering_->ReduceJSToNumberInput(node); + if (reduction.Changed()) return reduction.replacement(); + // TODO(jarin) Use PlainPrimitiveToNumber once we have it. + return graph()->NewNode( + javascript()->ToNumber(), node, jsgraph()->NoContextConstant(), + jsgraph()->EmptyFrameState(), graph()->start(), graph()->start()); } Node* ConvertToNumber(Node* node, Node* frame_state) { if (NodeProperties::GetBounds(node).upper->Is(Type::PlainPrimitive())) { - return ConvertPrimitiveToNumber(node); + return ConvertPlainPrimitiveToNumber(node); } else { Node* const n = graph()->NewNode(javascript()->ToNumber(), node, context(), @@ -470,21 +473,7 @@ Reduction JSTypedLowering::ReduceJSComparison(Node* node) { } return r.ChangeToPureOperator(stringOp); } - if (r.IsStrong() && !r.BothInputsAre(Type::Number())) { - return NoChange(); - } -#if 0 - // TODO(turbofan): General ToNumber disabled for now because: - // a) The inserted ToNumber operation screws up observability of valueOf. - // b) Deoptimization at ToNumber doesn't have corresponding bailout id. - Type* maybe_string = Type::Union(Type::String(), Type::Receiver(), zone()); - if (r.OneInputCannotBe(maybe_string)) { - // If one input cannot be a string, then emit a number comparison. - ... - } -#endif - if (r.BothInputsAre(Type::PlainPrimitive()) && - r.OneInputCannotBe(Type::StringOrReceiver())) { + if (r.OneInputCannotBe(Type::StringOrReceiver())) { const Operator* less_than; const Operator* less_than_or_equal; if (r.BothInputsAre(Type::Unsigned32())) { @@ -495,7 +484,11 @@ Reduction JSTypedLowering::ReduceJSComparison(Node* node) { less_than_or_equal = machine()->Int32LessThanOrEqual(); } else { // TODO(turbofan): mixed signed/unsigned int32 comparisons. - r.ConvertPrimitiveInputsToNumber(); + if (r.IsStrong() && !r.BothInputsAre(Type::Number())) { + return NoChange(); + } + Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); + r.ConvertInputsToNumber(frame_state); less_than = simplified()->NumberLessThan(); less_than_or_equal = simplified()->NumberLessThanOrEqual(); } @@ -1192,18 +1185,6 @@ Reduction JSTypedLowering::Reduce(Node* node) { } -Node* JSTypedLowering::ConvertPrimitiveToNumber(Node* input) { - DCHECK(NodeProperties::GetBounds(input).upper->Is(Type::PlainPrimitive())); - // Avoid inserting too many eager ToNumber() operations. - Reduction const reduction = ReduceJSToNumberInput(input); - if (reduction.Changed()) return reduction.replacement(); - // TODO(jarin) Use PlainPrimitiveToNumber once we have it. - return graph()->NewNode( - javascript()->ToNumber(), input, jsgraph()->NoContextConstant(), - jsgraph()->EmptyFrameState(), graph()->start(), graph()->start()); -} - - Node* JSTypedLowering::Word32Shl(Node* const lhs, int32_t const rhs) { if (rhs == 0) return lhs; return graph()->NewNode(machine()->Word32Shl(), lhs, diff --git a/src/compiler/js-typed-lowering.h b/src/compiler/js-typed-lowering.h index a41fb51..b058a08 100644 --- a/src/compiler/js-typed-lowering.h +++ b/src/compiler/js-typed-lowering.h @@ -64,8 +64,6 @@ class JSTypedLowering final : public Reducer { Reduction ReduceUI32Shift(Node* node, Signedness left_signedness, const Operator* shift_op); - Node* ConvertPrimitiveToNumber(Node* input); - Node* Word32Shl(Node* const lhs, int32_t const rhs); Factory* factory() const; diff --git a/src/compiler/operator-properties.cc b/src/compiler/operator-properties.cc index a36caf5..0ee434c 100644 --- a/src/compiler/operator-properties.cc +++ b/src/compiler/operator-properties.cc @@ -40,13 +40,9 @@ int OperatorProperties::GetFrameStateInputCount(const Operator* op) { // Compare operations case IrOpcode::kJSEqual: - case IrOpcode::kJSGreaterThan: - case IrOpcode::kJSGreaterThanOrEqual: + case IrOpcode::kJSNotEqual: case IrOpcode::kJSHasProperty: case IrOpcode::kJSInstanceOf: - case IrOpcode::kJSLessThan: - case IrOpcode::kJSLessThanOrEqual: - case IrOpcode::kJSNotEqual: // Object operations case IrOpcode::kJSCreateLiteralArray: @@ -93,6 +89,15 @@ int OperatorProperties::GetFrameStateInputCount(const Operator* op) { case IrOpcode::kJSSubtract: return 2; + // Compare 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::kJSGreaterThan: + case IrOpcode::kJSGreaterThanOrEqual: + case IrOpcode::kJSLessThan: + case IrOpcode::kJSLessThanOrEqual: + return 2; + default: return 0; } diff --git a/test/mjsunit/compiler/deopt-tonumber-compare.js b/test/mjsunit/compiler/deopt-tonumber-compare.js new file mode 100644 index 0000000..9a7e992 --- /dev/null +++ b/test/mjsunit/compiler/deopt-tonumber-compare.js @@ -0,0 +1,44 @@ +// 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: --allow-natives-syntax + +var m = (function() { + "use asm"; + function f(x) { + return x < 0; + } + function g(x) { + return 0 < x; + } + return { f: f, g: g }; +})(); +var f = m.f; +var g = m.g; + +var counter = 0; + +function deopt(f) { + return { + toString : function() { + %DeoptimizeFunction(f); + counter++; + return "2"; + } + }; +} + +assertEquals(false, f(deopt(f))); +assertEquals(1, counter); + +assertEquals(true, g(deopt(g))); +assertEquals(2, counter); + +%OptimizeFunctionOnNextCall(f); +assertEquals(false, f(deopt(f))); +assertEquals(3, counter); + +%OptimizeFunctionOnNextCall(g); +assertEquals(true, g(deopt(g))); +assertEquals(4, counter); diff --git a/test/unittests/compiler/js-operator-unittest.cc b/test/unittests/compiler/js-operator-unittest.cc index a8a2d8c..20b0367 100644 --- a/test/unittests/compiler/js-operator-unittest.cc +++ b/test/unittests/compiler/js-operator-unittest.cc @@ -186,10 +186,10 @@ const SharedOperatorWithLanguageMode kSharedOperatorsWithLanguageMode[] = { control_input_count, value_output_count, effect_output_count, \ control_output_count \ } - SHARED(LessThan, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2), - 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(LessThan, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2), + SHARED(GreaterThan, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2), + SHARED(LessThanOrEqual, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2), + SHARED(GreaterThanOrEqual, Operator::kNoProperties, 2, 2, 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), diff --git a/test/unittests/compiler/scheduler-unittest.cc b/test/unittests/compiler/scheduler-unittest.cc index 4de1549..51fcb1b 100644 --- a/test/unittests/compiler/scheduler-unittest.cc +++ b/test/unittests/compiler/scheduler-unittest.cc @@ -650,7 +650,7 @@ TEST_F(SchedulerTest, BuildScheduleOneParameter) { TEST_F(SchedulerTest, BuildScheduleIfSplit) { - graph()->SetStart(graph()->NewNode(common()->Start(3))); + graph()->SetStart(graph()->NewNode(common()->Start(5))); Node* p1 = graph()->NewNode(common()->Parameter(0), graph()->start()); Node* p2 = graph()->NewNode(common()->Parameter(1), graph()->start()); @@ -658,7 +658,7 @@ TEST_F(SchedulerTest, BuildScheduleIfSplit) { Node* p4 = graph()->NewNode(common()->Parameter(3), graph()->start()); Node* p5 = graph()->NewNode(common()->Parameter(4), graph()->start()); Node* cmp = graph()->NewNode(js()->LessThanOrEqual(LanguageMode::SLOPPY), p1, - p2, p3, graph()->start(), graph()->start()); + p2, p3, p4, graph()->start(), graph()->start()); Node* branch = graph()->NewNode(common()->Branch(), cmp, graph()->start()); Node* true_branch = graph()->NewNode(common()->IfTrue(), branch); Node* false_branch = graph()->NewNode(common()->IfFalse(), branch); @@ -674,1334 +674,6 @@ TEST_F(SchedulerTest, BuildScheduleIfSplit) { } -TEST_F(SchedulerTest, BuildScheduleIfSplitWithEffects) { - const Operator* op; - Unique unique_constant = - Unique::CreateImmovable(factory()->undefined_value()); - - // Manually transcripted code for: - // function turbo_fan_test(a, b, c, y) { - // if (a < b) { - // return a + b - c * c - a + y; - // } else { - // return c * c - a; - // } - // } - Node* nil = graph()->NewNode(common()->Dead()); - op = common()->End(); - Node* n39 = graph()->NewNode(op, nil); - USE(n39); - op = common()->Merge(2); - Node* n37 = graph()->NewNode(op, nil, nil); - USE(n37); - op = common()->Return(); - Node* n29 = graph()->NewNode(op, nil, nil, nil); - USE(n29); - op = common()->Return(); - Node* n36 = graph()->NewNode(op, nil, nil, nil); - USE(n36); - op = js()->Add(LanguageMode::SLOPPY); - Node* n27 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil, nil); - USE(n27); - op = common()->IfSuccess(); - Node* n28 = graph()->NewNode(op, nil); - USE(n28); - op = js()->Subtract(LanguageMode::SLOPPY); - Node* n34 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil, nil); - USE(n34); - op = common()->IfSuccess(); - Node* n35 = graph()->NewNode(op, nil); - USE(n35); - op = js()->Subtract(LanguageMode::SLOPPY); - Node* n25 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil, nil); - USE(n25); - op = common()->Parameter(4); - Node* n5 = graph()->NewNode(op, nil); - USE(n5); - op = common()->Parameter(5); - Node* n7 = graph()->NewNode(op, nil); - USE(n7); - op = common()->FrameState(JS_FRAME, BailoutId(-1), - OutputFrameStateCombine::Ignore()); - Node* n13 = graph()->NewNode(op, nil, nil, nil, nil, nil); - USE(n13); - op = common()->IfSuccess(); - Node* n26 = graph()->NewNode(op, nil); - USE(n26); - op = js()->Multiply(LanguageMode::SLOPPY); - Node* n32 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil, nil); - USE(n32); - op = common()->Parameter(1); - Node* n2 = graph()->NewNode(op, nil); - USE(n2); - op = common()->IfSuccess(); - Node* n33 = graph()->NewNode(op, nil); - USE(n33); - op = js()->Subtract(LanguageMode::SLOPPY); - Node* n23 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil, nil); - USE(n23); - op = common()->IfSuccess(); - Node* n24 = graph()->NewNode(op, nil); - USE(n24); - op = common()->Start(4); - Node* n0 = graph()->NewNode(op); - USE(n0); - op = common()->StateValues(0); - Node* n11 = graph()->NewNode(op); - USE(n11); - op = common()->NumberConstant(0); - Node* n12 = graph()->NewNode(op); - USE(n12); - op = common()->HeapConstant(unique_constant); - Node* n6 = graph()->NewNode(op); - USE(n6); - op = common()->Parameter(3); - Node* n4 = graph()->NewNode(op, nil); - USE(n4); - op = js()->LessThan(LanguageMode::SLOPPY); - Node* n15 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil); - USE(n15); - op = common()->IfFalse(); - Node* n31 = graph()->NewNode(op, nil); - USE(n31); - op = js()->Add(LanguageMode::SLOPPY); - Node* n19 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil, nil); - USE(n19); - op = js()->Multiply(LanguageMode::SLOPPY); - Node* n21 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil, nil); - USE(n21); - op = common()->IfSuccess(); - Node* n22 = graph()->NewNode(op, nil); - USE(n22); - op = common()->Parameter(2); - Node* n3 = graph()->NewNode(op, nil); - USE(n3); - op = js()->StackCheck(); - Node* n9 = graph()->NewNode(op, nil, nil, nil, nil); - USE(n9); - op = common()->IfSuccess(); - Node* n10 = graph()->NewNode(op, nil); - USE(n10); - op = common()->Branch(); - Node* n17 = graph()->NewNode(op, nil, nil); - USE(n17); - op = common()->IfTrue(); - Node* n18 = graph()->NewNode(op, nil); - USE(n18); - op = common()->IfSuccess(); - Node* n20 = graph()->NewNode(op, nil); - USE(n20); - op = common()->IfSuccess(); - Node* n16 = graph()->NewNode(op, nil); - USE(n16); - n39->ReplaceInput(0, n37); - n37->ReplaceInput(0, n29); - n37->ReplaceInput(1, n36); - n29->ReplaceInput(0, n27); - n29->ReplaceInput(1, n27); - n29->ReplaceInput(2, n28); - n36->ReplaceInput(0, n34); - n36->ReplaceInput(1, n34); - n36->ReplaceInput(2, n35); - n27->ReplaceInput(0, n25); - n27->ReplaceInput(1, n5); - n27->ReplaceInput(2, n7); - n27->ReplaceInput(3, n13); - n27->ReplaceInput(4, n13); - n27->ReplaceInput(5, n25); - n27->ReplaceInput(6, n26); - n28->ReplaceInput(0, n27); - n34->ReplaceInput(0, n32); - n34->ReplaceInput(1, n2); - n34->ReplaceInput(2, n7); - n34->ReplaceInput(3, n13); - n34->ReplaceInput(4, n13); - n34->ReplaceInput(5, n32); - n34->ReplaceInput(6, n33); - n35->ReplaceInput(0, n34); - n25->ReplaceInput(0, n23); - n25->ReplaceInput(1, n2); - n25->ReplaceInput(2, n7); - n25->ReplaceInput(3, n13); - n25->ReplaceInput(4, n13); - n25->ReplaceInput(5, n23); - n25->ReplaceInput(6, n24); - n5->ReplaceInput(0, n0); - n7->ReplaceInput(0, n0); - n13->ReplaceInput(0, n11); - n13->ReplaceInput(1, n11); - n13->ReplaceInput(2, n11); - n13->ReplaceInput(3, n12); - n13->ReplaceInput(4, n6); - n26->ReplaceInput(0, n25); - n32->ReplaceInput(0, n4); - n32->ReplaceInput(1, n4); - n32->ReplaceInput(2, n7); - n32->ReplaceInput(3, n13); - n32->ReplaceInput(4, n13); - n32->ReplaceInput(5, n15); - n32->ReplaceInput(6, n31); - n2->ReplaceInput(0, n0); - n33->ReplaceInput(0, n32); - n23->ReplaceInput(0, n19); - n23->ReplaceInput(1, n21); - n23->ReplaceInput(2, n7); - n23->ReplaceInput(3, n13); - n23->ReplaceInput(4, n13); - n23->ReplaceInput(5, n21); - n23->ReplaceInput(6, n22); - n24->ReplaceInput(0, n23); - n4->ReplaceInput(0, n0); - n15->ReplaceInput(0, n2); - n15->ReplaceInput(1, n3); - n15->ReplaceInput(2, n7); - n15->ReplaceInput(3, n13); - n15->ReplaceInput(4, n9); - n15->ReplaceInput(5, n10); - n31->ReplaceInput(0, n17); - n19->ReplaceInput(0, n2); - n19->ReplaceInput(1, n3); - n19->ReplaceInput(2, n7); - n19->ReplaceInput(3, n13); - n19->ReplaceInput(4, n13); - n19->ReplaceInput(5, n15); - n19->ReplaceInput(6, n18); - n21->ReplaceInput(0, n4); - n21->ReplaceInput(1, n4); - n21->ReplaceInput(2, n7); - n21->ReplaceInput(3, n13); - n21->ReplaceInput(4, n13); - n21->ReplaceInput(5, n19); - n21->ReplaceInput(6, n20); - n22->ReplaceInput(0, n21); - n3->ReplaceInput(0, n0); - n9->ReplaceInput(0, n7); - n9->ReplaceInput(1, n13); - n9->ReplaceInput(2, n0); - n9->ReplaceInput(3, n0); - n10->ReplaceInput(0, n9); - n17->ReplaceInput(0, n15); - n17->ReplaceInput(1, n16); - n18->ReplaceInput(0, n17); - n20->ReplaceInput(0, n19); - n16->ReplaceInput(0, n15); - - graph()->SetStart(n0); - graph()->SetEnd(n39); - - ComputeAndVerifySchedule(34); -} - - -TEST_F(SchedulerTest, BuildScheduleSimpleLoop) { - const Operator* op; - Unique unique_constant = - Unique::CreateImmovable(factory()->undefined_value()); - - // Manually transcripted code for: - // function turbo_fan_test(a, b) { - // while (a < b) { - // a++; - // } - // return a; - // } - Node* nil = graph()->NewNode(common()->Dead()); - op = common()->End(); - Node* n34 = graph()->NewNode(op, nil); - USE(n34); - op = common()->Return(); - Node* n32 = graph()->NewNode(op, nil, nil, nil); - USE(n32); - op = common()->Phi(kMachAnyTagged, 2); - Node* n13 = graph()->NewNode(op, nil, nil, nil); - USE(n13); - op = js()->LessThan(LanguageMode::SLOPPY); - Node* n16 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil); - USE(n16); - op = common()->IfFalse(); - Node* n22 = graph()->NewNode(op, nil); - USE(n22); - op = common()->Parameter(1); - Node* n2 = graph()->NewNode(op, nil); - USE(n2); - op = js()->Add(LanguageMode::SLOPPY); - Node* n29 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil, nil); - USE(n29); - op = common()->Loop(2); - Node* n12 = graph()->NewNode(op, nil, nil); - USE(n12); - op = common()->Parameter(2); - Node* n3 = graph()->NewNode(op, nil); - USE(n3); - op = common()->Parameter(3); - Node* n5 = graph()->NewNode(op, nil); - USE(n5); - op = common()->FrameState(JS_FRAME, BailoutId(-1), - OutputFrameStateCombine::Ignore()); - Node* n11 = graph()->NewNode(op, nil, nil, nil, nil, nil); - USE(n11); - op = common()->EffectPhi(2); - Node* n14 = graph()->NewNode(op, nil, nil, nil); - USE(n14); - op = common()->Branch(); - Node* n19 = graph()->NewNode(op, nil, nil); - USE(n19); - op = common()->Start(2); - Node* n0 = graph()->NewNode(op); - USE(n0); - op = js()->ToNumber(); - Node* n26 = graph()->NewNode(op, nil, nil, nil, nil, nil); - USE(n26); - op = common()->NumberConstant(1); - Node* n28 = graph()->NewNode(op); - USE(n28); - op = common()->IfSuccess(); - Node* n27 = graph()->NewNode(op, nil); - USE(n27); - op = common()->IfSuccess(); - Node* n8 = graph()->NewNode(op, nil); - USE(n8); - op = common()->IfSuccess(); - Node* n30 = graph()->NewNode(op, nil); - USE(n30); - op = common()->StateValues(0); - Node* n9 = graph()->NewNode(op); - USE(n9); - op = common()->NumberConstant(0); - Node* n10 = graph()->NewNode(op); - USE(n10); - op = common()->HeapConstant(unique_constant); - Node* n4 = graph()->NewNode(op); - USE(n4); - op = js()->StackCheck(); - Node* n7 = graph()->NewNode(op, nil, nil, nil, nil); - USE(n7); - op = js()->ToBoolean(); - Node* n18 = graph()->NewNode(op, nil, nil); - USE(n18); - op = common()->IfSuccess(); - Node* n17 = graph()->NewNode(op, nil); - USE(n17); - op = js()->StackCheck(); - Node* n24 = graph()->NewNode(op, nil, nil, nil, nil); - USE(n24); - op = common()->IfSuccess(); - Node* n25 = graph()->NewNode(op, nil); - USE(n25); - op = common()->IfTrue(); - Node* n20 = graph()->NewNode(op, nil); - USE(n20); - n34->ReplaceInput(0, n32); - n32->ReplaceInput(0, n13); - n32->ReplaceInput(1, n16); - n32->ReplaceInput(2, n22); - n13->ReplaceInput(0, n2); - n13->ReplaceInput(1, n29); - n13->ReplaceInput(2, n12); - n16->ReplaceInput(0, n13); - n16->ReplaceInput(1, n3); - n16->ReplaceInput(2, n5); - n16->ReplaceInput(3, n11); - n16->ReplaceInput(4, n14); - n16->ReplaceInput(5, n12); - n22->ReplaceInput(0, n19); - n2->ReplaceInput(0, n0); - n29->ReplaceInput(0, n26); - n29->ReplaceInput(1, n28); - n29->ReplaceInput(2, n5); - n29->ReplaceInput(3, n11); - n29->ReplaceInput(4, n11); - n29->ReplaceInput(5, n26); - n29->ReplaceInput(6, n27); - n12->ReplaceInput(0, n8); - n12->ReplaceInput(1, n30); - n3->ReplaceInput(0, n0); - n5->ReplaceInput(0, n0); - n11->ReplaceInput(0, n9); - n11->ReplaceInput(1, n9); - n11->ReplaceInput(2, n9); - n11->ReplaceInput(3, n10); - n11->ReplaceInput(4, n4); - n14->ReplaceInput(0, n7); - n14->ReplaceInput(1, n29); - n14->ReplaceInput(2, n12); - n19->ReplaceInput(0, n18); - n19->ReplaceInput(1, n17); - n26->ReplaceInput(0, n13); - n26->ReplaceInput(1, n5); - n26->ReplaceInput(2, n11); - n26->ReplaceInput(3, n24); - n26->ReplaceInput(4, n25); - n27->ReplaceInput(0, n26); - n8->ReplaceInput(0, n7); - n30->ReplaceInput(0, n29); - n7->ReplaceInput(0, n5); - n7->ReplaceInput(1, n11); - n7->ReplaceInput(2, n0); - n7->ReplaceInput(3, n0); - n18->ReplaceInput(0, n16); - n18->ReplaceInput(1, n5); - n17->ReplaceInput(0, n16); - n24->ReplaceInput(0, n5); - n24->ReplaceInput(1, n11); - n24->ReplaceInput(2, n16); - n24->ReplaceInput(3, n20); - n25->ReplaceInput(0, n24); - n20->ReplaceInput(0, n19); - - graph()->SetStart(n0); - graph()->SetEnd(n34); - - ComputeAndVerifySchedule(30); -} - - -TEST_F(SchedulerTest, BuildScheduleComplexLoops) { - const Operator* op; - Unique unique_constant = - Unique::CreateImmovable(factory()->undefined_value()); - - // Manually transcripted code for: - // function turbo_fan_test(a, b, c) { - // while (a < b) { - // a++; - // while (c < b) { - // c++; - // } - // } - // while (a < b) { - // a += 2; - // } - // return a; - // } - Node* nil = graph()->NewNode(common()->Dead()); - op = common()->End(); - Node* n71 = graph()->NewNode(op, nil); - USE(n71); - op = common()->Return(); - Node* n69 = graph()->NewNode(op, nil, nil, nil); - USE(n69); - op = common()->Phi(kMachAnyTagged, 2); - Node* n53 = graph()->NewNode(op, nil, nil, nil); - USE(n53); - op = js()->LessThan(LanguageMode::SLOPPY); - Node* n55 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil); - USE(n55); - op = common()->IfFalse(); - Node* n61 = graph()->NewNode(op, nil); - USE(n61); - op = common()->Phi(kMachAnyTagged, 2); - Node* n14 = graph()->NewNode(op, nil, nil, nil); - USE(n14); - op = js()->Add(LanguageMode::SLOPPY); - Node* n66 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil, nil); - USE(n66); - op = common()->Loop(2); - Node* n52 = graph()->NewNode(op, nil, nil); - USE(n52); - op = common()->Parameter(2); - Node* n3 = graph()->NewNode(op, nil); - USE(n3); - op = common()->Parameter(4); - Node* n6 = graph()->NewNode(op, nil); - USE(n6); - op = common()->FrameState(JS_FRAME, BailoutId(-1), - OutputFrameStateCombine::Ignore()); - Node* n12 = graph()->NewNode(op, nil, nil, nil, nil, nil); - USE(n12); - op = common()->EffectPhi(2); - Node* n54 = graph()->NewNode(op, nil, nil, nil); - USE(n54); - op = common()->Branch(); - Node* n58 = graph()->NewNode(op, nil, nil); - USE(n58); - op = common()->Parameter(1); - Node* n2 = graph()->NewNode(op, nil); - USE(n2); - op = js()->Add(LanguageMode::SLOPPY); - Node* n31 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil, nil); - USE(n31); - op = common()->Loop(2); - Node* n13 = graph()->NewNode(op, nil, nil); - USE(n13); - op = common()->NumberConstant(2); - Node* n65 = graph()->NewNode(op); - USE(n65); - op = js()->StackCheck(); - Node* n63 = graph()->NewNode(op, nil, nil, nil, nil); - USE(n63); - op = common()->IfSuccess(); - Node* n64 = graph()->NewNode(op, nil); - USE(n64); - op = common()->IfFalse(); - Node* n24 = graph()->NewNode(op, nil); - USE(n24); - op = common()->IfSuccess(); - Node* n67 = graph()->NewNode(op, nil); - USE(n67); - op = common()->Start(3); - Node* n0 = graph()->NewNode(op); - USE(n0); - op = common()->StateValues(0); - Node* n10 = graph()->NewNode(op); - USE(n10); - op = common()->NumberConstant(0); - Node* n11 = graph()->NewNode(op); - USE(n11); - op = common()->HeapConstant(unique_constant); - Node* n5 = graph()->NewNode(op); - USE(n5); - op = js()->LessThan(LanguageMode::SLOPPY); - Node* n18 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil); - USE(n18); - op = js()->ToBoolean(); - Node* n57 = graph()->NewNode(op, nil, nil); - USE(n57); - op = common()->IfSuccess(); - Node* n56 = graph()->NewNode(op, nil); - USE(n56); - op = js()->ToNumber(); - Node* n28 = graph()->NewNode(op, nil, nil, nil, nil, nil); - USE(n28); - op = common()->NumberConstant(1); - Node* n30 = graph()->NewNode(op); - USE(n30); - op = common()->IfSuccess(); - Node* n29 = graph()->NewNode(op, nil); - USE(n29); - op = common()->IfSuccess(); - Node* n9 = graph()->NewNode(op, nil); - USE(n9); - op = common()->IfFalse(); - Node* n42 = graph()->NewNode(op, nil); - USE(n42); - op = common()->IfTrue(); - Node* n59 = graph()->NewNode(op, nil); - USE(n59); - op = common()->Branch(); - Node* n21 = graph()->NewNode(op, nil, nil); - USE(n21); - op = common()->EffectPhi(2); - Node* n16 = graph()->NewNode(op, nil, nil, nil); - USE(n16); - op = js()->StackCheck(); - Node* n26 = graph()->NewNode(op, nil, nil, nil, nil); - USE(n26); - op = common()->IfSuccess(); - Node* n27 = graph()->NewNode(op, nil); - USE(n27); - op = js()->StackCheck(); - Node* n8 = graph()->NewNode(op, nil, nil, nil, nil); - USE(n8); - op = common()->Branch(); - Node* n39 = graph()->NewNode(op, nil, nil); - USE(n39); - op = js()->ToBoolean(); - Node* n20 = graph()->NewNode(op, nil, nil); - USE(n20); - op = common()->IfSuccess(); - Node* n19 = graph()->NewNode(op, nil); - USE(n19); - op = js()->LessThan(LanguageMode::SLOPPY); - Node* n36 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil); - USE(n36); - op = common()->IfTrue(); - Node* n22 = graph()->NewNode(op, nil); - USE(n22); - op = js()->ToBoolean(); - Node* n38 = graph()->NewNode(op, nil, nil); - USE(n38); - op = common()->IfSuccess(); - Node* n37 = graph()->NewNode(op, nil); - USE(n37); - op = common()->Phi(kMachAnyTagged, 2); - Node* n34 = graph()->NewNode(op, nil, nil, nil); - USE(n34); - op = common()->EffectPhi(2); - Node* n35 = graph()->NewNode(op, nil, nil, nil); - USE(n35); - op = common()->Loop(2); - Node* n33 = graph()->NewNode(op, nil, nil); - USE(n33); - op = common()->Phi(kMachAnyTagged, 2); - Node* n15 = graph()->NewNode(op, nil, nil, nil); - USE(n15); - op = js()->Add(LanguageMode::SLOPPY); - Node* n48 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil, nil); - USE(n48); - op = common()->IfSuccess(); - Node* n32 = graph()->NewNode(op, nil); - USE(n32); - op = common()->IfSuccess(); - Node* n49 = graph()->NewNode(op, nil); - USE(n49); - op = common()->Parameter(3); - Node* n4 = graph()->NewNode(op, nil); - USE(n4); - op = js()->ToNumber(); - Node* n46 = graph()->NewNode(op, nil, nil, nil, nil, nil); - USE(n46); - op = common()->IfSuccess(); - Node* n47 = graph()->NewNode(op, nil); - USE(n47); - op = js()->StackCheck(); - Node* n44 = graph()->NewNode(op, nil, nil, nil, nil); - USE(n44); - op = common()->IfSuccess(); - Node* n45 = graph()->NewNode(op, nil); - USE(n45); - op = common()->IfTrue(); - Node* n40 = graph()->NewNode(op, nil); - USE(n40); - n71->ReplaceInput(0, n69); - n69->ReplaceInput(0, n53); - n69->ReplaceInput(1, n55); - n69->ReplaceInput(2, n61); - n53->ReplaceInput(0, n14); - n53->ReplaceInput(1, n66); - n53->ReplaceInput(2, n52); - n55->ReplaceInput(0, n53); - n55->ReplaceInput(1, n3); - n55->ReplaceInput(2, n6); - n55->ReplaceInput(3, n12); - n55->ReplaceInput(4, n54); - n55->ReplaceInput(5, n52); - n61->ReplaceInput(0, n58); - n14->ReplaceInput(0, n2); - n14->ReplaceInput(1, n31); - n14->ReplaceInput(2, n13); - n66->ReplaceInput(0, n53); - n66->ReplaceInput(1, n65); - n66->ReplaceInput(2, n6); - n66->ReplaceInput(3, n12); - n66->ReplaceInput(4, n12); - n66->ReplaceInput(5, n63); - n66->ReplaceInput(6, n64); - n52->ReplaceInput(0, n24); - n52->ReplaceInput(1, n67); - n3->ReplaceInput(0, n0); - n6->ReplaceInput(0, n0); - n12->ReplaceInput(0, n10); - n12->ReplaceInput(1, n10); - n12->ReplaceInput(2, n10); - n12->ReplaceInput(3, n11); - n12->ReplaceInput(4, n5); - n54->ReplaceInput(0, n18); - n54->ReplaceInput(1, n66); - n54->ReplaceInput(2, n52); - n58->ReplaceInput(0, n57); - n58->ReplaceInput(1, n56); - n2->ReplaceInput(0, n0); - n31->ReplaceInput(0, n28); - n31->ReplaceInput(1, n30); - n31->ReplaceInput(2, n6); - n31->ReplaceInput(3, n12); - n31->ReplaceInput(4, n12); - n31->ReplaceInput(5, n28); - n31->ReplaceInput(6, n29); - n13->ReplaceInput(0, n9); - n13->ReplaceInput(1, n42); - n63->ReplaceInput(0, n6); - n63->ReplaceInput(1, n12); - n63->ReplaceInput(2, n55); - n63->ReplaceInput(3, n59); - n64->ReplaceInput(0, n63); - n24->ReplaceInput(0, n21); - n67->ReplaceInput(0, n66); - n18->ReplaceInput(0, n14); - n18->ReplaceInput(1, n3); - n18->ReplaceInput(2, n6); - n18->ReplaceInput(3, n12); - n18->ReplaceInput(4, n16); - n18->ReplaceInput(5, n13); - n57->ReplaceInput(0, n55); - n57->ReplaceInput(1, n6); - n56->ReplaceInput(0, n55); - n28->ReplaceInput(0, n14); - n28->ReplaceInput(1, n6); - n28->ReplaceInput(2, n12); - n28->ReplaceInput(3, n26); - n28->ReplaceInput(4, n27); - n29->ReplaceInput(0, n28); - n9->ReplaceInput(0, n8); - n42->ReplaceInput(0, n39); - n59->ReplaceInput(0, n58); - n21->ReplaceInput(0, n20); - n21->ReplaceInput(1, n19); - n16->ReplaceInput(0, n8); - n16->ReplaceInput(1, n36); - n16->ReplaceInput(2, n13); - n26->ReplaceInput(0, n6); - n26->ReplaceInput(1, n12); - n26->ReplaceInput(2, n18); - n26->ReplaceInput(3, n22); - n27->ReplaceInput(0, n26); - n8->ReplaceInput(0, n6); - n8->ReplaceInput(1, n12); - n8->ReplaceInput(2, n0); - n8->ReplaceInput(3, n0); - n39->ReplaceInput(0, n38); - n39->ReplaceInput(1, n37); - n20->ReplaceInput(0, n18); - n20->ReplaceInput(1, n6); - n19->ReplaceInput(0, n18); - n36->ReplaceInput(0, n34); - n36->ReplaceInput(1, n3); - n36->ReplaceInput(2, n6); - n36->ReplaceInput(3, n12); - n36->ReplaceInput(4, n35); - n36->ReplaceInput(5, n33); - n22->ReplaceInput(0, n21); - n38->ReplaceInput(0, n36); - n38->ReplaceInput(1, n6); - n37->ReplaceInput(0, n36); - n34->ReplaceInput(0, n15); - n34->ReplaceInput(1, n48); - n34->ReplaceInput(2, n33); - n35->ReplaceInput(0, n31); - n35->ReplaceInput(1, n48); - n35->ReplaceInput(2, n33); - n33->ReplaceInput(0, n32); - n33->ReplaceInput(1, n49); - n15->ReplaceInput(0, n4); - n15->ReplaceInput(1, n34); - n15->ReplaceInput(2, n13); - n48->ReplaceInput(0, n46); - n48->ReplaceInput(1, n30); - n48->ReplaceInput(2, n6); - n48->ReplaceInput(3, n12); - n48->ReplaceInput(4, n12); - n48->ReplaceInput(5, n46); - n48->ReplaceInput(6, n47); - n32->ReplaceInput(0, n31); - n49->ReplaceInput(0, n48); - n4->ReplaceInput(0, n0); - n46->ReplaceInput(0, n34); - n46->ReplaceInput(1, n6); - n46->ReplaceInput(2, n12); - n46->ReplaceInput(3, n44); - n46->ReplaceInput(4, n45); - n47->ReplaceInput(0, n46); - n44->ReplaceInput(0, n6); - n44->ReplaceInput(1, n12); - n44->ReplaceInput(2, n36); - n44->ReplaceInput(3, n40); - n45->ReplaceInput(0, n44); - n40->ReplaceInput(0, n39); - - graph()->SetStart(n0); - graph()->SetEnd(n71); - - ComputeAndVerifySchedule(65); -} - - -TEST_F(SchedulerTest, BuildScheduleBreakAndContinue) { - const Operator* op; - Unique unique_constant = - Unique::CreateImmovable(factory()->undefined_value()); - - // Manually transcripted code for: - // function turbo_fan_test(a, b, c) { - // var d = 0; - // while (a < b) { - // a++; - // while (c < b) { - // c++; - // if (d == 0) break; - // a++; - // } - // if (a == 1) continue; - // d++; - // } - // return a + d; - // } - Node* nil = graph()->NewNode(common()->Dead()); - op = common()->End(); - Node* n86 = graph()->NewNode(op, nil); - USE(n86); - op = common()->Return(); - Node* n84 = graph()->NewNode(op, nil, nil, nil); - USE(n84); - op = js()->Add(LanguageMode::SLOPPY); - Node* n82 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil, nil); - USE(n82); - op = common()->IfSuccess(); - Node* n83 = graph()->NewNode(op, nil); - USE(n83); - op = common()->Phi(kMachAnyTagged, 2); - Node* n15 = graph()->NewNode(op, nil, nil, nil); - USE(n15); - op = common()->Phi(kMachAnyTagged, 2); - Node* n17 = graph()->NewNode(op, nil, nil, nil); - USE(n17); - op = common()->Parameter(4); - Node* n6 = graph()->NewNode(op, nil); - USE(n6); - op = common()->FrameState(JS_FRAME, BailoutId(-1), - OutputFrameStateCombine::Ignore()); - Node* n12 = graph()->NewNode(op, nil, nil, nil, nil, nil); - USE(n12); - op = js()->LessThan(LanguageMode::SLOPPY); - Node* n19 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil); - USE(n19); - op = common()->IfFalse(); - Node* n25 = graph()->NewNode(op, nil); - USE(n25); - op = common()->Parameter(1); - Node* n2 = graph()->NewNode(op, nil); - USE(n2); - op = common()->Phi(kMachAnyTagged, 2); - Node* n35 = graph()->NewNode(op, nil, nil, nil); - USE(n35); - op = common()->Loop(2); - Node* n14 = graph()->NewNode(op, nil, nil); - USE(n14); - op = common()->NumberConstant(0); - Node* n11 = graph()->NewNode(op); - USE(n11); - op = common()->Phi(kMachAnyTagged, 2); - Node* n81 = graph()->NewNode(op, nil, nil, nil); - USE(n81); - op = common()->Start(3); - Node* n0 = graph()->NewNode(op); - USE(n0); - op = common()->StateValues(0); - Node* n10 = graph()->NewNode(op); - USE(n10); - op = common()->HeapConstant(unique_constant); - Node* n5 = graph()->NewNode(op); - USE(n5); - op = common()->Parameter(2); - Node* n3 = graph()->NewNode(op, nil); - USE(n3); - op = common()->EffectPhi(2); - Node* n18 = graph()->NewNode(op, nil, nil, nil); - USE(n18); - op = common()->Branch(); - Node* n22 = graph()->NewNode(op, nil, nil); - USE(n22); - op = js()->Add(LanguageMode::SLOPPY); - Node* n32 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil, nil); - USE(n32); - op = js()->Add(LanguageMode::SLOPPY); - Node* n64 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil, nil); - USE(n64); - op = common()->Loop(2); - Node* n34 = graph()->NewNode(op, nil, nil); - USE(n34); - op = common()->IfSuccess(); - Node* n9 = graph()->NewNode(op, nil); - USE(n9); - op = common()->Merge(2); - Node* n72 = graph()->NewNode(op, nil, nil); - USE(n72); - op = js()->Add(LanguageMode::SLOPPY); - Node* n78 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil, nil); - USE(n78); - op = js()->StackCheck(); - Node* n8 = graph()->NewNode(op, nil, nil, nil, nil); - USE(n8); - op = common()->EffectPhi(2); - Node* n80 = graph()->NewNode(op, nil, nil, nil); - USE(n80); - op = js()->ToBoolean(); - Node* n21 = graph()->NewNode(op, nil, nil); - USE(n21); - op = common()->IfSuccess(); - Node* n20 = graph()->NewNode(op, nil); - USE(n20); - op = js()->ToNumber(); - Node* n29 = graph()->NewNode(op, nil, nil, nil, nil, nil); - USE(n29); - op = common()->NumberConstant(1); - Node* n31 = graph()->NewNode(op); - USE(n31); - op = common()->IfSuccess(); - Node* n30 = graph()->NewNode(op, nil); - USE(n30); - op = js()->ToNumber(); - Node* n62 = graph()->NewNode(op, nil, nil, nil, nil, nil); - USE(n62); - op = common()->IfSuccess(); - Node* n63 = graph()->NewNode(op, nil); - USE(n63); - op = common()->IfSuccess(); - Node* n33 = graph()->NewNode(op, nil); - USE(n33); - op = common()->IfSuccess(); - Node* n65 = graph()->NewNode(op, nil); - USE(n65); - op = common()->IfTrue(); - Node* n71 = graph()->NewNode(op, nil); - USE(n71); - op = common()->IfSuccess(); - Node* n79 = graph()->NewNode(op, nil); - USE(n79); - op = js()->ToNumber(); - Node* n76 = graph()->NewNode(op, nil, nil, nil, nil, nil); - USE(n76); - op = common()->IfSuccess(); - Node* n77 = graph()->NewNode(op, nil); - USE(n77); - op = js()->Equal(); - Node* n67 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil); - USE(n67); - op = js()->StackCheck(); - Node* n27 = graph()->NewNode(op, nil, nil, nil, nil); - USE(n27); - op = common()->IfSuccess(); - Node* n28 = graph()->NewNode(op, nil); - USE(n28); - op = js()->Equal(); - Node* n52 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil); - USE(n52); - op = common()->IfFalse(); - Node* n60 = graph()->NewNode(op, nil); - USE(n60); - op = common()->Branch(); - Node* n70 = graph()->NewNode(op, nil, nil); - USE(n70); - op = common()->IfFalse(); - Node* n74 = graph()->NewNode(op, nil); - USE(n74); - op = common()->EffectPhi(2); - Node* n57 = graph()->NewNode(op, nil, nil, nil); - USE(n57); - op = common()->Merge(2); - Node* n45 = graph()->NewNode(op, nil, nil); - USE(n45); - op = common()->IfTrue(); - Node* n23 = graph()->NewNode(op, nil); - USE(n23); - op = js()->Add(LanguageMode::SLOPPY); - Node* n50 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil, nil); - USE(n50); - op = common()->IfSuccess(); - Node* n51 = graph()->NewNode(op, nil); - USE(n51); - op = common()->Branch(); - Node* n55 = graph()->NewNode(op, nil, nil); - USE(n55); - op = js()->ToBoolean(); - Node* n69 = graph()->NewNode(op, nil, nil); - USE(n69); - op = common()->IfSuccess(); - Node* n68 = graph()->NewNode(op, nil); - USE(n68); - op = js()->LessThan(LanguageMode::SLOPPY); - Node* n38 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil); - USE(n38); - op = common()->IfFalse(); - Node* n44 = graph()->NewNode(op, nil); - USE(n44); - op = common()->IfTrue(); - Node* n56 = graph()->NewNode(op, nil); - USE(n56); - op = js()->ToNumber(); - Node* n48 = graph()->NewNode(op, nil, nil, nil, nil, nil); - USE(n48); - op = common()->IfSuccess(); - Node* n49 = graph()->NewNode(op, nil); - USE(n49); - op = js()->ToBoolean(); - Node* n54 = graph()->NewNode(op, nil, nil); - USE(n54); - op = common()->IfSuccess(); - Node* n53 = graph()->NewNode(op, nil); - USE(n53); - op = common()->Phi(kMachAnyTagged, 2); - Node* n36 = graph()->NewNode(op, nil, nil, nil); - USE(n36); - op = common()->EffectPhi(2); - Node* n37 = graph()->NewNode(op, nil, nil, nil); - USE(n37); - op = common()->Branch(); - Node* n41 = graph()->NewNode(op, nil, nil); - USE(n41); - op = js()->StackCheck(); - Node* n46 = graph()->NewNode(op, nil, nil, nil, nil); - USE(n46); - op = common()->IfSuccess(); - Node* n47 = graph()->NewNode(op, nil); - USE(n47); - op = common()->Phi(kMachAnyTagged, 2); - Node* n16 = graph()->NewNode(op, nil, nil, nil); - USE(n16); - op = js()->ToBoolean(); - Node* n40 = graph()->NewNode(op, nil, nil); - USE(n40); - op = common()->IfSuccess(); - Node* n39 = graph()->NewNode(op, nil); - USE(n39); - op = common()->IfTrue(); - Node* n42 = graph()->NewNode(op, nil); - USE(n42); - op = common()->Parameter(3); - Node* n4 = graph()->NewNode(op, nil); - USE(n4); - op = common()->Phi(kMachAnyTagged, 2); - Node* n58 = graph()->NewNode(op, nil, nil, nil); - USE(n58); - n86->ReplaceInput(0, n84); - n84->ReplaceInput(0, n82); - n84->ReplaceInput(1, n82); - n84->ReplaceInput(2, n83); - n82->ReplaceInput(0, n15); - n82->ReplaceInput(1, n17); - n82->ReplaceInput(2, n6); - n82->ReplaceInput(3, n12); - n82->ReplaceInput(4, n12); - n82->ReplaceInput(5, n19); - n82->ReplaceInput(6, n25); - n83->ReplaceInput(0, n82); - n15->ReplaceInput(0, n2); - n15->ReplaceInput(1, n35); - n15->ReplaceInput(2, n14); - n17->ReplaceInput(0, n11); - n17->ReplaceInput(1, n81); - n17->ReplaceInput(2, n14); - n6->ReplaceInput(0, n0); - n12->ReplaceInput(0, n10); - n12->ReplaceInput(1, n10); - n12->ReplaceInput(2, n10); - n12->ReplaceInput(3, n11); - n12->ReplaceInput(4, n5); - n19->ReplaceInput(0, n15); - n19->ReplaceInput(1, n3); - n19->ReplaceInput(2, n6); - n19->ReplaceInput(3, n12); - n19->ReplaceInput(4, n18); - n19->ReplaceInput(5, n14); - n25->ReplaceInput(0, n22); - n2->ReplaceInput(0, n0); - n35->ReplaceInput(0, n32); - n35->ReplaceInput(1, n64); - n35->ReplaceInput(2, n34); - n14->ReplaceInput(0, n9); - n14->ReplaceInput(1, n72); - n81->ReplaceInput(0, n17); - n81->ReplaceInput(1, n78); - n81->ReplaceInput(2, n72); - n3->ReplaceInput(0, n0); - n18->ReplaceInput(0, n8); - n18->ReplaceInput(1, n80); - n18->ReplaceInput(2, n14); - n22->ReplaceInput(0, n21); - n22->ReplaceInput(1, n20); - n32->ReplaceInput(0, n29); - n32->ReplaceInput(1, n31); - n32->ReplaceInput(2, n6); - n32->ReplaceInput(3, n12); - n32->ReplaceInput(4, n12); - n32->ReplaceInput(5, n29); - n32->ReplaceInput(6, n30); - n64->ReplaceInput(0, n62); - n64->ReplaceInput(1, n31); - n64->ReplaceInput(2, n6); - n64->ReplaceInput(3, n12); - n64->ReplaceInput(4, n12); - n64->ReplaceInput(5, n62); - n64->ReplaceInput(6, n63); - n34->ReplaceInput(0, n33); - n34->ReplaceInput(1, n65); - n9->ReplaceInput(0, n8); - n72->ReplaceInput(0, n71); - n72->ReplaceInput(1, n79); - n78->ReplaceInput(0, n76); - n78->ReplaceInput(1, n31); - n78->ReplaceInput(2, n6); - n78->ReplaceInput(3, n12); - n78->ReplaceInput(4, n12); - n78->ReplaceInput(5, n76); - n78->ReplaceInput(6, n77); - n8->ReplaceInput(0, n6); - n8->ReplaceInput(1, n12); - n8->ReplaceInput(2, n0); - n8->ReplaceInput(3, n0); - n80->ReplaceInput(0, n67); - n80->ReplaceInput(1, n78); - n80->ReplaceInput(2, n72); - n21->ReplaceInput(0, n19); - n21->ReplaceInput(1, n6); - n20->ReplaceInput(0, n19); - n29->ReplaceInput(0, n15); - n29->ReplaceInput(1, n6); - n29->ReplaceInput(2, n12); - n29->ReplaceInput(3, n27); - n29->ReplaceInput(4, n28); - n30->ReplaceInput(0, n29); - n62->ReplaceInput(0, n35); - n62->ReplaceInput(1, n6); - n62->ReplaceInput(2, n12); - n62->ReplaceInput(3, n52); - n62->ReplaceInput(4, n60); - n63->ReplaceInput(0, n62); - n33->ReplaceInput(0, n32); - n65->ReplaceInput(0, n64); - n71->ReplaceInput(0, n70); - n79->ReplaceInput(0, n78); - n76->ReplaceInput(0, n17); - n76->ReplaceInput(1, n6); - n76->ReplaceInput(2, n12); - n76->ReplaceInput(3, n67); - n76->ReplaceInput(4, n74); - n77->ReplaceInput(0, n76); - n67->ReplaceInput(0, n35); - n67->ReplaceInput(1, n31); - n67->ReplaceInput(2, n6); - n67->ReplaceInput(3, n12); - n67->ReplaceInput(4, n57); - n67->ReplaceInput(5, n45); - n27->ReplaceInput(0, n6); - n27->ReplaceInput(1, n12); - n27->ReplaceInput(2, n19); - n27->ReplaceInput(3, n23); - n28->ReplaceInput(0, n27); - n52->ReplaceInput(0, n17); - n52->ReplaceInput(1, n11); - n52->ReplaceInput(2, n6); - n52->ReplaceInput(3, n12); - n52->ReplaceInput(4, n50); - n52->ReplaceInput(5, n51); - n60->ReplaceInput(0, n55); - n70->ReplaceInput(0, n69); - n70->ReplaceInput(1, n68); - n74->ReplaceInput(0, n70); - n57->ReplaceInput(0, n38); - n57->ReplaceInput(1, n52); - n57->ReplaceInput(2, n45); - n45->ReplaceInput(0, n44); - n45->ReplaceInput(1, n56); - n23->ReplaceInput(0, n22); - n50->ReplaceInput(0, n48); - n50->ReplaceInput(1, n31); - n50->ReplaceInput(2, n6); - n50->ReplaceInput(3, n12); - n50->ReplaceInput(4, n12); - n50->ReplaceInput(5, n48); - n50->ReplaceInput(6, n49); - n51->ReplaceInput(0, n50); - n55->ReplaceInput(0, n54); - n55->ReplaceInput(1, n53); - n69->ReplaceInput(0, n67); - n69->ReplaceInput(1, n6); - n68->ReplaceInput(0, n67); - n38->ReplaceInput(0, n36); - n38->ReplaceInput(1, n3); - n38->ReplaceInput(2, n6); - n38->ReplaceInput(3, n12); - n38->ReplaceInput(4, n37); - n38->ReplaceInput(5, n34); - n44->ReplaceInput(0, n41); - n56->ReplaceInput(0, n55); - n48->ReplaceInput(0, n36); - n48->ReplaceInput(1, n6); - n48->ReplaceInput(2, n12); - n48->ReplaceInput(3, n46); - n48->ReplaceInput(4, n47); - n49->ReplaceInput(0, n48); - n54->ReplaceInput(0, n52); - n54->ReplaceInput(1, n6); - n53->ReplaceInput(0, n52); - n36->ReplaceInput(0, n16); - n36->ReplaceInput(1, n50); - n36->ReplaceInput(2, n34); - n37->ReplaceInput(0, n32); - n37->ReplaceInput(1, n64); - n37->ReplaceInput(2, n34); - n41->ReplaceInput(0, n40); - n41->ReplaceInput(1, n39); - n46->ReplaceInput(0, n6); - n46->ReplaceInput(1, n12); - n46->ReplaceInput(2, n38); - n46->ReplaceInput(3, n42); - n47->ReplaceInput(0, n46); - n16->ReplaceInput(0, n4); - n16->ReplaceInput(1, n58); - n16->ReplaceInput(2, n14); - n40->ReplaceInput(0, n38); - n40->ReplaceInput(1, n6); - n39->ReplaceInput(0, n38); - n42->ReplaceInput(0, n41); - n4->ReplaceInput(0, n0); - n58->ReplaceInput(0, n36); - n58->ReplaceInput(1, n50); - n58->ReplaceInput(2, n45); - - graph()->SetStart(n0); - graph()->SetEnd(n86); - - ComputeAndVerifySchedule(83); -} - - -TEST_F(SchedulerTest, BuildScheduleSimpleLoopWithCodeMotion) { - const Operator* op; - Unique unique_constant = - Unique::CreateImmovable(factory()->undefined_value()); - - // Manually transcripted code for: - // function turbo_fan_test(a, b, c) { - // while (a < b) { - // a += b + c; - // } - // return a; - // } - Node* nil = graph()->NewNode(common()->Dead()); - op = common()->End(); - Node* n34 = graph()->NewNode(op, nil); - USE(n34); - op = common()->Return(); - Node* n32 = graph()->NewNode(op, nil, nil, nil); - USE(n32); - op = common()->Phi(kMachAnyTagged, 2); - Node* n14 = graph()->NewNode(op, nil, nil, nil); - USE(n14); - op = js()->LessThan(LanguageMode::SLOPPY); - Node* n17 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil); - USE(n17); - op = common()->IfFalse(); - Node* n23 = graph()->NewNode(op, nil); - USE(n23); - op = common()->Parameter(1); - Node* n2 = graph()->NewNode(op, nil); - USE(n2); - op = js()->Add(LanguageMode::SLOPPY); - Node* n29 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil, nil); - USE(n29); - op = common()->Loop(2); - Node* n13 = graph()->NewNode(op, nil, nil); - USE(n13); - op = common()->Parameter(2); - Node* n3 = graph()->NewNode(op, nil); - USE(n3); - op = common()->Parameter(4); - Node* n6 = graph()->NewNode(op, nil); - USE(n6); - op = common()->FrameState(JS_FRAME, BailoutId(-1), - OutputFrameStateCombine::Ignore()); - Node* n12 = graph()->NewNode(op, nil, nil, nil, nil, nil); - USE(n12); - op = common()->EffectPhi(2); - Node* n15 = graph()->NewNode(op, nil, nil, nil); - USE(n15); - op = common()->Branch(); - Node* n20 = graph()->NewNode(op, nil, nil); - USE(n20); - op = common()->Start(3); - Node* n0 = graph()->NewNode(op); - USE(n0); - op = js()->Add(LanguageMode::SLOPPY); - Node* n27 = graph()->NewNode(op, nil, nil, nil, nil, nil, nil, nil); - USE(n27); - op = common()->IfSuccess(); - Node* n28 = graph()->NewNode(op, nil); - USE(n28); - op = common()->IfSuccess(); - Node* n9 = graph()->NewNode(op, nil); - USE(n9); - op = common()->IfSuccess(); - Node* n30 = graph()->NewNode(op, nil); - USE(n30); - op = common()->StateValues(0); - Node* n10 = graph()->NewNode(op); - USE(n10); - op = common()->NumberConstant(0); - Node* n11 = graph()->NewNode(op); - USE(n11); - op = common()->HeapConstant(unique_constant); - Node* n5 = graph()->NewNode(op); - USE(n5); - op = js()->StackCheck(); - Node* n8 = graph()->NewNode(op, nil, nil, nil, nil); - USE(n8); - op = js()->ToBoolean(); - Node* n19 = graph()->NewNode(op, nil, nil); - USE(n19); - op = common()->IfSuccess(); - Node* n18 = graph()->NewNode(op, nil); - USE(n18); - op = common()->Parameter(3); - Node* n4 = graph()->NewNode(op, nil); - USE(n4); - op = js()->StackCheck(); - Node* n25 = graph()->NewNode(op, nil, nil, nil, nil); - USE(n25); - op = common()->IfSuccess(); - Node* n26 = graph()->NewNode(op, nil); - USE(n26); - op = common()->IfTrue(); - Node* n21 = graph()->NewNode(op, nil); - USE(n21); - n34->ReplaceInput(0, n32); - n32->ReplaceInput(0, n14); - n32->ReplaceInput(1, n17); - n32->ReplaceInput(2, n23); - n14->ReplaceInput(0, n2); - n14->ReplaceInput(1, n29); - n14->ReplaceInput(2, n13); - n17->ReplaceInput(0, n14); - n17->ReplaceInput(1, n3); - n17->ReplaceInput(2, n6); - n17->ReplaceInput(3, n12); - n17->ReplaceInput(4, n15); - n17->ReplaceInput(5, n13); - n23->ReplaceInput(0, n20); - n2->ReplaceInput(0, n0); - n29->ReplaceInput(0, n14); - n29->ReplaceInput(1, n27); - n29->ReplaceInput(2, n6); - n29->ReplaceInput(3, n12); - n29->ReplaceInput(4, n12); - n29->ReplaceInput(5, n27); - n29->ReplaceInput(6, n28); - n13->ReplaceInput(0, n9); - n13->ReplaceInput(1, n30); - n3->ReplaceInput(0, n0); - n6->ReplaceInput(0, n0); - n12->ReplaceInput(0, n10); - n12->ReplaceInput(1, n10); - n12->ReplaceInput(2, n10); - n12->ReplaceInput(3, n11); - n12->ReplaceInput(4, n5); - n15->ReplaceInput(0, n8); - n15->ReplaceInput(1, n29); - n15->ReplaceInput(2, n13); - n20->ReplaceInput(0, n19); - n20->ReplaceInput(1, n18); - n27->ReplaceInput(0, n3); - n27->ReplaceInput(1, n4); - n27->ReplaceInput(2, n6); - n27->ReplaceInput(3, n12); - n27->ReplaceInput(4, n12); - n27->ReplaceInput(5, n25); - n27->ReplaceInput(6, n26); - n28->ReplaceInput(0, n27); - n9->ReplaceInput(0, n8); - n30->ReplaceInput(0, n29); - n8->ReplaceInput(0, n6); - n8->ReplaceInput(1, n12); - n8->ReplaceInput(2, n0); - n8->ReplaceInput(3, n0); - n19->ReplaceInput(0, n17); - n19->ReplaceInput(1, n6); - n18->ReplaceInput(0, n17); - n4->ReplaceInput(0, n0); - n25->ReplaceInput(0, n6); - n25->ReplaceInput(1, n12); - n25->ReplaceInput(2, n17); - n25->ReplaceInput(3, n21); - n26->ReplaceInput(0, n25); - n21->ReplaceInput(0, n20); - - graph()->SetStart(n0); - graph()->SetEnd(n34); - - ComputeAndVerifySchedule(30); -} - - namespace { Node* CreateDiamond(Graph* graph, CommonOperatorBuilder* common, Node* cond) { -- 2.7.4