summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/branch-elimination.h
blob: a7ac926c7abd767618166b7f24435540f540bb32 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_COMPILER_BRANCH_CONDITION_ELIMINATION_H_
#define V8_COMPILER_BRANCH_CONDITION_ELIMINATION_H_

#include "src/compiler/graph-reducer.h"

namespace v8 {
namespace internal {
namespace compiler {

class JSGraph;


class BranchElimination final : public AdvancedReducer {
 public:
  BranchElimination(Editor* editor, JSGraph* js_graph, Zone* zone);
  ~BranchElimination() final;

  Reduction Reduce(Node* node) final;

 private:
  struct BranchCondition {
    Node* condition;
    bool is_true;
    BranchCondition* next;

    BranchCondition(Node* condition, bool is_true, BranchCondition* next)
        : condition(condition), is_true(is_true), next(next) {}
  };

  // Class for tracking information about branch conditions.
  // At the moment it is a linked list of conditions and their values
  // (true or false).
  class ControlPathConditions {
   public:
    Maybe<bool> LookupCondition(Node* condition) const;

    const ControlPathConditions* AddCondition(Zone* zone, Node* condition,
                                              bool is_true) const;
    static const ControlPathConditions* Empty(Zone* zone);
    void Merge(const ControlPathConditions& other);

    bool operator==(const ControlPathConditions& other) const;
    bool operator!=(const ControlPathConditions& other) const {
      return !(*this == other);
    }

   private:
    ControlPathConditions(BranchCondition* head, size_t condition_count)
        : head_(head), condition_count_(condition_count) {}

    BranchCondition* head_;
    // We keep track of the list length so that we can find the longest
    // common tail easily.
    size_t condition_count_;
  };

  // Maps each control node to the condition information known about the node.
  // If the information is nullptr, then we have not calculated the information
  // yet.
  class PathConditionsForControlNodes {
   public:
    PathConditionsForControlNodes(Zone* zone, size_t size_hint)
        : info_for_node_(size_hint, nullptr, zone) {}
    const ControlPathConditions* Get(Node* node);
    void Set(Node* node, const ControlPathConditions* conditions);

   private:
    ZoneVector<const ControlPathConditions*> info_for_node_;
  };

  Reduction ReduceBranch(Node* node);
  Reduction ReduceIf(Node* node, bool is_true_branch);
  Reduction ReduceLoop(Node* node);
  Reduction ReduceMerge(Node* node);
  Reduction ReduceStart(Node* node);
  Reduction ReduceOtherControl(Node* node);

  Reduction TakeConditionsFromFirstControl(Node* node);
  Reduction UpdateConditions(Node* node,
                             const ControlPathConditions* conditions);

  Node* dead() const { return dead_; }

  PathConditionsForControlNodes node_conditions_;
  Zone* zone_;
  Node* dead_;
};

}  // namespace compiler
}  // namespace internal
}  // namespace v8

#endif  // V8_COMPILER_BRANCH_CONDITION_ELIMINATION_H_