Jlm
LoopUnswitchingTests.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 
10 #include <jlm/rvsdg/gamma.hpp>
12 #include <jlm/rvsdg/TestType.hpp>
13 #include <jlm/rvsdg/theta.hpp>
14 #include <jlm/rvsdg/view.hpp>
15 #include <jlm/util/Statistics.hpp>
16 
17 TEST(LoopUnswitchingTests, Test1)
18 {
19  using namespace jlm::llvm;
20  using namespace jlm::rvsdg;
21 
22  // Arrange
23  const auto valueType = TestType::createValueType();
24 
25  LlvmRvsdgModule rvsdgModule(jlm::util::FilePath(""), "", "");
26  auto & graph = rvsdgModule.Rvsdg();
27 
28  auto x = &GraphImport::Create(graph, valueType, "x");
29  auto y = &GraphImport::Create(graph, valueType, "y");
30  auto z = &GraphImport::Create(graph, valueType, "z");
31 
32  auto thetaNode = ThetaNode::create(&graph.GetRootRegion());
33 
34  auto loopVarX = thetaNode->AddLoopVar(x);
35  auto loopVarY = thetaNode->AddLoopVar(y);
36  thetaNode->AddLoopVar(z);
37 
38  auto a = TestOperation::createNode(
39  thetaNode->subregion(),
40  { loopVarX.pre, loopVarY.pre },
41  { BitType::Create(1) })
42  ->output(0);
43  auto & predicateNode = MatchOperation::CreateNode(*a, { { 1, 0 } }, 1, 2);
44 
45  auto gamma = GammaNode::create(predicateNode.output(0), 2);
46 
47  auto entryVarX = gamma->AddEntryVar(loopVarX.pre);
48  auto entryVarY = gamma->AddEntryVar(loopVarY.pre);
49 
50  auto b = TestOperation::createNode(
51  gamma->subregion(0),
52  { entryVarX.branchArgument[0], entryVarY.branchArgument[0] },
53  { valueType })
54  ->output(0);
55  auto c = TestOperation::createNode(
56  gamma->subregion(1),
57  { entryVarX.branchArgument[1], entryVarY.branchArgument[1] },
58  { valueType })
59  ->output(0);
60 
61  auto exitVarY = gamma->AddExitVar({ b, c });
62 
63  loopVarY.post->divert_to(exitVarY.output);
64 
65  thetaNode->set_predicate(predicateNode.output(0));
66 
67  auto & ex1 = GraphExport::Create(*thetaNode->output(0), "x");
68  auto & ex2 = GraphExport::Create(*thetaNode->output(1), "y");
69  auto & ex3 = GraphExport::Create(*thetaNode->output(2), "z");
70 
71  view(&graph.GetRootRegion(), stdout);
72 
73  // Act
76  rvsdgModule,
79 
80  view(&graph.GetRootRegion(), stdout);
81 
82  // Assert
83  EXPECT_NE(jlm::rvsdg::TryGetOwnerNode<jlm::rvsdg::GammaNode>(*ex1.origin()), nullptr);
84  auto [testNode, testOperation] = TryGetSimpleNodeAndOptionalOp<TestOperation>(*ex2.origin());
85  EXPECT_NE(testNode, nullptr);
86  EXPECT_NE(testOperation, nullptr);
87  EXPECT_NE(jlm::rvsdg::TryGetOwnerNode<jlm::rvsdg::GammaNode>(*ex3.origin()), nullptr);
88 }
89 
90 TEST(LoopUnswitchingTests, Test2)
91 {
92  using namespace jlm::llvm;
93  using namespace jlm::rvsdg;
94 
95  // Arrange
96  const auto valueType = TestType::createValueType();
97 
98  LlvmRvsdgModule rvsdgModule(jlm::util::FilePath(""), "", "");
99  auto & graph = rvsdgModule.Rvsdg();
100 
101  auto x = &GraphImport::Create(graph, valueType, "x");
102 
103  auto thetaNode = ThetaNode::create(&graph.GetRootRegion());
104 
105  auto loopVarX = thetaNode->AddLoopVar(x);
106 
107  auto n1 =
108  TestOperation::createNode(thetaNode->subregion(), { loopVarX.pre }, { BitType::Create(1) })
109  ->output(0);
110  auto n2 =
111  TestOperation::createNode(thetaNode->subregion(), { loopVarX.pre }, { valueType })->output(0);
112  auto & predicateNode = MatchOperation::CreateNode(*n1, { { 1, 0 } }, 1, 2);
113 
114  auto gammaNode = GammaNode::create(predicateNode.output(0), 2);
115 
116  auto ev1 = gammaNode->AddEntryVar(n1);
117  auto ev2 = gammaNode->AddEntryVar(loopVarX.pre);
118  auto ev3 = gammaNode->AddEntryVar(n2);
119 
120  gammaNode->AddExitVar(ev1.branchArgument);
121  gammaNode->AddExitVar(ev2.branchArgument);
122  gammaNode->AddExitVar(ev3.branchArgument);
123 
124  loopVarX.post->divert_to(gammaNode->output(1));
125 
126  thetaNode->set_predicate(predicateNode.output(0));
127 
128  auto & ex = GraphExport::Create(*thetaNode->output(0), "x");
129 
130  view(&graph.GetRootRegion(), stdout);
131 
132  // Act
135  rvsdgModule,
138 
139  view(&graph.GetRootRegion(), stdout);
140 
141  // Assert
142  EXPECT_NE(jlm::rvsdg::TryGetOwnerNode<jlm::rvsdg::GammaNode>(*ex.origin()), nullptr);
143 }
static jlm::util::StatisticsCollector statisticsCollector
TEST(LoopUnswitchingTests, Test1)
static std::shared_ptr< const LoopUnswitchingDefaultHeuristic > create()
static void CreateAndRun(rvsdg::RvsdgModule &rvsdgModule, util::StatisticsCollector &statisticsCollector, std::shared_ptr< const LoopUnswitchingHeuristic > heuristic)
Graph & Rvsdg() noexcept
Definition: RvsdgModule.hpp:57
Global memory state passed between functions.
std::string view(const rvsdg::Region *region)
Definition: view.cpp:142