Jlm
Loading...
Searching...
No Matches
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
12
13TEST(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
25 rvsdgModule.Rvsdg().GetRootRegion(),
26 LlvmLambdaOperation::Create(functionType, "f", Linkage::externalLinkage));
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
41 rvsdgModule.Rvsdg().GetRootRegion(),
42 LlvmLambdaOperation::Create(functionType, "f", Linkage::externalLinkage));
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
57 rvsdgModule.Rvsdg().GetRootRegion(),
58 LlvmLambdaOperation::Create(functionType, "f", Linkage::externalLinkage));
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
75TEST(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(),
88 LlvmLambdaOperation::Create(functionType, "f", Linkage::externalLinkage));
89 auto result = TestOperation::createNode(&rvsdg->GetRootRegion(), {}, { vt })->output(0);
90
91 EXPECT_THROW(lambdaNode->finalize({ result }), jlm::util::Error);
92}
93
97TEST(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(),
113 LlvmLambdaOperation::Create(functionType, "f", Linkage::externalLinkage));
114
115 auto lambdaBinder0 = lambdaNode->AddContextVar(*x);
116 auto lambdaBinder1 = lambdaNode->AddContextVar(*x);
117 lambdaNode->AddContextVar(*x);
118
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
167TEST(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(),
183 LlvmLambdaOperation::Create(functionType, "f", Linkage::externalLinkage));
184
185 lambdaNode->AddContextVar(*x);
186 auto lambdaInput1 = lambdaNode->AddContextVar(*x);
187 lambdaNode->AddContextVar(*x);
188
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)
static const auto vt
Definition PullTests.cpp:16
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:141
Graph & Rvsdg() noexcept
static std::shared_ptr< const TestType > createValueType()
Definition TestType.cpp:67
Global memory state passed between functions.
NodeType * TryGetOwnerNode(const rvsdg::Input &input) noexcept
Checks if this is an input to a node of specified type.
Definition node.hpp:872