17d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Copyright 2013 the V8 project authors. All rights reserved.
27d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Use of this source code is governed by a BSD-style license that can be
37d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// found in the LICENSE file.
47d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
57d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#ifndef V8_COMPILER_GRAPH_BUILDER_H_
67d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#define V8_COMPILER_GRAPH_BUILDER_H_
77d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
87d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/v8.h"
97d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/allocation.h"
117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/common-operator.h"
127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/graph.h"
137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/unique.h"
147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgnamespace v8 {
167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgnamespace internal {
177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgnamespace compiler {
187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgclass Node;
207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// A common base class for anything that creates nodes in a graph.
227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgclass GraphBuilder {
237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public:
247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  explicit GraphBuilder(Graph* graph) : graph_(graph) {}
257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  virtual ~GraphBuilder() {}
267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
272c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  Node* NewNode(const Operator* op) {
287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    return MakeNode(op, 0, static_cast<Node**>(NULL));
297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
312c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  Node* NewNode(const Operator* op, Node* n1) { return MakeNode(op, 1, &n1); }
327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
332c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  Node* NewNode(const Operator* op, Node* n1, Node* n2) {
347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    Node* buffer[] = {n1, n2};
35fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org    return MakeNode(op, arraysize(buffer), buffer);
367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
382c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3) {
397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    Node* buffer[] = {n1, n2, n3};
40fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org    return MakeNode(op, arraysize(buffer), buffer);
417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
432c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4) {
447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    Node* buffer[] = {n1, n2, n3, n4};
45fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org    return MakeNode(op, arraysize(buffer), buffer);
467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
482c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                Node* n5) {
507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    Node* buffer[] = {n1, n2, n3, n4, n5};
51fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org    return MakeNode(op, arraysize(buffer), buffer);
527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
542c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
552c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org                Node* n5, Node* n6) {
567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    Node* nodes[] = {n1, n2, n3, n4, n5, n6};
57fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org    return MakeNode(op, arraysize(nodes), nodes);
587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
602c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  Node* NewNode(const Operator* op, int value_input_count,
612c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org                Node** value_inputs) {
627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    return MakeNode(op, value_input_count, value_inputs);
637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Graph* graph() const { return graph_; }
667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org protected:
687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Base implementation used by all factory methods.
692c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  virtual Node* MakeNode(const Operator* op, int value_input_count,
707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                         Node** value_inputs) = 0;
717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org private:
737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Graph* graph_;
747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org};
757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// The StructuredGraphBuilder produces a high-level IR graph. It is used as the
787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// base class for concrete implementations (e.g the AstGraphBuilder or the
797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// StubGraphBuilder).
807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgclass StructuredGraphBuilder : public GraphBuilder {
817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public:
827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  StructuredGraphBuilder(Graph* graph, CommonOperatorBuilder* common);
837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  virtual ~StructuredGraphBuilder() {}
847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Creates a new Phi node having {count} input values.
867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* NewPhi(int count, Node* input, Node* control);
877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* NewEffectPhi(int count, Node* input, Node* control);
887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Helpers for merging control, effect or value dependencies.
907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* MergeControl(Node* control, Node* other);
917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* MergeEffect(Node* value, Node* other, Node* control);
927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* MergeValue(Node* value, Node* other, Node* control);
937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Helpers to create new control nodes.
957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* NewIfTrue() { return NewNode(common()->IfTrue()); }
967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* NewIfFalse() { return NewNode(common()->IfFalse()); }
977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* NewMerge() { return NewNode(common()->Merge(1)); }
987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* NewLoop() { return NewNode(common()->Loop(1)); }
997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* NewBranch(Node* condition) {
1007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    return NewNode(common()->Branch(), condition);
1017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
1027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org protected:
1047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  class Environment;
105ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  friend class Environment;
1067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  friend class ControlBuilder;
1077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // The following method creates a new node having the specified operator and
1097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // ensures effect and control dependencies are wired up. The dependencies
1107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // tracked by the environment might be mutated.
1112c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  virtual Node* MakeNode(const Operator* op, int value_input_count,
1122c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org                         Node** value_inputs) FINAL;
1137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1148640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  Environment* environment() const { return environment_; }
1157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void set_environment(Environment* env) { environment_ = env; }
1167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* current_context() const { return current_context_; }
1187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void set_current_context(Node* context) { current_context_ = context; }
1197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* exit_control() const { return exit_control_; }
1217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void set_exit_control(Node* node) { exit_control_ = node; }
1227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* dead_control();
1247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // TODO(mstarzinger): Use phase-local zone instead!
1267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Zone* zone() const { return graph()->zone(); }
1277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Isolate* isolate() const { return zone()->isolate(); }
1287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CommonOperatorBuilder* common() const { return common_; }
1297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Helper to wrap a Handle<T> into a Unique<T>.
1317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  template <class T>
1321af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org  Unique<T> MakeUnique(Handle<T> object) {
1331af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org    return Unique<T>::CreateUninitialized(object);
1347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
1357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Support for control flow builders. The concrete type of the environment
1377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // depends on the graph builder, but environments themselves are not virtual.
1387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  virtual Environment* CopyEnvironment(Environment* env);
1397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Helper to indicate a node exits the function body.
1417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void UpdateControlDependencyToLeaveFunction(Node* exit);
1427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org private:
1447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CommonOperatorBuilder* common_;
1457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Environment* environment_;
1467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Node representing the control dependency for dead code.
1487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  SetOncePointer<Node> dead_control_;
1497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Node representing the current context within the function body.
1517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* current_context_;
1527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Merge of all control nodes that exit the function body.
1547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* exit_control_;
1557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  DISALLOW_COPY_AND_ASSIGN(StructuredGraphBuilder);
1577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org};
1587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// The abstract execution environment contains static knowledge about
1617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// execution state at arbitrary control-flow points. It allows for
1627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// simulation of the control-flow at compile time.
1637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgclass StructuredGraphBuilder::Environment : public ZoneObject {
1647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public:
1657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Environment(StructuredGraphBuilder* builder, Node* control_dependency);
1667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Environment(const Environment& copy);
1677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Control dependency tracked by this environment.
1697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* GetControlDependency() { return control_dependency_; }
1707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void UpdateControlDependency(Node* dependency) {
1717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    control_dependency_ = dependency;
1727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
1737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Effect dependency tracked by this environment.
1757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* GetEffectDependency() { return effect_dependency_; }
1767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void UpdateEffectDependency(Node* dependency) {
1777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    effect_dependency_ = dependency;
1787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
1797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Mark this environment as being unreachable.
1817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void MarkAsUnreachable() {
1827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    UpdateControlDependency(builder()->dead_control());
1837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
1847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  bool IsMarkedAsUnreachable() {
1857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    return GetControlDependency()->opcode() == IrOpcode::kDead;
1867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
1877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Merge another environment into this one.
1897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void Merge(Environment* other);
1907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Copies this environment at a control-flow split point.
1927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Environment* CopyForConditional() { return builder()->CopyEnvironment(this); }
1937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Copies this environment to a potentially unreachable control-flow point.
1957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Environment* CopyAsUnreachable() {
1967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    Environment* env = builder()->CopyEnvironment(this);
1977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    env->MarkAsUnreachable();
1987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    return env;
1997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
2007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Copies this environment at a loop header control-flow point.
2027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Environment* CopyForLoop() {
2037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    PrepareForLoop();
2047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    return builder()->CopyEnvironment(this);
2057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
2067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
207ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  Node* GetContext() { return builder_->current_context(); }
208ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org
2097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org protected:
2107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // TODO(mstarzinger): Use phase-local zone instead!
2117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Zone* zone() const { return graph()->zone(); }
2127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Graph* graph() const { return builder_->graph(); }
2137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  StructuredGraphBuilder* builder() const { return builder_; }
2147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CommonOperatorBuilder* common() { return builder_->common(); }
2157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  NodeVector* values() { return &values_; }
2167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Prepare environment to be used as loop header.
2187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void PrepareForLoop();
2197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org private:
2217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  StructuredGraphBuilder* builder_;
2227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* control_dependency_;
2237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* effect_dependency_;
2247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  NodeVector values_;
2257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org};
2267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
2277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
2287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}  // namespace v8::internal::compiler
2297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#endif  // V8_COMPILER_GRAPH_BUILDER_H__
231