Home | History | Annotate | Download | only in compiler
      1 // Copyright 2014 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 #include "src/compiler/common-operator.h"
      6 #include "src/compiler/diamond.h"
      7 #include "test/unittests/compiler/graph-unittest.h"
      8 #include "test/unittests/compiler/node-test-utils.h"
      9 #include "testing/gmock-support.h"
     10 
     11 using testing::AllOf;
     12 using testing::Capture;
     13 using testing::CaptureEq;
     14 
     15 namespace v8 {
     16 namespace internal {
     17 namespace compiler {
     18 
     19 class DiamondTest : public GraphTest {
     20  public:
     21   DiamondTest() : GraphTest(5) {}
     22 };
     23 
     24 
     25 TEST_F(DiamondTest, SimpleDiamond) {
     26   Node* p = Parameter(0);
     27   Diamond d(graph(), common(), p);
     28   EXPECT_THAT(d.branch, IsBranch(p, graph()->start()));
     29   EXPECT_THAT(d.if_true, IsIfTrue(d.branch));
     30   EXPECT_THAT(d.if_false, IsIfFalse(d.branch));
     31   EXPECT_THAT(d.merge, IsMerge(d.if_true, d.if_false));
     32 }
     33 
     34 
     35 TEST_F(DiamondTest, DiamondChainDiamond) {
     36   Node* p0 = Parameter(0);
     37   Node* p1 = Parameter(1);
     38   Diamond d0(graph(), common(), p0);
     39   Diamond d1(graph(), common(), p1);
     40   d1.Chain(d0);
     41   EXPECT_THAT(d1.branch, IsBranch(p1, d0.merge));
     42   EXPECT_THAT(d0.branch, IsBranch(p0, graph()->start()));
     43 }
     44 
     45 
     46 TEST_F(DiamondTest, DiamondChainNode) {
     47   Node* p1 = Parameter(1);
     48   Diamond d1(graph(), common(), p1);
     49   Node* other = graph()->NewNode(common()->Merge(0));
     50   d1.Chain(other);
     51   EXPECT_THAT(d1.branch, IsBranch(p1, other));
     52 }
     53 
     54 
     55 TEST_F(DiamondTest, DiamondChainN) {
     56   Node* params[5] = {Parameter(0), Parameter(1), Parameter(2), Parameter(3),
     57                      Parameter(4)};
     58   Diamond d[5] = {Diamond(graph(), common(), params[0]),
     59                   Diamond(graph(), common(), params[1]),
     60                   Diamond(graph(), common(), params[2]),
     61                   Diamond(graph(), common(), params[3]),
     62                   Diamond(graph(), common(), params[4])};
     63 
     64   for (int i = 1; i < 5; i++) {
     65     d[i].Chain(d[i - 1]);
     66     EXPECT_THAT(d[i].branch, IsBranch(params[i], d[i - 1].merge));
     67   }
     68 }
     69 
     70 
     71 TEST_F(DiamondTest, DiamondNested_true) {
     72   Node* p0 = Parameter(0);
     73   Node* p1 = Parameter(1);
     74   Diamond d0(graph(), common(), p0);
     75   Diamond d1(graph(), common(), p1);
     76 
     77   d1.Nest(d0, true);
     78 
     79   EXPECT_THAT(d0.branch, IsBranch(p0, graph()->start()));
     80   EXPECT_THAT(d0.if_true, IsIfTrue(d0.branch));
     81   EXPECT_THAT(d0.if_false, IsIfFalse(d0.branch));
     82   EXPECT_THAT(d0.merge, IsMerge(d1.merge, d0.if_false));
     83 
     84   EXPECT_THAT(d1.branch, IsBranch(p1, d0.if_true));
     85   EXPECT_THAT(d1.if_true, IsIfTrue(d1.branch));
     86   EXPECT_THAT(d1.if_false, IsIfFalse(d1.branch));
     87   EXPECT_THAT(d1.merge, IsMerge(d1.if_true, d1.if_false));
     88 }
     89 
     90 
     91 TEST_F(DiamondTest, DiamondNested_false) {
     92   Node* p0 = Parameter(0);
     93   Node* p1 = Parameter(1);
     94   Diamond d0(graph(), common(), p0);
     95   Diamond d1(graph(), common(), p1);
     96 
     97   d1.Nest(d0, false);
     98 
     99   EXPECT_THAT(d0.branch, IsBranch(p0, graph()->start()));
    100   EXPECT_THAT(d0.if_true, IsIfTrue(d0.branch));
    101   EXPECT_THAT(d0.if_false, IsIfFalse(d0.branch));
    102   EXPECT_THAT(d0.merge, IsMerge(d0.if_true, d1.merge));
    103 
    104   EXPECT_THAT(d1.branch, IsBranch(p1, d0.if_false));
    105   EXPECT_THAT(d1.if_true, IsIfTrue(d1.branch));
    106   EXPECT_THAT(d1.if_false, IsIfFalse(d1.branch));
    107   EXPECT_THAT(d1.merge, IsMerge(d1.if_true, d1.if_false));
    108 }
    109 
    110 
    111 TEST_F(DiamondTest, DiamondPhis) {
    112   Node* p0 = Parameter(0);
    113   Node* p1 = Parameter(1);
    114   Node* p2 = Parameter(2);
    115   Diamond d(graph(), common(), p0);
    116 
    117   MachineRepresentation types[] = {MachineRepresentation::kTagged,
    118                                    MachineRepresentation::kWord32};
    119 
    120   for (size_t i = 0; i < arraysize(types); i++) {
    121     Node* phi = d.Phi(types[i], p1, p2);
    122 
    123     EXPECT_THAT(d.branch, IsBranch(p0, graph()->start()));
    124     EXPECT_THAT(d.if_true, IsIfTrue(d.branch));
    125     EXPECT_THAT(d.if_false, IsIfFalse(d.branch));
    126     EXPECT_THAT(d.merge, IsMerge(d.if_true, d.if_false));
    127     EXPECT_THAT(phi, IsPhi(types[i], p1, p2, d.merge));
    128   }
    129 }
    130 
    131 
    132 TEST_F(DiamondTest, BranchHint) {
    133   Diamond dn(graph(), common(), Parameter(0));
    134   CHECK(BranchHint::kNone == BranchHintOf(dn.branch->op()));
    135 
    136   Diamond dt(graph(), common(), Parameter(0), BranchHint::kTrue);
    137   CHECK(BranchHint::kTrue == BranchHintOf(dt.branch->op()));
    138 
    139   Diamond df(graph(), common(), Parameter(0), BranchHint::kFalse);
    140   CHECK(BranchHint::kFalse == BranchHintOf(df.branch->op()));
    141 }
    142 
    143 
    144 }  // namespace compiler
    145 }  // namespace internal
    146 }  // namespace v8
    147