1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_COMPILER_DIAMOND_H_
6 #define V8_COMPILER_DIAMOND_H_
7 
8 #include "src/compiler/common-operator.h"
9 #include "src/compiler/graph.h"
10 #include "src/compiler/node.h"
11 
12 namespace v8 {
13 namespace internal {
14 namespace compiler {
15 
16 // A helper to make it easier to build diamond-shaped control patterns.
17 struct Diamond {
18   Graph* graph;
19   CommonOperatorBuilder* common;
20   Node* branch;
21   Node* if_true;
22   Node* if_false;
23   Node* merge;
24 
25   Diamond(Graph* g, CommonOperatorBuilder* b, Node* cond,
26           BranchHint hint = BranchHint::kNone) {
27     graph = g;
28     common = b;
29     branch = graph->NewNode(common->Branch(hint), cond, graph->start());
30     if_true = graph->NewNode(common->IfTrue(), branch);
31     if_false = graph->NewNode(common->IfFalse(), branch);
32     merge = graph->NewNode(common->Merge(2), if_true, if_false);
33   }
34 
35   // Place {this} after {that} in control flow order.
36   void Chain(Diamond& that) { branch->ReplaceInput(1, that.merge); }
37 
38   // Place {this} after {that} in control flow order.
39   void Chain(Node* that) { branch->ReplaceInput(1, that); }
40 
41   // Nest {this} into either the if_true or if_false branch of {that}.
42   void Nest(Diamond& that, bool if_true) {
43     if (if_true) {
44       branch->ReplaceInput(1, that.if_true);
45       that.merge->ReplaceInput(0, merge);
46     } else {
47       branch->ReplaceInput(1, that.if_false);
48       that.merge->ReplaceInput(1, merge);
49     }
50   }
51 
52   Node* Phi(MachineRepresentation rep, Node* tv, Node* fv) {
53     return graph->NewNode(common->Phi(rep, 2), tv, fv, merge);
54   }
55 };
56 
57 }  // namespace compiler
58 }  // namespace internal
59 }  // namespace v8
60 
61 #endif  // V8_COMPILER_DIAMOND_H_
62