Jlm
PullTests.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2017 Nico Reißmann <nico.reissmann@gmail.com>
3  * See COPYING for terms of redistribution.
4  */
5 
6 #include <gtest/gtest.h>
7 
9 #include <jlm/llvm/opt/pull.hpp>
10 #include <jlm/rvsdg/gamma.hpp>
12 #include <jlm/rvsdg/TestType.hpp>
13 #include <jlm/rvsdg/view.hpp>
14 #include <jlm/util/Statistics.hpp>
15 
18 
19 TEST(NodeSinkingTests, testPullInTop)
20 {
21  using namespace jlm::llvm;
22  using namespace jlm::rvsdg;
23 
25  TestOperation uop({ vt }, { vt });
26  TestOperation bop({ vt, vt }, { vt });
27  TestOperation cop({ ct, vt }, { ct });
28 
30  auto & graph = rm.Rvsdg();
31 
32  auto c = &jlm::rvsdg::GraphImport::Create(graph, ct, "c");
33  auto x = &jlm::rvsdg::GraphImport::Create(graph, vt, "x");
34 
35  auto n1 = TestOperation::createNode(&graph.GetRootRegion(), { x }, { vt })->output(0);
36  auto n2 = TestOperation::createNode(&graph.GetRootRegion(), { x }, { vt })->output(0);
37  auto n3 = TestOperation::createNode(&graph.GetRootRegion(), { n2 }, { vt })->output(0);
38  auto n4 = TestOperation::createNode(&graph.GetRootRegion(), { c, n1 }, { ct })->output(0);
39  auto n5 = TestOperation::createNode(&graph.GetRootRegion(), { n1, n3 }, { vt })->output(0);
40 
41  auto gamma = jlm::rvsdg::GammaNode::create(n4, 2);
42 
43  gamma->AddEntryVar(n4);
44  auto ev = gamma->AddEntryVar(n5);
45  gamma->AddExitVar(ev.branchArgument);
46 
47  jlm::rvsdg::GraphExport::Create(*gamma->output(0), "x");
49 
50  // jlm::rvsdg::view(graph, stdout);
51  pullin_top(gamma);
52  // jlm::rvsdg::view(graph, stdout);
53 
54  EXPECT_EQ(gamma->subregion(0)->numNodes(), 2u);
55  EXPECT_EQ(gamma->subregion(1)->numNodes(), 2u);
56 }
57 
58 TEST(NodeSinkingTests, testPullInBottom)
59 {
60  using namespace jlm::llvm;
61  using namespace jlm::rvsdg;
62 
63  // Arrange
64  auto valueType = TestType::createValueType();
65  const auto controlType = ControlType::Create(2);
66 
67  Graph rvsdg;
68  auto c = &jlm::rvsdg::GraphImport::Create(rvsdg, controlType, "c");
69  auto x = &jlm::rvsdg::GraphImport::Create(rvsdg, valueType, "x");
70 
71  auto gammaNode = GammaNode::create(c, 2);
72 
73  auto entryVar = gammaNode->AddEntryVar(x);
74  gammaNode->AddExitVar(entryVar.branchArgument);
75 
76  auto node1 =
77  TestOperation::createNode(&rvsdg.GetRootRegion(), { gammaNode->output(0), x }, { valueType });
78  auto node2 = TestOperation::createNode(
79  &rvsdg.GetRootRegion(),
80  { gammaNode->output(0), node1->output(0) },
81  { valueType });
82 
83  auto & xp = GraphExport::Create(*node2->output(0), "x");
84 
85  view(rvsdg, stdout);
86 
87  // Act
88  const auto sunkNodes = NodeSinking::sinkDependentNodesIntoGamma(*gammaNode);
89  rvsdg.PruneNodes();
90 
91  view(rvsdg, stdout);
92 
93  // Assert
94  EXPECT_EQ(sunkNodes, 2u);
95  EXPECT_EQ(rvsdg.GetRootRegion().numNodes(), 1u);
96 
97  EXPECT_EQ(jlm::rvsdg::TryGetOwnerNode<jlm::rvsdg::Node>(*xp.origin()), gammaNode);
98  EXPECT_EQ(gammaNode->subregion(0)->numNodes(), 2u);
99  EXPECT_EQ(gammaNode->subregion(1)->numNodes(), 2u);
100 }
101 
102 TEST(NodeSinkingTests, testPull)
103 {
104  using namespace jlm::llvm;
105  using namespace jlm::rvsdg;
106 
108  auto & graph = rm.Rvsdg();
109 
111 
112  auto croot = TestOperation::createNode(&graph.GetRootRegion(), {}, { vt })->output(0);
113 
114  /* outer gamma */
115  auto gamma1 = jlm::rvsdg::GammaNode::create(p, 2);
116  auto ev1 = gamma1->AddEntryVar(p);
117  auto ev2 = gamma1->AddEntryVar(croot);
118 
119  auto cg1 = TestOperation::createNode(gamma1->subregion(0), {}, { vt })->output(0);
120 
121  /* inner gamma */
122  auto gamma2 = jlm::rvsdg::GammaNode::create(ev1.branchArgument[1], 2);
123  auto ev3 = gamma2->AddEntryVar(ev2.branchArgument[1]);
124  auto cg2 = TestOperation::createNode(gamma2->subregion(0), {}, { vt })->output(0);
125  auto un =
126  TestOperation::createNode(gamma2->subregion(1), { ev3.branchArgument[1] }, { vt })->output(0);
127  auto g2xv = gamma2->AddExitVar({ cg2, un });
128 
129  auto g1xv = gamma1->AddExitVar({ cg1, g2xv.output });
130 
131  jlm::rvsdg::GraphExport::Create(*g1xv.output, "");
132 
133  jlm::rvsdg::view(graph, stdout);
134  jlm::llvm::NodeSinking pullin;
135  pullin.Run(rm, statisticsCollector);
136  graph.PruneNodes();
137  jlm::rvsdg::view(graph, stdout);
138 
139  EXPECT_EQ(graph.GetRootRegion().numNodes(), 1u);
140 }
static const auto vt
Definition: PullTests.cpp:16
static jlm::util::StatisticsCollector statisticsCollector
Definition: PullTests.cpp:17
TEST(NodeSinkingTests, testPullInTop)
Definition: PullTests.cpp:19
Node Sinking Optimization.
Definition: pull.hpp:24
void Run(rvsdg::RvsdgModule &module, util::StatisticsCollector &statisticsCollector) override
Perform RVSDG transformation.
Definition: pull.cpp:399
static size_t sinkDependentNodesIntoGamma(rvsdg::GammaNode &gammaNode)
Definition: pull.cpp:216
static std::shared_ptr< const ControlType > Create(std::size_t nalternatives)
Instantiates control type.
Definition: control.cpp:50
static GammaNode * create(jlm::rvsdg::Output *predicate, size_t nalternatives)
Definition: gamma.hpp:161
static GraphExport & Create(Output &origin, std::string name)
Definition: graph.cpp:62
static GraphImport & Create(Graph &graph, std::shared_ptr< const rvsdg::Type > type, std::string name)
Definition: graph.cpp:36
void PruneNodes()
Definition: graph.hpp:116
Region & GetRootRegion() const noexcept
Definition: graph.hpp:99
size_t numNodes() const noexcept
Definition: region.hpp:481
Graph & Rvsdg() noexcept
Definition: RvsdgModule.hpp:57
static std::shared_ptr< const TestType > createValueType()
Definition: TestType.cpp:67
Global memory state passed between functions.
void pullin_top(rvsdg::GammaNode *gamma)
Definition: pull.cpp:135
std::string view(const rvsdg::Region *region)
Definition: view.cpp:142