Jlm
Loading...
Searching...
No Matches
MlirToJlmConverterTests.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2024 Louis Maurin <louis7maurin@gmail.com>
3 * Copyright 2024 Magnus Själander <work@sjalander.com>
4 * See COPYING for terms of redistribution.
5 */
6
7#include <gtest/gtest.h>
8
15
16#include <jlm/rvsdg/view.hpp>
17
18TEST(MlirToJlmConverterTests, TestLambda)
19{
20 {
21 using namespace mlir::rvsdg;
22 using namespace mlir::jlm;
23
24 // Setup MLIR Context and load dialects
25 std::cout << "Creating MLIR context" << std::endl;
26 auto context = std::make_unique<mlir::MLIRContext>();
27 context->getOrLoadDialect<RVSDGDialect>();
28 context->getOrLoadDialect<JLMDialect>();
29 context->getOrLoadDialect<mlir::arith::ArithDialect>();
30 context->getOrLoadDialect<mlir::LLVM::LLVMDialect>();
31 auto Builder_ = std::make_unique<mlir::OpBuilder>(context.get());
32
33 auto omega = Builder_->create<OmegaNode>(Builder_->getUnknownLoc());
34 auto & omegaRegion = omega.getRegion();
35 auto * omegaBlock = new mlir::Block;
36 omegaRegion.push_back(omegaBlock);
37
38 // Handle function arguments
39 std::cout << "Creating function arguments" << std::endl;
40 ::llvm::SmallVector<mlir::Type> arguments;
41 arguments.push_back(Builder_->getType<IOStateEdgeType>());
42 arguments.push_back(Builder_->getType<MemStateEdgeType>());
43 ::llvm::ArrayRef argumentsArray(arguments);
44
45 // Handle function results
46 std::cout << "Creating function results" << std::endl;
47 ::llvm::SmallVector<mlir::Type> results;
48 results.push_back(Builder_->getIntegerType(32));
49 results.push_back(Builder_->getType<IOStateEdgeType>());
50 results.push_back(Builder_->getType<MemStateEdgeType>());
51 ::llvm::ArrayRef resultsArray(results);
52
53 // Add function attributes
54 std::cout << "Creating function attributes" << std::endl;
55 ::llvm::SmallVector<mlir::NamedAttribute> attributes;
56 auto attributeName = Builder_->getStringAttr("sym_name");
57 auto attributeValue = Builder_->getStringAttr("test");
58 auto symbolName = Builder_->getNamedAttr(attributeName, attributeValue);
59 attributes.push_back(symbolName);
60 ::llvm::ArrayRef<::mlir::NamedAttribute> attributesRef(attributes);
61
62 // Add inputs to the function
63 ::llvm::SmallVector<mlir::Value> inputs;
64
65 // Create the lambda node and add it to the region/block it resides in
66 std::cout << "Creating LambdaNode" << std::endl;
67 auto lambda = Builder_->create<LambdaNode>(
68 Builder_->getUnknownLoc(),
69 Builder_->getType<mlir::FunctionType>(arguments, results),
70 inputs,
71 attributesRef);
72 omegaBlock->push_back(lambda);
73 auto & lambdaRegion = lambda.getRegion();
74 auto * lambdaBlock = new mlir::Block;
75 lambdaRegion.push_back(lambdaBlock);
76
77 // Add arguments to the region
78 std::cout << "Adding arguments to the region" << std::endl;
79 lambdaBlock->addArgument(Builder_->getType<IOStateEdgeType>(), Builder_->getUnknownLoc());
80 lambdaBlock->addArgument(Builder_->getType<MemStateEdgeType>(), Builder_->getUnknownLoc());
81
82 auto constOp = Builder_->create<mlir::arith::ConstantIntOp>(Builder_->getUnknownLoc(), 1, 32);
83 lambdaBlock->push_back(constOp);
84
85 ::llvm::SmallVector<mlir::Value> regionResults;
86 regionResults.push_back(constOp);
87 regionResults.push_back(lambdaBlock->getArgument(0));
88 regionResults.push_back(lambdaBlock->getArgument(1));
89
90 // Handle the result of the lambda
91 std::cout << "Creating LambdaResult" << std::endl;
92 auto lambdaResult = Builder_->create<LambdaResult>(Builder_->getUnknownLoc(), regionResults);
93 lambdaBlock->push_back(lambdaResult);
94
95 // Handle the result of the omega
96 std::cout << "Creating OmegaResult" << std::endl;
97 ::llvm::SmallVector<mlir::Value> omegaRegionResults;
98 omegaRegionResults.push_back(lambda.getResult());
99 ::llvm::SmallVector<mlir::Type> omegaResultTypes;
100 omegaResultTypes.push_back(lambda.getResult().getType());
101
102 // Create exportNames ArrayAttr
103 ::llvm::SmallVector<::mlir::Attribute> exportNamesList;
104 exportNamesList.push_back(Builder_->getStringAttr("test"));
105 auto exportNamesAttr = ::mlir::ArrayAttr::get(Builder_->getContext(), exportNamesList);
106 ::llvm::SmallVector<::mlir::NamedAttribute> namedAttrs;
107 namedAttrs.push_back({ Builder_->getStringAttr("exportNames"), exportNamesAttr });
108
109 auto omegaResult = Builder_->create<OmegaResult>(
110 Builder_->getUnknownLoc(),
111 omegaResultTypes,
112 omegaRegionResults,
113 namedAttrs);
114 omegaBlock->push_back(omegaResult);
115
116 std::unique_ptr<mlir::Block> rootBlock = std::make_unique<mlir::Block>();
117 rootBlock->push_back(omega);
118
119 // Convert the MLIR to RVSDG and check the result
120 std::cout << "Converting MLIR to RVSDG" << std::endl;
121 auto rvsdgModule = jlm::mlir::MlirToJlmConverter::CreateAndConvert(rootBlock);
122 auto region = &rvsdgModule->Rvsdg().GetRootRegion();
123 {
124 using namespace jlm::rvsdg;
125 std::cout << "Checking the result" << std::endl;
126
127 EXPECT_EQ(region->numNodes(), 1u);
128 auto convertedLambda =
129 jlm::util::assertedCast<jlm::rvsdg::LambdaNode>(region->Nodes().begin().ptr());
130 EXPECT_TRUE(is<jlm::llvm::LlvmLambdaOperation>(convertedLambda->GetOperation()));
131
132 EXPECT_EQ(convertedLambda->subregion()->numNodes(), 1u);
133 EXPECT_TRUE(is<jlm::llvm::IntegerConstantOperation>(
134 convertedLambda->subregion()->Nodes().begin().ptr()));
135 }
136 }
137}
138
145TEST(MlirToJlmConverterTests, TestDivOperation)
146{
147 {
148 using namespace mlir::rvsdg;
149 using namespace mlir::jlm;
150
151 // Setup MLIR Context and load dialects
152 std::cout << "Creating MLIR context" << std::endl;
153 auto context = std::make_unique<mlir::MLIRContext>();
154 context->getOrLoadDialect<RVSDGDialect>();
155 context->getOrLoadDialect<JLMDialect>();
156 context->getOrLoadDialect<mlir::arith::ArithDialect>();
157 context->getOrLoadDialect<mlir::LLVM::LLVMDialect>();
158 auto Builder_ = std::make_unique<mlir::OpBuilder>(context.get());
159
160 auto omega = Builder_->create<OmegaNode>(Builder_->getUnknownLoc());
161 auto & omegaRegion = omega.getRegion();
162 auto * omegaBlock = new mlir::Block;
163 omegaRegion.push_back(omegaBlock);
164
165 // Handle function arguments
166 std::cout << "Creating function arguments" << std::endl;
167 ::llvm::SmallVector<mlir::Type> arguments;
168 arguments.push_back(Builder_->getIntegerType(32));
169 arguments.push_back(Builder_->getType<IOStateEdgeType>());
170 arguments.push_back(Builder_->getType<MemStateEdgeType>());
171 ::llvm::ArrayRef argumentsArray(arguments);
172
173 // Handle function results
174 std::cout << "Creating function results" << std::endl;
175 ::llvm::SmallVector<mlir::Type> results;
176 results.push_back(Builder_->getIntegerType(32));
177 results.push_back(Builder_->getType<IOStateEdgeType>());
178 results.push_back(Builder_->getType<MemStateEdgeType>());
179 ::llvm::ArrayRef resultsArray(results);
180
181 // Add function attributes
182 std::cout << "Creating function attributes" << std::endl;
183 ::llvm::SmallVector<mlir::NamedAttribute> attributes;
184 auto attributeName = Builder_->getStringAttr("sym_name");
185 auto attributeValue = Builder_->getStringAttr("test");
186 auto symbolName = Builder_->getNamedAttr(attributeName, attributeValue);
187 attributes.push_back(symbolName);
188 ::llvm::ArrayRef<::mlir::NamedAttribute> attributesRef(attributes);
189
190 // Add inputs to the function
191 ::llvm::SmallVector<mlir::Value> inputs;
192
193 // Create the lambda node and add it to the region/block it resides in
194 std::cout << "Creating LambdaNode" << std::endl;
195 auto lambda = Builder_->create<LambdaNode>(
196 Builder_->getUnknownLoc(),
197 Builder_->getType<mlir::FunctionType>(arguments, results),
198 inputs,
199 attributesRef);
200 omegaBlock->push_back(lambda);
201 auto & lambdaRegion = lambda.getRegion();
202 auto * lambdaBlock = new mlir::Block;
203 lambdaRegion.push_back(lambdaBlock);
204
205 // Add arguments to the region
206 std::cout << "Adding arguments to the region" << std::endl;
207 lambdaBlock->addArgument(Builder_->getIntegerType(32), Builder_->getUnknownLoc());
208 lambdaBlock->addArgument(Builder_->getType<IOStateEdgeType>(), Builder_->getUnknownLoc());
209 lambdaBlock->addArgument(Builder_->getType<MemStateEdgeType>(), Builder_->getUnknownLoc());
210
211 // ConstOp1 is not connected to anything
212 auto constOp1 = Builder_->create<mlir::arith::ConstantIntOp>(Builder_->getUnknownLoc(), 20, 32);
213 lambdaBlock->push_back(constOp1);
214
215 // ConstOp2 is connected as second argument of the divide operation
216 auto constOp2 = Builder_->create<mlir::arith::ConstantIntOp>(Builder_->getUnknownLoc(), 5, 32);
217 lambdaBlock->push_back(constOp2);
218
219 // lambdaBlock->getArguments();
220 for (unsigned int i = 0; i < lambdaBlock->getNumArguments(); ++i)
221 {
222 auto arg = lambdaBlock->getArgument(i);
223 if (arg.getType().isa<IOStateEdgeType>())
224 {
225 std::cout << "Argument " << i << " is an IOStateEdgeType" << std::endl;
226 }
227 else if (arg.getType().isa<MemStateEdgeType>())
228 {
229 std::cout << "Argument " << i << " is a MemStateEdgeType" << std::endl;
230 }
231 else if (arg.getType().isa<mlir::IntegerType>())
232 {
233 std::cout << "Argument " << i << " is an IntegerType" << std::endl;
234 }
235 }
236
239 auto divideOp = Builder_->create<mlir::arith::DivUIOp>(
240 Builder_->getUnknownLoc(),
241 lambdaBlock->getArgument(0),
242 constOp2);
243 lambdaBlock->push_back(divideOp);
244
245 ::llvm::SmallVector<mlir::Value> regionResults;
246 regionResults.push_back(divideOp->getResult(0));
247 regionResults.push_back(lambdaBlock->getArgument(1));
248 regionResults.push_back(lambdaBlock->getArgument(2));
249
250 // Handle the result of the lambda
251 std::cout << "Creating LambdaResult" << std::endl;
252 auto lambdaResult = Builder_->create<LambdaResult>(Builder_->getUnknownLoc(), regionResults);
253 lambdaBlock->push_back(lambdaResult);
254
255 // Handle the result of the omega
256 std::cout << "Creating OmegaResult" << std::endl;
257 ::llvm::SmallVector<mlir::Value> omegaRegionResults;
258 omegaRegionResults.push_back(lambda.getResult());
259 ::llvm::SmallVector<mlir::Type> omegaResultTypes;
260 omegaResultTypes.push_back(lambda.getResult().getType());
261
262 // Create exportNames ArrayAttr
263 ::llvm::SmallVector<::mlir::Attribute> exportNamesList;
264 exportNamesList.push_back(Builder_->getStringAttr("test"));
265 auto exportNamesAttr = ::mlir::ArrayAttr::get(Builder_->getContext(), exportNamesList);
266 ::llvm::SmallVector<::mlir::NamedAttribute> namedAttrs;
267 namedAttrs.push_back({ Builder_->getStringAttr("exportNames"), exportNamesAttr });
268
269 auto omegaResult = Builder_->create<OmegaResult>(
270 Builder_->getUnknownLoc(),
271 omegaResultTypes,
272 omegaRegionResults,
273 namedAttrs);
274 omegaBlock->push_back(omegaResult);
275
276 std::unique_ptr<mlir::Block> rootBlock = std::make_unique<mlir::Block>();
277 rootBlock->push_back(omega);
278
279 // Convert the MLIR to RVSDG and check the result
280 std::cout << "Converting MLIR to RVSDG" << std::endl;
281 auto rvsdgModule = jlm::mlir::MlirToJlmConverter::CreateAndConvert(rootBlock);
282 auto region = &rvsdgModule->Rvsdg().GetRootRegion();
283
284 jlm::rvsdg::view(region, stdout);
285
286 {
287 using namespace jlm::rvsdg;
288
289 EXPECT_EQ(region->numNodes(), 1u);
290
291 // Get the lambda block
292 auto convertedLambda =
293 jlm::util::assertedCast<jlm::rvsdg::LambdaNode>(region->Nodes().begin().ptr());
294 EXPECT_TRUE(is<jlm::llvm::LlvmLambdaOperation>(convertedLambda));
295
296 // 2 Constants + 1 DivUIOp
297 EXPECT_EQ(convertedLambda->subregion()->numNodes(), 3u);
298
299 // Traverse the rvsgd graph upwards to check connections
300 NodeOutput * lambdaResultOriginNodeOutput =
301 dynamic_cast<jlm::rvsdg::NodeOutput *>(convertedLambda->subregion()->result(0)->origin());
302 EXPECT_NE(lambdaResultOriginNodeOutput, nullptr);
303 Node * lambdaResultOriginNode = lambdaResultOriginNodeOutput->node();
304 EXPECT_TRUE(is<jlm::llvm::IntegerUDivOperation>(lambdaResultOriginNode->GetOperation()));
305 EXPECT_EQ(lambdaResultOriginNode->ninputs(), 2u);
306
307 // Check first input
308 RegionArgument * DivInput0 =
309 dynamic_cast<jlm::rvsdg::RegionArgument *>(lambdaResultOriginNode->input(0)->origin());
310 EXPECT_NE(DivInput0, nullptr);
311 EXPECT_TRUE(jlm::rvsdg::is<BitType>(DivInput0->Type()));
312 EXPECT_EQ(std::dynamic_pointer_cast<const BitType>(DivInput0->Type())->nbits(), 32u);
313
314 // Check second input
316 *lambdaResultOriginNode->input(1)->origin());
317 EXPECT_NE(DivInput1Node, nullptr);
318 EXPECT_TRUE(is<jlm::llvm::IntegerConstantOperation>(DivInput1Node->GetOperation()));
319 auto DivInput1Constant =
320 dynamic_cast<const jlm::llvm::IntegerConstantOperation *>(&DivInput1Node->GetOperation());
321 EXPECT_EQ(DivInput1Constant->Representation().to_int(), 5u);
322 EXPECT_TRUE(is<const BitType>(DivInput1Constant->result(0)));
323 EXPECT_EQ(
324 std::dynamic_pointer_cast<const BitType>(DivInput1Constant->result(0))->nbits(),
325 32u);
326 }
327 }
328}
329
337TEST(MlirToJlmConverterTests, TestCompZeroExt)
338{
339 {
340 using namespace mlir::rvsdg;
341 using namespace mlir::jlm;
342
343 // Setup MLIR Context and load dialects
344 std::cout << "Creating MLIR context" << std::endl;
345 auto context = std::make_unique<mlir::MLIRContext>();
346 context->getOrLoadDialect<RVSDGDialect>();
347 context->getOrLoadDialect<JLMDialect>();
348 context->getOrLoadDialect<mlir::arith::ArithDialect>();
349 context->getOrLoadDialect<mlir::LLVM::LLVMDialect>();
350 auto Builder_ = std::make_unique<mlir::OpBuilder>(context.get());
351
352 auto omega = Builder_->create<OmegaNode>(Builder_->getUnknownLoc());
353 auto & omegaRegion = omega.getRegion();
354 auto * omegaBlock = new mlir::Block;
355 omegaRegion.push_back(omegaBlock);
356
357 // Handle function arguments
358 std::cout << "Creating function arguments" << std::endl;
359 ::llvm::SmallVector<mlir::Type> arguments;
360 arguments.push_back(Builder_->getIntegerType(32));
361 arguments.push_back(Builder_->getType<IOStateEdgeType>());
362 arguments.push_back(Builder_->getType<MemStateEdgeType>());
363 ::llvm::ArrayRef argumentsArray(arguments);
364
365 // Handle function results
366 std::cout << "Creating function results" << std::endl;
367 ::llvm::SmallVector<mlir::Type> results;
368 results.push_back(Builder_->getIntegerType(32));
369 results.push_back(Builder_->getType<IOStateEdgeType>());
370 results.push_back(Builder_->getType<MemStateEdgeType>());
371 ::llvm::ArrayRef resultsArray(results);
372
373 // Add function attributes
374 std::cout << "Creating function attributes" << std::endl;
375 ::llvm::SmallVector<mlir::NamedAttribute> attributes;
376 auto attributeName = Builder_->getStringAttr("sym_name");
377 auto attributeValue = Builder_->getStringAttr("test");
378 auto symbolName = Builder_->getNamedAttr(attributeName, attributeValue);
379 attributes.push_back(symbolName);
380 ::llvm::ArrayRef<::mlir::NamedAttribute> attributesRef(attributes);
381
382 // Add inputs to the function
383 ::llvm::SmallVector<mlir::Value> inputs;
384
385 // Create the lambda node and add it to the region/block it resides in
386 std::cout << "Creating LambdaNode" << std::endl;
387 auto lambda = Builder_->create<LambdaNode>(
388 Builder_->getUnknownLoc(),
389 Builder_->getType<mlir::FunctionType>(arguments, results),
390 inputs,
391 attributesRef);
392 omegaBlock->push_back(lambda);
393 auto & lambdaRegion = lambda.getRegion();
394 auto * lambdaBlock = new mlir::Block;
395 lambdaRegion.push_back(lambdaBlock);
396
397 // Add arguments to the region
398 std::cout << "Adding arguments to the region" << std::endl;
399 lambdaBlock->addArgument(Builder_->getIntegerType(32), Builder_->getUnknownLoc());
400 lambdaBlock->addArgument(Builder_->getType<IOStateEdgeType>(), Builder_->getUnknownLoc());
401 lambdaBlock->addArgument(Builder_->getType<MemStateEdgeType>(), Builder_->getUnknownLoc());
402
403 // ConstOp1 is connected to the second argument of the add operation
404 auto constOp1 = Builder_->create<mlir::arith::ConstantIntOp>(Builder_->getUnknownLoc(), 20, 32);
405 lambdaBlock->push_back(constOp1);
406
407 // ConstOp2 is connected as second argument of the compare operation
408 auto constOp2 = Builder_->create<mlir::arith::ConstantIntOp>(Builder_->getUnknownLoc(), 5, 32);
409 lambdaBlock->push_back(constOp2);
410
413 auto AddOp = Builder_->create<mlir::arith::AddIOp>(
414 Builder_->getUnknownLoc(),
415 lambdaBlock->getArgument(0),
416 constOp1);
417 lambdaBlock->push_back(AddOp);
418
419 auto compOp = Builder_->create<mlir::arith::CmpIOp>(
420 Builder_->getUnknownLoc(),
421 mlir::arith::CmpIPredicate::eq,
422 AddOp.getResult(),
423 constOp2);
424 lambdaBlock->push_back(compOp);
425
426 auto zeroExtOp = Builder_->create<mlir::arith::ExtUIOp>(
427 Builder_->getUnknownLoc(),
428 Builder_->getIntegerType(32),
429 compOp.getResult());
430 lambdaBlock->push_back(zeroExtOp);
431
432 // Handle the result of the lambda
433 ::llvm::SmallVector<mlir::Value> regionResults;
434 regionResults.push_back(zeroExtOp->getResult(0));
435 regionResults.push_back(lambdaBlock->getArgument(1));
436 regionResults.push_back(lambdaBlock->getArgument(2));
437 std::cout << "Creating LambdaResult" << std::endl;
438 auto lambdaResult = Builder_->create<LambdaResult>(Builder_->getUnknownLoc(), regionResults);
439 lambdaBlock->push_back(lambdaResult);
440
441 // Handle the result of the omega
442 std::cout << "Creating OmegaResult" << std::endl;
443 ::llvm::SmallVector<mlir::Value> omegaRegionResults;
444 omegaRegionResults.push_back(lambda.getResult());
445 ::llvm::SmallVector<mlir::Type> omegaResultTypes;
446 omegaResultTypes.push_back(lambda.getResult().getType());
447
448 // Create exportNames ArrayAttr
449 ::llvm::SmallVector<::mlir::Attribute> exportNamesList;
450 exportNamesList.push_back(Builder_->getStringAttr("test"));
451 auto exportNamesAttr = ::mlir::ArrayAttr::get(Builder_->getContext(), exportNamesList);
452 ::llvm::SmallVector<::mlir::NamedAttribute> namedAttrs;
453 namedAttrs.push_back({ Builder_->getStringAttr("exportNames"), exportNamesAttr });
454
455 auto omegaResult = Builder_->create<OmegaResult>(
456 Builder_->getUnknownLoc(),
457 omegaResultTypes,
458 omegaRegionResults,
459 namedAttrs);
460 omegaBlock->push_back(omegaResult);
461
462 std::unique_ptr<mlir::Block> rootBlock = std::make_unique<mlir::Block>();
463 rootBlock->push_back(omega);
464
465 // Convert the MLIR to RVSDG and check the result
466 std::cout << "Converting MLIR to RVSDG" << std::endl;
467 auto rvsdgModule = jlm::mlir::MlirToJlmConverter::CreateAndConvert(rootBlock);
468 auto region = &rvsdgModule->Rvsdg().GetRootRegion();
469
470 {
471 using namespace jlm::rvsdg;
472
473 std::cout << "Checking the result" << std::endl;
474
475 EXPECT_EQ(region->numNodes(), 1u);
476
477 // Get the lambda block
478 auto convertedLambda =
479 jlm::util::assertedCast<jlm::rvsdg::LambdaNode>(region->Nodes().begin().ptr());
480 EXPECT_TRUE(is<jlm::llvm::LlvmLambdaOperation>(convertedLambda));
481
482 // 2 Constants + AddOp + CompOp + ZeroExtOp
483 EXPECT_EQ(convertedLambda->subregion()->numNodes(), 5u);
484
485 // Traverse the rvsgd graph upwards to check connections
486 std::cout << "Testing lambdaResultOriginNodeOuput\n";
488 *convertedLambda->subregion()->result(0)->origin());
489 EXPECT_NE(ZExtNode, nullptr);
490 EXPECT_TRUE(is<jlm::llvm::ZExtOperation>(ZExtNode->GetOperation()));
491 EXPECT_EQ(ZExtNode->ninputs(), 1u);
492
493 // Check ZExt
494 auto ZExtOp = dynamic_cast<const jlm::llvm::ZExtOperation *>(&ZExtNode->GetOperation());
495 EXPECT_EQ(ZExtOp->nsrcbits(), 1u);
496 EXPECT_EQ(ZExtOp->ndstbits(), 32u);
497
498 // Check ZExt input
499 std::cout << "Testing input 0\n";
500 auto BitEqNode =
501 jlm::rvsdg::TryGetOwnerNode<jlm::rvsdg::SimpleNode>(*ZExtNode->input(0)->origin());
502 EXPECT_TRUE(is<jlm::llvm::IntegerEqOperation>(BitEqNode->GetOperation()));
503
504 // Check BitEq
505 EXPECT_EQ(
506 dynamic_cast<const jlm::llvm::IntegerEqOperation *>(&BitEqNode->GetOperation())
507 ->Type()
508 .nbits(),
509 32u);
510 EXPECT_EQ(BitEqNode->ninputs(), 2u);
511
512 // Check BitEq input 0
513 auto AddNode =
514 jlm::rvsdg::TryGetOwnerNode<jlm::rvsdg::SimpleNode>(*BitEqNode->input(0)->origin());
515 EXPECT_TRUE(is<jlm::llvm::IntegerAddOperation>(AddNode->GetOperation()));
516 EXPECT_EQ(AddNode->ninputs(), 2u);
517
518 // Check BitEq input 1
519 auto Const2Node =
520 jlm::rvsdg::TryGetOwnerNode<jlm::rvsdg::SimpleNode>(*BitEqNode->input(1)->origin());
521 EXPECT_TRUE(is<jlm::llvm::IntegerConstantOperation>(Const2Node->GetOperation()));
522
523 // Check Const2
524 auto Const2Op =
525 dynamic_cast<const jlm::llvm::IntegerConstantOperation *>(&Const2Node->GetOperation());
526 EXPECT_EQ(Const2Op->Representation().to_int(), 5u);
527 EXPECT_TRUE(is<const BitType>(Const2Op->result(0)));
528 EXPECT_EQ(std::dynamic_pointer_cast<const BitType>(Const2Op->result(0))->nbits(), 32u);
529
530 // Check add op
531 auto AddOp = dynamic_cast<const jlm::llvm::IntegerAddOperation *>(&AddNode->GetOperation());
532 EXPECT_EQ(AddOp->Type().nbits(), 32u);
533
534 // Check add input0
535 RegionArgument * AddInput0 =
536 dynamic_cast<jlm::rvsdg::RegionArgument *>(AddNode->input(0)->origin());
537 EXPECT_NE(AddInput0, nullptr);
538 EXPECT_TRUE(jlm::rvsdg::is<BitType>(AddInput0->Type()));
539 EXPECT_EQ(std::dynamic_pointer_cast<const BitType>(AddInput0->Type())->nbits(), 32u);
540
541 // Check add input1
542 auto Const1Node =
543 jlm::rvsdg::TryGetOwnerNode<jlm::rvsdg::SimpleNode>(*AddNode->input(1)->origin());
544 EXPECT_TRUE(is<jlm::llvm::IntegerConstantOperation>(Const1Node->GetOperation()));
545
546 // Check Const1
547 auto Const1Op =
548 dynamic_cast<const jlm::llvm::IntegerConstantOperation *>(&Const1Node->GetOperation());
549 EXPECT_EQ(Const1Op->Representation().to_int(), 20u);
550 EXPECT_TRUE(is<const BitType>(Const1Op->result(0)));
551 EXPECT_EQ(std::dynamic_pointer_cast<const BitType>(Const1Op->result(0))->nbits(), 32u);
552 }
553 }
554}
555
561TEST(MlirToJlmConverterTests, TestMatchOp)
562{
563 {
564 using namespace mlir::rvsdg;
565 using namespace mlir::jlm;
566
567 // Setup MLIR Context and load dialects
568 std::cout << "Creating MLIR context" << std::endl;
569 auto context = std::make_unique<mlir::MLIRContext>();
570 context->getOrLoadDialect<RVSDGDialect>();
571 context->getOrLoadDialect<JLMDialect>();
572 context->getOrLoadDialect<mlir::arith::ArithDialect>();
573 context->getOrLoadDialect<mlir::LLVM::LLVMDialect>();
574 auto Builder_ = std::make_unique<mlir::OpBuilder>(context.get());
575
576 auto omega = Builder_->create<OmegaNode>(Builder_->getUnknownLoc());
577 auto & omegaRegion = omega.getRegion();
578 auto * omegaBlock = new mlir::Block;
579 omegaRegion.push_back(omegaBlock);
580
581 // Handle function arguments
582 std::cout << "Creating function arguments" << std::endl;
583 ::llvm::SmallVector<mlir::Type> arguments;
584 arguments.push_back(Builder_->getIntegerType(32));
585 arguments.push_back(Builder_->getType<IOStateEdgeType>());
586 arguments.push_back(Builder_->getType<MemStateEdgeType>());
587 ::llvm::ArrayRef argumentsArray(arguments);
588
589 // Handle function results
590 std::cout << "Creating function results" << std::endl;
591 ::llvm::SmallVector<mlir::Type> results;
592 results.push_back(::mlir::rvsdg::RVSDG_CTRLType::get(Builder_->getContext(), 4));
593 results.push_back(Builder_->getType<IOStateEdgeType>());
594 results.push_back(Builder_->getType<MemStateEdgeType>());
595 ::llvm::ArrayRef resultsArray(results);
596
597 // Add function attributes
598 std::cout << "Creating function attributes" << std::endl;
599 ::llvm::SmallVector<mlir::NamedAttribute> attributes;
600 auto attributeName = Builder_->getStringAttr("sym_name");
601 auto attributeValue = Builder_->getStringAttr("test");
602 auto symbolName = Builder_->getNamedAttr(attributeName, attributeValue);
603 attributes.push_back(symbolName);
604 ::llvm::ArrayRef<::mlir::NamedAttribute> attributesRef(attributes);
605
606 // Add inputs to the function
607 ::llvm::SmallVector<mlir::Value> inputs;
608
609 // Create the lambda node and add it to the region/block it resides in
610 std::cout << "Creating LambdaNode" << std::endl;
611 auto lambda = Builder_->create<LambdaNode>(
612 Builder_->getUnknownLoc(),
613 Builder_->getType<mlir::FunctionType>(arguments, results),
614 inputs,
615 attributesRef);
616 omegaBlock->push_back(lambda);
617 auto & lambdaRegion = lambda.getRegion();
618 auto * lambdaBlock = new mlir::Block;
619 lambdaRegion.push_back(lambdaBlock);
620
621 // Add arguments to the region
622 std::cout << "Adding arguments to the region" << std::endl;
623 lambdaBlock->addArgument(Builder_->getIntegerType(32), Builder_->getUnknownLoc());
624 lambdaBlock->addArgument(Builder_->getType<IOStateEdgeType>(), Builder_->getUnknownLoc());
625 lambdaBlock->addArgument(Builder_->getType<MemStateEdgeType>(), Builder_->getUnknownLoc());
626
627 ::llvm::SmallVector<::mlir::Attribute> mappingVector;
628
629 mappingVector.push_back(::mlir::rvsdg::MatchRuleAttr::get(
630 Builder_->getContext(),
631 ::llvm::ArrayRef(static_cast<int64_t>(0)),
632 4));
633 mappingVector.push_back(::mlir::rvsdg::MatchRuleAttr::get(
634 Builder_->getContext(),
635 ::llvm::ArrayRef(static_cast<int64_t>(1)),
636 5));
637 mappingVector.push_back(::mlir::rvsdg::MatchRuleAttr::get(
638 Builder_->getContext(),
639 ::llvm::ArrayRef(static_cast<int64_t>(1)),
640 6));
642 mappingVector.push_back(
643 ::mlir::rvsdg::MatchRuleAttr::get(Builder_->getContext(), ::llvm::ArrayRef<int64_t>(), 2));
644
645 auto Match = Builder_->create<::mlir::rvsdg::Match>(
646 Builder_->getUnknownLoc(),
647 ::mlir::rvsdg::RVSDG_CTRLType::get(
648 Builder_->getContext(),
649 mappingVector.size()), // Control, ouput type
650 // omegaBlock->getArgument(0), // input
651 lambdaBlock->getArgument(0), // input
652 ::mlir::ArrayAttr::get(Builder_->getContext(), ::llvm::ArrayRef(mappingVector)));
653 lambdaBlock->push_back(Match);
654
655 // Handle the result of the lambda
656 ::llvm::SmallVector<mlir::Value> regionResults;
657 regionResults.push_back(Match->getResult(0));
658 regionResults.push_back(lambdaBlock->getArgument(1));
659 regionResults.push_back(lambdaBlock->getArgument(2));
660 std::cout << "Creating LambdaResult" << std::endl;
661 auto lambdaResult = Builder_->create<LambdaResult>(Builder_->getUnknownLoc(), regionResults);
662 lambdaBlock->push_back(lambdaResult);
663
664 // Handle the result of the omega
665 std::cout << "Creating OmegaResult" << std::endl;
666 ::llvm::SmallVector<mlir::Value> omegaRegionResults;
667 omegaRegionResults.push_back(lambda.getResult());
668 ::llvm::SmallVector<mlir::Type> omegaResultTypes;
669 omegaResultTypes.push_back(lambda.getResult().getType());
670
671 // Create exportNames ArrayAttr
672 ::llvm::SmallVector<::mlir::Attribute> exportNamesList;
673 exportNamesList.push_back(Builder_->getStringAttr("test"));
674 auto exportNamesAttr = ::mlir::ArrayAttr::get(Builder_->getContext(), exportNamesList);
675 ::llvm::SmallVector<::mlir::NamedAttribute> namedAttrs;
676 namedAttrs.push_back({ Builder_->getStringAttr("exportNames"), exportNamesAttr });
677
678 auto omegaResult = Builder_->create<OmegaResult>(
679 Builder_->getUnknownLoc(),
680 omegaResultTypes,
681 omegaRegionResults,
682 namedAttrs);
683 omegaBlock->push_back(omegaResult);
684
685 // Convert the MLIR to RVSDG and check the result
686 std::cout << "Converting MLIR to RVSDG" << std::endl;
687 std::unique_ptr<mlir::Block> rootBlock = std::make_unique<mlir::Block>();
688 rootBlock->push_back(omega);
689 auto rvsdgModule = jlm::mlir::MlirToJlmConverter::CreateAndConvert(rootBlock);
690 auto region = &rvsdgModule->Rvsdg().GetRootRegion();
691
692 {
693 using namespace jlm::rvsdg;
694
695 // Get the lambda block
696 auto convertedLambda =
697 jlm::util::assertedCast<jlm::rvsdg::LambdaNode>(region->Nodes().begin().ptr());
698 EXPECT_TRUE(is<jlm::llvm::LlvmLambdaOperation>(convertedLambda));
699
700 auto lambdaRegion = convertedLambda->subregion();
701
702 auto matchNode =
703 jlm::rvsdg::TryGetOwnerNode<jlm::rvsdg::SimpleNode>(*lambdaRegion->result(0)->origin());
704 EXPECT_TRUE(is<MatchOperation>(matchNode->GetOperation()));
705
706 auto matchOp = dynamic_cast<const MatchOperation *>(&matchNode->GetOperation());
707 EXPECT_EQ(matchOp->narguments(), 1u);
708 EXPECT_TRUE(is<const BitType>(matchOp->argument(0)));
709 EXPECT_EQ(std::dynamic_pointer_cast<const BitType>(matchOp->argument(0))->nbits(), 32u);
710
711 // 3 alternatives + default
712 EXPECT_EQ(matchOp->nalternatives(), 4u);
713
714 EXPECT_EQ(matchOp->default_alternative(), 2u);
715
716 for (auto mapping : *matchOp)
717 {
718 EXPECT_TRUE(
719 (mapping.first == 0 && mapping.second == 4)
720 || (mapping.first == 1 && mapping.second == 5)
721 || (mapping.first == 1 && mapping.second == 6));
722 }
723 }
724 }
725}
726
732TEST(MlirToJlmConverterTests, TestGammaOp)
733{
734 {
735 using namespace mlir::rvsdg;
736 using namespace mlir::jlm;
737
738 // Setup MLIR Context and load dialects
739 std::cout << "Creating MLIR context" << std::endl;
740 auto context = std::make_unique<mlir::MLIRContext>();
741 context->getOrLoadDialect<RVSDGDialect>();
742 context->getOrLoadDialect<JLMDialect>();
743 context->getOrLoadDialect<mlir::arith::ArithDialect>();
744 context->getOrLoadDialect<mlir::LLVM::LLVMDialect>();
745 auto Builder_ = std::make_unique<mlir::OpBuilder>(context.get());
746
747 auto omega = Builder_->create<OmegaNode>(Builder_->getUnknownLoc());
748 auto & omegaRegion = omega.getRegion();
749 auto * omegaBlock = new mlir::Block;
750 omegaRegion.push_back(omegaBlock);
751
752 // Handle function arguments
753 std::cout << "Creating function arguments" << std::endl;
754 ::llvm::SmallVector<mlir::Type> arguments;
755 arguments.push_back(::mlir::rvsdg::RVSDG_CTRLType::get(Builder_->getContext(), 3));
756 arguments.push_back(Builder_->getType<IOStateEdgeType>());
757 arguments.push_back(Builder_->getType<MemStateEdgeType>());
758 ::llvm::ArrayRef argumentsArray(arguments);
759
760 // Handle function results
761 std::cout << "Creating function results" << std::endl;
762 ::llvm::SmallVector<mlir::Type> results;
763 results.push_back(Builder_->getIntegerType(32));
764 results.push_back(Builder_->getIntegerType(32));
765 results.push_back(Builder_->getType<IOStateEdgeType>());
766 results.push_back(Builder_->getType<MemStateEdgeType>());
767 ::llvm::ArrayRef resultsArray(results);
768
769 // Add function attributes
770 std::cout << "Creating function attributes" << std::endl;
771 ::llvm::SmallVector<mlir::NamedAttribute> attributes;
772 auto attributeName = Builder_->getStringAttr("sym_name");
773 auto attributeValue = Builder_->getStringAttr("test");
774 auto symbolName = Builder_->getNamedAttr(attributeName, attributeValue);
775 attributes.push_back(symbolName);
776 ::llvm::ArrayRef<::mlir::NamedAttribute> attributesRef(attributes);
777
778 // Add inputs to the function
779 ::llvm::SmallVector<mlir::Value> inputs;
780
781 // Create the lambda node and add it to the region/block it resides in
782 std::cout << "Creating LambdaNode" << std::endl;
783 auto lambda = Builder_->create<LambdaNode>(
784 Builder_->getUnknownLoc(),
785 Builder_->getType<mlir::FunctionType>(arguments, results),
786 inputs,
787 attributesRef);
788 omegaBlock->push_back(lambda);
789 auto & lambdaRegion = lambda.getRegion();
790 auto * lambdaBlock = new mlir::Block;
791 lambdaRegion.push_back(lambdaBlock);
792
793 // Add arguments to the region
794 std::cout << "Adding arguments to the region" << std::endl;
795 lambdaBlock->addArgument(
796 ::mlir::rvsdg::RVSDG_CTRLType::get(Builder_->getContext(), 3),
797 Builder_->getUnknownLoc());
798 lambdaBlock->addArgument(Builder_->getType<IOStateEdgeType>(), Builder_->getUnknownLoc());
799 lambdaBlock->addArgument(Builder_->getType<MemStateEdgeType>(), Builder_->getUnknownLoc());
800
801 auto entryVar1 = Builder_->create<mlir::arith::ConstantIntOp>(Builder_->getUnknownLoc(), 5, 32);
802 lambdaBlock->push_back(entryVar1);
803 auto entryVar2 = Builder_->create<mlir::arith::ConstantIntOp>(Builder_->getUnknownLoc(), 6, 32);
804 lambdaBlock->push_back(entryVar2);
805
806 ::llvm::SmallVector<::mlir::Type> typeRangeOuput;
807 typeRangeOuput.push_back(::mlir::IntegerType::get(Builder_->getContext(), 32));
808 typeRangeOuput.push_back(::mlir::IntegerType::get(Builder_->getContext(), 32));
809 ::mlir::rvsdg::GammaNode gamma = Builder_->create<::mlir::rvsdg::GammaNode>(
810 Builder_->getUnknownLoc(),
811 ::mlir::TypeRange(::llvm::ArrayRef(typeRangeOuput)), // Ouputs types
812 lambdaBlock->getArgument(0), // predicate
813 ::mlir::ValueRange(::llvm::ArrayRef<::mlir::Value>({ entryVar1, entryVar2 })), // Inputs
814 static_cast<unsigned>(3) // regionsCount
815 );
816 lambdaBlock->push_back(gamma);
817
818 for (size_t i = 0; i < gamma.getNumRegions(); ++i)
819 {
820 auto & gammaBlock = gamma.getRegion(i).emplaceBlock();
821 auto exitvar1 =
822 Builder_->create<mlir::arith::ConstantIntOp>(Builder_->getUnknownLoc(), i + 1, 32);
823 gammaBlock.push_back(exitvar1);
824 auto exitvar2 =
825 Builder_->create<mlir::arith::ConstantIntOp>(Builder_->getUnknownLoc(), 10 * (i + 1), 32);
826 gammaBlock.push_back(exitvar2);
827 auto gammaResult = Builder_->create<::mlir::rvsdg::GammaResult>(
828 Builder_->getUnknownLoc(),
829 ::llvm::SmallVector<mlir::Value>({ exitvar1, exitvar2 }));
830 gammaBlock.push_back(gammaResult);
831 }
832
833 // Handle the result of the lambda
834 ::llvm::SmallVector<mlir::Value> regionResults;
835 regionResults.push_back(gamma->getResult(0));
836 regionResults.push_back(gamma->getResult(1));
837 regionResults.push_back(lambdaBlock->getArgument(1));
838 regionResults.push_back(lambdaBlock->getArgument(2));
839 std::cout << "Creating LambdaResult" << std::endl;
840 auto lambdaResult = Builder_->create<LambdaResult>(Builder_->getUnknownLoc(), regionResults);
841 lambdaBlock->push_back(lambdaResult);
842
843 // Handle the result of the omega
844 std::cout << "Creating OmegaResult" << std::endl;
845 ::llvm::SmallVector<mlir::Value> omegaRegionResults;
846 omegaRegionResults.push_back(lambda.getResult());
847 ::llvm::SmallVector<mlir::Type> omegaResultTypes;
848 omegaResultTypes.push_back(lambda.getResult().getType());
849
850 // Create exportNames ArrayAttr
851 ::llvm::SmallVector<::mlir::Attribute> exportNamesList;
852 exportNamesList.push_back(Builder_->getStringAttr("test"));
853 auto exportNamesAttr = ::mlir::ArrayAttr::get(Builder_->getContext(), exportNamesList);
854 ::llvm::SmallVector<::mlir::NamedAttribute> namedAttrs;
855 namedAttrs.push_back({ Builder_->getStringAttr("exportNames"), exportNamesAttr });
856
857 auto omegaResult = Builder_->create<OmegaResult>(
858 Builder_->getUnknownLoc(),
859 omegaResultTypes,
860 omegaRegionResults,
861 namedAttrs);
862 omegaBlock->push_back(omegaResult);
863
864 // Convert the MLIR to RVSDG and check the result
865 std::cout << "Converting MLIR to RVSDG" << std::endl;
866 std::unique_ptr<mlir::Block> rootBlock = std::make_unique<mlir::Block>();
867 rootBlock->push_back(omega);
868 auto rvsdgModule = jlm::mlir::MlirToJlmConverter::CreateAndConvert(rootBlock);
869 auto region = &rvsdgModule->Rvsdg().GetRootRegion();
870
871 {
872 using namespace jlm::rvsdg;
873
874 EXPECT_EQ(region->numNodes(), 1u);
875
876 // Get the lambda block
877 auto convertedLambda =
878 jlm::util::assertedCast<jlm::rvsdg::LambdaNode>(region->Nodes().begin().ptr());
879 EXPECT_TRUE(is<jlm::llvm::LlvmLambdaOperation>(convertedLambda->GetOperation()));
880
881 auto lambdaRegion = convertedLambda->subregion();
882
883 // 2 constants + gamma
884 EXPECT_EQ(lambdaRegion->numNodes(), 3u);
885
887 *lambdaRegion->result(0)->origin());
888
889 std::cout << "Checking gamma operation" << std::endl;
890 auto gammaOp = dynamic_cast<const GammaOperation *>(&gammaNode->GetOperation());
891 EXPECT_EQ(gammaNode->ninputs(), 3u);
892 EXPECT_EQ(gammaOp->nalternatives(), 3u);
893 EXPECT_EQ(gammaNode->noutputs(), 2u);
894 }
895 }
896}
897
903TEST(MlirToJlmConverterTests, TestThetaOp)
904{
905 {
906 using namespace mlir::rvsdg;
907 using namespace mlir::jlm;
908
909 // Setup MLIR Context and load dialects
910 std::cout << "Creating MLIR context" << std::endl;
911 auto context = std::make_unique<mlir::MLIRContext>();
912 context->getOrLoadDialect<RVSDGDialect>();
913 context->getOrLoadDialect<JLMDialect>();
914 context->getOrLoadDialect<mlir::arith::ArithDialect>();
915 context->getOrLoadDialect<mlir::LLVM::LLVMDialect>();
916 auto Builder_ = std::make_unique<mlir::OpBuilder>(context.get());
917
918 auto omega = Builder_->create<OmegaNode>(Builder_->getUnknownLoc());
919 auto & omegaRegion = omega.getRegion();
920 auto * omegaBlock = new mlir::Block;
921 omegaRegion.push_back(omegaBlock);
922
923 // Add function attributes
924 std::cout << "Creating function attributes" << std::endl;
925 auto attributeName = Builder_->getStringAttr("sym_name");
926 auto attributeValue = Builder_->getStringAttr("test");
927 auto symbolName = Builder_->getNamedAttr(attributeName, attributeValue);
928
929 auto iotype = Builder_->getType<IOStateEdgeType>();
930 auto memtype = Builder_->getType<MemStateEdgeType>();
931
932 // Create the lambda node and add it to the region/block it resides in
933 std::cout << "Creating LambdaNode" << std::endl;
934 auto lambda = Builder_->create<LambdaNode>(
935 Builder_->getUnknownLoc(),
936 Builder_->getType<mlir::FunctionType>(
937 ::mlir::TypeRange({ iotype, memtype }),
938 ::mlir::TypeRange({ iotype, memtype })),
939 ::llvm::SmallVector<mlir::Value>(),
940 ::llvm::ArrayRef<::mlir::NamedAttribute>({ symbolName }));
941 omegaBlock->push_back(lambda);
942 auto & lambdaRegion = lambda.getRegion();
943 auto * lambdaBlock = new mlir::Block;
944 lambdaRegion.push_back(lambdaBlock);
945
946 // Add arguments to the region
947 std::cout << "Adding arguments to the region" << std::endl;
948 lambdaBlock->addArgument(iotype, Builder_->getUnknownLoc());
949 lambdaBlock->addArgument(memtype, Builder_->getUnknownLoc());
950
951 auto theta = Builder_->create<::mlir::rvsdg::ThetaNode>(
952 Builder_->getUnknownLoc(),
953 ::mlir::TypeRange({ iotype, memtype }), // Ouputs types
954 ::mlir::ValueRange({ lambdaBlock->getArgument(0), lambdaBlock->getArgument(1) }), // Inputs
955 ::llvm::SmallVector<::mlir::NamedAttribute>({}));
956 lambdaBlock->push_back(theta);
957
958 auto & thetaBlock = theta.getRegion().emplaceBlock();
959 thetaBlock.addArgument(iotype, Builder_->getUnknownLoc());
960 thetaBlock.addArgument(memtype, Builder_->getUnknownLoc());
961 auto predicate = Builder_->create<mlir::rvsdg::ConstantCtrl>(
962 Builder_->getUnknownLoc(),
963 Builder_->getType<::mlir::rvsdg::RVSDG_CTRLType>(2),
964 0);
965 thetaBlock.push_back(predicate);
966
967 auto thetaResult = Builder_->create<::mlir::rvsdg::ThetaResult>(
968 Builder_->getUnknownLoc(),
969 predicate,
970 ::llvm::SmallVector<mlir::Value>(thetaBlock.getArguments()));
971 thetaBlock.push_back(thetaResult);
972
973 // Handle the result of the lambda
974 ::llvm::SmallVector<mlir::Value> regionResults;
975 regionResults.push_back(theta->getResult(0));
976 regionResults.push_back(theta->getResult(1));
977 std::cout << "Creating LambdaResult" << std::endl;
978 auto lambdaResult = Builder_->create<LambdaResult>(Builder_->getUnknownLoc(), regionResults);
979 lambdaBlock->push_back(lambdaResult);
980
981 // Handle the result of the omega
982 std::cout << "Creating OmegaResult" << std::endl;
983 ::llvm::SmallVector<mlir::Value> omegaRegionResults;
984 omegaRegionResults.push_back(lambda.getResult());
985 ::llvm::SmallVector<mlir::Type> omegaResultTypes;
986 omegaResultTypes.push_back(lambda.getResult().getType());
987
988 // Create exportNames ArrayAttr
989 ::llvm::SmallVector<::mlir::Attribute> exportNamesList;
990 exportNamesList.push_back(Builder_->getStringAttr("test"));
991 auto exportNamesAttr = ::mlir::ArrayAttr::get(Builder_->getContext(), exportNamesList);
992 ::llvm::SmallVector<::mlir::NamedAttribute> namedAttrs;
993 namedAttrs.push_back({ Builder_->getStringAttr("exportNames"), exportNamesAttr });
994
995 auto omegaResult = Builder_->create<OmegaResult>(
996 Builder_->getUnknownLoc(),
997 omegaResultTypes,
998 omegaRegionResults,
999 namedAttrs);
1000 omegaBlock->push_back(omegaResult);
1001
1002 // Convert the MLIR to RVSDG and check the result
1003 std::cout << "Converting MLIR to RVSDG" << std::endl;
1004 std::unique_ptr<mlir::Block> rootBlock = std::make_unique<mlir::Block>();
1005 rootBlock->push_back(omega);
1006 auto rvsdgModule = jlm::mlir::MlirToJlmConverter::CreateAndConvert(rootBlock);
1007 auto region = &rvsdgModule->Rvsdg().GetRootRegion();
1008
1009 {
1010 using namespace jlm::rvsdg;
1011
1012 EXPECT_EQ(region->numNodes(), 1u);
1013
1014 // Get the lambda block
1015 auto convertedLambda =
1016 jlm::util::assertedCast<jlm::rvsdg::LambdaNode>(region->Nodes().begin().ptr());
1017 EXPECT_TRUE(is<jlm::llvm::LlvmLambdaOperation>(convertedLambda->GetOperation()));
1018
1019 auto lambdaRegion = convertedLambda->subregion();
1020
1021 // Just the theta node
1022 EXPECT_EQ(lambdaRegion->numNodes(), 1u);
1023
1025 *lambdaRegion->result(0)->origin());
1026
1027 std::cout << "Checking theta node" << std::endl;
1028 EXPECT_EQ(thetaNode->ninputs(), 2u);
1029 EXPECT_EQ(thetaNode->GetLoopVars().size(), 2u);
1030 EXPECT_EQ(thetaNode->noutputs(), 2u);
1031 EXPECT_EQ(thetaNode->nsubregions(), 1u);
1032 EXPECT_TRUE(is<jlm::rvsdg::ControlType>(thetaNode->predicate()->Type()));
1033 auto predicateType =
1034 std::dynamic_pointer_cast<const ControlType>(thetaNode->predicate()->Type());
1035 EXPECT_EQ(predicateType->nalternatives(), 2u);
1036 std::cout << predicate.getValue() << std::endl;
1037 }
1038 }
1039}
TEST(MlirToJlmConverterTests, TestLambda)
util::HashSet< rvsdg::Output * > arguments
const rvsdg::BitType & Type() const noexcept
static std::unique_ptr< llvm::LlvmRvsdgModule > CreateAndConvert(std::unique_ptr<::mlir::Block > &block)
size_t nbits() const noexcept
Definition type.hpp:26
Output * origin() const noexcept
Definition node.hpp:58
Node * node() const noexcept
Definition node.hpp:572
NodeInput * input(size_t index) const noexcept
Definition node.hpp:615
virtual const Operation & GetOperation() const noexcept=0
size_t ninputs() const noexcept
Definition node.hpp:609
const std::shared_ptr< const rvsdg::Type > & Type() const noexcept
Definition node.hpp:366
Represents the argument of a region.
Definition region.hpp:41
std::string view(const rvsdg::Region *region)
Definition view.cpp:142
NodeType * TryGetOwnerNode(const rvsdg::Input &input) noexcept
Checks if this is an input to a node of specified type.
Definition node.hpp:872