Jlm
LambdaTests.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2020 Nico Reißmann <nico.reissmann@gmail.com>
3  * See COPYING for terms of redistribution.
4  */
5 
6 #include <gtest/gtest.h>
7 
11 #include <jlm/rvsdg/TestType.hpp>
12 
13 TEST(LambdaTests, TestArgumentIterators)
14 {
15  using namespace jlm::llvm;
16  using namespace jlm::rvsdg;
17 
19  jlm::llvm::LlvmRvsdgModule rvsdgModule(jlm::util::FilePath(""), "", "");
20 
21  {
22  auto functionType = jlm::rvsdg::FunctionType::Create({ vt }, { vt });
23 
24  auto lambda = jlm::rvsdg::LambdaNode::Create(
25  rvsdgModule.Rvsdg().GetRootRegion(),
27  lambda->finalize({ lambda->GetFunctionArguments()[0] });
28 
29  std::vector<const jlm::rvsdg::Output *> functionArguments;
30  for (auto argument : lambda->GetFunctionArguments())
31  functionArguments.push_back(argument);
32 
33  EXPECT_EQ(functionArguments.size(), 1u);
34  EXPECT_EQ(functionArguments[0], lambda->GetFunctionArguments()[0]);
35  }
36 
37  {
38  auto functionType = jlm::rvsdg::FunctionType::Create({}, { vt });
39 
40  auto lambda = jlm::rvsdg::LambdaNode::Create(
41  rvsdgModule.Rvsdg().GetRootRegion(),
43 
44  auto nullaryNode = TestOperation::createNode(lambda->subregion(), {}, { vt })->output(0);
45 
46  lambda->finalize({ nullaryNode });
47 
48  EXPECT_TRUE(lambda->GetFunctionArguments().empty());
49  }
50 
51  {
52  auto rvsdgImport = &jlm::rvsdg::GraphImport::Create(rvsdgModule.Rvsdg(), vt, "");
53 
54  auto functionType = jlm::rvsdg::FunctionType::Create({ vt, vt, vt }, { vt, vt });
55 
56  auto lambda = jlm::rvsdg::LambdaNode::Create(
57  rvsdgModule.Rvsdg().GetRootRegion(),
59 
60  auto cv = lambda->AddContextVar(*rvsdgImport).inner;
61 
62  lambda->finalize({ lambda->GetFunctionArguments()[0], cv });
63 
64  std::vector<const jlm::rvsdg::Output *> functionArguments;
65  for (auto argument : lambda->GetFunctionArguments())
66  functionArguments.push_back(argument);
67 
68  EXPECT_EQ(functionArguments.size(), 3u);
69  EXPECT_EQ(functionArguments[0], lambda->GetFunctionArguments()[0]);
70  EXPECT_EQ(functionArguments[1], lambda->GetFunctionArguments()[1]);
71  EXPECT_EQ(functionArguments[2], lambda->GetFunctionArguments()[2]);
72  }
73 }
74 
75 TEST(LambdaTests, TestInvalidOperandRegion)
76 {
77  using namespace jlm::llvm;
78  using namespace jlm::rvsdg;
79 
81  auto functionType = jlm::rvsdg::FunctionType::Create({}, { vt });
82 
83  auto rvsdgModule = jlm::llvm::LlvmRvsdgModule::Create(jlm::util::FilePath(""), "", "");
84  auto rvsdg = &rvsdgModule->Rvsdg();
85 
86  auto lambdaNode = jlm::rvsdg::LambdaNode::Create(
87  rvsdg->GetRootRegion(),
89  auto result = TestOperation::createNode(&rvsdg->GetRootRegion(), {}, { vt })->output(0);
90 
91  EXPECT_THROW(lambdaNode->finalize({ result }), jlm::util::Error);
92 }
93 
97 TEST(LambdaTests, TestRemoveLambdaInputsWhere)
98 {
99  using namespace jlm::llvm;
100  using namespace jlm::rvsdg;
101 
102  // Arrange
103  auto valueType = TestType::createValueType();
104  auto functionType = jlm::rvsdg::FunctionType::Create({}, { valueType });
105 
106  auto rvsdgModule = jlm::llvm::LlvmRvsdgModule::Create(jlm::util::FilePath(""), "", "");
107  auto & rvsdg = rvsdgModule->Rvsdg();
108 
109  auto x = &jlm::rvsdg::GraphImport::Create(rvsdg, valueType, "x");
110 
111  auto lambdaNode = jlm::rvsdg::LambdaNode::Create(
112  rvsdg.GetRootRegion(),
114 
115  auto lambdaBinder0 = lambdaNode->AddContextVar(*x);
116  auto lambdaBinder1 = lambdaNode->AddContextVar(*x);
117  lambdaNode->AddContextVar(*x);
118 
119  auto result = jlm::rvsdg::CreateOpNode<TestOperation>(
120  { lambdaBinder1.inner },
121  std::vector<std::shared_ptr<const Type>>{ valueType },
122  std::vector<std::shared_ptr<const Type>>{ valueType })
123  .output(0);
124 
125  lambdaNode->finalize({ result });
126 
127  // Act & Assert
128  // Try to remove lambdaInput1 even though it is used
129  auto numRemovedInputs = lambdaNode->RemoveLambdaInputsWhere(
130  [&](const jlm::rvsdg::Input & input)
131  {
132  return input.index() == lambdaBinder1.input->index();
133  });
134  EXPECT_EQ(numRemovedInputs, 0u);
135  EXPECT_EQ(lambdaNode->ninputs(), 3u);
136  EXPECT_EQ(lambdaNode->GetContextVars().size(), 3u);
137 
138  // Remove lambdaInput2
139  numRemovedInputs = lambdaNode->RemoveLambdaInputsWhere(
140  [&](const jlm::rvsdg::Input & input)
141  {
142  return input.index() == 2;
143  });
144  EXPECT_EQ(numRemovedInputs, 1u);
145  EXPECT_EQ(lambdaNode->ninputs(), 2u);
146  EXPECT_EQ(lambdaNode->GetContextVars().size(), 2u);
147  EXPECT_EQ(lambdaNode->input(0), lambdaBinder0.input);
148  EXPECT_EQ(lambdaNode->input(1), lambdaBinder1.input);
149 
150  // Remove lambdaInput0
151  numRemovedInputs = lambdaNode->RemoveLambdaInputsWhere(
152  [&](const jlm::rvsdg::Input & input)
153  {
154  return input.index() == 0;
155  });
156  EXPECT_EQ(numRemovedInputs, 1u);
157  EXPECT_EQ(lambdaNode->ninputs(), 1u);
158  EXPECT_EQ(lambdaNode->GetContextVars().size(), 1u);
159  EXPECT_EQ(lambdaNode->input(0), lambdaBinder1.input);
160  EXPECT_EQ(lambdaBinder1.input->index(), 0u);
161  EXPECT_EQ(lambdaBinder1.inner->index(), 0u);
162 }
163 
167 TEST(LambdaTests, TestPruneLambdaInputs)
168 {
169  using namespace jlm::llvm;
170  using namespace jlm::rvsdg;
171 
172  // Arrange
173  auto valueType = TestType::createValueType();
174  auto functionType = jlm::rvsdg::FunctionType::Create({}, { valueType });
175 
176  auto rvsdgModule = jlm::llvm::LlvmRvsdgModule::Create(jlm::util::FilePath(""), "", "");
177  auto & rvsdg = rvsdgModule->Rvsdg();
178 
179  auto x = &jlm::rvsdg::GraphImport::Create(rvsdg, valueType, "x");
180 
181  auto lambdaNode = jlm::rvsdg::LambdaNode::Create(
182  rvsdg.GetRootRegion(),
184 
185  lambdaNode->AddContextVar(*x);
186  auto lambdaInput1 = lambdaNode->AddContextVar(*x);
187  lambdaNode->AddContextVar(*x);
188 
189  auto result = jlm::rvsdg::CreateOpNode<TestOperation>(
190  { lambdaInput1.inner },
191  std::vector<std::shared_ptr<const Type>>{ valueType },
192  std::vector<std::shared_ptr<const Type>>{ valueType })
193  .output(0);
194 
195  lambdaNode->finalize({ result });
196 
197  // Act
198  auto numRemovedInputs = lambdaNode->PruneLambdaInputs();
199 
200  // Assert
201  EXPECT_EQ(numRemovedInputs, 2u);
202  EXPECT_EQ(lambdaNode->ninputs(), 1u);
203  EXPECT_EQ(lambdaNode->GetContextVars().size(), 1u);
204  EXPECT_EQ(lambdaNode->input(0), lambdaInput1.input);
205  EXPECT_EQ(lambdaNode->GetContextVars()[0].inner, lambdaInput1.inner);
206  EXPECT_EQ(lambdaInput1.input->index(), 0u);
207  EXPECT_EQ(lambdaInput1.inner->index(), 0u);
208 }
TEST(LambdaTests, TestArgumentIterators)
Definition: LambdaTests.cpp:13
static const auto vt
Definition: PullTests.cpp:16
static std::unique_ptr< LlvmLambdaOperation > Create(std::shared_ptr< const jlm::rvsdg::FunctionType > type, std::string name, const jlm::llvm::Linkage &linkage, jlm::llvm::CallingConvention callingConvention, jlm::llvm::AttributeSet attributes)
Definition: lambda.hpp:84
static std::unique_ptr< LlvmRvsdgModule > Create(const util::FilePath &sourceFileName, const std::string &targetTriple, const std::string &dataLayout)
static std::shared_ptr< const FunctionType > Create(std::vector< std::shared_ptr< const jlm::rvsdg::Type >> argumentTypes, std::vector< std::shared_ptr< const jlm::rvsdg::Type >> resultTypes)
static GraphImport & Create(Graph &graph, std::shared_ptr< const rvsdg::Type > type, std::string name)
Definition: graph.cpp:36
Region & GetRootRegion() const noexcept
Definition: graph.hpp:99
size_t index() const noexcept
Definition: node.hpp:52
static LambdaNode * Create(rvsdg::Region &parent, std::unique_ptr< LambdaOperation > operation)
Definition: lambda.cpp:140
Graph & Rvsdg() noexcept
Definition: RvsdgModule.hpp:57
static std::shared_ptr< const TestType > createValueType()
Definition: TestType.cpp:67
Global memory state passed between functions.