1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2014 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/compiler/js-typed-lowering.h"
6f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
7c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch#include "src/ast/modules.h"
8f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/builtins/builtins-utils.h"
9014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/code-factory.h"
10014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compilation-dependencies.h"
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/access-builder.h"
12958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/compiler/js-graph.h"
13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler/linkage.h"
14958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/compiler/node-matchers.h"
15014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler/node-properties.h"
16014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler/operator-properties.h"
17f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/compiler/type-cache.h"
18f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/compiler/types.h"
1962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/objects-inl.h"
20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 {
22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal {
23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace compiler {
24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// A helper class to simplify the process of reducing a single binop node with a
26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// JSOperator. This class manages the rewriting of context, control, and effect
27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// dependencies during lowering of a binop and contains numerous helper
28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// functions for matching the types of inputs to an operation.
29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass JSBinopReduction final {
30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  JSBinopReduction(JSTypedLowering* lowering, Node* node)
32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : lowering_(lowering), node_(node) {}
33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
34f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  bool GetCompareNumberOperationHint(NumberOperationHint* hint) {
35f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) {
36f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      DCHECK_EQ(1, node_->op()->EffectOutputCount());
37f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      switch (CompareOperationHintOf(node_->op())) {
38f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        case CompareOperationHint::kSignedSmall:
39f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          *hint = NumberOperationHint::kSignedSmall;
40f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          return true;
41f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        case CompareOperationHint::kNumber:
42f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          *hint = NumberOperationHint::kNumber;
43f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          return true;
44f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        case CompareOperationHint::kNumberOrOddball:
45f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          *hint = NumberOperationHint::kNumberOrOddball;
46f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          return true;
47f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        case CompareOperationHint::kAny:
48f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        case CompareOperationHint::kNone:
4962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        case CompareOperationHint::kString:
5062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        case CompareOperationHint::kReceiver:
5162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        case CompareOperationHint::kInternalizedString:
52f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          break;
53f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      }
5413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    }
55f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return false;
5613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
5713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
5862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  bool IsInternalizedStringCompareOperation() {
5962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) {
6062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      DCHECK_EQ(1, node_->op()->EffectOutputCount());
6162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return (CompareOperationHintOf(node_->op()) ==
6262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch              CompareOperationHint::kInternalizedString) &&
6362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch             BothInputsMaybe(Type::InternalizedString());
6462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
6562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return false;
6662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
6762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
6862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  bool IsReceiverCompareOperation() {
6962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) {
7062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      DCHECK_EQ(1, node_->op()->EffectOutputCount());
7162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return (CompareOperationHintOf(node_->op()) ==
7262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch              CompareOperationHint::kReceiver) &&
7362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch             BothInputsMaybe(Type::Receiver());
7462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
7562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return false;
7662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
7762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
7862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  bool IsStringCompareOperation() {
7962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) {
8062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      DCHECK_EQ(1, node_->op()->EffectOutputCount());
8162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return (CompareOperationHintOf(node_->op()) ==
8262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch              CompareOperationHint::kString) &&
8362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch             BothInputsMaybe(Type::String());
8462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
8562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return false;
8662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
8762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
88f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Check if a string addition will definitely result in creating a ConsString,
89f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // i.e. if the combined length of the resulting string exceeds the ConsString
90f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // minimum length.
91f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool ShouldCreateConsString() {
92f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    DCHECK_EQ(IrOpcode::kJSAdd, node_->opcode());
9362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    DCHECK(OneInputIs(Type::String()));
94f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (BothInputsAre(Type::String()) ||
95f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        ((lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) &&
96f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch         BinaryOperationHintOf(node_->op()) == BinaryOperationHint::kString)) {
97c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      HeapObjectBinopMatcher m(node_);
98c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      if (m.right().HasValue() && m.right().Value()->IsString()) {
99c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        Handle<String> right_string = Handle<String>::cast(m.right().Value());
100f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        if (right_string->length() >= ConsString::kMinLength) return true;
101f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      }
102c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      if (m.left().HasValue() && m.left().Value()->IsString()) {
103c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        Handle<String> left_string = Handle<String>::cast(m.left().Value());
104f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        if (left_string->length() >= ConsString::kMinLength) {
105f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          // The invariant for ConsString requires the left hand side to be
106f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          // a sequential or external string if the right hand side is the
107f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          // empty string. Since we don't know anything about the right hand
108f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          // side here, we must ensure that the left hand side satisfy the
109f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          // constraints independent of the right hand side.
110f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          return left_string->IsSeqString() || left_string->IsExternalString();
111f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        }
112f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      }
113f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
114f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return false;
115f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
116f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
11762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Inserts a CheckReceiver for the left input.
11862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  void CheckLeftInputToReceiver() {
11962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* left_input = graph()->NewNode(simplified()->CheckReceiver(), left(),
12062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                        effect(), control());
12162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    node_->ReplaceInput(0, left_input);
12262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    update_effect(left_input);
12362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
12462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
12562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Checks that both inputs are Receiver, and if we don't know
12662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // statically that one side is already a Receiver, insert a
12762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // CheckReceiver node.
12862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  void CheckInputsToReceiver() {
12962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (!left_type()->Is(Type::Receiver())) {
13062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      CheckLeftInputToReceiver();
13162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
13262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (!right_type()->Is(Type::Receiver())) {
13362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Node* right_input = graph()->NewNode(simplified()->CheckReceiver(),
13462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                           right(), effect(), control());
13562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      node_->ReplaceInput(1, right_input);
13662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      update_effect(right_input);
13762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
13862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
13962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
14062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Checks that both inputs are String, and if we don't know
14162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // statically that one side is already a String, insert a
14262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // CheckString node.
14362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  void CheckInputsToString() {
14462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (!left_type()->Is(Type::String())) {
14562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Node* left_input = graph()->NewNode(simplified()->CheckString(), left(),
14662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                          effect(), control());
14762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      node_->ReplaceInput(0, left_input);
14862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      update_effect(left_input);
14962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
15062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (!right_type()->Is(Type::String())) {
15162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Node* right_input = graph()->NewNode(simplified()->CheckString(), right(),
15262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                           effect(), control());
15362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      node_->ReplaceInput(1, right_input);
15462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      update_effect(right_input);
15562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
15662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
15762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
15862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Checks that both inputs are InternalizedString, and if we don't know
15962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // statically that one side is already an InternalizedString, insert a
16062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // CheckInternalizedString node.
16162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  void CheckInputsToInternalizedString() {
16262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (!left_type()->Is(Type::UniqueName())) {
16362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Node* left_input = graph()->NewNode(
16462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          simplified()->CheckInternalizedString(), left(), effect(), control());
16562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      node_->ReplaceInput(0, left_input);
16662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      update_effect(left_input);
16762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
16862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (!right_type()->Is(Type::UniqueName())) {
16962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Node* right_input =
17062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          graph()->NewNode(simplified()->CheckInternalizedString(), right(),
17162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                           effect(), control());
17262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      node_->ReplaceInput(1, right_input);
17362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      update_effect(right_input);
17462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
17562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
17662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
177f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void ConvertInputsToNumber() {
178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // To convert the inputs to numbers, we have to provide frame states
179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // for lazy bailouts in the ToNumber conversions.
180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // We use a little hack here: we take the frame state before the binary
181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // operation and use it to construct the frame states for the conversion
182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // so that after the deoptimization, the binary operation IC gets
183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // already converted values from full code. This way we are sure that we
184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // will not re-do any of the side effects.
185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Node* left_input = nullptr;
187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Node* right_input = nullptr;
188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool left_is_primitive = left_type()->Is(Type::PlainPrimitive());
189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool right_is_primitive = right_type()->Is(Type::PlainPrimitive());
190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool handles_exception = NodeProperties::IsExceptionalCall(node_);
191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!left_is_primitive && !right_is_primitive && handles_exception) {
193f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ConvertBothInputsToNumber(&left_input, &right_input);
194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      left_input = left_is_primitive
19613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                       ? ConvertPlainPrimitiveToNumber(left())
197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       : ConvertSingleInputToNumber(
198f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                             left(), CreateFrameStateForLeftInput());
199f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      right_input =
200f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          right_is_primitive
201f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              ? ConvertPlainPrimitiveToNumber(right())
202f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              : ConvertSingleInputToNumber(
203f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                    right(), CreateFrameStateForRightInput(left_input));
204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    node_->ReplaceInput(0, left_input);
207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    node_->ReplaceInput(1, right_input);
208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
210958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void ConvertInputsToUI32(Signedness left_signedness,
211958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                           Signedness right_signedness) {
212958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    node_->ReplaceInput(0, ConvertToUI32(left(), left_signedness));
213958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    node_->ReplaceInput(1, ConvertToUI32(right(), right_signedness));
214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void SwapInputs() {
217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* l = left();
218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Node* r = right();
219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    node_->ReplaceInput(0, r);
220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    node_->ReplaceInput(1, l);
221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Remove all effect and control inputs and outputs to this node and change
224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // to the pure operator {op}, possibly inserting a boolean inversion.
225958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Reduction ChangeToPureOperator(const Operator* op, bool invert = false,
226958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                 Type* type = Type::Any()) {
227958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK_EQ(0, op->EffectInputCount());
228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK_EQ(false, OperatorProperties::HasContextInput(op));
229958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK_EQ(0, op->ControlInputCount());
230958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK_EQ(2, op->ValueInputCount());
231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Remove the effects from the node, and update its effect/control usages.
233958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (node_->op()->EffectInputCount() > 0) {
234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      lowering_->RelaxEffectsAndControls(node_);
235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Remove the inputs corresponding to context, effect, and control.
237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    NodeProperties::RemoveNonValueInputs(node_);
238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Finally, update the operator to the new one.
239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    NodeProperties::ChangeOp(node_, op);
240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
241958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // TODO(jarin): Replace the explicit typing hack with a call to some method
242958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // that encapsulates changing the operator and re-typing.
243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Type* node_type = NodeProperties::GetType(node_);
244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    NodeProperties::SetType(node_, Type::Intersect(node_type, type, zone()));
245958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (invert) {
247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Insert an boolean not to invert the value.
248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Node* value = graph()->NewNode(simplified()->BooleanNot(), node_);
249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      node_->ReplaceUses(value);
250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Note: ReplaceUses() smashes all uses, so smash it back here.
251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      value->ReplaceInput(0, node_);
252958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      return lowering_->Replace(value);
253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return lowering_->Changed(node_);
255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
257f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Reduction ChangeToSpeculativeOperator(const Operator* op, bool invert,
258f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                        Type* upper_bound) {
25913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    DCHECK_EQ(1, op->EffectInputCount());
26013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    DCHECK_EQ(1, op->EffectOutputCount());
26113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    DCHECK_EQ(false, OperatorProperties::HasContextInput(op));
26213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    DCHECK_EQ(1, op->ControlInputCount());
26313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    DCHECK_EQ(0, op->ControlOutputCount());
26413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    DCHECK_EQ(0, OperatorProperties::GetFrameStateInputCount(op));
26513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    DCHECK_EQ(2, op->ValueInputCount());
26613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
26713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    DCHECK_EQ(1, node_->op()->EffectInputCount());
26813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    DCHECK_EQ(1, node_->op()->EffectOutputCount());
26913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    DCHECK_EQ(1, node_->op()->ControlInputCount());
27013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    DCHECK_EQ(2, node_->op()->ValueInputCount());
27113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
27213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    // Reconnect the control output to bypass the IfSuccess node and
27313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    // possibly disconnect from the IfException node.
27413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    for (Edge edge : node_->use_edges()) {
27513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      Node* const user = edge.from();
27613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      DCHECK(!user->IsDead());
27713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      if (NodeProperties::IsControlEdge(edge)) {
27813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        if (user->opcode() == IrOpcode::kIfSuccess) {
27913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          user->ReplaceUses(NodeProperties::GetControlInput(node_));
28013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          user->Kill();
28113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        } else {
28213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          DCHECK_EQ(user->opcode(), IrOpcode::kIfException);
28313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          edge.UpdateTo(jsgraph()->Dead());
28413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        }
28513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      }
28613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    }
28713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
288f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // Remove the frame state and the context.
289f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (OperatorProperties::HasFrameStateInput(node_->op())) {
290f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      node_->RemoveInput(NodeProperties::FirstFrameStateIndex(node_));
291f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
29213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    node_->RemoveInput(NodeProperties::FirstContextIndex(node_));
29313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
29413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    NodeProperties::ChangeOp(node_, op);
29513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
29613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    // Update the type to number.
29713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    Type* node_type = NodeProperties::GetType(node_);
29813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    NodeProperties::SetType(node_,
29913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                            Type::Intersect(node_type, upper_bound, zone()));
30013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
301f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (invert) {
302f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      // Insert an boolean not to invert the value.
303f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      Node* value = graph()->NewNode(simplified()->BooleanNot(), node_);
304f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      node_->ReplaceUses(value);
305f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      // Note: ReplaceUses() smashes all uses, so smash it back here.
306f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      value->ReplaceInput(0, node_);
307f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      return lowering_->Replace(value);
308f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
30913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    return lowering_->Changed(node_);
31013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
31113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
312958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Reduction ChangeToPureOperator(const Operator* op, Type* type) {
313958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return ChangeToPureOperator(op, false, type);
314958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
315958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
316f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Reduction ChangeToSpeculativeOperator(const Operator* op, Type* type) {
317f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return ChangeToSpeculativeOperator(op, false, type);
318f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
319f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
320f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const Operator* NumberOp() {
321f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    switch (node_->opcode()) {
322f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      case IrOpcode::kJSAdd:
323f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        return simplified()->NumberAdd();
324f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      case IrOpcode::kJSSubtract:
325f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        return simplified()->NumberSubtract();
326f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      case IrOpcode::kJSMultiply:
327f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        return simplified()->NumberMultiply();
328f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      case IrOpcode::kJSDivide:
329f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        return simplified()->NumberDivide();
330f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      case IrOpcode::kJSModulus:
331f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        return simplified()->NumberModulus();
332f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      case IrOpcode::kJSBitwiseAnd:
333f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        return simplified()->NumberBitwiseAnd();
334f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      case IrOpcode::kJSBitwiseOr:
335f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        return simplified()->NumberBitwiseOr();
336f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      case IrOpcode::kJSBitwiseXor:
337f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        return simplified()->NumberBitwiseXor();
338f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      case IrOpcode::kJSShiftLeft:
339f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        return simplified()->NumberShiftLeft();
340f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      case IrOpcode::kJSShiftRight:
341f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        return simplified()->NumberShiftRight();
342f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      case IrOpcode::kJSShiftRightLogical:
343f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        return simplified()->NumberShiftRightLogical();
344f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      default:
345f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        break;
346f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
347f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    UNREACHABLE();
348f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return nullptr;
349f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
350f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
35162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  const Operator* NumberOpFromSpeculativeNumberOp() {
352f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    switch (node_->opcode()) {
35362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      case IrOpcode::kSpeculativeNumberAdd:
35462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        return simplified()->NumberAdd();
35562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      case IrOpcode::kSpeculativeNumberSubtract:
35662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        return simplified()->NumberSubtract();
35762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      case IrOpcode::kSpeculativeNumberMultiply:
35862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        return simplified()->NumberMultiply();
35962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      case IrOpcode::kSpeculativeNumberDivide:
36062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        return simplified()->NumberDivide();
36162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      case IrOpcode::kSpeculativeNumberModulus:
36262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        return simplified()->NumberModulus();
363f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      default:
364f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        break;
365f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
366f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    UNREACHABLE();
367f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return nullptr;
368f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
369f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool LeftInputIs(Type* t) { return left_type()->Is(t); }
371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool RightInputIs(Type* t) { return right_type()->Is(t); }
373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool OneInputIs(Type* t) { return LeftInputIs(t) || RightInputIs(t); }
375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool BothInputsAre(Type* t) { return LeftInputIs(t) && RightInputIs(t); }
377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
37862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  bool BothInputsMaybe(Type* t) {
37962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return left_type()->Maybe(t) && right_type()->Maybe(t);
38062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
38162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool OneInputCannotBe(Type* t) {
383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return !left_type()->Maybe(t) || !right_type()->Maybe(t);
384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool NeitherInputCanBe(Type* t) {
387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return !left_type()->Maybe(t) && !right_type()->Maybe(t);
388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* effect() { return NodeProperties::GetEffectInput(node_); }
391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* control() { return NodeProperties::GetControlInput(node_); }
392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* context() { return NodeProperties::GetContextInput(node_); }
393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* left() { return NodeProperties::GetValueInput(node_, 0); }
394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* right() { return NodeProperties::GetValueInput(node_, 1); }
395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Type* left_type() { return NodeProperties::GetType(node_->InputAt(0)); }
396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Type* right_type() { return NodeProperties::GetType(node_->InputAt(1)); }
397f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Type* type() { return NodeProperties::GetType(node_); }
398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SimplifiedOperatorBuilder* simplified() { return lowering_->simplified(); }
400958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Graph* graph() const { return lowering_->graph(); }
401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  JSGraph* jsgraph() { return lowering_->jsgraph(); }
402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  JSOperatorBuilder* javascript() { return lowering_->javascript(); }
403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CommonOperatorBuilder* common() { return jsgraph()->common(); }
404958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Zone* zone() const { return graph()->zone(); }
405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  JSTypedLowering* lowering_;  // The containing lowering instance.
408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* node_;                 // The original node.
409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
410f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* CreateFrameStateForLeftInput() {
411f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // Deoptimization is disabled => return dummy frame state instead.
412f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Node* dummy_state = NodeProperties::GetFrameStateInput(node_);
413f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    DCHECK(OpParameter<FrameStateInfo>(dummy_state).bailout_id().IsNone());
414f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return dummy_state;
415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
417f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* CreateFrameStateForRightInput(Node* converted_left) {
418f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // Deoptimization is disabled => return dummy frame state instead.
419f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Node* dummy_state = NodeProperties::GetFrameStateInput(node_);
420f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    DCHECK(OpParameter<FrameStateInfo>(dummy_state).bailout_id().IsNone());
421f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return dummy_state;
422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
42413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Node* ConvertPlainPrimitiveToNumber(Node* node) {
425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(NodeProperties::GetType(node)->Is(Type::PlainPrimitive()));
426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Avoid inserting too many eager ToNumber() operations.
427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Reduction const reduction = lowering_->ReduceJSToNumberInput(node);
428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (reduction.Changed()) return reduction.replacement();
42913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (NodeProperties::GetType(node)->Is(Type::Number())) {
430bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      return node;
431bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
43213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    return graph()->NewNode(simplified()->PlainPrimitiveToNumber(), node);
433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* ConvertSingleInputToNumber(Node* node, Node* frame_state) {
436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(!NodeProperties::GetType(node)->Is(Type::PlainPrimitive()));
437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Node* const n = graph()->NewNode(javascript()->ToNumber(), node, context(),
438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                     frame_state, effect(), control());
439bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    Node* const if_success = graph()->NewNode(common()->IfSuccess(), n);
440bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    NodeProperties::ReplaceControlInput(node_, if_success);
441bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    NodeProperties::ReplaceUses(node_, node_, node_, node_, n);
442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    update_effect(n);
443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return n;
444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
446f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void ConvertBothInputsToNumber(Node** left_result, Node** right_result) {
447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Node* projections[2];
448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Find {IfSuccess} and {IfException} continuations of the operation.
450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    NodeProperties::CollectControlProjections(node_, projections, 2);
451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Node* if_exception = projections[1];
452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Node* if_success = projections[0];
453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Insert two ToNumber() operations that both potentially throw.
455f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Node* left_state = CreateFrameStateForLeftInput();
456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Node* left_conv =
457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        graph()->NewNode(javascript()->ToNumber(), left(), context(),
458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         left_state, effect(), control());
459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Node* left_success = graph()->NewNode(common()->IfSuccess(), left_conv);
460f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Node* right_state = CreateFrameStateForRightInput(left_conv);
461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Node* right_conv =
462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        graph()->NewNode(javascript()->ToNumber(), right(), context(),
463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         right_state, left_conv, left_success);
464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Node* left_exception =
465f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        graph()->NewNode(common()->IfException(), left_conv, left_conv);
466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Node* right_exception =
467f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        graph()->NewNode(common()->IfException(), right_conv, right_conv);
468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    NodeProperties::ReplaceControlInput(if_success, right_conv);
469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    update_effect(right_conv);
470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Wire conversions to existing {IfException} continuation.
472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Node* exception_merge = if_exception;
473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Node* exception_value =
474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         left_exception, right_exception, exception_merge);
476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Node* exception_effect =
477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        graph()->NewNode(common()->EffectPhi(2), left_exception,
478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         right_exception, exception_merge);
479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (Edge edge : exception_merge->use_edges()) {
480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (NodeProperties::IsEffectEdge(edge)) edge.UpdateTo(exception_effect);
481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (NodeProperties::IsValueEdge(edge)) edge.UpdateTo(exception_value);
482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    NodeProperties::RemoveType(exception_merge);
484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    exception_merge->ReplaceInput(0, left_exception);
485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    exception_merge->ReplaceInput(1, right_exception);
486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    NodeProperties::ChangeOp(exception_merge, common()->Merge(2));
487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    *left_result = left_conv;
489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    *right_result = right_conv;
490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
492958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Node* ConvertToUI32(Node* node, Signedness signedness) {
493958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // Avoid introducing too many eager NumberToXXnt32() operations.
494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Type* type = NodeProperties::GetType(node);
495958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (signedness == kSigned) {
496958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (!type->Is(Type::Signed32())) {
497958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        node = graph()->NewNode(simplified()->NumberToInt32(), node);
498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
499958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {
500958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      DCHECK_EQ(kUnsigned, signedness);
501958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (!type->Is(Type::Unsigned32())) {
502958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        node = graph()->NewNode(simplified()->NumberToUint32(), node);
503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
505958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return node;
506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void update_effect(Node* effect) {
509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    NodeProperties::ReplaceEffectInput(node_, effect);
510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// TODO(turbofan): js-typed-lowering improvements possible
515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// - immediately put in type bounds for all new nodes
516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// - relax effects from generic but not-side-effecting operations
517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochJSTypedLowering::JSTypedLowering(Editor* editor,
519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 CompilationDependencies* dependencies,
520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 Flags flags, JSGraph* jsgraph, Zone* zone)
521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : AdvancedReducer(editor),
522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      dependencies_(dependencies),
523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      flags_(flags),
524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      jsgraph_(jsgraph),
52562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      pointer_comparable_type_(Type::Union(
52662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          Type::Oddball(),
52762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          Type::Union(
52862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch              Type::SymbolOrReceiver(),
52962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch              Type::HeapConstant(factory()->empty_string(), graph()->zone()),
53062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch              graph()->zone()),
53162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          graph()->zone())),
532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      type_cache_(TypeCache::Get()) {
533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t k = 0; k < arraysize(shifted_int32_ranges_); ++k) {
534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    double min = kMinInt / (1 << k);
535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    double max = kMaxInt / (1 << k);
536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    shifted_int32_ranges_[k] = Type::Range(min, max, graph()->zone());
537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
54062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochReduction JSTypedLowering::ReduceSpeculativeNumberAdd(Node* node) {
541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  JSBinopReduction r(this, node);
54262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  NumberOperationHint hint = NumberOperationHintOf(node->op());
54362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (hint == NumberOperationHint::kNumberOrOddball &&
54462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      r.BothInputsAre(Type::PlainPrimitive()) &&
54562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      r.NeitherInputCanBe(Type::StringOrReceiver())) {
54662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // SpeculativeNumberAdd(x:-string, y:-string) =>
54762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    //     NumberAdd(ToNumber(x), ToNumber(y))
54862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    r.ConvertInputsToNumber();
54962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number());
55013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
55162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return NoChange();
55262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
55362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
55462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochReduction JSTypedLowering::ReduceJSAdd(Node* node) {
55562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  JSBinopReduction r(this, node);
55613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if (r.BothInputsAre(Type::Number())) {
557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // JSAdd(x:number, y:number) => NumberAdd(x, y)
558f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    r.ConvertInputsToNumber();
55913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number());
560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
561f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if ((r.BothInputsAre(Type::PlainPrimitive()) ||
562f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch       !(flags() & kDeoptimizationEnabled)) &&
563f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      r.NeitherInputCanBe(Type::StringOrReceiver())) {
564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // JSAdd(x:-string, y:-string) => NumberAdd(ToNumber(x), ToNumber(y))
565f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    r.ConvertInputsToNumber();
566958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number());
567958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
568bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (r.OneInputIs(Type::String())) {
569f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (r.ShouldCreateConsString()) {
570f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return ReduceCreateConsString(node);
571f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
572bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    StringAddFlags flags = STRING_ADD_CHECK_NONE;
573bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    if (!r.LeftInputIs(Type::String())) {
574bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      flags = STRING_ADD_CONVERT_LEFT;
575bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    } else if (!r.RightInputIs(Type::String())) {
576bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      flags = STRING_ADD_CONVERT_RIGHT;
577bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
57862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Operator::Properties properties = node->op()->properties();
57962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (r.NeitherInputCanBe(Type::Receiver())) {
58062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      // Both sides are already strings, so we know that the
58162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      // string addition will not cause any observable side
58262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      // effects; it can still throw obviously.
58362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      properties = Operator::kNoWrite | Operator::kNoDeopt;
58462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
585bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    // JSAdd(x:string, y) => CallStub[StringAdd](x, y)
586bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    // JSAdd(x, y:string) => CallStub[StringAdd](x, y)
587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Callable const callable =
588bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        CodeFactory::StringAdd(isolate(), flags, NOT_TENURED);
589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CallDescriptor const* const desc = Linkage::GetStubCallDescriptor(
590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        isolate(), graph()->zone(), callable.descriptor(), 0,
59162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        CallDescriptor::kNeedsFrameState, properties);
592f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    node->InsertInput(graph()->zone(), 0,
594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                      jsgraph()->HeapConstant(callable.code()));
595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    NodeProperties::ChangeOp(node, common()->Call(desc));
596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return Changed(node);
597958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
598958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return NoChange();
599958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
600958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
601f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochReduction JSTypedLowering::ReduceNumberBinop(Node* node) {
602958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  JSBinopReduction r(this, node);
603f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (r.BothInputsAre(Type::PlainPrimitive()) ||
604f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      !(flags() & kDeoptimizationEnabled)) {
605f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    r.ConvertInputsToNumber();
606f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return r.ChangeToPureOperator(r.NumberOp(), Type::Number());
60713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
608958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return NoChange();
609958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
610958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
61162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochReduction JSTypedLowering::ReduceSpeculativeNumberBinop(Node* node) {
61213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  JSBinopReduction r(this, node);
61362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  NumberOperationHint hint = NumberOperationHintOf(node->op());
61462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (hint == NumberOperationHint::kNumberOrOddball &&
61562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      r.BothInputsAre(Type::NumberOrOddball())) {
61662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    r.ConvertInputsToNumber();
61762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return r.ChangeToPureOperator(r.NumberOpFromSpeculativeNumberOp(),
61862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                  Type::Number());
61913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
62062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return NoChange();
62162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
62262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
62362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochReduction JSTypedLowering::ReduceInt32Binop(Node* node) {
62462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  JSBinopReduction r(this, node);
625f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (r.BothInputsAre(Type::PlainPrimitive()) ||
626f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      !(flags() & kDeoptimizationEnabled)) {
627f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    r.ConvertInputsToNumber();
628f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    r.ConvertInputsToUI32(kSigned, kSigned);
629f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return r.ChangeToPureOperator(r.NumberOp(), Type::Signed32());
63013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
631f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return NoChange();
63213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
63313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
634f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochReduction JSTypedLowering::ReduceUI32Shift(Node* node, Signedness signedness) {
635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  JSBinopReduction r(this, node);
636f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (r.BothInputsAre(Type::PlainPrimitive()) ||
637f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      !(flags() & kDeoptimizationEnabled)) {
638f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    r.ConvertInputsToNumber();
639f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    r.ConvertInputsToUI32(signedness, kUnsigned);
640f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return r.ChangeToPureOperator(r.NumberOp(), signedness == kUnsigned
641f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                                    ? Type::Unsigned32()
642f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                                    : Type::Signed32());
643f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
644f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return NoChange();
645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
647f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochReduction JSTypedLowering::ReduceCreateConsString(Node* node) {
648f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* first = NodeProperties::GetValueInput(node, 0);
649f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* second = NodeProperties::GetValueInput(node, 1);
650f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* context = NodeProperties::GetContextInput(node);
651f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* frame_state = NodeProperties::GetFrameStateInput(node);
652f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* effect = NodeProperties::GetEffectInput(node);
653f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* control = NodeProperties::GetControlInput(node);
654f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
655f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Make sure {first} is actually a String.
656f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Type* first_type = NodeProperties::GetType(first);
657f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!first_type->Is(Type::String())) {
658f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    first = effect =
659f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        graph()->NewNode(simplified()->CheckString(), first, effect, control);
660f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    first_type = NodeProperties::GetType(first);
661f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
662f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
663f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Make sure {second} is actually a String.
664f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Type* second_type = NodeProperties::GetType(second);
665f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!second_type->Is(Type::String())) {
666f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    second = effect =
667f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        graph()->NewNode(simplified()->CheckString(), second, effect, control);
668f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    second_type = NodeProperties::GetType(second);
669f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
670f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
671f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Determine the {first} length.
672c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  HeapObjectBinopMatcher m(node);
673f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* first_length =
674c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      (m.left().HasValue() && m.left().Value()->IsString())
675f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          ? jsgraph()->Constant(
676c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                Handle<String>::cast(m.left().Value())->length())
677f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          : effect = graph()->NewNode(
678f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                simplified()->LoadField(AccessBuilder::ForStringLength()),
679f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                first, effect, control);
680f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
681f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Determine the {second} length.
682f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* second_length =
683c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      (m.right().HasValue() && m.right().Value()->IsString())
684f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          ? jsgraph()->Constant(
685c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                Handle<String>::cast(m.right().Value())->length())
686f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          : effect = graph()->NewNode(
687f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                simplified()->LoadField(AccessBuilder::ForStringLength()),
688f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                second, effect, control);
689f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
690f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Compute the resulting length.
691f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* length =
692f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      graph()->NewNode(simplified()->NumberAdd(), first_length, second_length);
693f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
694f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Check if we would overflow the allowed maximum string length.
695f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* check = graph()->NewNode(simplified()->NumberLessThanOrEqual(), length,
696f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                 jsgraph()->Constant(String::kMaxLength));
697c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (isolate()->IsStringLengthOverflowIntact()) {
698c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // Add a code dependency on the string length overflow protector.
699c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    dependencies()->AssumePropertyCell(factory()->string_length_protector());
700c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
701c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // We can just deoptimize if the {check} fails. Besides generating a
702c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // shorter code sequence than the version below, this has the additional
703c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // benefit of not holding on to the lazy {frame_state} and thus potentially
704c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // reduces the number of live ranges and allows for more truncations.
705c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    effect = graph()->NewNode(simplified()->CheckIf(), check, effect, control);
706c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  } else {
707c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    Node* branch =
708c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
709c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
710c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    Node* efalse = effect;
711c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    {
712c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      // Throw a RangeError in case of overflow.
713c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      Node* vfalse = efalse = graph()->NewNode(
714c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          javascript()->CallRuntime(Runtime::kThrowInvalidStringLength),
715c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          context, frame_state, efalse, if_false);
716c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      if_false = graph()->NewNode(common()->IfSuccess(), vfalse);
717c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      if_false = graph()->NewNode(common()->Throw(), vfalse, efalse, if_false);
718c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      // TODO(bmeurer): This should be on the AdvancedReducer somehow.
719c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      NodeProperties::MergeControlToEnd(graph(), common(), if_false);
720c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      Revisit(graph()->end());
721c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
722c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      // Update potential {IfException} uses of {node} to point to the
723c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      // %ThrowInvalidStringLength runtime call node instead.
724c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      for (Edge edge : node->use_edges()) {
725c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        if (edge.from()->opcode() == IrOpcode::kIfException) {
726c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          DCHECK(NodeProperties::IsControlEdge(edge) ||
727c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                 NodeProperties::IsEffectEdge(edge));
728c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          edge.UpdateTo(vfalse);
729c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          Revisit(edge.from());
730c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        }
731f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      }
732f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
733c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    control = graph()->NewNode(common()->IfTrue(), branch);
734f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
735f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
736f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Figure out the map for the resulting ConsString.
737f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // TODO(turbofan): We currently just use the cons_string_map here for
738f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // the sake of simplicity; we could also try to be smarter here and
739f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // use the one_byte_cons_string_map instead when the resulting ConsString
740f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // contains only one byte characters.
741f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* value_map = jsgraph()->HeapConstant(factory()->cons_string_map());
742f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
743f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Allocate the resulting ConsString.
744f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  effect = graph()->NewNode(
745f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      common()->BeginRegion(RegionObservability::kNotObservable), effect);
746f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* value = effect =
747f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      graph()->NewNode(simplified()->Allocate(NOT_TENURED),
748f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                       jsgraph()->Constant(ConsString::kSize), effect, control);
749f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  NodeProperties::SetType(value, Type::OtherString());
750f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  effect = graph()->NewNode(simplified()->StoreField(AccessBuilder::ForMap()),
751f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                            value, value_map, effect, control);
752f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  effect = graph()->NewNode(
753f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      simplified()->StoreField(AccessBuilder::ForNameHashField()), value,
754c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      jsgraph()->Constant(Name::kEmptyHashField), effect, control);
755f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  effect = graph()->NewNode(
756f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      simplified()->StoreField(AccessBuilder::ForStringLength()), value, length,
757f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      effect, control);
758f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  effect = graph()->NewNode(
759f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      simplified()->StoreField(AccessBuilder::ForConsStringFirst()), value,
760f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      first, effect, control);
761f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  effect = graph()->NewNode(
762f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      simplified()->StoreField(AccessBuilder::ForConsStringSecond()), value,
763f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      second, effect, control);
764f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
765f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Morph the {node} into a {FinishRegion}.
766f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ReplaceWithValue(node, node, node, control);
767f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  node->ReplaceInput(0, value);
768f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  node->ReplaceInput(1, effect);
769f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  node->TrimInputCount(2);
770f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  NodeProperties::ChangeOp(node, common()->FinishRegion());
771f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return Changed(node);
772f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
773f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochReduction JSTypedLowering::ReduceJSComparison(Node* node) {
775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  JSBinopReduction r(this, node);
776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (r.BothInputsAre(Type::String())) {
777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // If both inputs are definitely strings, perform a string comparison.
778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const Operator* stringOp;
779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    switch (node->opcode()) {
780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case IrOpcode::kJSLessThan:
781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        stringOp = simplified()->StringLessThan();
782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        break;
783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case IrOpcode::kJSGreaterThan:
784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        stringOp = simplified()->StringLessThan();
785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        r.SwapInputs();  // a > b => b < a
786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        break;
787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case IrOpcode::kJSLessThanOrEqual:
788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        stringOp = simplified()->StringLessThanOrEqual();
789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        break;
790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case IrOpcode::kJSGreaterThanOrEqual:
791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        stringOp = simplified()->StringLessThanOrEqual();
792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        r.SwapInputs();  // a >= b => b <= a
793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        break;
794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      default:
795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return NoChange();
796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
797bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    r.ChangeToPureOperator(stringOp);
798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return Changed(node);
799958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
80013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
801f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  NumberOperationHint hint;
802f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const Operator* less_than;
803f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const Operator* less_than_or_equal;
804f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (r.BothInputsAre(Type::Signed32()) ||
805f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      r.BothInputsAre(Type::Unsigned32())) {
806f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    less_than = simplified()->NumberLessThan();
807f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    less_than_or_equal = simplified()->NumberLessThanOrEqual();
808f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  } else if (r.GetCompareNumberOperationHint(&hint)) {
809f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    less_than = simplified()->SpeculativeNumberLessThan(hint);
810f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    less_than_or_equal = simplified()->SpeculativeNumberLessThanOrEqual(hint);
811f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  } else if (r.OneInputCannotBe(Type::StringOrReceiver()) &&
812f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch             (r.BothInputsAre(Type::PlainPrimitive()) ||
813f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              !(flags() & kDeoptimizationEnabled))) {
814f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    r.ConvertInputsToNumber();
815f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    less_than = simplified()->NumberLessThan();
816f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    less_than_or_equal = simplified()->NumberLessThanOrEqual();
81762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else if (r.IsStringCompareOperation()) {
81862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    r.CheckInputsToString();
81962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    less_than = simplified()->StringLessThan();
82062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    less_than_or_equal = simplified()->StringLessThanOrEqual();
821f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  } else {
822f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return NoChange();
823f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
824f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const Operator* comparison;
825f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  switch (node->opcode()) {
826f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case IrOpcode::kJSLessThan:
827f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      comparison = less_than;
828f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
829f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case IrOpcode::kJSGreaterThan:
830f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      comparison = less_than;
831f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      r.SwapInputs();  // a > b => b < a
832f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
833f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case IrOpcode::kJSLessThanOrEqual:
834f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      comparison = less_than_or_equal;
835f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
836f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case IrOpcode::kJSGreaterThanOrEqual:
837f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      comparison = less_than_or_equal;
838f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      r.SwapInputs();  // a >= b => b <= a
839f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
840f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    default:
841f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      return NoChange();
842f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
843f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (comparison->EffectInputCount() > 0) {
844f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return r.ChangeToSpeculativeOperator(comparison, Type::Boolean());
845f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  } else {
846f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return r.ChangeToPureOperator(comparison);
847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
850c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochReduction JSTypedLowering::ReduceJSTypeOf(Node* node) {
851c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Node* const input = node->InputAt(0);
852c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Type* type = NodeProperties::GetType(input);
853c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Factory* const f = factory();
854c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (type->Is(Type::Boolean())) {
855c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    return Replace(jsgraph()->Constant(f->boolean_string()));
856c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  } else if (type->Is(Type::Number())) {
857c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    return Replace(jsgraph()->Constant(f->number_string()));
858c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  } else if (type->Is(Type::String())) {
859c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    return Replace(jsgraph()->Constant(f->string_string()));
860c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  } else if (type->Is(Type::Symbol())) {
861c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    return Replace(jsgraph()->Constant(f->symbol_string()));
86262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else if (type->Is(Type::OtherUndetectableOrUndefined())) {
863c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    return Replace(jsgraph()->Constant(f->undefined_string()));
86462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else if (type->Is(Type::NonCallableOrNull())) {
865c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    return Replace(jsgraph()->Constant(f->object_string()));
866c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  } else if (type->Is(Type::Function())) {
867c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    return Replace(jsgraph()->Constant(f->function_string()));
868c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  } else if (type->IsHeapConstant()) {
869c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    return Replace(jsgraph()->Constant(
870c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        Object::TypeOf(isolate(), type->AsHeapConstant()->Value())));
871c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
872c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
873c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return NoChange();
874c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
875c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
876bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochReduction JSTypedLowering::ReduceJSEqualTypeOf(Node* node, bool invert) {
87762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* input;
87862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Handle<String> type;
879bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  HeapObjectBinopMatcher m(node);
880bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (m.left().IsJSTypeOf() && m.right().HasValue() &&
881bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      m.right().Value()->IsString()) {
88262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    input = m.left().InputAt(0);
88362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    type = Handle<String>::cast(m.right().Value());
88462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else if (m.right().IsJSTypeOf() && m.left().HasValue() &&
88562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch             m.left().Value()->IsString()) {
88662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    input = m.right().InputAt(0);
88762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    type = Handle<String>::cast(m.left().Value());
88862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else {
88962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return NoChange();
890bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
89162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* value;
89262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (String::Equals(type, factory()->boolean_string())) {
89362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    value =
89462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        graph()->NewNode(common()->Select(MachineRepresentation::kTagged),
89562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                         graph()->NewNode(simplified()->ReferenceEqual(), input,
89662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                          jsgraph()->TrueConstant()),
89762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                         jsgraph()->TrueConstant(),
89862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                         graph()->NewNode(simplified()->ReferenceEqual(), input,
89962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                          jsgraph()->FalseConstant()));
90062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else if (String::Equals(type, factory()->function_string())) {
90162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    value = graph()->NewNode(simplified()->ObjectIsDetectableCallable(), input);
90262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else if (String::Equals(type, factory()->number_string())) {
90362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    value = graph()->NewNode(simplified()->ObjectIsNumber(), input);
90462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else if (String::Equals(type, factory()->object_string())) {
90562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    value = graph()->NewNode(
90662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        common()->Select(MachineRepresentation::kTagged),
90762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        graph()->NewNode(simplified()->ObjectIsNonCallable(), input),
90862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        jsgraph()->TrueConstant(),
90962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        graph()->NewNode(simplified()->ReferenceEqual(), input,
91062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                         jsgraph()->NullConstant()));
91162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else if (String::Equals(type, factory()->string_string())) {
91262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    value = graph()->NewNode(simplified()->ObjectIsString(), input);
91362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else if (String::Equals(type, factory()->undefined_string())) {
91462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    value = graph()->NewNode(
91562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        common()->Select(MachineRepresentation::kTagged),
91662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        graph()->NewNode(simplified()->ReferenceEqual(), input,
91762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                         jsgraph()->NullConstant()),
91862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        jsgraph()->FalseConstant(),
91962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        graph()->NewNode(simplified()->ObjectIsUndetectable(), input));
92062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else {
92162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return NoChange();
92262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
92362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (invert) {
92462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    value = graph()->NewNode(simplified()->BooleanNot(), value);
92562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
92662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  ReplaceWithValue(node, value);
92762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return Replace(value);
928bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochReduction JSTypedLowering::ReduceJSEqual(Node* node, bool invert) {
931bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Reduction const reduction = ReduceJSEqualTypeOf(node, invert);
932f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (reduction.Changed()) return reduction;
933bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  JSBinopReduction r(this, node);
935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
93662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (r.BothInputsAre(Type::UniqueName())) {
93762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert);
93862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
93962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (r.IsInternalizedStringCompareOperation()) {
94062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    r.CheckInputsToInternalizedString();
94162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert);
94262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (r.BothInputsAre(Type::String())) {
944bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    return r.ChangeToPureOperator(simplified()->StringEqual(), invert);
945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (r.BothInputsAre(Type::Boolean())) {
947f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert);
948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (r.BothInputsAre(Type::Receiver())) {
950f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert);
951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
9523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (r.OneInputIs(Type::Undetectable())) {
9533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    RelaxEffectsAndControls(node);
9543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    node->RemoveInput(r.LeftInputIs(Type::Undetectable()) ? 0 : 1);
9553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    node->TrimInputCount(1);
9563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    NodeProperties::ChangeOp(node, simplified()->ObjectIsUndetectable());
957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (invert) {
958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Insert an boolean not to invert the value.
959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Node* value = graph()->NewNode(simplified()->BooleanNot(), node);
960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      node->ReplaceUses(value);
961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Note: ReplaceUses() smashes all uses, so smash it back here.
962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      value->ReplaceInput(0, node);
963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return Replace(value);
964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return Changed(node);
966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
967f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
968f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  NumberOperationHint hint;
969f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (r.BothInputsAre(Type::Signed32()) ||
970f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      r.BothInputsAre(Type::Unsigned32())) {
971f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return r.ChangeToPureOperator(simplified()->NumberEqual(), invert);
972f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  } else if (r.GetCompareNumberOperationHint(&hint)) {
973f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return r.ChangeToSpeculativeOperator(
974f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        simplified()->SpeculativeNumberEqual(hint), invert, Type::Boolean());
975f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  } else if (r.BothInputsAre(Type::Number())) {
976f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return r.ChangeToPureOperator(simplified()->NumberEqual(), invert);
97762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else if (r.IsReceiverCompareOperation()) {
97862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    r.CheckInputsToReceiver();
97962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert);
98062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else if (r.IsStringCompareOperation()) {
98162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    r.CheckInputsToString();
98262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return r.ChangeToPureOperator(simplified()->StringEqual(), invert);
983f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NoChange();
985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochReduction JSTypedLowering::ReduceJSStrictEqual(Node* node, bool invert) {
988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  JSBinopReduction r(this, node);
989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (r.left() == r.right()) {
990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // x === x is always true if x != NaN
991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!r.left_type()->Maybe(Type::NaN())) {
992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Node* replacement = jsgraph()->BooleanConstant(!invert);
993014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ReplaceWithValue(node, replacement);
994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return Replace(replacement);
995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
99762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (r.OneInputCannotBe(Type::NumberOrString())) {
99813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    // For values with canonical representation (i.e. neither String, nor
99962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // Number) an empty type intersection means the values cannot be strictly
100062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // equal.
1001958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (!r.left_type()->Maybe(r.right_type())) {
1002014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Node* replacement = jsgraph()->BooleanConstant(invert);
1003014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ReplaceWithValue(node, replacement);
1004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return Replace(replacement);
1005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1007f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1008bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Reduction const reduction = ReduceJSEqualTypeOf(node, invert);
1009f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (reduction.Changed()) return reduction;
1010f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
101162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (r.BothInputsAre(Type::Unique())) {
1012f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert);
1013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
101462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (r.OneInputIs(pointer_comparable_type_)) {
1015f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert);
1016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
101762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (r.IsInternalizedStringCompareOperation()) {
101862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    r.CheckInputsToInternalizedString();
1019f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert);
1020014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (r.BothInputsAre(Type::String())) {
1022bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    return r.ChangeToPureOperator(simplified()->StringEqual(), invert);
1023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1024f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1025f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  NumberOperationHint hint;
1026f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (r.BothInputsAre(Type::Signed32()) ||
1027f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      r.BothInputsAre(Type::Unsigned32())) {
1028f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return r.ChangeToPureOperator(simplified()->NumberEqual(), invert);
1029f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  } else if (r.GetCompareNumberOperationHint(&hint)) {
1030f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return r.ChangeToSpeculativeOperator(
1031f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        simplified()->SpeculativeNumberEqual(hint), invert, Type::Boolean());
1032f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  } else if (r.BothInputsAre(Type::Number())) {
1033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return r.ChangeToPureOperator(simplified()->NumberEqual(), invert);
103462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else if (r.IsReceiverCompareOperation()) {
103562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // For strict equality, it's enough to know that one input is a Receiver,
103662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // as a strict equality comparison with a Receiver can only yield true if
103762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // both sides refer to the same Receiver than.
103862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    r.CheckLeftInputToReceiver();
103962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert);
104062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else if (r.IsStringCompareOperation()) {
104162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    r.CheckInputsToString();
104262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return r.ChangeToPureOperator(simplified()->StringEqual(), invert);
1043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NoChange();
1045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1047958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierReduction JSTypedLowering::ReduceJSToBoolean(Node* node) {
1048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* const input = node->InputAt(0);
1049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Type* const input_type = NodeProperties::GetType(input);
1050958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (input_type->Is(Type::Boolean())) {
1051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // JSToBoolean(x:boolean) => x
1052958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return Replace(input);
1053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (input_type->Is(Type::OrderedNumber())) {
1054014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // JSToBoolean(x:ordered-number) => BooleanNot(NumberEqual(x,#0))
1055014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    node->ReplaceInput(0, graph()->NewNode(simplified()->NumberEqual(), input,
1056014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           jsgraph()->ZeroConstant()));
1057014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    node->TrimInputCount(1);
1058014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    NodeProperties::ChangeOp(node, simplified()->BooleanNot());
1059014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return Changed(node);
1060f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  } else if (input_type->Is(Type::Number())) {
1061f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // JSToBoolean(x:number) => NumberToBoolean(x)
1062f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    node->TrimInputCount(1);
1063f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    NodeProperties::ChangeOp(node, simplified()->NumberToBoolean());
1064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return Changed(node);
106562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else if (input_type->Is(Type::DetectableReceiverOrNull())) {
106662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // JSToBoolean(x:detectable receiver \/ null)
106762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    //   => BooleanNot(ReferenceEqual(x,#null))
106862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    node->ReplaceInput(0, graph()->NewNode(simplified()->ReferenceEqual(),
106962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                           input, jsgraph()->NullConstant()));
107062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    node->TrimInputCount(1);
107162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    NodeProperties::ChangeOp(node, simplified()->BooleanNot());
107262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return Changed(node);
107362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else if (input_type->Is(Type::ReceiverOrNullOrUndefined())) {
107462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // JSToBoolean(x:receiver \/ null \/ undefined)
107562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    //   => BooleanNot(ObjectIsUndetectable(x))
107662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    node->ReplaceInput(
107762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        0, graph()->NewNode(simplified()->ObjectIsUndetectable(), input));
107862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    node->TrimInputCount(1);
107962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    NodeProperties::ChangeOp(node, simplified()->BooleanNot());
108062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return Changed(node);
108162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else if (input_type->Is(Type::String())) {
108262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // JSToBoolean(x:string) => BooleanNot(ReferenceEqual(x,""))
108362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    node->ReplaceInput(0,
108462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                       graph()->NewNode(simplified()->ReferenceEqual(), input,
108562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                        jsgraph()->EmptyStringConstant()));
108662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    node->TrimInputCount(1);
108762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    NodeProperties::ChangeOp(node, simplified()->BooleanNot());
108862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return Changed(node);
1089958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return NoChange();
1091958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1092958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
10933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochReduction JSTypedLowering::ReduceJSToInteger(Node* node) {
10943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Node* const input = NodeProperties::GetValueInput(node, 0);
10953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Type* const input_type = NodeProperties::GetType(input);
10963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (input_type->Is(type_cache_.kIntegerOrMinusZero)) {
10973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    // JSToInteger(x:integer) => x
10983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    ReplaceWithValue(node, input);
10993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    return Replace(input);
11003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
11013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  return NoChange();
11023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
11033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
1104c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochReduction JSTypedLowering::ReduceJSToName(Node* node) {
1105c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Node* const input = NodeProperties::GetValueInput(node, 0);
1106c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Type* const input_type = NodeProperties::GetType(input);
1107c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (input_type->Is(Type::Name())) {
1108c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // JSToName(x:name) => x
1109c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    ReplaceWithValue(node, input);
1110c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    return Replace(input);
1111c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
1112c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return NoChange();
1113c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
1114c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
11153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochReduction JSTypedLowering::ReduceJSToLength(Node* node) {
11163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Node* input = NodeProperties::GetValueInput(node, 0);
11173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Type* input_type = NodeProperties::GetType(input);
11183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (input_type->Is(type_cache_.kIntegerOrMinusZero)) {
11193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    if (input_type->Max() <= 0.0) {
11203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      input = jsgraph()->ZeroConstant();
11213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    } else if (input_type->Min() >= kMaxSafeInteger) {
11223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      input = jsgraph()->Constant(kMaxSafeInteger);
11233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    } else {
11243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (input_type->Min() <= 0.0) {
1125f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        input = graph()->NewNode(simplified()->NumberMax(),
1126f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                 jsgraph()->ZeroConstant(), input);
11273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }
11283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (input_type->Max() > kMaxSafeInteger) {
1129f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        input = graph()->NewNode(simplified()->NumberMin(),
1130f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                 jsgraph()->Constant(kMaxSafeInteger), input);
11313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }
11323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
11333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    ReplaceWithValue(node, input);
11343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    return Replace(input);
11353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
11363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  return NoChange();
11373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
1138958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochReduction JSTypedLowering::ReduceJSToNumberInput(Node* input) {
1140109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Try constant-folding of JSToNumber with constant inputs.
1141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Type* input_type = NodeProperties::GetType(input);
1142c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (input_type->Is(Type::String())) {
1143c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    HeapObjectMatcher m(input);
1144c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    if (m.HasValue() && m.Value()->IsString()) {
1145c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      Handle<Object> input_value = m.Value();
1146109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return Replace(jsgraph()->Constant(
1147109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          String::ToNumber(Handle<String>::cast(input_value))));
1148c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    }
1149c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
1150c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (input_type->IsHeapConstant()) {
1151c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    Handle<Object> input_value = input_type->AsHeapConstant()->Value();
1152c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    if (input_value->IsOddball()) {
1153109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return Replace(jsgraph()->Constant(
1154109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          Oddball::ToNumber(Handle<Oddball>::cast(input_value))));
1155109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
1156109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
1157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (input_type->Is(Type::Number())) {
1158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // JSToNumber(x:number) => x
1159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Changed(input);
1160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (input_type->Is(Type::Undefined())) {
1162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // JSToNumber(undefined) => #NaN
1163958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return Replace(jsgraph()->NaNConstant());
1164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (input_type->Is(Type::Null())) {
1166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // JSToNumber(null) => #0
1167958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return Replace(jsgraph()->ZeroConstant());
1168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NoChange();
1170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1172958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierReduction JSTypedLowering::ReduceJSToNumber(Node* node) {
1173958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Try to reduce the input first.
1174958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Node* const input = node->InputAt(0);
1175958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Reduction reduction = ReduceJSToNumberInput(input);
1176958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (reduction.Changed()) {
1177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ReplaceWithValue(node, reduction.replacement());
1178958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return reduction;
1179958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Type* const input_type = NodeProperties::GetType(input);
1181958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (input_type->Is(Type::PlainPrimitive())) {
118213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    RelaxEffectsAndControls(node);
118313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    node->TrimInputCount(1);
118413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    NodeProperties::ChangeOp(node, simplified()->PlainPrimitiveToNumber());
118513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    return Changed(node);
1186958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1187958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return NoChange();
1188958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1189958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochReduction JSTypedLowering::ReduceJSToStringInput(Node* input) {
1191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (input->opcode() == IrOpcode::kJSToString) {
1192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Recursively try to reduce the input first.
1193958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Reduction result = ReduceJSToString(input);
1194958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (result.Changed()) return result;
1195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Changed(input);  // JSToString(JSToString(x)) => JSToString(x)
1196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Type* input_type = NodeProperties::GetType(input);
1198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (input_type->Is(Type::String())) {
1199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Changed(input);  // JSToString(x:string) => x
1200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (input_type->Is(Type::Boolean())) {
1202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return Replace(graph()->NewNode(
1203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        common()->Select(MachineRepresentation::kTagged), input,
1204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        jsgraph()->HeapConstant(factory()->true_string()),
1205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        jsgraph()->HeapConstant(factory()->false_string())));
1206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (input_type->Is(Type::Undefined())) {
1208958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return Replace(jsgraph()->HeapConstant(factory()->undefined_string()));
1209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (input_type->Is(Type::Null())) {
1211958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return Replace(jsgraph()->HeapConstant(factory()->null_string()));
1212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(turbofan): js-typed-lowering of ToString(x:number)
1214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NoChange();
1215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1217958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierReduction JSTypedLowering::ReduceJSToString(Node* node) {
1218958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Try to reduce the input first.
1219958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Node* const input = node->InputAt(0);
1220958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Reduction reduction = ReduceJSToStringInput(input);
1221958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (reduction.Changed()) {
1222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ReplaceWithValue(node, reduction.replacement());
1223958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return reduction;
1224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NoChange();
1226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochReduction JSTypedLowering::ReduceJSToObject(Node* node) {
1229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_EQ(IrOpcode::kJSToObject, node->opcode());
1230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* receiver = NodeProperties::GetValueInput(node, 0);
1231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Type* receiver_type = NodeProperties::GetType(receiver);
1232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* context = NodeProperties::GetContextInput(node);
1233f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* frame_state = NodeProperties::GetFrameStateInput(node);
1234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* effect = NodeProperties::GetEffectInput(node);
1235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* control = NodeProperties::GetControlInput(node);
1236f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (receiver_type->Is(Type::Receiver())) {
1237f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    ReplaceWithValue(node, receiver, effect, control);
1238f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return Replace(receiver);
1239f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
1240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1241f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // TODO(bmeurer/mstarzinger): Add support for lowering inside try blocks.
1242f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (receiver_type->Maybe(Type::NullOrUndefined()) &&
1243f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      NodeProperties::IsExceptionalCall(node)) {
1244f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // ToObject throws for null or undefined inputs.
1245f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return NoChange();
1246f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
1247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1248f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Check whether {receiver} is a spec object.
1249f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* check = graph()->NewNode(simplified()->ObjectIsReceiver(), receiver);
1250f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* branch =
1251f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
1252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1253f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
1254f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* etrue = effect;
1255f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* rtrue = receiver;
1256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1257f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
1258f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* efalse = effect;
1259f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* rfalse;
1260f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  {
1261f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // Convert {receiver} using the ToObjectStub.
1262f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Callable callable = CodeFactory::ToObject(isolate());
1263f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    CallDescriptor const* const desc = Linkage::GetStubCallDescriptor(
1264f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        isolate(), graph()->zone(), callable.descriptor(), 0,
1265f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        CallDescriptor::kNeedsFrameState, node->op()->properties());
1266f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    rfalse = efalse = graph()->NewNode(
1267f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        common()->Call(desc), jsgraph()->HeapConstant(callable.code()),
1268f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        receiver, context, frame_state, efalse, if_false);
1269f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if_false = graph()->NewNode(common()->IfSuccess(), rfalse);
1270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1272f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  control = graph()->NewNode(common()->Merge(2), if_true, if_false);
1273f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
1274f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1275f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Morph the {node} into an appropriate Phi.
1276f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ReplaceWithValue(node, node, effect, control);
1277f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  node->ReplaceInput(0, rtrue);
1278f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  node->ReplaceInput(1, rfalse);
1279f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  node->ReplaceInput(2, control);
1280f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  node->TrimInputCount(3);
1281f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  NodeProperties::ChangeOp(node,
1282f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                           common()->Phi(MachineRepresentation::kTagged, 2));
1283f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return Changed(node);
1284f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochReduction JSTypedLowering::ReduceJSLoadNamed(Node* node) {
1287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_EQ(IrOpcode::kJSLoadNamed, node->opcode());
1288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* receiver = NodeProperties::GetValueInput(node, 0);
1289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Type* receiver_type = NodeProperties::GetType(receiver);
1290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* effect = NodeProperties::GetEffectInput(node);
1291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* control = NodeProperties::GetControlInput(node);
1292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<Name> name = NamedAccessOf(node->op()).name();
1293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Optimize "length" property of strings.
1294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (name.is_identical_to(factory()->length_string()) &&
1295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      receiver_type->Is(Type::String())) {
1296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Node* value = effect = graph()->NewNode(
1297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        simplified()->LoadField(AccessBuilder::ForStringLength()), receiver,
1298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        effect, control);
1299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ReplaceWithValue(node, value, effect);
1300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return Replace(value);
1301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return NoChange();
1303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochReduction JSTypedLowering::ReduceJSLoadProperty(Node* node) {
1306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* key = NodeProperties::GetValueInput(node, 1);
1307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* base = NodeProperties::GetValueInput(node, 0);
1308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Type* key_type = NodeProperties::GetType(key);
1309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObjectMatcher mbase(base);
1310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (mbase.HasValue() && mbase.Value()->IsJSTypedArray()) {
1311958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Handle<JSTypedArray> const array =
1312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Handle<JSTypedArray>::cast(mbase.Value());
1313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!array->GetBuffer()->was_neutered()) {
1314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      array->GetBuffer()->set_is_neuterable(false);
1315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      BufferAccess const access(array->type());
1316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      size_t const k =
1317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          ElementSizeLog2Of(access.machine_type().representation());
1318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      double const byte_length = array->byte_length()->Number();
1319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      CHECK_LT(k, arraysize(shifted_int32_ranges_));
1320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (key_type->Is(shifted_int32_ranges_[k]) && byte_length <= kMaxInt) {
1321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // JSLoadProperty(typed-array, int32)
1322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Handle<FixedTypedArrayBase> elements =
1323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            Handle<FixedTypedArrayBase>::cast(handle(array->elements()));
1324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Node* buffer = jsgraph()->PointerConstant(elements->external_pointer());
1325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Node* length = jsgraph()->Constant(byte_length);
1326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Node* effect = NodeProperties::GetEffectInput(node);
1327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Node* control = NodeProperties::GetControlInput(node);
1328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Check if we can avoid the bounds check.
1329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (key_type->Min() >= 0 && key_type->Max() < array->length_value()) {
1330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Node* load = graph()->NewNode(
1331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              simplified()->LoadElement(
1332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  AccessBuilder::ForTypedArrayElement(array->type(), true)),
1333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              buffer, key, effect, control);
1334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          ReplaceWithValue(node, load, load);
1335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          return Replace(load);
1336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
1337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Compute byte offset.
1338f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        Node* offset =
1339f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            (k == 0) ? key : graph()->NewNode(
1340f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                 simplified()->NumberShiftLeft(), key,
1341f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                 jsgraph()->Constant(static_cast<double>(k)));
1342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Node* load = graph()->NewNode(simplified()->LoadBuffer(access), buffer,
1343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                      offset, length, effect, control);
1344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        ReplaceWithValue(node, load, load);
1345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return Replace(load);
1346958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
1347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NoChange();
1350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochReduction JSTypedLowering::ReduceJSStoreProperty(Node* node) {
1353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* key = NodeProperties::GetValueInput(node, 1);
1354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* base = NodeProperties::GetValueInput(node, 0);
1355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* value = NodeProperties::GetValueInput(node, 2);
1356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Type* key_type = NodeProperties::GetType(key);
1357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Type* value_type = NodeProperties::GetType(value);
135862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
135962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!value_type->Is(Type::PlainPrimitive())) return NoChange();
136062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
1361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapObjectMatcher mbase(base);
1362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (mbase.HasValue() && mbase.Value()->IsJSTypedArray()) {
1363958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Handle<JSTypedArray> const array =
1364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Handle<JSTypedArray>::cast(mbase.Value());
1365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!array->GetBuffer()->was_neutered()) {
1366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      array->GetBuffer()->set_is_neuterable(false);
1367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      BufferAccess const access(array->type());
1368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      size_t const k =
1369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          ElementSizeLog2Of(access.machine_type().representation());
1370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      double const byte_length = array->byte_length()->Number();
1371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      CHECK_LT(k, arraysize(shifted_int32_ranges_));
1372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (access.external_array_type() != kExternalUint8ClampedArray &&
1373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          key_type->Is(shifted_int32_ranges_[k]) && byte_length <= kMaxInt) {
1374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // JSLoadProperty(typed-array, int32)
1375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Handle<FixedTypedArrayBase> elements =
1376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            Handle<FixedTypedArrayBase>::cast(handle(array->elements()));
1377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Node* buffer = jsgraph()->PointerConstant(elements->external_pointer());
1378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Node* length = jsgraph()->Constant(byte_length);
1379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Node* effect = NodeProperties::GetEffectInput(node);
1380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Node* control = NodeProperties::GetControlInput(node);
1381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Convert to a number first.
138213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        if (!value_type->Is(Type::Number())) {
1383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Reduction number_reduction = ReduceJSToNumberInput(value);
1384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          if (number_reduction.Changed()) {
1385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            value = number_reduction.replacement();
1386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          } else {
138762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch            value =
138862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                graph()->NewNode(simplified()->PlainPrimitiveToNumber(), value);
1389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          }
1390958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        }
1391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Check if we can avoid the bounds check.
1392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (key_type->Min() >= 0 && key_type->Max() < array->length_value()) {
1393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          RelaxControls(node);
1394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          node->ReplaceInput(0, buffer);
1395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          DCHECK_EQ(key, node->InputAt(1));
1396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          node->ReplaceInput(2, value);
1397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          node->ReplaceInput(3, effect);
1398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          node->ReplaceInput(4, control);
1399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          node->TrimInputCount(5);
1400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          NodeProperties::ChangeOp(
1401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              node,
1402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              simplified()->StoreElement(
1403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  AccessBuilder::ForTypedArrayElement(array->type(), true)));
1404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          return Changed(node);
1405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
1406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Compute byte offset.
1407f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        Node* offset =
1408f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            (k == 0) ? key : graph()->NewNode(
1409f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                 simplified()->NumberShiftLeft(), key,
1410f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                 jsgraph()->Constant(static_cast<double>(k)));
1411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Turn into a StoreBuffer operation.
1412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        RelaxControls(node);
1413958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        node->ReplaceInput(0, buffer);
1414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        node->ReplaceInput(1, offset);
1415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        node->ReplaceInput(2, length);
1416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        node->ReplaceInput(3, value);
1417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        node->ReplaceInput(4, effect);
1418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        node->ReplaceInput(5, control);
1419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        node->TrimInputCount(6);
1420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        NodeProperties::ChangeOp(node, simplified()->StoreBuffer(access));
1421958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        return Changed(node);
1422958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
1423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NoChange();
1426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1428f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochReduction JSTypedLowering::ReduceJSOrdinaryHasInstance(Node* node) {
1429f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK_EQ(IrOpcode::kJSOrdinaryHasInstance, node->opcode());
1430f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* constructor = NodeProperties::GetValueInput(node, 0);
1431f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Type* constructor_type = NodeProperties::GetType(constructor);
1432f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* object = NodeProperties::GetValueInput(node, 1);
143362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Type* object_type = NodeProperties::GetType(object);
1434f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* context = NodeProperties::GetContextInput(node);
1435f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* frame_state = NodeProperties::GetFrameStateInput(node);
1436f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* effect = NodeProperties::GetEffectInput(node);
1437f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* control = NodeProperties::GetControlInput(node);
1438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
143962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Check if the {constructor} cannot be callable.
144062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // See ES6 section 7.3.19 OrdinaryHasInstance ( C, O ) step 1.
144162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!constructor_type->Maybe(Type::Callable())) {
144262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* value = jsgraph()->FalseConstant();
144362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    ReplaceWithValue(node, value, effect, control);
144462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return Replace(value);
144562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
144662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
144762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // If the {constructor} cannot be a JSBoundFunction and then {object}
144862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // cannot be a JSReceiver, then this can be constant-folded to false.
144962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // See ES6 section 7.3.19 OrdinaryHasInstance ( C, O ) step 2 and 3.
145062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!object_type->Maybe(Type::Receiver()) &&
145162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      !constructor_type->Maybe(Type::BoundFunction())) {
145262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* value = jsgraph()->FalseConstant();
145362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    ReplaceWithValue(node, value, effect, control);
145462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return Replace(value);
145562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
145662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
1457f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Check if the {constructor} is a (known) JSFunction.
1458c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (!constructor_type->IsHeapConstant() ||
1459c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      !constructor_type->AsHeapConstant()->Value()->IsJSFunction()) {
1460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return NoChange();
1461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<JSFunction> function =
1463c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      Handle<JSFunction>::cast(constructor_type->AsHeapConstant()->Value());
1464f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1465f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Check if the {function} already has an initial map (i.e. the
1466f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // {function} has been used as a constructor at least once).
1467f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!function->has_initial_map()) return NoChange();
1468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1469f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Check if the {function}s "prototype" is a JSReceiver.
1470f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!function->prototype()->IsJSReceiver()) return NoChange();
1471bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
1472f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Install a code dependency on the {function}s initial map.
1473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<Map> initial_map(function->initial_map(), isolate());
1474bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  dependencies()->AssumeInitialMapCantChange(initial_map);
1475f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* prototype =
1477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      jsgraph()->Constant(handle(initial_map->prototype(), isolate()));
1478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1479f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* check0 = graph()->NewNode(simplified()->ObjectIsSmi(), object);
1480f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* branch0 =
1481f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      graph()->NewNode(common()->Branch(BranchHint::kFalse), check0, control);
1482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1483f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
1484f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* etrue0 = effect;
1485f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* vtrue0 = jsgraph()->FalseConstant();
1486f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1487f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  control = graph()->NewNode(common()->IfFalse(), branch0);
1488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Loop through the {object}s prototype chain looking for the {prototype}.
1490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* loop = control = graph()->NewNode(common()->Loop(2), control, control);
1491f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* eloop = effect =
1492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      graph()->NewNode(common()->EffectPhi(2), effect, effect, loop);
1493f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* vloop = object = graph()->NewNode(
1494f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      common()->Phi(MachineRepresentation::kTagged, 2), object, object, loop);
1495f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // TODO(jarin): This is a very ugly hack to work-around the super-smart
1496f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // implicit typing of the Phi, which goes completely nuts if the {object}
1497f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // is for example a HeapConstant.
1498f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  NodeProperties::SetType(vloop, Type::NonInternal());
1499f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1500f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Load the {object} map and instance type.
1501f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* object_map = effect =
1502f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), object,
1503f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                       effect, control);
1504f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* object_instance_type = effect = graph()->NewNode(
1505f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      simplified()->LoadField(AccessBuilder::ForMapInstanceType()), object_map,
1506f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      effect, control);
1507f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1508f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Check if the {object} is a special receiver, because for special
1509f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // receivers, i.e. proxies or API objects that need access checks,
1510f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // we have to use the %HasInPrototypeChain runtime function instead.
1511f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* check1 = graph()->NewNode(
1512f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      simplified()->NumberLessThanOrEqual(), object_instance_type,
1513f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      jsgraph()->Constant(LAST_SPECIAL_RECEIVER_TYPE));
1514f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* branch1 =
1515f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      graph()->NewNode(common()->Branch(BranchHint::kFalse), check1, control);
1516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1517f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  control = graph()->NewNode(common()->IfFalse(), branch1);
1518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1519f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
1520f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* etrue1 = effect;
1521f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* vtrue1;
1522f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1523f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Check if the {object} is not a receiver at all.
1524f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* check10 =
1525f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      graph()->NewNode(simplified()->NumberLessThan(), object_instance_type,
1526f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                       jsgraph()->Constant(FIRST_JS_RECEIVER_TYPE));
1527f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* branch10 =
1528f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      graph()->NewNode(common()->Branch(BranchHint::kTrue), check10, if_true1);
1529f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1530f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // A primitive value cannot match the {prototype} we're looking for.
1531f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if_true1 = graph()->NewNode(common()->IfTrue(), branch10);
1532f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  vtrue1 = jsgraph()->FalseConstant();
1533f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1534f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch10);
1535f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* efalse1 = etrue1;
1536f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* vfalse1;
1537f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  {
1538f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // Slow path, need to call the %HasInPrototypeChain runtime function.
1539f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    vfalse1 = efalse1 = graph()->NewNode(
1540f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        javascript()->CallRuntime(Runtime::kHasInPrototypeChain), object,
1541f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        prototype, context, frame_state, efalse1, if_false1);
1542f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if_false1 = graph()->NewNode(common()->IfSuccess(), vfalse1);
1543f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1544f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // Replace any potential IfException on {node} to catch exceptions
1545f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // from this %HasInPrototypeChain runtime call instead.
1546f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    for (Edge edge : node->use_edges()) {
1547f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      if (edge.from()->opcode() == IrOpcode::kIfException) {
1548f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        edge.UpdateTo(vfalse1);
1549f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        Revisit(edge.from());
1550f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      }
1551f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
1552f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1554f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Load the {object} prototype.
1555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* object_prototype = effect = graph()->NewNode(
1556f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      simplified()->LoadField(AccessBuilder::ForMapPrototype()), object_map,
1557f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      effect, control);
1558f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1559f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Check if we reached the end of {object}s prototype chain.
1560f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* check2 = graph()->NewNode(simplified()->ReferenceEqual(),
1561f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                  object_prototype, jsgraph()->NullConstant());
1562f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* branch2 = graph()->NewNode(common()->Branch(), check2, control);
1563f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1564f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
1565f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* etrue2 = effect;
1566f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* vtrue2 = jsgraph()->FalseConstant();
1567f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1568f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  control = graph()->NewNode(common()->IfFalse(), branch2);
1569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1570f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Check if we reached the {prototype}.
1571f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* check3 = graph()->NewNode(simplified()->ReferenceEqual(),
1572f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                  object_prototype, prototype);
1573f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* branch3 = graph()->NewNode(common()->Branch(), check3, control);
1574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1575f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* if_true3 = graph()->NewNode(common()->IfTrue(), branch3);
1576f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* etrue3 = effect;
1577f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* vtrue3 = jsgraph()->TrueConstant();
1578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1579f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  control = graph()->NewNode(common()->IfFalse(), branch3);
1580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1581f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Close the loop.
1582f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  vloop->ReplaceInput(1, object_prototype);
1583f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  eloop->ReplaceInput(1, effect);
1584f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  loop->ReplaceInput(1, control);
1585f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1586f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  control = graph()->NewNode(common()->Merge(5), if_true0, if_true1, if_true2,
1587f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                             if_true3, if_false1);
1588f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  effect = graph()->NewNode(common()->EffectPhi(5), etrue0, etrue1, etrue2,
1589f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                            etrue3, efalse1, control);
1590f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1591f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Morph the {node} into an appropriate Phi.
1592f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ReplaceWithValue(node, node, effect, control);
1593f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  node->ReplaceInput(0, vtrue0);
1594f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  node->ReplaceInput(1, vtrue1);
1595f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  node->ReplaceInput(2, vtrue2);
1596f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  node->ReplaceInput(3, vtrue3);
1597f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  node->ReplaceInput(4, vfalse1);
1598f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  node->ReplaceInput(5, control);
1599f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  node->TrimInputCount(6);
1600f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  NodeProperties::ChangeOp(node,
1601f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                           common()->Phi(MachineRepresentation::kTagged, 5));
1602f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return Changed(node);
1603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1605958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierReduction JSTypedLowering::ReduceJSLoadContext(Node* node) {
1606958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK_EQ(IrOpcode::kJSLoadContext, node->opcode());
1607958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  ContextAccess const& access = ContextAccessOf(node->op());
1608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* effect = NodeProperties::GetEffectInput(node);
160962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* context = NodeProperties::GetContextInput(node);
1610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* control = graph()->start();
1611958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (size_t i = 0; i < access.depth(); ++i) {
161262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    context = effect = graph()->NewNode(
1613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        simplified()->LoadField(
1614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX)),
161562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        context, effect, control);
1616958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
161762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  node->ReplaceInput(0, context);
1618958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  node->ReplaceInput(1, effect);
161962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  node->AppendInput(jsgraph()->zone(), control);
1620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  NodeProperties::ChangeOp(
1621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      node,
1622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      simplified()->LoadField(AccessBuilder::ForContextSlot(access.index())));
1623958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return Changed(node);
1624958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1625958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1626958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierReduction JSTypedLowering::ReduceJSStoreContext(Node* node) {
1627958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK_EQ(IrOpcode::kJSStoreContext, node->opcode());
1628958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  ContextAccess const& access = ContextAccessOf(node->op());
1629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* effect = NodeProperties::GetEffectInput(node);
163062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* context = NodeProperties::GetContextInput(node);
1631014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* control = graph()->start();
163262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* value = NodeProperties::GetValueInput(node, 0);
1633958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (size_t i = 0; i < access.depth(); ++i) {
163462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    context = effect = graph()->NewNode(
1635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        simplified()->LoadField(
1636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX)),
163762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        context, effect, control);
1638958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
163962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  node->ReplaceInput(0, context);
164062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  node->ReplaceInput(1, value);
1641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  node->ReplaceInput(2, effect);
1642014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  NodeProperties::ChangeOp(
1643014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      node,
1644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      simplified()->StoreField(AccessBuilder::ForContextSlot(access.index())));
1645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return Changed(node);
1646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1648c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochReduction JSTypedLowering::ReduceJSLoadModule(Node* node) {
1649c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  DCHECK_EQ(IrOpcode::kJSLoadModule, node->opcode());
1650c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Node* effect = NodeProperties::GetEffectInput(node);
1651c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Node* control = NodeProperties::GetControlInput(node);
1652c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
1653c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  int32_t cell_index = OpParameter<int32_t>(node);
1654c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Node* module = NodeProperties::GetValueInput(node, 0);
1655c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
1656c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Node* array;
1657c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  int index;
1658c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (ModuleDescriptor::GetCellIndexKind(cell_index) ==
1659c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      ModuleDescriptor::kExport) {
1660c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    array = effect = graph()->NewNode(
1661c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        simplified()->LoadField(AccessBuilder::ForModuleRegularExports()),
1662c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        module, effect, control);
1663c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    index = cell_index - 1;
1664c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  } else {
1665c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    DCHECK_EQ(ModuleDescriptor::GetCellIndexKind(cell_index),
1666c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch              ModuleDescriptor::kImport);
1667c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    array = effect = graph()->NewNode(
1668c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        simplified()->LoadField(AccessBuilder::ForModuleRegularImports()),
1669c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        module, effect, control);
1670c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    index = -cell_index - 1;
1671c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
1672c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
1673c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Node* cell = effect = graph()->NewNode(
1674c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      simplified()->LoadField(AccessBuilder::ForFixedArraySlot(index)), array,
1675c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      effect, control);
1676c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
1677c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Node* value = effect =
1678c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      graph()->NewNode(simplified()->LoadField(AccessBuilder::ForCellValue()),
1679c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                       cell, effect, control);
1680c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
1681c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  ReplaceWithValue(node, value, effect, control);
1682c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return Changed(value);
1683c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
1684c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
1685c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochReduction JSTypedLowering::ReduceJSStoreModule(Node* node) {
1686c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  DCHECK_EQ(IrOpcode::kJSStoreModule, node->opcode());
1687c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Node* effect = NodeProperties::GetEffectInput(node);
1688c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Node* control = NodeProperties::GetControlInput(node);
1689c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
1690c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  int32_t cell_index = OpParameter<int32_t>(node);
1691c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Node* module = NodeProperties::GetValueInput(node, 0);
1692c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Node* value = NodeProperties::GetValueInput(node, 1);
1693c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
1694c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Node* array;
1695c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  int index;
1696c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (ModuleDescriptor::GetCellIndexKind(cell_index) ==
1697c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      ModuleDescriptor::kExport) {
1698c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    array = effect = graph()->NewNode(
1699c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        simplified()->LoadField(AccessBuilder::ForModuleRegularExports()),
1700c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        module, effect, control);
1701c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    index = cell_index - 1;
1702c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  } else {
1703c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    DCHECK_EQ(ModuleDescriptor::GetCellIndexKind(cell_index),
1704c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch              ModuleDescriptor::kImport);
1705c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    array = effect = graph()->NewNode(
1706c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        simplified()->LoadField(AccessBuilder::ForModuleRegularImports()),
1707c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        module, effect, control);
1708c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    index = -cell_index - 1;
1709c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
1710c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
1711c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Node* cell = effect = graph()->NewNode(
1712c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      simplified()->LoadField(AccessBuilder::ForFixedArraySlot(index)), array,
1713c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      effect, control);
1714c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
1715c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  effect =
1716c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      graph()->NewNode(simplified()->StoreField(AccessBuilder::ForCellValue()),
1717c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                       cell, value, effect, control);
1718c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
1719c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  ReplaceWithValue(node, effect, effect, control);
1720c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return Changed(value);
1721c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
1722c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
1723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochReduction JSTypedLowering::ReduceJSConvertReceiver(Node* node) {
1724014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_EQ(IrOpcode::kJSConvertReceiver, node->opcode());
1725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ConvertReceiverMode mode = ConvertReceiverModeOf(node->op());
1726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* receiver = NodeProperties::GetValueInput(node, 0);
1727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Type* receiver_type = NodeProperties::GetType(receiver);
1728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* context = NodeProperties::GetContextInput(node);
1729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Type* context_type = NodeProperties::GetType(context);
1730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* effect = NodeProperties::GetEffectInput(node);
1731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* control = NodeProperties::GetControlInput(node);
1732f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1733f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Check if {receiver} is known to be a receiver.
1734f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (receiver_type->Is(Type::Receiver())) {
1735f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    ReplaceWithValue(node, receiver, effect, control);
1736f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return Replace(receiver);
1737f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
1738f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1739f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // If the {receiver} is known to be null or undefined, we can just replace it
1740f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // with the global proxy unconditionally.
1741f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (receiver_type->Is(Type::NullOrUndefined()) ||
1742f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      mode == ConvertReceiverMode::kNullOrUndefined) {
1743c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    if (context_type->IsHeapConstant()) {
1744f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      Handle<JSObject> global_proxy(
1745c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          Handle<Context>::cast(context_type->AsHeapConstant()->Value())
1746f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              ->global_proxy(),
1747f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          isolate());
1748f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      receiver = jsgraph()->Constant(global_proxy);
1749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
1750f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      Node* native_context = effect = graph()->NewNode(
1751f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true),
175262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          context, effect);
1753f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      receiver = effect = graph()->NewNode(
1754f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          javascript()->LoadContext(0, Context::GLOBAL_PROXY_INDEX, true),
175562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          native_context, effect);
1756f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
1757f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    ReplaceWithValue(node, receiver, effect, control);
1758f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return Replace(receiver);
1759f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
1760014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1761f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // If {receiver} cannot be null or undefined we can skip a few checks.
1762f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (!receiver_type->Maybe(Type::NullOrUndefined()) ||
1763f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      mode == ConvertReceiverMode::kNotNullOrUndefined) {
1764f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Node* check = graph()->NewNode(simplified()->ObjectIsReceiver(), receiver);
1765f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Node* branch =
1766f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
1767f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1768f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
1769f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Node* etrue = effect;
1770f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Node* rtrue = receiver;
1771f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1772f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
1773f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Node* efalse = effect;
1774f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Node* rfalse;
1775f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    {
177662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      // Convert {receiver} using the ToObjectStub. The call does not require a
177762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      // frame-state in this case, because neither null nor undefined is passed.
1778f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      Callable callable = CodeFactory::ToObject(isolate());
1779f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      CallDescriptor const* const desc = Linkage::GetStubCallDescriptor(
1780f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          isolate(), graph()->zone(), callable.descriptor(), 0,
178162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          CallDescriptor::kNoFlags, node->op()->properties());
1782f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      rfalse = efalse = graph()->NewNode(
1783f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          common()->Call(desc), jsgraph()->HeapConstant(callable.code()),
178462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          receiver, context, efalse);
1785f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
1786f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1787f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    control = graph()->NewNode(common()->Merge(2), if_true, if_false);
1788f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
1789f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1790f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // Morph the {node} into an appropriate Phi.
1791f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    ReplaceWithValue(node, node, effect, control);
1792f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    node->ReplaceInput(0, rtrue);
1793f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    node->ReplaceInput(1, rfalse);
1794f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    node->ReplaceInput(2, control);
1795f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    node->TrimInputCount(3);
1796f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    NodeProperties::ChangeOp(node,
1797f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                             common()->Phi(MachineRepresentation::kTagged, 2));
1798f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return Changed(node);
1799f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
1800f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1801f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Check if {receiver} is already a JSReceiver.
1802f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* check0 = graph()->NewNode(simplified()->ObjectIsReceiver(), receiver);
1803f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* branch0 =
1804f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
1805f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
1806f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
1807f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1808f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Check {receiver} for undefined.
1809f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* check1 = graph()->NewNode(simplified()->ReferenceEqual(), receiver,
1810f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                  jsgraph()->UndefinedConstant());
1811f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* branch1 =
1812f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      graph()->NewNode(common()->Branch(BranchHint::kFalse), check1, if_false0);
1813f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
1814f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
1815f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1816f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Check {receiver} for null.
1817f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* check2 = graph()->NewNode(simplified()->ReferenceEqual(), receiver,
1818f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                  jsgraph()->NullConstant());
1819f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* branch2 =
1820f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      graph()->NewNode(common()->Branch(BranchHint::kFalse), check2, if_false1);
1821f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
1822f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
1823f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1824f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // We just use {receiver} directly.
1825f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* if_noop = if_true0;
1826f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* enoop = effect;
1827f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* rnoop = receiver;
1828f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1829f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Convert {receiver} using ToObject.
1830f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* if_convert = if_false2;
1831f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* econvert = effect;
1832f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* rconvert;
1833f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  {
183462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // Convert {receiver} using the ToObjectStub. The call does not require a
183562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // frame-state in this case, because neither null nor undefined is passed.
1836f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Callable callable = CodeFactory::ToObject(isolate());
1837f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    CallDescriptor const* const desc = Linkage::GetStubCallDescriptor(
1838f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        isolate(), graph()->zone(), callable.descriptor(), 0,
183962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        CallDescriptor::kNoFlags, node->op()->properties());
1840f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    rconvert = econvert = graph()->NewNode(
1841f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        common()->Call(desc), jsgraph()->HeapConstant(callable.code()),
184262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        receiver, context, econvert);
1843f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
1844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1845f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Replace {receiver} with global proxy of {context}.
1846f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* if_global = graph()->NewNode(common()->Merge(2), if_true1, if_true2);
1847f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* eglobal = effect;
1848f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* rglobal;
1849f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  {
1850c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    if (context_type->IsHeapConstant()) {
1851f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      Handle<JSObject> global_proxy(
1852c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          Handle<Context>::cast(context_type->AsHeapConstant()->Value())
1853f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              ->global_proxy(),
1854f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          isolate());
1855f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      rglobal = jsgraph()->Constant(global_proxy);
1856f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    } else {
1857f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      Node* native_context = eglobal = graph()->NewNode(
1858f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true),
185962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          context, eglobal);
1860f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      rglobal = eglobal = graph()->NewNode(
1861f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          javascript()->LoadContext(0, Context::GLOBAL_PROXY_INDEX, true),
186262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          native_context, eglobal);
1863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1865f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1866f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  control =
1867f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      graph()->NewNode(common()->Merge(3), if_noop, if_convert, if_global);
1868f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  effect = graph()->NewNode(common()->EffectPhi(3), enoop, econvert, eglobal,
1869f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                            control);
1870f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Morph the {node} into an appropriate Phi.
1871f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ReplaceWithValue(node, node, effect, control);
1872f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  node->ReplaceInput(0, rnoop);
1873f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  node->ReplaceInput(1, rconvert);
1874f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  node->ReplaceInput(2, rglobal);
1875f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  node->ReplaceInput(3, control);
1876f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  node->TrimInputCount(4);
1877f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  NodeProperties::ChangeOp(node,
1878f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                           common()->Phi(MachineRepresentation::kTagged, 3));
1879f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return Changed(node);
1880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1882f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochnamespace {
1883f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1884f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid ReduceBuiltin(Isolate* isolate, JSGraph* jsgraph, Node* node,
1885f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                   int builtin_index, int arity, CallDescriptor::Flags flags) {
1886f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Patch {node} to a direct CEntryStub call.
1887f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  //
1888f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // ----------- A r g u m e n t s -----------
1889f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // -- 0: CEntryStub
1890f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // --- Stack args ---
1891f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // -- 1: receiver
1892f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // -- [2, 2 + n[: the n actual arguments passed to the builtin
1893f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // -- 2 + n: argc, including the receiver and implicit args (Smi)
1894f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // -- 2 + n + 1: target
1895f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // -- 2 + n + 2: new_target
1896f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // --- Register args ---
1897f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // -- 2 + n + 3: the C entry point
1898f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // -- 2 + n + 4: argc (Int32)
1899f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // -----------------------------------
1900f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1901f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // The logic contained here is mirrored in Builtins::Generate_Adaptor.
1902f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Keep these in sync.
1903f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
190462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  const bool is_construct = (node->opcode() == IrOpcode::kJSConstruct);
1905f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1906f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DCHECK(Builtins::HasCppImplementation(builtin_index));
1907c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  DCHECK_EQ(0, flags & CallDescriptor::kSupportsTailCalls);
1908f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1909f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* target = NodeProperties::GetValueInput(node, 0);
1910f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* new_target = is_construct
1911f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                         ? NodeProperties::GetValueInput(node, arity + 1)
1912f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                         : jsgraph->UndefinedConstant();
1913f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1914f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // API and CPP builtins are implemented in C++, and we can inline both.
1915f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // CPP builtins create a builtin exit frame, API builtins don't.
1916f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const bool has_builtin_exit_frame = Builtins::IsCpp(builtin_index);
1917f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1918f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* stub = jsgraph->CEntryStubConstant(1, kDontSaveFPRegs, kArgvOnStack,
1919f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                           has_builtin_exit_frame);
1920f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  node->ReplaceInput(0, stub);
1921f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1922f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Zone* zone = jsgraph->zone();
1923f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (is_construct) {
1924f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // Unify representations between construct and call nodes.
1925f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // Remove new target and add receiver as a stack parameter.
1926f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Node* receiver = jsgraph->UndefinedConstant();
1927f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    node->RemoveInput(arity + 1);
1928f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    node->InsertInput(zone, 1, receiver);
1929f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
1930f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1931f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const int argc = arity + BuiltinArguments::kNumExtraArgsWithReceiver;
1932c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Node* argc_node = jsgraph->Constant(argc);
1933f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1934f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  static const int kStubAndReceiver = 2;
1935f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  int cursor = arity + kStubAndReceiver;
1936f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  node->InsertInput(zone, cursor++, argc_node);
1937f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  node->InsertInput(zone, cursor++, target);
1938f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  node->InsertInput(zone, cursor++, new_target);
1939f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1940f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Address entry = Builtins::CppEntryOf(builtin_index);
1941f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ExternalReference entry_ref(ExternalReference(entry, isolate));
1942f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* entry_node = jsgraph->ExternalConstant(entry_ref);
1943f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1944f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  node->InsertInput(zone, cursor++, entry_node);
1945f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  node->InsertInput(zone, cursor++, argc_node);
1946f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1947f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static const int kReturnCount = 1;
1948f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const char* debug_name = Builtins::name(builtin_index);
1949f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Operator::Properties properties = node->op()->properties();
1950f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CallDescriptor* desc = Linkage::GetCEntryStubCallDescriptor(
1951f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      zone, kReturnCount, argc, debug_name, properties, flags);
1952f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1953f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  NodeProperties::ChangeOp(node, jsgraph->common()->Call(desc));
1954f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1955f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1956f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool NeedsArgumentAdaptorFrame(Handle<SharedFunctionInfo> shared, int arity) {
1957f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  static const int sentinel = SharedFunctionInfo::kDontAdaptArgumentsSentinel;
1958f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  const int num_decl_parms = shared->internal_formal_parameter_count();
1959f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return (num_decl_parms != arity && num_decl_parms != sentinel);
1960f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
1961f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1962f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}  // namespace
1963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
196462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochReduction JSTypedLowering::ReduceJSConstruct(Node* node) {
196562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK_EQ(IrOpcode::kJSConstruct, node->opcode());
196662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  ConstructParameters const& p = ConstructParametersOf(node->op());
1967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_LE(2u, p.arity());
1968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int const arity = static_cast<int>(p.arity() - 2);
1969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* target = NodeProperties::GetValueInput(node, 0);
1970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Type* target_type = NodeProperties::GetType(target);
1971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* new_target = NodeProperties::GetValueInput(node, arity + 1);
1972f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* effect = NodeProperties::GetEffectInput(node);
1973f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* control = NodeProperties::GetControlInput(node);
1974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Check if {target} is a known JSFunction.
1976c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (target_type->IsHeapConstant() &&
1977c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      target_type->AsHeapConstant()->Value()->IsJSFunction()) {
1978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<JSFunction> function =
1979c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        Handle<JSFunction>::cast(target_type->AsHeapConstant()->Value());
1980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<SharedFunctionInfo> shared(function->shared(), isolate());
1981f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    const int builtin_index = shared->construct_stub()->builtin_index();
1982f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    const bool is_builtin = (builtin_index != -1);
1983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1984f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState;
1985f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1986f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (is_builtin && Builtins::HasCppImplementation(builtin_index) &&
1987f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        !NeedsArgumentAdaptorFrame(shared, arity)) {
1988f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      // Patch {node} to a direct CEntryStub call.
1989f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1990f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      // Load the context from the {target}.
1991f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      Node* context = effect = graph()->NewNode(
1992f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          simplified()->LoadField(AccessBuilder::ForJSFunctionContext()),
1993f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          target, effect, control);
1994f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      NodeProperties::ReplaceContextInput(node, context);
1995f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1996f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      // Update the effect dependency for the {node}.
1997f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      NodeProperties::ReplaceEffectInput(node, effect);
1998f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1999f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ReduceBuiltin(isolate(), jsgraph(), node, builtin_index, arity, flags);
2000f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    } else {
2001f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      // Patch {node} to an indirect call via the {function}s construct stub.
2002f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      Callable callable(handle(shared->construct_stub(), isolate()),
2003f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                        ConstructStubDescriptor(isolate()));
2004f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      node->RemoveInput(arity + 1);
2005f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      node->InsertInput(graph()->zone(), 0,
2006f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                        jsgraph()->HeapConstant(callable.code()));
2007f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      node->InsertInput(graph()->zone(), 2, new_target);
2008c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      node->InsertInput(graph()->zone(), 3, jsgraph()->Constant(arity));
2009f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      node->InsertInput(graph()->zone(), 4, jsgraph()->UndefinedConstant());
2010f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      node->InsertInput(graph()->zone(), 5, jsgraph()->UndefinedConstant());
2011f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      NodeProperties::ChangeOp(
2012f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          node, common()->Call(Linkage::GetStubCallDescriptor(
2013f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                    isolate(), graph()->zone(), callable.descriptor(),
2014f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                    1 + arity, flags)));
2015f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
2016014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return Changed(node);
2017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2018014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2019014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Check if {target} is a JSFunction.
2020014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (target_type->Is(Type::Function())) {
2021014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Patch {node} to an indirect call via the ConstructFunction builtin.
2022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Callable callable = CodeFactory::ConstructFunction(isolate());
2023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    node->RemoveInput(arity + 1);
2024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    node->InsertInput(graph()->zone(), 0,
2025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                      jsgraph()->HeapConstant(callable.code()));
2026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    node->InsertInput(graph()->zone(), 2, new_target);
2027c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    node->InsertInput(graph()->zone(), 3, jsgraph()->Constant(arity));
2028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    node->InsertInput(graph()->zone(), 4, jsgraph()->UndefinedConstant());
2029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    NodeProperties::ChangeOp(
2030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        node, common()->Call(Linkage::GetStubCallDescriptor(
2031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  isolate(), graph()->zone(), callable.descriptor(), 1 + arity,
2032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  CallDescriptor::kNeedsFrameState)));
2033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return Changed(node);
2034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return NoChange();
2037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
203962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochReduction JSTypedLowering::ReduceJSCallForwardVarargs(Node* node) {
204062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK_EQ(IrOpcode::kJSCallForwardVarargs, node->opcode());
204162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CallForwardVarargsParameters p = CallForwardVarargsParametersOf(node->op());
204262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* target = NodeProperties::GetValueInput(node, 0);
204362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Type* target_type = NodeProperties::GetType(target);
204462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
204562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Check if {target} is a JSFunction.
204662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (target_type->Is(Type::Function())) {
204762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // Compute flags for the call.
204862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState;
204962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (p.tail_call_mode() == TailCallMode::kAllow) {
205062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      flags |= CallDescriptor::kSupportsTailCalls;
205162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
205262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
205362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // Patch {node} to an indirect call via CallFunctionForwardVarargs.
205462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Callable callable = CodeFactory::CallFunctionForwardVarargs(isolate());
205562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    node->InsertInput(graph()->zone(), 0,
205662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                      jsgraph()->HeapConstant(callable.code()));
205762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    node->InsertInput(graph()->zone(), 2, jsgraph()->Constant(p.start_index()));
205862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    NodeProperties::ChangeOp(
205962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        node,
206062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        common()->Call(Linkage::GetStubCallDescriptor(
206162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch            isolate(), graph()->zone(), callable.descriptor(), 1, flags)));
206262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return Changed(node);
206362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
206462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
206562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return NoChange();
206662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
2067014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
206862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochReduction JSTypedLowering::ReduceJSCall(Node* node) {
206962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
207062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CallParameters const& p = CallParametersOf(node->op());
2071014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int const arity = static_cast<int>(p.arity() - 2);
2072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ConvertReceiverMode convert_mode = p.convert_mode();
2073014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* target = NodeProperties::GetValueInput(node, 0);
2074014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Type* target_type = NodeProperties::GetType(target);
2075014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* receiver = NodeProperties::GetValueInput(node, 1);
2076014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Type* receiver_type = NodeProperties::GetType(receiver);
2077014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* effect = NodeProperties::GetEffectInput(node);
2078014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* control = NodeProperties::GetControlInput(node);
2079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2080014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Try to infer receiver {convert_mode} from {receiver} type.
2081014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (receiver_type->Is(Type::NullOrUndefined())) {
2082014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    convert_mode = ConvertReceiverMode::kNullOrUndefined;
2083014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (!receiver_type->Maybe(Type::NullOrUndefined())) {
2084014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    convert_mode = ConvertReceiverMode::kNotNullOrUndefined;
2085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2086014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Check if {target} is a known JSFunction.
2088c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (target_type->IsHeapConstant() &&
2089c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      target_type->AsHeapConstant()->Value()->IsJSFunction()) {
2090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<JSFunction> function =
2091c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        Handle<JSFunction>::cast(target_type->AsHeapConstant()->Value());
2092014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<SharedFunctionInfo> shared(function->shared(), isolate());
2093f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    const int builtin_index = shared->code()->builtin_index();
2094f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    const bool is_builtin = (builtin_index != -1);
2095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Class constructors are callable, but [[Call]] will raise an exception.
2097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList ).
2098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (IsClassConstructor(shared->kind())) return NoChange();
2099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Load the context from the {target}.
2101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Node* context = effect = graph()->NewNode(
2102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        simplified()->LoadField(AccessBuilder::ForJSFunctionContext()), target,
2103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        effect, control);
2104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    NodeProperties::ReplaceContextInput(node, context);
2105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Check if we need to convert the {receiver}.
2107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (is_sloppy(shared->language_mode()) && !shared->native() &&
2108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        !receiver_type->Is(Type::Receiver())) {
2109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      receiver = effect =
2110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          graph()->NewNode(javascript()->ConvertReceiver(convert_mode),
211162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                           receiver, context, effect, control);
2112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      NodeProperties::ReplaceValueInput(node, receiver, 1);
2113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Update the effect dependency for the {node}.
2116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    NodeProperties::ReplaceEffectInput(node, effect);
2117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Compute flags for the call.
2119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState;
2120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (p.tail_call_mode() == TailCallMode::kAllow) {
2121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      flags |= CallDescriptor::kSupportsTailCalls;
2122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Node* new_target = jsgraph()->UndefinedConstant();
2125c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    Node* argument_count = jsgraph()->Constant(arity);
2126f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (NeedsArgumentAdaptorFrame(shared, arity)) {
2127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Patch {node} to an indirect call via the ArgumentsAdaptorTrampoline.
2128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Callable callable = CodeFactory::ArgumentAdaptor(isolate());
2129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      node->InsertInput(graph()->zone(), 0,
2130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                        jsgraph()->HeapConstant(callable.code()));
2131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      node->InsertInput(graph()->zone(), 2, new_target);
2132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      node->InsertInput(graph()->zone(), 3, argument_count);
2133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      node->InsertInput(
2134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          graph()->zone(), 4,
2135c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          jsgraph()->Constant(shared->internal_formal_parameter_count()));
2136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      NodeProperties::ChangeOp(
2137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          node, common()->Call(Linkage::GetStubCallDescriptor(
2138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    isolate(), graph()->zone(), callable.descriptor(),
2139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    1 + arity, flags)));
2140c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    } else if (is_builtin && Builtins::HasCppImplementation(builtin_index) &&
2141c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch               ((flags & CallDescriptor::kSupportsTailCalls) == 0)) {
2142f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // Patch {node} to a direct CEntryStub call.
2143f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      ReduceBuiltin(isolate(), jsgraph(), node, builtin_index, arity, flags);
2144f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    } else {
2145f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // Patch {node} to a direct call.
2146f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      node->InsertInput(graph()->zone(), arity + 2, new_target);
2147f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      node->InsertInput(graph()->zone(), arity + 3, argument_count);
2148f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      NodeProperties::ChangeOp(node,
2149f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                               common()->Call(Linkage::GetJSCallDescriptor(
2150f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                   graph()->zone(), false, 1 + arity, flags)));
2151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return Changed(node);
2153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Check if {target} is a JSFunction.
2156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (target_type->Is(Type::Function())) {
2157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Compute flags for the call.
2158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState;
2159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (p.tail_call_mode() == TailCallMode::kAllow) {
2160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      flags |= CallDescriptor::kSupportsTailCalls;
2161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Patch {node} to an indirect call via the CallFunction builtin.
2164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Callable callable = CodeFactory::CallFunction(isolate(), convert_mode);
2165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    node->InsertInput(graph()->zone(), 0,
2166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                      jsgraph()->HeapConstant(callable.code()));
2167c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    node->InsertInput(graph()->zone(), 2, jsgraph()->Constant(arity));
2168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    NodeProperties::ChangeOp(
2169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        node, common()->Call(Linkage::GetStubCallDescriptor(
2170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  isolate(), graph()->zone(), callable.descriptor(), 1 + arity,
2171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  flags)));
2172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return Changed(node);
2173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Maybe we did at least learn something about the {receiver}.
2176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (p.convert_mode() != convert_mode) {
2177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    NodeProperties::ChangeOp(
217862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        node,
217962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        javascript()->Call(p.arity(), p.frequency(), p.feedback(), convert_mode,
218062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                           p.tail_call_mode()));
2181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return Changed(node);
2182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return NoChange();
2185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochReduction JSTypedLowering::ReduceJSForInNext(Node* node) {
2189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_EQ(IrOpcode::kJSForInNext, node->opcode());
2190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* receiver = NodeProperties::GetValueInput(node, 0);
2191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* cache_array = NodeProperties::GetValueInput(node, 1);
2192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* cache_type = NodeProperties::GetValueInput(node, 2);
2193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* index = NodeProperties::GetValueInput(node, 3);
2194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* context = NodeProperties::GetContextInput(node);
2195f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* frame_state = NodeProperties::GetFrameStateInput(node);
2196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* effect = NodeProperties::GetEffectInput(node);
2197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* control = NodeProperties::GetControlInput(node);
2198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
219962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // We don't support lowering JSForInNext inside try blocks.
220062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (NodeProperties::IsExceptionalCall(node)) return NoChange();
220162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
220262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // We know that the {index} is in Unsigned32 range here, otherwise executing
220362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // the JSForInNext wouldn't be valid. Unfortunately due to OSR and generators
220462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // this is not always reflected in the types, hence we might need to rename
220562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // the {index} here.
220662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!NodeProperties::GetType(index)->Is(Type::Unsigned32())) {
220762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    index = graph()->NewNode(common()->TypeGuard(Type::Unsigned32()), index,
220862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                             control);
220962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
221062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
2211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Load the next {key} from the {cache_array}.
2212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* key = effect = graph()->NewNode(
2213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      simplified()->LoadElement(AccessBuilder::ForFixedArrayElement()),
2214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      cache_array, index, effect, control);
2215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Load the map of the {receiver}.
2217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* receiver_map = effect =
2218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
2219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       receiver, effect, control);
2220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Check if the expected map still matches that of the {receiver}.
2222f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* check0 = graph()->NewNode(simplified()->ReferenceEqual(), receiver_map,
2223f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                  cache_type);
2224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* branch0 =
2225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
2226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
2228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* etrue0;
2229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* vtrue0;
2230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  {
2231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Don't need filtering since expected map still matches that of the
2232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // {receiver}.
2233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    etrue0 = effect;
2234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vtrue0 = key;
2235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
2238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* efalse0;
2239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* vfalse0;
2240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  {
2241109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // Filter the {key} to check if it's still a valid property of the
2242109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // {receiver} (does the ToName conversion implicitly).
2243f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Callable const callable = CodeFactory::ForInFilter(isolate());
2244f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    CallDescriptor const* const desc = Linkage::GetStubCallDescriptor(
2245f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        isolate(), graph()->zone(), callable.descriptor(), 0,
2246f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        CallDescriptor::kNeedsFrameState);
2247109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    vfalse0 = efalse0 = graph()->NewNode(
2248f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        common()->Call(desc), jsgraph()->HeapConstant(callable.code()), key,
2249f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        receiver, context, frame_state, effect, if_false0);
2250109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if_false0 = graph()->NewNode(common()->IfSuccess(), vfalse0);
2251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
2254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
2255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ReplaceWithValue(node, node, effect, control);
2256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  node->ReplaceInput(0, vtrue0);
2257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  node->ReplaceInput(1, vfalse0);
2258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  node->ReplaceInput(2, control);
2259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  node->TrimInputCount(3);
2260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  NodeProperties::ChangeOp(node,
2261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           common()->Phi(MachineRepresentation::kTagged, 2));
2262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return Changed(node);
2263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
226562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochReduction JSTypedLowering::ReduceJSLoadMessage(Node* node) {
226662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK_EQ(IrOpcode::kJSLoadMessage, node->opcode());
226762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  ExternalReference const ref =
226862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      ExternalReference::address_of_pending_message_obj(isolate());
226962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  node->ReplaceInput(0, jsgraph()->ExternalConstant(ref));
227062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  NodeProperties::ChangeOp(
227162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      node, simplified()->LoadField(AccessBuilder::ForExternalTaggedValue()));
227262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return Changed(node);
227362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
227462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
227562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochReduction JSTypedLowering::ReduceJSStoreMessage(Node* node) {
227662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK_EQ(IrOpcode::kJSStoreMessage, node->opcode());
227762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  ExternalReference const ref =
227862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      ExternalReference::address_of_pending_message_obj(isolate());
227962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* value = NodeProperties::GetValueInput(node, 0);
228062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  node->ReplaceInput(0, jsgraph()->ExternalConstant(ref));
228162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  node->ReplaceInput(1, value);
228262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  NodeProperties::ChangeOp(
228362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      node, simplified()->StoreField(AccessBuilder::ForExternalTaggedValue()));
228462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return Changed(node);
228562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
228662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
228713e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochReduction JSTypedLowering::ReduceJSGeneratorStore(Node* node) {
228813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  DCHECK_EQ(IrOpcode::kJSGeneratorStore, node->opcode());
228913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Node* generator = NodeProperties::GetValueInput(node, 0);
229013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Node* continuation = NodeProperties::GetValueInput(node, 1);
229113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Node* offset = NodeProperties::GetValueInput(node, 2);
229213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Node* context = NodeProperties::GetContextInput(node);
229313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Node* effect = NodeProperties::GetEffectInput(node);
229413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Node* control = NodeProperties::GetControlInput(node);
229513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  int register_count = OpParameter<int>(node);
229613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
229762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  FieldAccess array_field = AccessBuilder::ForJSGeneratorObjectRegisterFile();
229813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  FieldAccess context_field = AccessBuilder::ForJSGeneratorObjectContext();
229913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  FieldAccess continuation_field =
230013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      AccessBuilder::ForJSGeneratorObjectContinuation();
230113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  FieldAccess input_or_debug_pos_field =
230213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      AccessBuilder::ForJSGeneratorObjectInputOrDebugPos();
230313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
230413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Node* array = effect = graph()->NewNode(simplified()->LoadField(array_field),
230513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                          generator, effect, control);
230613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
230713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  for (int i = 0; i < register_count; ++i) {
230813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    Node* value = NodeProperties::GetValueInput(node, 3 + i);
230913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    effect = graph()->NewNode(
231013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        simplified()->StoreField(AccessBuilder::ForFixedArraySlot(i)), array,
231113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        value, effect, control);
231213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
231313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
231413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  effect = graph()->NewNode(simplified()->StoreField(context_field), generator,
231513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                            context, effect, control);
231613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  effect = graph()->NewNode(simplified()->StoreField(continuation_field),
231713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                            generator, continuation, effect, control);
231813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  effect = graph()->NewNode(simplified()->StoreField(input_or_debug_pos_field),
231913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                            generator, offset, effect, control);
232013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
232113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  ReplaceWithValue(node, effect, effect, control);
232213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  return Changed(effect);
232313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
232413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
232513e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochReduction JSTypedLowering::ReduceJSGeneratorRestoreContinuation(Node* node) {
232613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  DCHECK_EQ(IrOpcode::kJSGeneratorRestoreContinuation, node->opcode());
232713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Node* generator = NodeProperties::GetValueInput(node, 0);
232813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Node* effect = NodeProperties::GetEffectInput(node);
232913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Node* control = NodeProperties::GetControlInput(node);
233013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
233113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  FieldAccess continuation_field =
233213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      AccessBuilder::ForJSGeneratorObjectContinuation();
233313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
233413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Node* continuation = effect = graph()->NewNode(
233513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      simplified()->LoadField(continuation_field), generator, effect, control);
233613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Node* executing = jsgraph()->Constant(JSGeneratorObject::kGeneratorExecuting);
233713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  effect = graph()->NewNode(simplified()->StoreField(continuation_field),
233813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                            generator, executing, effect, control);
233913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
234013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  ReplaceWithValue(node, continuation, effect, control);
234113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  return Changed(continuation);
234213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
234313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
234413e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochReduction JSTypedLowering::ReduceJSGeneratorRestoreRegister(Node* node) {
234513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  DCHECK_EQ(IrOpcode::kJSGeneratorRestoreRegister, node->opcode());
234613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Node* generator = NodeProperties::GetValueInput(node, 0);
234713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Node* effect = NodeProperties::GetEffectInput(node);
234813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Node* control = NodeProperties::GetControlInput(node);
234913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  int index = OpParameter<int>(node);
235013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
235162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  FieldAccess array_field = AccessBuilder::ForJSGeneratorObjectRegisterFile();
235213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  FieldAccess element_field = AccessBuilder::ForFixedArraySlot(index);
235313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
235413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Node* array = effect = graph()->NewNode(simplified()->LoadField(array_field),
235513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                          generator, effect, control);
235613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Node* element = effect = graph()->NewNode(
235713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      simplified()->LoadField(element_field), array, effect, control);
235813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Node* stale = jsgraph()->StaleRegisterConstant();
235913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  effect = graph()->NewNode(simplified()->StoreField(element_field), array,
236013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                            stale, effect, control);
236113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
236213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  ReplaceWithValue(node, element, effect, control);
236313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  return Changed(element);
236413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
2365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochReduction JSTypedLowering::Reduce(Node* node) {
2367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (node->opcode()) {
2368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case IrOpcode::kJSEqual:
2369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return ReduceJSEqual(node, false);
2370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case IrOpcode::kJSNotEqual:
2371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return ReduceJSEqual(node, true);
2372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case IrOpcode::kJSStrictEqual:
2373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return ReduceJSStrictEqual(node, false);
2374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case IrOpcode::kJSStrictNotEqual:
2375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return ReduceJSStrictEqual(node, true);
2376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case IrOpcode::kJSLessThan:         // fall through
2377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case IrOpcode::kJSGreaterThan:      // fall through
2378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case IrOpcode::kJSLessThanOrEqual:  // fall through
2379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case IrOpcode::kJSGreaterThanOrEqual:
2380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return ReduceJSComparison(node);
2381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case IrOpcode::kJSBitwiseOr:
2382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case IrOpcode::kJSBitwiseXor:
2383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case IrOpcode::kJSBitwiseAnd:
2384f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      return ReduceInt32Binop(node);
2385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case IrOpcode::kJSShiftLeft:
2386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case IrOpcode::kJSShiftRight:
2387f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      return ReduceUI32Shift(node, kSigned);
2388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case IrOpcode::kJSShiftRightLogical:
2389f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      return ReduceUI32Shift(node, kUnsigned);
2390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case IrOpcode::kJSAdd:
2391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return ReduceJSAdd(node);
2392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case IrOpcode::kJSSubtract:
2393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case IrOpcode::kJSMultiply:
2394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case IrOpcode::kJSDivide:
2395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case IrOpcode::kJSModulus:
2396f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      return ReduceNumberBinop(node);
2397f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case IrOpcode::kJSOrdinaryHasInstance:
2398f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return ReduceJSOrdinaryHasInstance(node);
2399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case IrOpcode::kJSToBoolean:
2400958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      return ReduceJSToBoolean(node);
24013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case IrOpcode::kJSToInteger:
24023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      return ReduceJSToInteger(node);
24033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case IrOpcode::kJSToLength:
24043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      return ReduceJSToLength(node);
2405c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case IrOpcode::kJSToName:
2406c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      return ReduceJSToName(node);
2407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case IrOpcode::kJSToNumber:
2408958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      return ReduceJSToNumber(node);
2409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case IrOpcode::kJSToString:
2410958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      return ReduceJSToString(node);
2411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case IrOpcode::kJSToObject:
2412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return ReduceJSToObject(node);
2413c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case IrOpcode::kJSTypeOf:
2414c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      return ReduceJSTypeOf(node);
2415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case IrOpcode::kJSLoadNamed:
2416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return ReduceJSLoadNamed(node);
2417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case IrOpcode::kJSLoadProperty:
2418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return ReduceJSLoadProperty(node);
2419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case IrOpcode::kJSStoreProperty:
2420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return ReduceJSStoreProperty(node);
2421958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case IrOpcode::kJSLoadContext:
2422958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      return ReduceJSLoadContext(node);
2423958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case IrOpcode::kJSStoreContext:
2424958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      return ReduceJSStoreContext(node);
2425c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case IrOpcode::kJSLoadModule:
2426c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      return ReduceJSLoadModule(node);
2427c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case IrOpcode::kJSStoreModule:
2428c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      return ReduceJSStoreModule(node);
2429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case IrOpcode::kJSConvertReceiver:
2430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return ReduceJSConvertReceiver(node);
243162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case IrOpcode::kJSConstruct:
243262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return ReduceJSConstruct(node);
243362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case IrOpcode::kJSCallForwardVarargs:
243462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return ReduceJSCallForwardVarargs(node);
243562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case IrOpcode::kJSCall:
243662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return ReduceJSCall(node);
2437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case IrOpcode::kJSForInNext:
2438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return ReduceJSForInNext(node);
243962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case IrOpcode::kJSLoadMessage:
244062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return ReduceJSLoadMessage(node);
244162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case IrOpcode::kJSStoreMessage:
244262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return ReduceJSStoreMessage(node);
244313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case IrOpcode::kJSGeneratorStore:
244413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      return ReduceJSGeneratorStore(node);
244513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case IrOpcode::kJSGeneratorRestoreContinuation:
244613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      return ReduceJSGeneratorRestoreContinuation(node);
244713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case IrOpcode::kJSGeneratorRestoreRegister:
244813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      return ReduceJSGeneratorRestoreRegister(node);
244962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // TODO(mstarzinger): Simplified operations hiding in JS-level reducer not
245062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // fooling anyone. Consider moving this into a separate reducer.
245162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case IrOpcode::kSpeculativeNumberAdd:
245262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return ReduceSpeculativeNumberAdd(node);
245362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case IrOpcode::kSpeculativeNumberSubtract:
245462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case IrOpcode::kSpeculativeNumberMultiply:
245562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case IrOpcode::kSpeculativeNumberDivide:
245662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case IrOpcode::kSpeculativeNumberModulus:
245762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return ReduceSpeculativeNumberBinop(node);
2458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    default:
2459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
2460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NoChange();
2462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2464958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2465958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierFactory* JSTypedLowering::factory() const { return jsgraph()->factory(); }
2466958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2467958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2468958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierGraph* JSTypedLowering::graph() const { return jsgraph()->graph(); }
2469958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2470958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochIsolate* JSTypedLowering::isolate() const { return jsgraph()->isolate(); }
2472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2474958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierJSOperatorBuilder* JSTypedLowering::javascript() const {
2475958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return jsgraph()->javascript();
2476958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
2477958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2478958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2479958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierCommonOperatorBuilder* JSTypedLowering::common() const {
2480958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return jsgraph()->common();
2481958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
2482958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochSimplifiedOperatorBuilder* JSTypedLowering::simplified() const {
2484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return jsgraph()->simplified();
2485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochCompilationDependencies* JSTypedLowering::dependencies() const {
2489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return dependencies_;
2490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace compiler
2493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace internal
2494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace v8
2495