Jlm
Loading...
Searching...
No Matches
TestRvsdgs.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
19#include <jlm/rvsdg/gamma.hpp>
20#include <jlm/rvsdg/theta.hpp>
21
22namespace jlm::llvm
23{
24
25std::unique_ptr<jlm::llvm::LlvmRvsdgModule>
27{
28 using namespace jlm::llvm;
29 using namespace jlm::rvsdg;
30
31 auto pointerType = PointerType::Create();
32 auto fcttype =
34
35 auto module = llvm::LlvmRvsdgModule::Create(jlm::util::FilePath(""), "", "");
36 auto graph = &module->Rvsdg();
37
41
42 auto constantOne = IntegerConstantOperation::Create(*fct->subregion(), { 32, 1 }).output(0);
43
44 auto d = AllocaOperation::create(jlm::rvsdg::BitType::Create(32), constantOne, 4);
45 auto c = AllocaOperation::create(pointerType, constantOne, 4);
46 auto b = AllocaOperation::create(pointerType, constantOne, 4);
47 auto a = AllocaOperation::create(pointerType, constantOne, 4);
48
50 std::vector<jlm::rvsdg::Output *>{ d[1], fct->GetFunctionArguments()[0] });
51 auto merge_c =
52 MemoryStateMergeOperation::Create(std::vector<jlm::rvsdg::Output *>({ c[1], merge_d }));
53 auto merge_b =
54 MemoryStateMergeOperation::Create(std::vector<jlm::rvsdg::Output *>({ b[1], merge_c }));
55 auto merge_a =
56 MemoryStateMergeOperation::Create(std::vector<jlm::rvsdg::Output *>({ a[1], merge_b }));
57
58 auto a_amp_b = StoreNonVolatileOperation::Create(a[0], b[0], { merge_a }, 4);
59 auto b_amp_c = StoreNonVolatileOperation::Create(b[0], c[0], { a_amp_b[0] }, 4);
60 auto c_amp_d = StoreNonVolatileOperation::Create(c[0], d[0], { b_amp_c[0] }, 4);
61
62 fct->finalize({ c_amp_d[0] });
63
64 GraphExport::Create(*fct->output(), "f");
65
66 /* extract nodes */
67
68 this->lambda = fct;
69
71
76
77 return module;
78}
79
80std::unique_ptr<jlm::llvm::LlvmRvsdgModule>
82{
83 using namespace jlm::llvm;
84 using namespace jlm::rvsdg;
85
86 auto pointerType = PointerType::Create();
87 auto fcttype =
89
90 auto module = llvm::LlvmRvsdgModule::Create(jlm::util::FilePath(""), "", "");
91 auto graph = &module->Rvsdg();
92
96
97 auto constantOne = IntegerConstantOperation::Create(*fct->subregion(), { 32, 1 }).output(0);
98
99 auto a = AllocaOperation::create(jlm::rvsdg::BitType::Create(32), constantOne, 4);
100 auto b = AllocaOperation::create(jlm::rvsdg::BitType::Create(32), constantOne, 4);
101 auto x = AllocaOperation::create(pointerType, constantOne, 4);
102 auto y = AllocaOperation::create(pointerType, constantOne, 4);
103 auto p = AllocaOperation::create(pointerType, constantOne, 4);
104
106 std::vector<jlm::rvsdg::Output *>{ a[1], fct->GetFunctionArguments()[0] });
107 auto merge_b =
108 MemoryStateMergeOperation::Create(std::vector<jlm::rvsdg::Output *>({ b[1], merge_a }));
109 auto merge_x =
110 MemoryStateMergeOperation::Create(std::vector<jlm::rvsdg::Output *>({ x[1], merge_b }));
111 auto merge_y =
112 MemoryStateMergeOperation::Create(std::vector<jlm::rvsdg::Output *>({ y[1], merge_x }));
113 auto merge_p =
114 MemoryStateMergeOperation::Create(std::vector<jlm::rvsdg::Output *>({ p[1], merge_y }));
115
116 auto x_amp_a = StoreNonVolatileOperation::Create(x[0], a[0], { merge_p }, 4);
117 auto y_amp_b = StoreNonVolatileOperation::Create(y[0], b[0], { x_amp_a[0] }, 4);
118 auto p_amp_x = StoreNonVolatileOperation::Create(p[0], x[0], { y_amp_b[0] }, 4);
119 auto p_amp_y = StoreNonVolatileOperation::Create(p[0], y[0], { p_amp_x[0] }, 4);
120
121 fct->finalize({ p_amp_y[0] });
122
123 GraphExport::Create(*fct->output(), "f");
124
125 /* extract nodes */
126
127 this->lambda = fct;
128
130
136
137 return module;
138}
139
140std::unique_ptr<jlm::llvm::LlvmRvsdgModule>
142{
143 using namespace jlm::llvm;
144 using namespace jlm::rvsdg;
145
146 auto mt = MemoryStateType::Create();
147 auto pointerType = PointerType::Create();
148 auto intType = BitType::Create(32);
149 auto fcttype = rvsdg::FunctionType::Create(
151 { intType, MemoryStateType::Create() });
152
153 auto module = llvm::LlvmRvsdgModule::Create(jlm::util::FilePath("LoadTest1.c"), "", "");
154 auto graph = &module->Rvsdg();
155
156 auto fct = rvsdg::LambdaNode::Create(
159
161 fct->GetFunctionArguments()[0],
162 { fct->GetFunctionArguments()[1] },
163 pointerType,
164 4);
165 auto ld2 = LoadNonVolatileOperation::Create(ld1[0], { ld1[1] }, intType, 4);
166
167 fct->finalize(ld2);
168
169 GraphExport::Create(*fct->output(), "f");
170
171 /* extract nodes */
172
173 this->lambda = fct;
174
177
178 return module;
179}
180
181std::unique_ptr<jlm::llvm::LlvmRvsdgModule>
183{
184 using namespace jlm::llvm;
185 using namespace jlm::rvsdg;
186
187 auto mt = MemoryStateType::Create();
188 auto pointerType = PointerType::Create();
189 auto fcttype =
191
192 auto module = llvm::LlvmRvsdgModule::Create(jlm::util::FilePath(""), "", "");
193 auto graph = &module->Rvsdg();
194
195 auto fct = rvsdg::LambdaNode::Create(
198
199 auto constantOne = IntegerConstantOperation::Create(*fct->subregion(), { 32, 1 }).output(0);
200
201 auto a = AllocaOperation::create(jlm::rvsdg::BitType::Create(32), constantOne, 4);
202 auto b = AllocaOperation::create(jlm::rvsdg::BitType::Create(32), constantOne, 4);
203 auto x = AllocaOperation::create(pointerType, constantOne, 4);
204 auto y = AllocaOperation::create(pointerType, constantOne, 4);
205 auto p = AllocaOperation::create(pointerType, constantOne, 4);
206
208 std::vector<jlm::rvsdg::Output *>{ a[1], fct->GetFunctionArguments()[0] });
209 auto merge_b =
210 MemoryStateMergeOperation::Create(std::vector<jlm::rvsdg::Output *>({ b[1], merge_a }));
211 auto merge_x =
212 MemoryStateMergeOperation::Create(std::vector<jlm::rvsdg::Output *>({ x[1], merge_b }));
213 auto merge_y =
214 MemoryStateMergeOperation::Create(std::vector<jlm::rvsdg::Output *>({ y[1], merge_x }));
215 auto merge_p =
216 MemoryStateMergeOperation::Create(std::vector<jlm::rvsdg::Output *>({ p[1], merge_y }));
217
218 auto x_amp_a = StoreNonVolatileOperation::Create(x[0], a[0], { merge_p }, 4);
219 auto y_amp_b = StoreNonVolatileOperation::Create(y[0], b[0], x_amp_a, 4);
220 auto p_amp_x = StoreNonVolatileOperation::Create(p[0], x[0], y_amp_b, 4);
221
222 auto ld1 = LoadNonVolatileOperation::Create(p[0], p_amp_x, pointerType, 4);
223 auto ld2 = LoadNonVolatileOperation::Create(ld1[0], { ld1[1] }, pointerType, 4);
224 auto y_star_p = StoreNonVolatileOperation::Create(y[0], ld2[0], { ld2[1] }, 4);
225
226 fct->finalize({ y_star_p[0] });
227
228 GraphExport::Create(*fct->output(), "f");
229
230 /* extract nodes */
231
232 this->lambda = fct;
233
234 this->size = rvsdg::TryGetOwnerNode<rvsdg::Node>(*constantOne);
235
241
244
245 return module;
246}
247
248std::unique_ptr<jlm::llvm::LlvmRvsdgModule>
250{
251 using namespace jlm::llvm;
252 using namespace jlm::rvsdg;
253
254 auto memoryStateType = MemoryStateType::Create();
255 auto functionType = rvsdg::FunctionType::Create(
258 auto pointerType = PointerType::Create();
259
260 auto rvsdgModule = llvm::LlvmRvsdgModule::Create(jlm::util::FilePath(""), "", "");
261 auto & rvsdg = rvsdgModule->Rvsdg();
262
264 rvsdg.GetRootRegion(),
266
267 auto undefValue = UndefValueOperation::Create(*Lambda_->subregion(), pointerType);
268 auto loadResults = LoadNonVolatileOperation::Create(
269 undefValue,
272 4);
273
274 Lambda_->finalize(loadResults);
275 GraphExport::Create(*Lambda_->output(), "f");
276
277 /*
278 * Extract nodes
279 */
281
282 return rvsdgModule;
283}
284
285std::unique_ptr<jlm::llvm::LlvmRvsdgModule>
287{
288 using namespace jlm::llvm;
289 using namespace jlm::rvsdg;
290
291 auto module = llvm::LlvmRvsdgModule::Create(jlm::util::FilePath(""), "", "");
292 auto graph = &module->Rvsdg();
293
294 auto structType =
295 StructType::CreateIdentified({ BitType::Create(32), BitType::Create(32) }, false);
296
297 auto mt = MemoryStateType::Create();
298 auto fcttype = rvsdg::FunctionType::Create(
301
302 auto fct = rvsdg::LambdaNode::Create(
305
306 auto zero = IntegerConstantOperation::Create(*fct->subregion(), { 32, 0 }).output(0);
307 auto one = IntegerConstantOperation::Create(*fct->subregion(), { 32, 1 }).output(0);
308
309 auto gepx =
310 GetElementPtrOperation::create(fct->GetFunctionArguments()[0], { zero, zero }, structType);
312 gepx,
313 { fct->GetFunctionArguments()[1] },
315 4);
316
317 auto gepy =
318 GetElementPtrOperation::create(fct->GetFunctionArguments()[0], { zero, one }, structType);
319 auto ldy = LoadNonVolatileOperation::Create(gepy, { ldx[1] }, jlm::rvsdg::BitType::Create(32), 4);
320
321 auto sum = IntegerAddOperation::createNode(32, *ldx[0], *ldy[0]).output(0);
322
323 fct->finalize({ sum, ldy[1] });
324
325 GraphExport::Create(*fct->output(), "f");
326
327 /*
328 * Assign nodes
329 */
330 this->lambda = fct;
331
334
335 return module;
336}
337
338std::unique_ptr<jlm::llvm::LlvmRvsdgModule>
340{
341 using namespace jlm::llvm;
342 using namespace jlm::rvsdg;
343
344 auto pointerType = PointerType::Create();
346
347 auto module = llvm::LlvmRvsdgModule::Create(jlm::util::FilePath(""), "", "");
348 auto graph = &module->Rvsdg();
349
350 auto fct = rvsdg::LambdaNode::Create(
353
354 auto cast = BitCastOperation::create(fct->GetFunctionArguments()[0], pointerType);
355
356 fct->finalize({ cast });
357
358 GraphExport::Create(*fct->output(), "f");
359
360 // Assign nodes
361 this->lambda = fct;
363
364 return module;
365}
366
367std::unique_ptr<jlm::llvm::LlvmRvsdgModule>
369{
370 using namespace jlm::llvm;
371 using namespace jlm::rvsdg;
372
373 auto module = llvm::LlvmRvsdgModule::Create(jlm::util::FilePath(""), "", "");
374 auto graph = &module->Rvsdg();
375
376 auto setupBit2PtrFunction = [&]()
377 {
378 auto iOStateType = IOStateType::Create();
379 auto memoryStateType = MemoryStateType::Create();
380 auto functionType = rvsdg::FunctionType::Create(
383
384 auto lambda = rvsdg::LambdaNode::Create(
387 auto valueArgument = lambda->GetFunctionArguments()[0];
388 auto iOStateArgument = lambda->GetFunctionArguments()[1];
389 auto memoryStateArgument = lambda->GetFunctionArguments()[2];
390
391 auto cast = IntToPtrOperation::create(valueArgument);
392
393 lambda->finalize({ cast, iOStateArgument, memoryStateArgument });
394
395 return std::make_tuple(lambda, rvsdg::TryGetOwnerNode<rvsdg::Node>(*cast));
396 };
397
398 auto setupTestFunction = [&](rvsdg::Output * b2p)
399 {
400 auto iOStateType = IOStateType::Create();
401 auto memoryStateType = MemoryStateType::Create();
402 auto functionType = rvsdg::FunctionType::Create(
405
406 auto lambda = rvsdg::LambdaNode::Create(
409 auto valueArgument = lambda->GetFunctionArguments()[0];
410 auto iOStateArgument = lambda->GetFunctionArguments()[1];
411 auto memoryStateArgument = lambda->GetFunctionArguments()[2];
412
413 auto cvbits2ptr = lambda->AddContextVar(*b2p).inner;
414
415 auto & call = CallOperation::CreateNode(
416 cvbits2ptr,
417 rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(*b2p).GetOperation().Type(),
418 { valueArgument, iOStateArgument, memoryStateArgument });
419
420 lambda->finalize(
422 GraphExport::Create(*lambda->output(), "testfct");
423
424 return std::make_tuple(lambda, &call);
425 };
426
427 auto [lambdaBits2Ptr, bitsToPtrNode] = setupBit2PtrFunction();
428 auto [lambdaTest, callNode] = setupTestFunction(lambdaBits2Ptr->output());
429
430 // Assign nodes
431 this->LambdaBits2Ptr_ = lambdaBits2Ptr;
432 this->LambdaTest_ = lambdaTest;
433
434 this->BitsToPtrNode_ = bitsToPtrNode;
435
436 this->CallNode_ = callNode;
437
438 return module;
439}
440
441std::unique_ptr<jlm::llvm::LlvmRvsdgModule>
443{
444 using namespace jlm::llvm;
445 using namespace jlm::rvsdg;
446
447 auto mt = MemoryStateType::Create();
448 auto fcttype = rvsdg::FunctionType::Create(
451
452 auto module = llvm::LlvmRvsdgModule::Create(jlm::util::FilePath(""), "", "");
453 auto graph = &module->Rvsdg();
454
455 auto fct = rvsdg::LambdaNode::Create(
458
459 auto constantPointerNullResult =
462 fct->GetFunctionArguments()[0],
463 constantPointerNullResult,
464 { fct->GetFunctionArguments()[1] },
465 4);
466
467 fct->finalize({ st[0] });
468
469 GraphExport::Create(*fct->output(), "f");
470
471 /*
472 * Assign nodes
473 */
474 this->lambda = fct;
475 this->constantPointerNullNode = rvsdg::TryGetOwnerNode<rvsdg::Node>(*constantPointerNullResult);
476
477 return module;
478}
479
480std::unique_ptr<jlm::llvm::LlvmRvsdgModule>
482{
483 using namespace jlm::llvm;
484 using namespace jlm::rvsdg;
485
486 auto module = llvm::LlvmRvsdgModule::Create(jlm::util::FilePath(""), "", "");
487 auto graph = &module->Rvsdg();
488
489 auto SetupF = [&]()
490 {
491 auto pt = PointerType::Create();
492 auto iOStateType = IOStateType::Create();
493 auto memoryStateType = MemoryStateType::Create();
494 auto functionType = rvsdg::FunctionType::Create(
500
501 auto lambda = rvsdg::LambdaNode::Create(
504 auto pointerArgument1 = lambda->GetFunctionArguments()[0];
505 auto pointerArgument2 = lambda->GetFunctionArguments()[1];
506 auto iOStateArgument = lambda->GetFunctionArguments()[2];
507 auto memoryStateArgument = lambda->GetFunctionArguments()[3];
508
510 pointerArgument1,
511 { memoryStateArgument },
513 4);
515 pointerArgument2,
516 { ld1[1] },
518 4);
519
520 auto sum = IntegerAddOperation::createNode(32, *ld1[0], *ld2[0]).output(0);
521
522 lambda->finalize({ sum, iOStateArgument, ld2[1] });
523
524 return lambda;
525 };
526
527 auto SetupG = [&]()
528 {
529 auto pt = PointerType::Create();
530 auto iOStateType = IOStateType::Create();
531 auto memoryStateType = MemoryStateType::Create();
532 auto functionType = rvsdg::FunctionType::Create(
538
539 auto lambda = rvsdg::LambdaNode::Create(
542 auto pointerArgument1 = lambda->GetFunctionArguments()[0];
543 auto pointerArgument2 = lambda->GetFunctionArguments()[1];
544 auto iOStateArgument = lambda->GetFunctionArguments()[2];
545 auto memoryStateArgument = lambda->GetFunctionArguments()[3];
546
548 pointerArgument1,
549 { memoryStateArgument },
551 4);
553 pointerArgument2,
554 { ld1[1] },
556 4);
557
558 auto diff = IntegerSubOperation::createNode(32, *ld1[0], *ld2[0]).output(0);
559
560 lambda->finalize({ diff, iOStateArgument, ld2[1] });
561
562 return lambda;
563 };
564
565 auto SetupH = [&](rvsdg::LambdaNode * f, rvsdg::LambdaNode * g)
566 {
567 auto iOStateType = IOStateType::Create();
568 auto memoryStateType = MemoryStateType::Create();
569 auto functionType = rvsdg::FunctionType::Create(
572
573 auto lambda = rvsdg::LambdaNode::Create(
576 auto iOStateArgument = lambda->GetFunctionArguments()[0];
577 auto memoryStateArgument = lambda->GetFunctionArguments()[1];
578
579 auto cvf = lambda->AddContextVar(*f->output()).inner;
580 auto cvg = lambda->AddContextVar(*g->output()).inner;
581
582 auto constantOne = IntegerConstantOperation::Create(*lambda->subregion(), { 32, 1 }).output(0);
583
584 auto x = AllocaOperation::create(jlm::rvsdg::BitType::Create(32), constantOne, 4);
585 auto y = AllocaOperation::create(jlm::rvsdg::BitType::Create(32), constantOne, 4);
586 auto z = AllocaOperation::create(jlm::rvsdg::BitType::Create(32), constantOne, 4);
587
589 std::vector<jlm::rvsdg::Output *>({ x[1], memoryStateArgument }));
590 auto my = MemoryStateMergeOperation::Create(std::vector<jlm::rvsdg::Output *>({ y[1], mx }));
591 auto mz = MemoryStateMergeOperation::Create(std::vector<jlm::rvsdg::Output *>({ z[1], my }));
592
593 auto five = IntegerConstantOperation::Create(*lambda->subregion(), { 32, 5 }).output(0);
594 auto six = IntegerConstantOperation::Create(*lambda->subregion(), { 32, 6 }).output(0);
595 auto seven = IntegerConstantOperation::Create(*lambda->subregion(), { 32, 7 }).output(0);
596
597 auto stx = StoreNonVolatileOperation::Create(x[0], five, { mz }, 4);
598 auto sty = StoreNonVolatileOperation::Create(y[0], six, { stx[0] }, 4);
599 auto stz = StoreNonVolatileOperation::Create(z[0], seven, { sty[0] }, 4);
600
601 auto & callF = CallOperation::CreateNode(
602 cvf,
603 f->GetOperation().Type(),
604 { x[0], y[0], iOStateArgument, stz[0] });
605 auto & callG = CallOperation::CreateNode(
606 cvg,
607 g->GetOperation().Type(),
608 { z[0],
609 z[0],
610 &CallOperation::GetIOStateOutput(callF),
611 &CallOperation::GetMemoryStateOutput(callF) });
612
613 auto sum = IntegerAddOperation::createNode(32, *callF.output(0), *callG.output(0)).output(0);
614
615 lambda->finalize({ sum,
618 GraphExport::Create(*lambda->output(), "h");
619
620 auto allocaX = rvsdg::TryGetOwnerNode<rvsdg::SimpleNode>(*x[0]);
621 auto allocaY = rvsdg::TryGetOwnerNode<rvsdg::SimpleNode>(*y[0]);
622 auto allocaZ = rvsdg::TryGetOwnerNode<rvsdg::SimpleNode>(*z[0]);
623
624 return std::make_tuple(lambda, allocaX, allocaY, allocaZ, &callF, &callG);
625 };
626
627 auto lambdaF = SetupF();
628 auto lambdaG = SetupG();
629 auto [lambdaH, allocaX, allocaY, allocaZ, callF, callG] = SetupH(lambdaF, lambdaG);
630
631 /*
632 * Assign nodes
633 */
634 this->lambda_f = lambdaF;
635 this->lambda_g = lambdaG;
636 this->lambda_h = lambdaH;
637
638 this->alloca_x = allocaX;
639 this->alloca_y = allocaY;
640 this->alloca_z = allocaZ;
641
642 this->CallF_ = callF;
643 this->CallG_ = callG;
644
645 return module;
646}
647
648std::unique_ptr<jlm::llvm::LlvmRvsdgModule>
650{
651 using namespace jlm::llvm;
652 using namespace jlm::rvsdg;
653
654 auto module = llvm::LlvmRvsdgModule::Create(jlm::util::FilePath(""), "", "");
655 auto graph = &module->Rvsdg();
656
657 auto SetupCreate = [&]()
658 {
659 auto pt32 = PointerType::Create();
660 auto iOStateType = IOStateType::Create();
661 auto memoryStateType = MemoryStateType::Create();
662 auto functionType = rvsdg::FunctionType::Create(
665
666 auto lambda = rvsdg::LambdaNode::Create(
669 auto valueArgument = lambda->GetFunctionArguments()[0];
670 auto iOStateArgument = lambda->GetFunctionArguments()[1];
671 auto memoryStateArgument = lambda->GetFunctionArguments()[2];
672
673 auto four = IntegerConstantOperation::Create(*lambda->subregion(), { 32, 4 }).output(0);
674 auto prod = IntegerMulOperation::createNode(32, *valueArgument, *four).output(0);
675
676 auto & mallocNode = MallocOperation::createNode(*prod, *iOStateArgument);
677 auto cast = BitCastOperation::create(&MallocOperation::addressOutput(mallocNode), pt32);
679 std::vector({ &MallocOperation::memoryStateOutput(mallocNode), memoryStateArgument }));
680
681 lambda->finalize({ cast, &MallocOperation::ioStateOutput(mallocNode), mx });
682
683 return std::make_tuple(lambda, &mallocNode);
684 };
685
686 auto SetupDestroy = [&]()
687 {
688 auto pointerType = PointerType::Create();
689 auto iOStateType = IOStateType::Create();
690 auto memoryStateType = MemoryStateType::Create();
691 auto functionType = rvsdg::FunctionType::Create(
694
695 auto lambda = rvsdg::LambdaNode::Create(
698 auto pointerArgument = lambda->GetFunctionArguments()[0];
699 auto iOStateArgument = lambda->GetFunctionArguments()[1];
700 auto memoryStateArgument = lambda->GetFunctionArguments()[2];
701
702 auto cast = BitCastOperation::create(pointerArgument, pointerType);
703 auto & freeNode = FreeOperation::createNode(*cast, *iOStateArgument, { memoryStateArgument });
704
705 lambda->finalize({ &FreeOperation::getIOStateOutput(freeNode),
707
708 return std::make_tuple(lambda, &freeNode);
709 };
710
711 auto SetupTest = [&](rvsdg::LambdaNode * lambdaCreate, rvsdg::LambdaNode * lambdaDestroy)
712 {
713 auto iOStateType = IOStateType::Create();
714 auto memoryStateType = MemoryStateType::Create();
715 auto functionType = rvsdg::FunctionType::Create(
718
719 auto lambda = rvsdg::LambdaNode::Create(
722 auto iOStateArgument = lambda->GetFunctionArguments()[0];
723 auto memoryStateArgument = lambda->GetFunctionArguments()[1];
724
725 auto create_cv = lambda->AddContextVar(*lambdaCreate->output()).inner;
726 auto destroy_cv = lambda->AddContextVar(*lambdaDestroy->output()).inner;
727
728 auto six = IntegerConstantOperation::Create(*lambda->subregion(), { 32, 6 }).output(0);
729 auto seven = IntegerConstantOperation::Create(*lambda->subregion(), { 32, 7 }).output(0);
730
731 auto & create1 = CallOperation::CreateNode(
732 create_cv,
733 lambdaCreate->GetOperation().Type(),
734 { six, iOStateArgument, memoryStateArgument });
735 auto & create2 = CallOperation::CreateNode(
736 create_cv,
737 lambdaCreate->GetOperation().Type(),
738 { seven,
739 &CallOperation::GetIOStateOutput(create1),
740 &CallOperation::GetMemoryStateOutput(create1) });
741
742 auto & destroy1 = CallOperation::CreateNode(
743 destroy_cv,
744 lambdaDestroy->GetOperation().Type(),
745 { create1.output(0),
746 &CallOperation::GetIOStateOutput(create2),
747 &CallOperation::GetMemoryStateOutput(create2) });
748 auto & destroy2 = CallOperation::CreateNode(
749 destroy_cv,
750 lambdaDestroy->GetOperation().Type(),
751 { create2.output(0),
752 &CallOperation::GetIOStateOutput(destroy1),
753 &CallOperation::GetMemoryStateOutput(destroy1) });
754
755 lambda->finalize({ &CallOperation::GetIOStateOutput(destroy2),
757 GraphExport::Create(*lambda->output(), "test");
758
759 return std::make_tuple(lambda, &create1, &create2, &destroy1, &destroy2);
760 };
761
762 auto [lambdaCreate, mallocNode] = SetupCreate();
763 auto [lambdaDestroy, freeNode] = SetupDestroy();
764 auto [lambdaTest, callCreate1, callCreate2, callDestroy1, callDestroy2] =
765 SetupTest(lambdaCreate, lambdaDestroy);
766
767 /*
768 * Assign nodes
769 */
770 this->lambda_create = lambdaCreate;
771 this->lambda_destroy = lambdaDestroy;
772 this->lambda_test = lambdaTest;
773
774 this->malloc = mallocNode;
775 this->free = freeNode;
776
777 this->CallCreate1_ = callCreate1;
778 this->CallCreate2_ = callCreate2;
779
780 this->CallDestroy1_ = callDestroy1;
781 this->CallDestroy2_ = callDestroy2;
782
783 return module;
784}
785
786std::unique_ptr<jlm::llvm::LlvmRvsdgModule>
788{
789 using namespace jlm::llvm;
790 using namespace jlm::rvsdg;
791
792 auto iOStateType = IOStateType::Create();
793 auto memoryStateType = MemoryStateType::Create();
794 auto constantFunctionType = rvsdg::FunctionType::Create(
797 auto pointerType = PointerType::Create();
798
799 auto module = llvm::LlvmRvsdgModule::Create(jlm::util::FilePath(""), "", "");
800 auto graph = &module->Rvsdg();
801
802 auto SetupConstantFunction = [&](ssize_t n, const std::string & name)
803 {
804 auto lambda = rvsdg::LambdaNode::Create(
807 auto iOStateArgument = lambda->GetFunctionArguments()[0];
808 auto memoryStateArgument = lambda->GetFunctionArguments()[1];
809
810 auto constant = IntegerConstantOperation::Create(*lambda->subregion(), { 32, n }).output(0);
811
812 return lambda->finalize({ constant, iOStateArgument, memoryStateArgument });
813 };
814
815 auto SetupIndirectCallFunction = [&]()
816 {
817 auto iOStateType = IOStateType::Create();
818 auto memoryStateType = MemoryStateType::Create();
819 auto functionType = rvsdg::FunctionType::Create(
822
823 auto lambda = rvsdg::LambdaNode::Create(
826 auto pointerArgument = lambda->GetFunctionArguments()[0];
827 auto functionOfPointer =
828 rvsdg::CreateOpNode<PointerToFunctionOperation>({ pointerArgument }, constantFunctionType)
829 .output(0);
830 auto iOStateArgument = lambda->GetFunctionArguments()[1];
831 auto memoryStateArgument = lambda->GetFunctionArguments()[2];
832
833 auto & call = CallOperation::CreateNode(
834 functionOfPointer,
835 constantFunctionType,
836 { iOStateArgument, memoryStateArgument });
837
838 auto lambdaOutput = lambda->finalize(outputs(&call));
839
840 return std::make_tuple(lambdaOutput, &call);
841 };
842
843 auto SetupTestFunction =
844 [&](rvsdg::Output * fctindcall, rvsdg::Output * fctthree, rvsdg::Output * fctfour)
845 {
846 auto functionType = rvsdg::FunctionType::Create(
849
850 auto lambda = rvsdg::LambdaNode::Create(
853 auto iOStateArgument = lambda->GetFunctionArguments()[0];
854 auto memoryStateArgument = lambda->GetFunctionArguments()[1];
855
856 auto fctindcall_cv = lambda->AddContextVar(*fctindcall).inner;
857 auto fctfour_cv = lambda->AddContextVar(*fctfour).inner;
858 auto fctthree_cv = lambda->AddContextVar(*fctthree).inner;
859
860 auto & call_four = CallOperation::CreateNode(
861 fctindcall_cv,
862 rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(*fctindcall).GetOperation().Type(),
863 { fctfour_cv, iOStateArgument, memoryStateArgument });
864 auto & call_three = CallOperation::CreateNode(
865 fctindcall_cv,
866 rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(*fctindcall).GetOperation().Type(),
867 { fctthree_cv,
868 &CallOperation::GetIOStateOutput(call_four),
869 &CallOperation::GetMemoryStateOutput(call_four) });
870
871 auto add =
872 IntegerAddOperation::createNode(32, *call_four.output(0), *call_three.output(0)).output(0);
873
874 auto lambdaOutput = lambda->finalize({ add,
877 GraphExport::Create(*lambda->output(), "test");
878
879 return std::make_tuple(lambdaOutput, &call_three, &call_four);
880 };
881
882 auto fctfour = SetupConstantFunction(4, "four");
883 auto fctthree = SetupConstantFunction(3, "three");
884 auto [fctindcall, callIndirectFunction] = SetupIndirectCallFunction();
885 auto [fcttest, callFunctionThree, callFunctionFour] = SetupTestFunction(
886 fctindcall,
887 rvsdg::CreateOpNode<FunctionToPointerOperation>({ fctthree }, constantFunctionType).output(0),
888 rvsdg::CreateOpNode<FunctionToPointerOperation>({ fctfour }, constantFunctionType).output(0));
889
890 /*
891 * Assign
892 */
897
898 this->CallIndcall_ = callIndirectFunction;
899 this->CallThree_ = callFunctionThree;
900 this->CallFour_ = callFunctionFour;
901
902 return module;
903}
904
905std::unique_ptr<jlm::llvm::LlvmRvsdgModule>
907{
908 using namespace jlm::llvm;
909 using namespace jlm::rvsdg;
910
911 auto iOStateType = IOStateType::Create();
912 auto memoryStateType = MemoryStateType::Create();
913 auto constantFunctionType = rvsdg::FunctionType::Create(
916 auto pointerType = PointerType::Create();
917
918 auto module = llvm::LlvmRvsdgModule::Create(jlm::util::FilePath(""), "", "");
919 auto graph = &module->Rvsdg();
920
921 auto SetupG1 = [&]()
922 {
923 auto delta = rvsdg::DeltaNode::Create(
927 "g1",
929 "",
930 false,
931 4));
932
933 auto constant = IntegerConstantOperation::Create(*delta->subregion(), { 32, 1 }).output(0);
934
935 return &delta->finalize(constant);
936 };
937
938 auto SetupG2 = [&]()
939 {
940 auto delta = rvsdg::DeltaNode::Create(
944 "g2",
946 "",
947 false,
948 4));
949
950 auto constant = IntegerConstantOperation::Create(*delta->subregion(), { 32, 2 }).output(0);
951
952 return &delta->finalize(constant);
953 };
954
955 auto SetupConstantFunction = [&](ssize_t n, const std::string & name)
956 {
957 auto lambda = rvsdg::LambdaNode::Create(
960 auto iOStateArgument = lambda->GetFunctionArguments()[0];
961 auto memoryStateArgument = lambda->GetFunctionArguments()[1];
962
963 auto constant = IntegerConstantOperation::Create(*lambda->subregion(), { 32, n }).output(0);
964
965 return lambda->finalize({ constant, iOStateArgument, memoryStateArgument });
966 };
967
968 auto functionIType = rvsdg::FunctionType::Create(
971
972 auto SetupI = [&]()
973 {
974 auto iOStateType = IOStateType::Create();
975 auto memoryStateType = MemoryStateType::Create();
976
977 auto lambda = rvsdg::LambdaNode::Create(
980 auto pointerArgument = lambda->GetFunctionArguments()[0];
981 auto iOStateArgument = lambda->GetFunctionArguments()[1];
982 auto memoryStateArgument = lambda->GetFunctionArguments()[2];
983
984 auto & call = CallOperation::CreateNode(
985 rvsdg::CreateOpNode<PointerToFunctionOperation>({ pointerArgument }, constantFunctionType)
986 .output(0),
987 constantFunctionType,
988 { iOStateArgument, memoryStateArgument });
989
990 auto lambdaOutput = lambda->finalize(outputs(&call));
991
992 return std::make_tuple(lambdaOutput, &call);
993 };
994
995 auto SetupIndirectCallFunction = [&](ssize_t n,
996 const std::string & name,
997 rvsdg::Output & functionI,
998 rvsdg::Output & argumentFunction)
999 {
1000 auto pointerType = PointerType::Create();
1001
1002 auto functionType = rvsdg::FunctionType::Create(
1005
1006 auto lambda = rvsdg::LambdaNode::Create(
1009 auto pointerArgument = lambda->GetFunctionArguments()[0];
1010 auto iOStateArgument = lambda->GetFunctionArguments()[1];
1011 auto memoryStateArgument = lambda->GetFunctionArguments()[2];
1012
1013 auto functionICv = lambda->AddContextVar(functionI).inner;
1014 auto argumentFunctionCv = lambda->AddContextVar(argumentFunction).inner;
1015 auto argumentFunctionPtr = rvsdg::CreateOpNode<FunctionToPointerOperation>(
1016 { argumentFunctionCv },
1017 constantFunctionType)
1018 .output(0);
1019
1020 auto five = IntegerConstantOperation::Create(*lambda->subregion(), { 32, n }).output(0);
1021 auto storeNode =
1022 StoreNonVolatileOperation::Create(pointerArgument, five, { memoryStateArgument }, 4);
1023
1024 auto & call = CallOperation::CreateNode(
1025 functionICv,
1026 functionIType,
1027 { argumentFunctionPtr, iOStateArgument, storeNode[0] });
1028
1029 auto lambdaOutput = lambda->finalize(outputs(&call));
1030
1031 return std::make_tuple(lambdaOutput, &call);
1032 };
1033
1034 auto SetupTestFunction = [&](rvsdg::Output & functionX,
1035 rvsdg::Output & functionY,
1036 rvsdg::Output & globalG1,
1037 rvsdg::Output & globalG2)
1038 {
1039 auto functionType = rvsdg::FunctionType::Create(
1042
1043 auto lambda = rvsdg::LambdaNode::Create(
1046 auto iOStateArgument = lambda->GetFunctionArguments()[0];
1047 auto memoryStateArgument = lambda->GetFunctionArguments()[1];
1048
1049 auto functionXCv = lambda->AddContextVar(functionX).inner;
1050 auto functionYCv = lambda->AddContextVar(functionY).inner;
1051 auto globalG1Cv = lambda->AddContextVar(globalG1).inner;
1052 auto globalG2Cv = lambda->AddContextVar(globalG2).inner;
1053
1054 auto constantOne = IntegerConstantOperation::Create(*lambda->subregion(), { 32, 1 }).output(0);
1055
1056 auto pxAlloca = AllocaOperation::create(jlm::rvsdg::BitType::Create(32), constantOne, 4);
1057 auto pyAlloca = AllocaOperation::create(jlm::rvsdg::BitType::Create(32), constantOne, 4);
1058
1059 auto pxMerge = MemoryStateMergeOperation::Create(
1060 std::vector<jlm::rvsdg::Output *>{ pxAlloca[1], memoryStateArgument });
1061 auto pyMerge = MemoryStateMergeOperation::Create(
1062 std::vector<jlm::rvsdg::Output *>({ pyAlloca[1], pxMerge }));
1063
1064 auto & callX = CallOperation::CreateNode(
1065 functionXCv,
1066 rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(functionX).GetOperation().Type(),
1067 { pxAlloca[0], iOStateArgument, pyMerge });
1068
1069 auto & callY = CallOperation::CreateNode(
1070 functionYCv,
1071 rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(functionY).GetOperation().Type(),
1072 { pyAlloca[0],
1075
1077 globalG1Cv,
1080 4);
1082 globalG2Cv,
1083 { loadG1[1] },
1085 4);
1086
1087 auto sum = IntegerAddOperation::createNode(32, *callX.output(0), *callY.output(0)).output(0);
1088 sum = IntegerAddOperation::createNode(32, *sum, *loadG1[0]).output(0);
1089 sum = IntegerAddOperation::createNode(32, *sum, *loadG2[0]).output(0);
1090
1091 auto lambdaOutput = lambda->finalize({ sum,
1094 GraphExport::Create(*lambdaOutput, "test");
1095
1096 return std::make_tuple(
1097 lambdaOutput,
1098 &callX,
1099 &callY,
1100 jlm::util::assertedCast<rvsdg::SimpleNode>(
1102 jlm::util::assertedCast<rvsdg::SimpleNode>(
1104 };
1105
1106 auto SetupTest2Function = [&](rvsdg::Output & functionX)
1107 {
1108 auto functionType = rvsdg::FunctionType::Create(
1111
1112 auto lambda = rvsdg::LambdaNode::Create(
1115 auto iOStateArgument = lambda->GetFunctionArguments()[0];
1116 auto memoryStateArgument = lambda->GetFunctionArguments()[1];
1117
1118 auto constantOne = IntegerConstantOperation::Create(*lambda->subregion(), { 32, 1 }).output(0);
1119
1120 auto pzAlloca = AllocaOperation::create(jlm::rvsdg::BitType::Create(32), constantOne, 4);
1121 auto pzMerge = MemoryStateMergeOperation::Create(
1122 std::vector<jlm::rvsdg::Output *>{ pzAlloca[1], memoryStateArgument });
1123
1124 auto functionXCv = lambda->AddContextVar(functionX).inner;
1125
1126 auto & callX = CallOperation::CreateNode(
1127 functionXCv,
1128 rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(functionX).GetOperation().Type(),
1129 { pzAlloca[0], iOStateArgument, pzMerge });
1130
1131 auto lambdaOutput = lambda->finalize(outputs(&callX));
1132 GraphExport::Create(*lambdaOutput, "test2");
1133
1134 return std::make_tuple(
1135 lambdaOutput,
1136 &callX,
1137 jlm::util::assertedCast<jlm::rvsdg::SimpleNode>(
1139 };
1140
1141 auto deltaG1 = SetupG1();
1142 auto deltaG2 = SetupG2();
1143 auto lambdaThree = SetupConstantFunction(3, "three");
1144 auto lambdaFour = SetupConstantFunction(4, "four");
1145 auto [lambdaI, indirectCall] = SetupI();
1146 auto [lambdaX, callIWithThree] = SetupIndirectCallFunction(5, "x", *lambdaI, *lambdaThree);
1147 auto [lambdaY, callIWithFour] = SetupIndirectCallFunction(6, "y", *lambdaI, *lambdaFour);
1148 auto [lambdaTest, testCallX, callY, allocaPx, allocaPy] =
1149 SetupTestFunction(*lambdaX, *lambdaY, *deltaG1, *deltaG2);
1150 auto [lambdaTest2, test2CallX, allocaPz] = SetupTest2Function(*lambdaX);
1151
1152 /*
1153 * Assign
1154 */
1164
1165 this->IndirectCall_ = indirectCall;
1166 this->CallIWithThree_ = callIWithThree;
1167 this->CallIWithFour_ = callIWithFour;
1168 this->TestCallX_ = testCallX;
1169 this->Test2CallX_ = test2CallX;
1170 this->CallY_ = callY;
1171
1172 this->AllocaPx_ = allocaPx;
1173 this->AllocaPy_ = allocaPy;
1174 this->AllocaPz_ = allocaPz;
1175
1176 return module;
1177}
1178
1179std::unique_ptr<jlm::llvm::LlvmRvsdgModule>
1181{
1182 using namespace jlm::llvm;
1183 using namespace jlm::rvsdg;
1184
1185 auto rvsdgModule = llvm::LlvmRvsdgModule::Create(jlm::util::FilePath(""), "", "");
1186 auto rvsdg = &rvsdgModule->Rvsdg();
1187
1188 auto pointerType = PointerType::Create();
1189 auto iOStateType = IOStateType::Create();
1190 auto memoryStateType = MemoryStateType::Create();
1191 auto functionGType = rvsdg::FunctionType::Create(
1197
1198 auto SetupFunctionGDeclaration = [&]()
1199 {
1201 *rvsdg,
1202 functionGType,
1203 "g",
1206 };
1207
1208 auto SetupFunctionF = [&](jlm::rvsdg::RegionArgument * functionG)
1209 {
1210 auto pointerType = PointerType::Create();
1211 auto iOStateType = IOStateType::Create();
1212 auto memoryStateType = MemoryStateType::Create();
1213 auto functionType = rvsdg::FunctionType::Create(
1219
1220 auto lambda = rvsdg::LambdaNode::Create(
1221 rvsdg->GetRootRegion(),
1223 auto pathArgument = lambda->GetFunctionArguments()[0];
1224 auto modeArgument = lambda->GetFunctionArguments()[1];
1225 auto iOStateArgument = lambda->GetFunctionArguments()[2];
1226 auto memoryStateArgument = lambda->GetFunctionArguments()[3];
1227
1228 auto functionGCv = lambda->AddContextVar(*functionG).inner;
1229
1230 auto constantOne = IntegerConstantOperation::Create(*lambda->subregion(), { 32, 1 }).output(0);
1231
1232 auto allocaPath = AllocaOperation::create(pointerType, constantOne, 4);
1233 auto allocaMode = AllocaOperation::create(pointerType, constantOne, 4);
1234
1235 auto mergePath = MemoryStateMergeOperation::Create(
1236 std::vector<jlm::rvsdg::Output *>{ allocaPath[1], memoryStateArgument });
1237 auto mergeMode = MemoryStateMergeOperation::Create(
1238 std::vector<jlm::rvsdg::Output *>({ allocaMode[1], mergePath }));
1239
1240 auto storePath =
1241 StoreNonVolatileOperation::Create(allocaPath[0], pathArgument, { mergeMode }, 4);
1242 auto storeMode =
1243 StoreNonVolatileOperation::Create(allocaMode[0], modeArgument, { storePath[0] }, 4);
1244
1245 auto loadPath = LoadNonVolatileOperation::Create(allocaPath[0], storeMode, pointerType, 4);
1246 auto loadMode =
1247 LoadNonVolatileOperation::Create(allocaMode[0], { loadPath[1] }, pointerType, 4);
1248
1249 auto & callG = CallOperation::CreateNode(
1250 functionGCv,
1251 functionGType,
1252 { loadPath[0], loadMode[0], iOStateArgument, loadMode[1] });
1253
1254 lambda->finalize(outputs(&callG));
1255 GraphExport::Create(*lambda->output(), "f");
1256
1257 return std::make_tuple(lambda, &callG);
1258 };
1259
1260 this->ExternalGArgument_ = SetupFunctionGDeclaration();
1261 auto [lambdaF, callG] = SetupFunctionF(ExternalGArgument_);
1262
1263 this->LambdaF_ = lambdaF;
1264 this->CallG_ = callG;
1265
1266 return rvsdgModule;
1267}
1268
1269std::unique_ptr<jlm::llvm::LlvmRvsdgModule>
1271{
1272 using namespace jlm::llvm;
1273
1274 auto rvsdgModule = LlvmRvsdgModule::Create(jlm::util::FilePath(""), "", "");
1275 auto & rvsdg = rvsdgModule->Rvsdg();
1276
1277 auto pointerType = PointerType::Create();
1278 auto structType = StructType::CreateIdentified(
1279 "myStruct",
1281 false);
1282 auto iOStateType = IOStateType::Create();
1283 auto memoryStateType = MemoryStateType::Create();
1284 VariableArgumentType varArgType;
1285 auto lambdaLlvmLifetimeStartType = rvsdg::FunctionType::Create(
1291 auto lambdaLlvmLifetimeEndType = rvsdg::FunctionType::Create(
1297 auto lambdaFType = rvsdg::FunctionType::Create(
1300 auto lambdaGType = rvsdg::FunctionType::Create(
1302 {
1305 });
1306
1307 auto llvmLifetimeStart = &LlvmGraphImport::createFunctionImport(
1308 rvsdg,
1309 lambdaLlvmLifetimeStartType,
1310 "llvm.lifetime.start.p0",
1313 auto llvmLifetimeEnd = &LlvmGraphImport::createFunctionImport(
1314 rvsdg,
1315 lambdaLlvmLifetimeEndType,
1316 "llvm.lifetime.end.p0",
1320 rvsdg,
1321 lambdaFType,
1322 "f",
1325
1326 // Setup function g()
1328 rvsdg.GetRootRegion(),
1330 auto iOStateArgument = LambdaG_->GetFunctionArguments()[0];
1331 auto memoryStateArgument = LambdaG_->GetFunctionArguments()[1];
1332 auto llvmLifetimeStartArgument = LambdaG_->AddContextVar(*llvmLifetimeStart).inner;
1333 auto llvmLifetimeEndArgument = LambdaG_->AddContextVar(*llvmLifetimeEnd).inner;
1334 auto lambdaFArgument = LambdaG_->AddContextVar(*ExternalFArgument_).inner;
1335
1336 auto constantOne = IntegerConstantOperation::Create(*LambdaG_->subregion(), { 64, 1 }).output(0);
1337 auto twentyFour = IntegerConstantOperation::Create(*LambdaG_->subregion(), { 64, 24 }).output(0);
1338
1339 auto allocaResults = AllocaOperation::create(structType, constantOne, 16);
1340 auto memoryState = MemoryStateMergeOperation::Create(
1341 std::vector<jlm::rvsdg::Output *>{ allocaResults[1], memoryStateArgument });
1342
1343 auto & callLLvmLifetimeStart = CallOperation::CreateNode(
1344 llvmLifetimeStartArgument,
1345 lambdaLlvmLifetimeStartType,
1346 { twentyFour, allocaResults[0], iOStateArgument, memoryState });
1347
1349 lambdaFArgument,
1350 lambdaFType,
1351 { allocaResults[0],
1352 &CallOperation::GetIOStateOutput(callLLvmLifetimeStart),
1353 &CallOperation::GetMemoryStateOutput(callLLvmLifetimeStart) });
1354
1355 auto zero = IntegerConstantOperation::Create(*LambdaG_->subregion(), { 64, 0 }).output(0);
1357 auto two = IntegerConstantOperation::Create(*LambdaG_->subregion(), { 32, 2 }).output(0);
1358
1359 auto gepResult1 = GetElementPtrOperation::create(allocaResults[0], { zero, one }, structType);
1360 auto loadResults1 = LoadNonVolatileOperation::Create(
1361 gepResult1,
1363 pointerType,
1364 8);
1365 auto loadResults2 =
1366 LoadNonVolatileOperation::Create(loadResults1[0], { loadResults1[1] }, pointerType, 8);
1367
1368 auto gepResult2 = GetElementPtrOperation::create(allocaResults[0], { zero, two }, structType);
1369 auto loadResults3 =
1370 LoadNonVolatileOperation::Create(gepResult2, { loadResults2[1] }, pointerType, 8);
1371 auto loadResults4 =
1372 LoadNonVolatileOperation::Create(loadResults1[0], { loadResults3[1] }, pointerType, 8);
1373
1374 auto storeResults1 =
1375 StoreNonVolatileOperation::Create(loadResults1[0], loadResults4[0], { loadResults4[1] }, 8);
1376
1377 auto loadResults5 =
1378 LoadNonVolatileOperation::Create(gepResult2, { storeResults1[0] }, pointerType, 8);
1379 auto storeResults2 =
1380 StoreNonVolatileOperation::Create(loadResults5[0], loadResults2[0], { loadResults5[1] }, 8);
1381
1382 auto & callLLvmLifetimeEnd = CallOperation::CreateNode(
1383 llvmLifetimeEndArgument,
1384 lambdaLlvmLifetimeEndType,
1385 { twentyFour,
1386 allocaResults[0],
1388 storeResults2[0] });
1389
1390 LambdaG_->finalize(outputs(&callLLvmLifetimeEnd));
1391
1392 return rvsdgModule;
1393}
1394
1395std::unique_ptr<jlm::llvm::LlvmRvsdgModule>
1397{
1398 using namespace jlm::llvm;
1399 using namespace jlm::rvsdg;
1400
1401 auto mt = MemoryStateType::Create();
1402 auto pt = PointerType::Create();
1403 auto fcttype = rvsdg::FunctionType::Create(
1411
1412 auto module = llvm::LlvmRvsdgModule::Create(jlm::util::FilePath(""), "", "");
1413 auto graph = &module->Rvsdg();
1414
1415 auto fct = rvsdg::LambdaNode::Create(
1418
1419 auto zero = IntegerConstantOperation::Create(*fct->subregion(), { 32, 0 }).output(0);
1420 auto biteq = IntegerEqOperation::createNode(32, *fct->GetFunctionArguments()[0], *zero).output(0);
1421 auto & predicateNode = MatchOperation::CreateNode(*biteq, { { 0, 1 } }, 0, 2);
1422
1423 auto gammanode = GammaNode::create(predicateNode.output(0), 2);
1424 auto p1ev = gammanode->AddEntryVar(fct->GetFunctionArguments()[1]);
1425 auto p2ev = gammanode->AddEntryVar(fct->GetFunctionArguments()[2]);
1426 auto p3ev = gammanode->AddEntryVar(fct->GetFunctionArguments()[3]);
1427 auto p4ev = gammanode->AddEntryVar(fct->GetFunctionArguments()[4]);
1428
1429 auto tmp1 = gammanode->AddExitVar({ p1ev.branchArgument[0], p3ev.branchArgument[1] });
1430 auto tmp2 = gammanode->AddExitVar({ p2ev.branchArgument[0], p4ev.branchArgument[1] });
1431
1433 tmp1.output,
1434 { fct->GetFunctionArguments()[5] },
1436 4);
1437 auto ld2 =
1438 LoadNonVolatileOperation::Create(tmp2.output, { ld1[1] }, jlm::rvsdg::BitType::Create(32), 4);
1439 auto sum = IntegerAddOperation::createNode(32, *ld1[0], *ld2[0]).output(0);
1440
1441 fct->finalize({ sum, ld2[1] });
1442
1443 GraphExport::Create(*fct->output(), "f");
1444
1445 /*
1446 * Assign nodes
1447 */
1448 this->lambda = fct;
1449 this->gamma = gammanode;
1450
1451 return module;
1452}
1453
1454std::unique_ptr<llvm::LlvmRvsdgModule>
1456{
1457 using namespace jlm::llvm;
1458 using namespace jlm::rvsdg;
1459
1460 auto rvsdgModule = llvm::LlvmRvsdgModule::Create(util::FilePath(""), "", "");
1461 auto rvsdg = &rvsdgModule->Rvsdg();
1462
1463 auto SetupLambdaF = [&]()
1464 {
1465 auto SetupGamma = [](rvsdg::Output * predicate,
1466 rvsdg::Output * xAddress,
1467 rvsdg::Output * yAddress,
1468 rvsdg::Output * zAddress,
1469 rvsdg::Output * memoryState)
1470 {
1471 auto gammaNode = rvsdg::GammaNode::create(predicate, 2);
1472
1473 auto gammaInputX = gammaNode->AddEntryVar(xAddress);
1474 auto gammaInputY = gammaNode->AddEntryVar(yAddress);
1475 auto gammaInputZ = gammaNode->AddEntryVar(zAddress);
1476 auto gammaInputMemoryState = gammaNode->AddEntryVar(memoryState);
1477
1478 // gamma subregion 0
1479 auto loadXResults = LoadNonVolatileOperation::Create(
1480 gammaInputX.branchArgument[0],
1481 { gammaInputMemoryState.branchArgument[0] },
1483 4);
1484
1485 auto one = IntegerConstantOperation::Create(*gammaNode->subregion(0), { 32, 1 }).output(0);
1486 auto storeZRegion0Results = StoreNonVolatileOperation::Create(
1487 gammaInputZ.branchArgument[0],
1488 one,
1489 { loadXResults[1] },
1490 4);
1491
1492 // gamma subregion 1
1493 auto loadYResults = LoadNonVolatileOperation::Create(
1494 gammaInputY.branchArgument[1],
1495 { gammaInputMemoryState.branchArgument[1] },
1497 4);
1498
1499 auto two = IntegerConstantOperation::Create(*gammaNode->subregion(1), { 32, 2 }).output(0);
1500 auto storeZRegion1Results = StoreNonVolatileOperation::Create(
1501 gammaInputZ.branchArgument[1],
1502 two,
1503 { loadYResults[1] },
1504 4);
1505
1506 // finalize gamma
1507 auto gammaOutputA = gammaNode->AddExitVar({ loadXResults[0], loadYResults[0] });
1508 auto gammaOutputMemoryState =
1509 gammaNode->AddExitVar({ storeZRegion0Results[0], storeZRegion1Results[0] });
1510
1511 return std::make_tuple(gammaOutputA.output, gammaOutputMemoryState.output);
1512 };
1513
1514 auto iOStateType = IOStateType::Create();
1515 auto memoryStateType = MemoryStateType::Create();
1516 auto pointerType = PointerType::Create();
1517 auto functionType = rvsdg::FunctionType::Create(
1524
1525 auto lambda = rvsdg::LambdaNode::Create(
1526 rvsdg->GetRootRegion(),
1528 auto cArgument = lambda->GetFunctionArguments()[0];
1529 auto xArgument = lambda->GetFunctionArguments()[1];
1530 auto yArgument = lambda->GetFunctionArguments()[2];
1531 auto iOStateArgument = lambda->GetFunctionArguments()[3];
1532 auto memoryStateArgument = lambda->GetFunctionArguments()[4];
1533
1534 auto constantOne = IntegerConstantOperation::Create(*lambda->subregion(), { 32, 1 }).output(0);
1535
1536 auto allocaZResults = AllocaOperation::create(pointerType, constantOne, 4);
1537
1538 auto memoryState = MemoryStateMergeOperation::Create(
1539 std::vector<jlm::rvsdg::Output *>{ allocaZResults[1], memoryStateArgument });
1540
1541 auto nullPointer = ConstantPointerNullOperation::createNode(*lambda->subregion()).output(0);
1542 auto storeZResults =
1543 StoreNonVolatileOperation::Create(allocaZResults[0], nullPointer, { memoryState }, 4);
1544
1545 auto zero = IntegerConstantOperation::Create(*lambda->subregion(), { 32, 0 }).output(0);
1546 auto & intEq = IntegerEqOperation::createNode(32, *cArgument, *zero);
1547 auto & predicateNode = MatchOperation::CreateNode(*intEq.output(0), { { 0, 1 } }, 0, 2);
1548
1549 auto [gammaOutputA, gammaOutputMemoryState] =
1550 SetupGamma(predicateNode.output(0), xArgument, yArgument, allocaZResults[0], memoryState);
1551
1552 auto loadZResults = LoadNonVolatileOperation::Create(
1553 allocaZResults[0],
1554 { gammaOutputMemoryState },
1556 4);
1557
1558 auto sum = IntegerAddOperation::createNode(32, *gammaOutputA, *loadZResults[0]).output(0);
1559
1560 lambda->finalize({ sum, iOStateArgument, loadZResults[1] });
1561
1562 return std::make_tuple(
1563 lambda->output(),
1565 rvsdg::TryGetOwnerNode<rvsdg::Node>(*allocaZResults[0]));
1566 };
1567
1568 auto SetupLambdaGH = [&](rvsdg::Output & lambdaF,
1569 int64_t cValue,
1570 int64_t xValue,
1571 int64_t yValue,
1572 const char * functionName)
1573 {
1574 auto iOStateType = IOStateType::Create();
1575 auto memoryStateType = MemoryStateType::Create();
1576 auto pointerType = PointerType::Create();
1577 auto functionType = rvsdg::FunctionType::Create(
1580
1581 auto lambda = rvsdg::LambdaNode::Create(
1582 rvsdg->GetRootRegion(),
1583 llvm::LlvmLambdaOperation::Create(functionType, functionName, Linkage::externalLinkage));
1584 auto iOStateArgument = lambda->GetFunctionArguments()[0];
1585 auto memoryStateArgument = lambda->GetFunctionArguments()[1];
1586 auto lambdaFArgument = lambda->AddContextVar(lambdaF).inner;
1587
1588 auto constantOne = IntegerConstantOperation::Create(*lambda->subregion(), { 32, 4 }).output(0);
1589
1590 auto allocaXResults = AllocaOperation::create(rvsdg::BitType::Create(32), constantOne, 4);
1591 auto allocaYResults = AllocaOperation::create(pointerType, constantOne, 4);
1592
1593 auto memoryState = MemoryStateMergeOperation::Create(
1594 std::vector<jlm::rvsdg::Output *>{ allocaXResults[1], memoryStateArgument });
1596 std::vector<jlm::rvsdg::Output *>({ allocaYResults[1], memoryState }));
1597
1598 auto predicate =
1599 IntegerConstantOperation::Create(*lambda->subregion(), { 32, cValue }).output(0);
1600 auto x = IntegerConstantOperation::Create(*lambda->subregion(), { 32, xValue }).output(0);
1601 auto y = IntegerConstantOperation::Create(*lambda->subregion(), { 32, yValue }).output(0);
1602
1603 auto storeXResults =
1604 StoreNonVolatileOperation::Create(allocaXResults[0], x, { allocaXResults[1] }, 4);
1605
1606 auto storeYResults =
1607 StoreNonVolatileOperation::Create(allocaYResults[0], y, { storeXResults[0] }, 4);
1608
1609 auto & call = CallOperation::CreateNode(
1610 lambdaFArgument,
1611 rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(lambdaF).GetOperation().Type(),
1612 { predicate, allocaXResults[0], allocaYResults[0], iOStateArgument, storeYResults[0] });
1613
1614 lambda->finalize(outputs(&call));
1615 GraphExport::Create(*lambda->output(), functionName);
1616
1617 return std::make_tuple(
1618 lambda->output(),
1619 &call,
1620 rvsdg::TryGetOwnerNode<rvsdg::Node>(*allocaXResults[0]),
1621 rvsdg::TryGetOwnerNode<rvsdg::Node>(*allocaYResults[1]));
1622 };
1623
1624 auto [lambdaF, gammaNode, allocaZ] = SetupLambdaF();
1625 auto [lambdaG, callFromG, allocaXFromG, allocaYFromG] = SetupLambdaGH(*lambdaF, 0, 1, 2, "g");
1626 auto [lambdaH, callFromH, allocaXFromH, allocaYFromH] = SetupLambdaGH(*lambdaF, 1, 3, 4, "h");
1627
1628 // Assign nodes
1629 this->LambdaF_ = &rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(*lambdaF);
1630 this->LambdaG_ = &rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(*lambdaG);
1631 this->LambdaH_ = &rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(*lambdaH);
1632
1633 this->Gamma_ = gammaNode;
1634
1635 this->CallFromG_ = callFromG;
1636 this->CallFromH_ = callFromH;
1637
1638 this->AllocaXFromG_ = allocaXFromG;
1639 this->AllocaYFromG_ = allocaYFromG;
1640 this->AllocaXFromH_ = allocaXFromH;
1641 this->AllocaYFromH_ = allocaYFromH;
1642 this->AllocaZ_ = allocaZ;
1643
1644 return rvsdgModule;
1645}
1646
1647std::unique_ptr<jlm::llvm::LlvmRvsdgModule>
1648ThetaTest::SetupRvsdg()
1649{
1650 using namespace jlm::llvm;
1651 using namespace jlm::rvsdg;
1652
1653 auto mt = MemoryStateType::Create();
1654 auto pointerType = PointerType::Create();
1655 auto fcttype = rvsdg::FunctionType::Create(
1657 PointerType::Create(),
1659 MemoryStateType::Create() },
1660 { MemoryStateType::Create() });
1661
1662 auto module = llvm::LlvmRvsdgModule::Create(jlm::util::FilePath(""), "", "");
1663 auto graph = &module->Rvsdg();
1664
1665 auto fct = rvsdg::LambdaNode::Create(
1666 graph->GetRootRegion(),
1667 llvm::LlvmLambdaOperation::Create(fcttype, "f", Linkage::externalLinkage));
1668
1669 auto zero = IntegerConstantOperation::Create(*fct->subregion(), { 32, 0 }).output(0);
1670
1671 auto thetanode = jlm::rvsdg::ThetaNode::create(fct->subregion());
1672
1673 auto n = thetanode->AddLoopVar(zero);
1674 auto l = thetanode->AddLoopVar(fct->GetFunctionArguments()[0]);
1675 auto a = thetanode->AddLoopVar(fct->GetFunctionArguments()[1]);
1676 auto c = thetanode->AddLoopVar(fct->GetFunctionArguments()[2]);
1677 auto s = thetanode->AddLoopVar(fct->GetFunctionArguments()[3]);
1678
1679 auto gepnode = GetElementPtrOperation::create(a.pre, { n.pre }, BitType::Create(32));
1680 auto store = StoreNonVolatileOperation::Create(gepnode, c.pre, { s.pre }, 4);
1681
1682 auto one = IntegerConstantOperation::Create(*thetanode->subregion(), { 32, 1 }).output(0);
1683 auto sum = IntegerAddOperation::createNode(32, *n.pre, *one).output(0);
1684 auto cmp = IntegerUltOperation::createNode(32, *sum, *l.pre).output(0);
1685 auto & predicateNode = MatchOperation::CreateNode(*cmp, { { 1, 1 } }, 0, 2);
1686
1687 n.post->divert_to(sum);
1688 s.post->divert_to(store[0]);
1689 thetanode->set_predicate(predicateNode.output(0));
1690
1691 fct->finalize({ s.output });
1692 GraphExport::Create(*fct->output(), "f");
1693
1694 /*
1695 * Assign nodes
1696 */
1697 this->lambda = fct;
1698 this->theta = thetanode;
1699 this->gep = rvsdg::TryGetOwnerNode<rvsdg::Node>(*gepnode);
1700
1701 return module;
1702}
1703
1704std::unique_ptr<jlm::llvm::LlvmRvsdgModule>
1705DeltaTest1::SetupRvsdg()
1706{
1707 using namespace jlm::llvm;
1708 using namespace jlm::rvsdg;
1709
1710 auto module = llvm::LlvmRvsdgModule::Create(jlm::util::FilePath(""), "", "");
1711 auto graph = &module->Rvsdg();
1712
1713 auto SetupGlobalF = [&]()
1714 {
1715 auto dfNode = jlm::rvsdg::DeltaNode::Create(
1716 &graph->GetRootRegion(),
1717 LlvmDeltaOperation::Create(
1719 "f",
1720 Linkage::externalLinkage,
1721 "",
1722 false,
1723 4));
1724
1725 auto constant = IntegerConstantOperation::Create(*dfNode->subregion(), { 32, 0 }).output(0);
1726
1727 return &dfNode->finalize(constant);
1728 };
1729
1730 auto SetupFunctionG = [&]()
1731 {
1732 auto pt = PointerType::Create();
1733 auto iOStateType = IOStateType::Create();
1734 auto memoryStateType = MemoryStateType::Create();
1735 auto functionType = rvsdg::FunctionType::Create(
1736 { PointerType::Create(), IOStateType::Create(), MemoryStateType::Create() },
1737 { jlm::rvsdg::BitType::Create(32), IOStateType::Create(), MemoryStateType::Create() });
1738
1739 auto lambda = rvsdg::LambdaNode::Create(
1740 graph->GetRootRegion(),
1741 llvm::LlvmLambdaOperation::Create(functionType, "g", Linkage::externalLinkage));
1742 auto pointerArgument = lambda->GetFunctionArguments()[0];
1743 auto iOStateArgument = lambda->GetFunctionArguments()[1];
1744 auto memoryStateArgument = lambda->GetFunctionArguments()[2];
1745
1746 auto ld = LoadNonVolatileOperation::Create(
1747 pointerArgument,
1748 { memoryStateArgument },
1750 4);
1751
1752 return lambda->finalize({ ld[0], iOStateArgument, ld[1] });
1753 };
1754
1755 auto SetupFunctionH = [&](rvsdg::Output * f, rvsdg::Output * g)
1756 {
1757 auto iOStateType = IOStateType::Create();
1758 auto memoryStateType = MemoryStateType::Create();
1759 auto functionType = rvsdg::FunctionType::Create(
1760 { IOStateType::Create(), MemoryStateType::Create() },
1761 { jlm::rvsdg::BitType::Create(32), IOStateType::Create(), MemoryStateType::Create() });
1762
1763 auto lambda = rvsdg::LambdaNode::Create(
1764 graph->GetRootRegion(),
1765 llvm::LlvmLambdaOperation::Create(functionType, "h", Linkage::externalLinkage));
1766 auto iOStateArgument = lambda->GetFunctionArguments()[0];
1767 auto memoryStateArgument = lambda->GetFunctionArguments()[1];
1768
1769 auto cvf = lambda->AddContextVar(*f).inner;
1770 auto cvg = lambda->AddContextVar(*g).inner;
1771
1772 auto five = IntegerConstantOperation::Create(*lambda->subregion(), { 32, 5 }).output(0);
1773 auto st = StoreNonVolatileOperation::Create(cvf, five, { memoryStateArgument }, 4);
1774 auto & callG = CallOperation::CreateNode(
1775 cvg,
1776 rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(*g).GetOperation().Type(),
1777 { cvf, iOStateArgument, st[0] });
1778
1779 auto lambdaOutput = lambda->finalize(outputs(&callG));
1780 GraphExport::Create(*lambda->output(), "h");
1781
1782 return std::make_tuple(lambdaOutput, &callG, rvsdg::TryGetOwnerNode<rvsdg::Node>(*five));
1783 };
1784
1785 auto f = SetupGlobalF();
1786 auto g = SetupFunctionG();
1787 auto [h, callFunctionG, constantFive] = SetupFunctionH(f, g);
1788
1789 /*
1790 * Assign nodes
1791 */
1794
1796
1797 this->CallG_ = callFunctionG;
1798 this->constantFive = constantFive;
1799
1800 return module;
1801}
1802
1803std::unique_ptr<jlm::llvm::LlvmRvsdgModule>
1804DeltaTest2::SetupRvsdg()
1805{
1806 using namespace jlm::llvm;
1807 using namespace jlm::rvsdg;
1808
1809 auto module = llvm::LlvmRvsdgModule::Create(jlm::util::FilePath(""), "", "");
1810 auto graph = &module->Rvsdg();
1811
1812 auto SetupD1 = [&]()
1813 {
1814 auto delta = jlm::rvsdg::DeltaNode::Create(
1815 &graph->GetRootRegion(),
1816 LlvmDeltaOperation::Create(
1818 "d1",
1819 Linkage::externalLinkage,
1820 "",
1821 false,
1822 4));
1823
1824 auto constant = IntegerConstantOperation::Create(*delta->subregion(), { 32, 0 }).output(0);
1825
1826 return &delta->finalize(constant);
1827 };
1828
1829 auto SetupD2 = [&]()
1830 {
1831 auto delta = jlm::rvsdg::DeltaNode::Create(
1832 &graph->GetRootRegion(),
1833 LlvmDeltaOperation::Create(
1835 "d2",
1836 Linkage::externalLinkage,
1837 "",
1838 false,
1839 4));
1840
1841 auto constant = IntegerConstantOperation::Create(*delta->subregion(), { 32, 0 }).output(0);
1842
1843 return &delta->finalize(constant);
1844 };
1845
1846 auto SetupF1 = [&](rvsdg::Output * d1)
1847 {
1848 auto iOStateType = IOStateType::Create();
1849 auto memoryStateType = MemoryStateType::Create();
1850 auto functionType = rvsdg::FunctionType::Create(
1851 { IOStateType::Create(), MemoryStateType::Create() },
1852 { IOStateType::Create(), MemoryStateType::Create() });
1853
1854 auto lambda = rvsdg::LambdaNode::Create(
1855 graph->GetRootRegion(),
1856 llvm::LlvmLambdaOperation::Create(functionType, "f1", Linkage::externalLinkage));
1857 auto iOStateArgument = lambda->GetFunctionArguments()[0];
1858 auto memoryStateArgument = lambda->GetFunctionArguments()[1];
1859
1860 auto cvd1 = lambda->AddContextVar(*d1).inner;
1861 auto b2 = IntegerConstantOperation::Create(*lambda->subregion(), { 32, 2 }).output(0);
1862 auto st = StoreNonVolatileOperation::Create(cvd1, b2, { memoryStateArgument }, 4);
1863
1864 return lambda->finalize({ iOStateArgument, st[0] });
1865 };
1866
1867 auto SetupF2 = [&](rvsdg::Output * f1, rvsdg::Output * d1, rvsdg::Output * d2)
1868 {
1869 auto iOStateType = IOStateType::Create();
1870 auto memoryStateType = MemoryStateType::Create();
1871 auto functionType = rvsdg::FunctionType::Create(
1872 { IOStateType::Create(), MemoryStateType::Create() },
1873 { IOStateType::Create(), MemoryStateType::Create() });
1874
1875 auto lambda = rvsdg::LambdaNode::Create(
1876 graph->GetRootRegion(),
1877 llvm::LlvmLambdaOperation::Create(functionType, "f2", Linkage::externalLinkage));
1878 auto iOStateArgument = lambda->GetFunctionArguments()[0];
1879 auto memoryStateArgument = lambda->GetFunctionArguments()[1];
1880
1881 auto cvd1 = lambda->AddContextVar(*d1).inner;
1882 auto cvd2 = lambda->AddContextVar(*d2).inner;
1883 auto cvf1 = lambda->AddContextVar(*f1).inner;
1884
1885 auto b5 = IntegerConstantOperation::Create(*lambda->subregion(), { 32, 5 }).output(0);
1886 auto b42 = IntegerConstantOperation::Create(*lambda->subregion(), { 32, 42 }).output(0);
1887 auto st = StoreNonVolatileOperation::Create(cvd1, b5, { memoryStateArgument }, 4);
1888 auto & call = CallOperation::CreateNode(
1889 cvf1,
1890 rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(*f1).GetOperation().Type(),
1891 { iOStateArgument, st[0] });
1892 st = StoreNonVolatileOperation::Create(
1893 cvd2,
1894 b42,
1895 { &CallOperation::GetMemoryStateOutput(call) },
1896 4);
1897
1898 auto lambdaOutput = lambda->finalize(outputs(&call));
1899 GraphExport::Create(*lambdaOutput, "f2");
1900
1901 return std::make_tuple(lambdaOutput, &call);
1902 };
1903
1904 auto d1 = SetupD1();
1905 auto d2 = SetupD2();
1906 auto f1 = SetupF1(d1);
1907 auto [f2, callF1] = SetupF2(f1, d1, d2);
1908
1909 // Assign nodes
1910 this->lambda_f1 = &rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(*f1);
1911 this->lambda_f2 = &rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(*f2);
1912
1913 this->delta_d1 = &rvsdg::AssertGetOwnerNode<rvsdg::DeltaNode>(*d1);
1914 this->delta_d2 = &rvsdg::AssertGetOwnerNode<rvsdg::DeltaNode>(*d2);
1915
1916 this->CallF1_ = callF1;
1917
1918 return module;
1919}
1920
1921std::unique_ptr<jlm::llvm::LlvmRvsdgModule>
1922DeltaTest3::SetupRvsdg()
1923{
1924 using namespace jlm::llvm;
1925 using namespace jlm::rvsdg;
1926
1927 auto module = llvm::LlvmRvsdgModule::Create(jlm::util::FilePath(""), "", "");
1928 auto graph = &module->Rvsdg();
1929
1930 auto SetupG1 = [&]()
1931 {
1932 auto delta = jlm::rvsdg::DeltaNode::Create(
1933 &graph->GetRootRegion(),
1934 LlvmDeltaOperation::Create(
1936 "g1",
1937 Linkage::externalLinkage,
1938 "",
1939 false,
1940 4));
1941
1942 auto constant = IntegerConstantOperation::Create(*delta->subregion(), { 32, 1 }).output(0);
1943
1944 return &delta->finalize(constant);
1945 };
1946
1947 auto SetupG2 = [&](rvsdg::Output & g1)
1948 {
1949 auto pointerType = PointerType::Create();
1950
1951 auto delta = jlm::rvsdg::DeltaNode::Create(
1952 &graph->GetRootRegion(),
1953 LlvmDeltaOperation::Create(pointerType, "g2", Linkage::externalLinkage, "", false, 4));
1954
1955 auto ctxVar = delta->AddContextVar(g1);
1956
1957 return &delta->finalize(ctxVar.inner);
1958 };
1959
1960 auto SetupF = [&](rvsdg::Output & g1, rvsdg::Output & g2)
1961 {
1962 auto iOStateType = IOStateType::Create();
1963 auto memoryStateType = MemoryStateType::Create();
1964 auto functionType = rvsdg::FunctionType::Create(
1965 { IOStateType::Create(), MemoryStateType::Create() },
1966 { jlm::rvsdg::BitType::Create(16), IOStateType::Create(), MemoryStateType::Create() });
1967
1968 auto lambda = rvsdg::LambdaNode::Create(
1969 graph->GetRootRegion(),
1970 llvm::LlvmLambdaOperation::Create(functionType, "f", Linkage::externalLinkage));
1971 auto iOStateArgument = lambda->GetFunctionArguments()[0];
1972 auto memoryStateArgument = lambda->GetFunctionArguments()[1];
1973 auto g1CtxVar = lambda->AddContextVar(g1).inner;
1974 auto g2CtxVar = lambda->AddContextVar(g2).inner;
1975
1976 auto loadResults = LoadNonVolatileOperation::Create(
1977 g2CtxVar,
1978 { memoryStateArgument },
1979 PointerType::Create(),
1980 8);
1981 auto storeResults =
1982 StoreNonVolatileOperation::Create(g2CtxVar, loadResults[0], { loadResults[1] }, 8);
1983
1984 loadResults = LoadNonVolatileOperation::Create(
1985 g1CtxVar,
1986 storeResults,
1988 8);
1989 auto & truncResult = TruncOperation::create(16, *loadResults[0]);
1990
1991 return lambda->finalize({ &truncResult, iOStateArgument, loadResults[1] });
1992 };
1993
1994 auto SetupTest = [&](rvsdg::Output & lambdaF)
1995 {
1996 auto iOStateType = IOStateType::Create();
1997 auto memoryStateType = MemoryStateType::Create();
1998 auto functionType = rvsdg::FunctionType::Create(
1999 { IOStateType::Create(), MemoryStateType::Create() },
2000 { IOStateType::Create(), MemoryStateType::Create() });
2001
2002 auto lambda = rvsdg::LambdaNode::Create(
2003 graph->GetRootRegion(),
2004 llvm::LlvmLambdaOperation::Create(functionType, "test", Linkage::externalLinkage));
2005 auto iOStateArgument = lambda->GetFunctionArguments()[0];
2006 auto memoryStateArgument = lambda->GetFunctionArguments()[1];
2007
2008 auto lambdaFArgument = lambda->AddContextVar(lambdaF).inner;
2009
2010 auto & call = CallOperation::CreateNode(
2011 lambdaFArgument,
2012 rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(lambdaF).GetOperation().Type(),
2013 { iOStateArgument, memoryStateArgument });
2014
2015 auto lambdaOutput = lambda->finalize(
2016 { &CallOperation::GetIOStateOutput(call), &CallOperation::GetMemoryStateOutput(call) });
2017 GraphExport::Create(*lambdaOutput, "test");
2018
2019 return std::make_tuple(lambdaOutput, &call);
2020 };
2021
2022 auto g1 = SetupG1();
2023 auto g2 = SetupG2(*g1);
2024 auto f = SetupF(*g1, *g2);
2025 auto [test, callF] = SetupTest(*f);
2026
2027 /*
2028 * Assign nodes
2029 */
2031 this->LambdaTest_ = &rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(*test);
2032
2033 this->DeltaG1_ = &rvsdg::AssertGetOwnerNode<rvsdg::DeltaNode>(*g1);
2034 this->DeltaG2_ = &rvsdg::AssertGetOwnerNode<rvsdg::DeltaNode>(*g2);
2035
2036 this->CallF_ = callF;
2037
2038 return module;
2039}
2040
2041std::unique_ptr<jlm::llvm::LlvmRvsdgModule>
2042ImportTest::SetupRvsdg()
2043{
2044 using namespace jlm::llvm;
2045 using namespace jlm::rvsdg;
2046
2047 auto module = llvm::LlvmRvsdgModule::Create(jlm::util::FilePath(""), "", "");
2048 auto graph = &module->Rvsdg();
2049
2050 auto SetupF1 = [&](jlm::rvsdg::Output * d1)
2051 {
2052 auto iOStateType = IOStateType::Create();
2053 auto memoryStateType = MemoryStateType::Create();
2054 auto functionType = rvsdg::FunctionType::Create(
2055 { IOStateType::Create(), MemoryStateType::Create() },
2056 { IOStateType::Create(), MemoryStateType::Create() });
2057
2058 auto lambda = rvsdg::LambdaNode::Create(
2059 graph->GetRootRegion(),
2060 llvm::LlvmLambdaOperation::Create(functionType, "f1", Linkage::externalLinkage));
2061 auto iOStateArgument = lambda->GetFunctionArguments()[0];
2062 auto memoryStateArgument = lambda->GetFunctionArguments()[1];
2063
2064 auto cvd1 = lambda->AddContextVar(*d1).inner;
2065
2066 auto b5 = IntegerConstantOperation::Create(*lambda->subregion(), { 32, 5 }).output(0);
2067 auto st = StoreNonVolatileOperation::Create(cvd1, b5, { memoryStateArgument }, 4);
2068
2069 return lambda->finalize({ iOStateArgument, st[0] });
2070 };
2071
2072 auto SetupF2 = [&](rvsdg::Output * f1, jlm::rvsdg::Output * d1, jlm::rvsdg::Output * d2)
2073 {
2074 auto iOStateType = IOStateType::Create();
2075 auto memoryStateType = MemoryStateType::Create();
2076 auto functionType = rvsdg::FunctionType::Create(
2077 { IOStateType::Create(), MemoryStateType::Create() },
2078 { IOStateType::Create(), MemoryStateType::Create() });
2079
2080 auto lambda = rvsdg::LambdaNode::Create(
2081 graph->GetRootRegion(),
2082 llvm::LlvmLambdaOperation::Create(functionType, "f2", Linkage::externalLinkage));
2083 auto iOStateArgument = lambda->GetFunctionArguments()[0];
2084 auto memoryStateArgument = lambda->GetFunctionArguments()[1];
2085
2086 auto cvd1 = lambda->AddContextVar(*d1).inner;
2087 auto cvd2 = lambda->AddContextVar(*d2).inner;
2088 auto cvf1 = lambda->AddContextVar(*f1).inner;
2089 auto b2 = IntegerConstantOperation::Create(*lambda->subregion(), { 32, 2 }).output(0);
2090 auto b21 = IntegerConstantOperation::Create(*lambda->subregion(), { 32, 21 }).output(0);
2091 auto st = StoreNonVolatileOperation::Create(cvd1, b2, { memoryStateArgument }, 4);
2092 auto & call = CallOperation::CreateNode(
2093 cvf1,
2094 rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(*f1).GetOperation().Type(),
2095 { iOStateArgument, st[0] });
2096 st = StoreNonVolatileOperation::Create(
2097 cvd2,
2098 b21,
2099 { &CallOperation::GetMemoryStateOutput(call) },
2100 4);
2101
2102 auto lambdaOutput = lambda->finalize(outputs(&call));
2103 GraphExport::Create(*lambda->output(), "f2");
2104
2105 return std::make_tuple(lambdaOutput, &call);
2106 };
2107
2109 *graph,
2110 BitType::Create(32),
2111 PointerType::Create(),
2112 "d1",
2113 Linkage::externalLinkage,
2114 false,
2115 4);
2117 *graph,
2119 PointerType::Create(),
2120 "d2",
2121 Linkage::externalLinkage,
2122 false,
2123 4);
2124
2125 auto f1 = SetupF1(d1);
2126 auto [f2, callF1] = SetupF2(f1, d1, d2);
2127
2128 // Assign nodes
2129 this->lambda_f1 = &rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(*f1);
2130 this->lambda_f2 = &rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(*f2);
2131
2132 this->CallF1_ = callF1;
2133
2134 this->import_d1 = d1;
2135 this->import_d2 = d2;
2136
2137 return module;
2138}
2139
2140std::unique_ptr<jlm::llvm::LlvmRvsdgModule>
2141PhiTest1::SetupRvsdg()
2142{
2143 using namespace jlm::llvm;
2144 using namespace jlm::rvsdg;
2145
2146 auto module = llvm::LlvmRvsdgModule::Create(jlm::util::FilePath(""), "", "");
2147 auto graph = &module->Rvsdg();
2148
2149 auto iOStateType = IOStateType::Create();
2150 auto memoryStateType = MemoryStateType::Create();
2151 auto fibFunctionType = rvsdg::FunctionType::Create(
2153 PointerType::Create(),
2154 IOStateType::Create(),
2155 MemoryStateType::Create() },
2156 { IOStateType::Create(), MemoryStateType::Create() });
2157
2158 auto SetupFib = [&]()
2159 {
2160 auto pt = PointerType::Create();
2161
2163 pb.begin(&graph->GetRootRegion());
2164 auto fibrv = pb.AddFixVar(fibFunctionType);
2165
2166 auto lambda = rvsdg::LambdaNode::Create(
2167 *pb.subregion(),
2168 llvm::LlvmLambdaOperation::Create(fibFunctionType, "fib", Linkage::externalLinkage));
2169 auto valueArgument = lambda->GetFunctionArguments()[0];
2170 auto pointerArgument = lambda->GetFunctionArguments()[1];
2171 auto iOStateArgument = lambda->GetFunctionArguments()[2];
2172 auto memoryStateArgument = lambda->GetFunctionArguments()[3];
2173 auto ctxVarFib = lambda->AddContextVar(*fibrv.recref).inner;
2174
2175 auto two = IntegerConstantOperation::Create(*lambda->subregion(), { 64, 2 }).output(0);
2176 auto bitult = IntegerUltOperation::createNode(64, *valueArgument, *two).output(0);
2177 auto & predicateNode = MatchOperation::CreateNode(*bitult, { { 0, 1 } }, 0, 2);
2178
2179 auto gammaNode = GammaNode::create(predicateNode.output(0), 2);
2180 auto nev = gammaNode->AddEntryVar(valueArgument);
2181 auto resultev = gammaNode->AddEntryVar(pointerArgument);
2182 auto fibev = gammaNode->AddEntryVar(ctxVarFib);
2183 auto gIIoState = gammaNode->AddEntryVar(iOStateArgument);
2184 auto gIMemoryState = gammaNode->AddEntryVar(memoryStateArgument);
2185
2186 /* gamma subregion 0 */
2187 auto one = IntegerConstantOperation::Create(*gammaNode->subregion(0), { 64, 1 }).output(0);
2188 auto nm1 = IntegerSubOperation::createNode(64, *nev.branchArgument[0], *one).output(0);
2189 auto & callFibm1 = CallOperation::CreateNode(
2190 fibev.branchArgument[0],
2191 fibFunctionType,
2192 { nm1,
2193 resultev.branchArgument[0],
2194 gIIoState.branchArgument[0],
2195 gIMemoryState.branchArgument[0] });
2196
2197 two = IntegerConstantOperation::Create(*gammaNode->subregion(0), { 64, 2 }).output(0);
2198 auto nm2 = IntegerSubOperation::createNode(64, *nev.branchArgument[0], *two).output(0);
2199 auto & callFibm2 = CallOperation::CreateNode(
2200 fibev.branchArgument[0],
2201 fibFunctionType,
2202 { nm2,
2203 resultev.branchArgument[0],
2204 &CallOperation::GetIOStateOutput(callFibm1),
2205 &CallOperation::GetMemoryStateOutput(callFibm1) });
2206
2207 auto gepnm1 = GetElementPtrOperation::create(
2208 resultev.branchArgument[0],
2209 { nm1 },
2211 auto ldnm1 = LoadNonVolatileOperation::Create(
2212 gepnm1,
2213 { &CallOperation::GetMemoryStateOutput(callFibm2) },
2215 8);
2216
2217 auto gepnm2 = GetElementPtrOperation::create(
2218 resultev.branchArgument[0],
2219 { nm2 },
2221 auto ldnm2 =
2222 LoadNonVolatileOperation::Create(gepnm2, { ldnm1[1] }, jlm::rvsdg::BitType::Create(64), 8);
2223
2224 auto sum = IntegerAddOperation::createNode(64, *ldnm1[0], *ldnm2[0]).output(0);
2225
2226 /* gamma subregion 1 */
2227 /* Nothing needs to be done */
2228
2229 auto sumex = gammaNode->AddExitVar({ sum, nev.branchArgument[1] });
2230 auto gOIoState = gammaNode->AddExitVar(
2231 { &CallOperation::GetIOStateOutput(callFibm2), gIIoState.branchArgument[1] });
2232 auto gOMemoryState = gammaNode->AddExitVar({ ldnm2[1], gIMemoryState.branchArgument[1] });
2233
2234 auto gepn = GetElementPtrOperation::create(
2235 pointerArgument,
2236 { valueArgument },
2238 auto store = StoreNonVolatileOperation::Create(gepn, sumex.output, { gOMemoryState.output }, 8);
2239
2240 auto lambdaOutput = lambda->finalize({ gOIoState.output, store[0] });
2241
2242 fibrv.result->divert_to(lambdaOutput);
2243 auto phiNode = pb.end();
2244
2245 return std::make_tuple(phiNode, lambdaOutput, gammaNode, &callFibm1, &callFibm2);
2246 };
2247
2248 auto SetupTestFunction = [&](rvsdg::PhiNode * phiNode)
2249 {
2250 auto at = ArrayType::Create(jlm::rvsdg::BitType::Create(64), 10);
2251 auto iOStateType = IOStateType::Create();
2252 auto memoryStateType = MemoryStateType::Create();
2253 auto functionType = rvsdg::FunctionType::Create(
2254 { IOStateType::Create(), MemoryStateType::Create() },
2255 { IOStateType::Create(), MemoryStateType::Create() });
2256
2257 auto lambda = rvsdg::LambdaNode::Create(
2258 graph->GetRootRegion(),
2259 llvm::LlvmLambdaOperation::Create(functionType, "test", Linkage::externalLinkage));
2260 auto iOStateArgument = lambda->GetFunctionArguments()[0];
2261 auto memoryStateArgument = lambda->GetFunctionArguments()[1];
2262 auto fibcv = lambda->AddContextVar(*phiNode->output(0)).inner;
2263
2264 auto constantOne = IntegerConstantOperation::Create(*lambda->subregion(), { 64, 1 }).output(0);
2265 auto constantTen = IntegerConstantOperation::Create(*lambda->subregion(), { 64, 10 }).output(0);
2266
2267 auto allocaResults = AllocaOperation::create(at, constantOne, 16);
2268 auto state = MemoryStateMergeOperation::Create(
2269 std::vector<jlm::rvsdg::Output *>{ allocaResults[1], memoryStateArgument });
2270
2271 auto zero = IntegerConstantOperation::Create(*lambda->subregion(), { 64, 0 }).output(0);
2272 auto gep = GetElementPtrOperation::create(allocaResults[0], { zero, zero }, at);
2273
2274 auto & call = CallOperation::CreateNode(
2275 fibcv,
2276 fibFunctionType,
2277 { constantTen, gep, iOStateArgument, state });
2278
2279 auto lambdaOutput = lambda->finalize(outputs(&call));
2280 GraphExport::Create(*lambdaOutput, "test");
2281
2282 return std::make_tuple(
2283 lambdaOutput,
2284 &call,
2286 };
2287
2288 auto [phiNode, fibfct, gammaNode, callFib1, callFib2] = SetupFib();
2289 auto [testfct, callFib, alloca] = SetupTestFunction(phiNode);
2290
2291 // Assign nodes
2292 this->lambda_fib = &rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(*fibfct);
2293 this->lambda_test = &rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(*testfct);
2294
2295 this->gamma = gammaNode;
2296 this->phi = phiNode;
2297
2298 this->CallFibm1_ = callFib1;
2299 this->CallFibm2_ = callFib2;
2300
2301 this->CallFib_ = callFib;
2302
2303 this->alloca = alloca;
2304
2305 return module;
2306}
2307
2308std::unique_ptr<jlm::llvm::LlvmRvsdgModule>
2309PhiTest2::SetupRvsdg()
2310{
2311 using namespace jlm::llvm;
2312 using namespace jlm::rvsdg;
2313
2314 auto iOStateType = IOStateType::Create();
2315 auto memoryStateType = MemoryStateType::Create();
2316
2317 auto pointerType = PointerType::Create();
2318
2319 auto constantFunctionType = rvsdg::FunctionType::Create(
2320 { IOStateType::Create(), MemoryStateType::Create() },
2321 { jlm::rvsdg::BitType::Create(32), IOStateType::Create(), MemoryStateType::Create() });
2322
2323 auto recursiveFunctionType = rvsdg::FunctionType::Create(
2324 { PointerType::Create(), IOStateType::Create(), MemoryStateType::Create() },
2325 { jlm::rvsdg::BitType::Create(32), IOStateType::Create(), MemoryStateType::Create() });
2326
2327 auto functionIType = rvsdg::FunctionType::Create(
2328 { PointerType::Create(), IOStateType::Create(), MemoryStateType::Create() },
2329 { jlm::rvsdg::BitType::Create(32), IOStateType::Create(), MemoryStateType::Create() });
2330
2331 auto recFunctionType = rvsdg::FunctionType::Create(
2332 { PointerType::Create(), IOStateType::Create(), MemoryStateType::Create() },
2333 { jlm::rvsdg::BitType::Create(32), IOStateType::Create(), MemoryStateType::Create() });
2334
2335 auto module = llvm::LlvmRvsdgModule::Create(jlm::util::FilePath(""), "", "");
2336 auto graph = &module->Rvsdg();
2337
2338 auto SetupEight = [&]()
2339 {
2340 auto lambda = rvsdg::LambdaNode::Create(
2341 graph->GetRootRegion(),
2342 llvm::LlvmLambdaOperation::Create(constantFunctionType, "eight", Linkage::externalLinkage));
2343 auto iOStateArgument = lambda->GetFunctionArguments()[0];
2344 auto memoryStateArgument = lambda->GetFunctionArguments()[1];
2345
2346 auto constant = IntegerConstantOperation::Create(*lambda->subregion(), { 32, 8 }).output(0);
2347
2348 return lambda->finalize({ constant, iOStateArgument, memoryStateArgument });
2349 };
2350
2351 auto SetupI = [&]()
2352 {
2353 auto lambda = rvsdg::LambdaNode::Create(
2354 graph->GetRootRegion(),
2355 llvm::LlvmLambdaOperation::Create(functionIType, "i", Linkage::externalLinkage));
2356 auto pointerArgument = lambda->GetFunctionArguments()[0];
2357 auto functionArgument =
2358 rvsdg::CreateOpNode<PointerToFunctionOperation>({ pointerArgument }, constantFunctionType)
2359 .output(0);
2360 auto iOStateArgument = lambda->GetFunctionArguments()[1];
2361 auto memoryStateArgument = lambda->GetFunctionArguments()[2];
2362
2363 auto & call = CallOperation::CreateNode(
2364 functionArgument,
2365 constantFunctionType,
2366 { iOStateArgument, memoryStateArgument });
2367
2368 auto lambdaOutput = lambda->finalize(outputs(&call));
2369
2370 return std::make_tuple(lambdaOutput, &call);
2371 };
2372
2373 auto SetupA = [&](jlm::rvsdg::Region & region,
2374 jlm::rvsdg::Output & functionB,
2375 jlm::rvsdg::Output & functionD)
2376 {
2377 auto lambda = rvsdg::LambdaNode::Create(
2378 region,
2379 llvm::LlvmLambdaOperation::Create(recFunctionType, "a", Linkage::externalLinkage));
2380 auto pointerArgument = lambda->GetFunctionArguments()[0];
2381 auto iOStateArgument = lambda->GetFunctionArguments()[1];
2382 auto memoryStateArgument = lambda->GetFunctionArguments()[2];
2383
2384 auto functionBCv = lambda->AddContextVar(functionB).inner;
2385 auto functionDCv = lambda->AddContextVar(functionD).inner;
2386
2387 auto one = IntegerConstantOperation::Create(*lambda->subregion(), { 32, 1 }).output(0);
2388 auto storeNode =
2389 StoreNonVolatileOperation::Create(pointerArgument, one, { memoryStateArgument }, 4);
2390
2391 auto constantOne = IntegerConstantOperation::Create(*lambda->subregion(), { 32, 1 }).output(0);
2392
2393 auto paAlloca = AllocaOperation::create(jlm::rvsdg::BitType::Create(32), constantOne, 4);
2394 auto paMerge = MemoryStateMergeOperation::Create(
2395 std::vector<jlm::rvsdg::Output *>({ paAlloca[1], storeNode[0] }));
2396
2397 auto & callB = CallOperation::CreateNode(
2398 functionBCv,
2399 recFunctionType,
2400 { paAlloca[0], iOStateArgument, paMerge });
2401
2402 auto & callD = CallOperation::CreateNode(
2403 functionDCv,
2404 recFunctionType,
2405 { paAlloca[0],
2406 &CallOperation::GetIOStateOutput(callB),
2407 &CallOperation::GetMemoryStateOutput(callB) });
2408
2409 auto sum = IntegerAddOperation::createNode(32, *callB.output(0), *callD.output(0)).output(0);
2410
2411 auto lambdaOutput = lambda->finalize({ sum,
2412 &CallOperation::GetIOStateOutput(callD),
2413 &CallOperation::GetMemoryStateOutput(callD) });
2414
2415 return std::make_tuple(
2416 lambdaOutput,
2417 &callB,
2418 &callD,
2419 jlm::util::assertedCast<jlm::rvsdg::SimpleNode>(
2421 };
2422
2423 auto SetupB = [&](jlm::rvsdg::Region & region,
2424 jlm::rvsdg::Output & functionI,
2425 jlm::rvsdg::Output & functionC,
2426 jlm::rvsdg::Output & functionEight)
2427 {
2428 auto lambda = rvsdg::LambdaNode::Create(
2429 region,
2430 llvm::LlvmLambdaOperation::Create(recFunctionType, "b", Linkage::externalLinkage));
2431 auto pointerArgument = lambda->GetFunctionArguments()[0];
2432 auto iOStateArgument = lambda->GetFunctionArguments()[1];
2433 auto memoryStateArgument = lambda->GetFunctionArguments()[2];
2434
2435 auto functionICv = lambda->AddContextVar(functionI).inner;
2436 auto functionCCv = lambda->AddContextVar(functionC).inner;
2437 auto functionEightCv = lambda->AddContextVar(functionEight).inner;
2438
2439 auto two = IntegerConstantOperation::Create(*lambda->subregion(), { 32, 2 }).output(0);
2440 auto storeNode =
2441 StoreNonVolatileOperation::Create(pointerArgument, two, { memoryStateArgument }, 4);
2442
2443 auto constantOne = IntegerConstantOperation::Create(*lambda->subregion(), { 32, 1 }).output(0);
2444
2445 auto pbAlloca = AllocaOperation::create(jlm::rvsdg::BitType::Create(32), constantOne, 4);
2446 auto pbMerge = MemoryStateMergeOperation::Create(
2447 std::vector<jlm::rvsdg::Output *>({ pbAlloca[1], storeNode[0] }));
2448
2449 auto & callI = CallOperation::CreateNode(
2450 functionICv,
2451 functionIType,
2452 { rvsdg::CreateOpNode<FunctionToPointerOperation>({ functionEightCv }, constantFunctionType)
2453 .output(0),
2454 iOStateArgument,
2455 pbMerge });
2456
2457 auto & callC = CallOperation::CreateNode(
2458 functionCCv,
2459 recFunctionType,
2460 { pbAlloca[0],
2461 &CallOperation::GetIOStateOutput(callI),
2462 &CallOperation::GetMemoryStateOutput(callI) });
2463
2464 auto sum = IntegerAddOperation::createNode(32, *callI.output(0), *callC.output(0)).output(0);
2465
2466 auto lambdaOutput = lambda->finalize({ sum,
2467 &CallOperation::GetIOStateOutput(callC),
2468 &CallOperation::GetMemoryStateOutput(callC) });
2469
2470 return std::make_tuple(
2471 lambdaOutput,
2472 &callI,
2473 &callC,
2474 jlm::util::assertedCast<jlm::rvsdg::SimpleNode>(
2476 };
2477
2478 auto SetupC = [&](jlm::rvsdg::Region & region, jlm::rvsdg::Output & functionA)
2479 {
2480 auto lambda = rvsdg::LambdaNode::Create(
2481 region,
2482 llvm::LlvmLambdaOperation::Create(recFunctionType, "c", Linkage::externalLinkage));
2483 auto xArgument = lambda->GetFunctionArguments()[0];
2484 auto iOStateArgument = lambda->GetFunctionArguments()[1];
2485 auto memoryStateArgument = lambda->GetFunctionArguments()[2];
2486
2487 auto functionACv = lambda->AddContextVar(functionA).inner;
2488
2489 auto three = IntegerConstantOperation::Create(*lambda->subregion(), { 32, 3 }).output(0);
2490 auto storeNode =
2491 StoreNonVolatileOperation::Create(xArgument, three, { memoryStateArgument }, 4);
2492
2493 auto constanOne = IntegerConstantOperation::Create(*lambda->subregion(), { 32, 1 }).output(0);
2494 auto pcAlloca = AllocaOperation::create(jlm::rvsdg::BitType::Create(32), constanOne, 4);
2495 auto pcMerge = MemoryStateMergeOperation::Create(
2496 std::vector<jlm::rvsdg::Output *>({ pcAlloca[1], storeNode[0] }));
2497
2498 auto & callA = CallOperation::CreateNode(
2499 functionACv,
2500 recFunctionType,
2501 { pcAlloca[0], iOStateArgument, pcMerge });
2502
2503 auto loadX = LoadNonVolatileOperation::Create(
2504 xArgument,
2505 { &CallOperation::GetMemoryStateOutput(callA) },
2507 4);
2508
2509 auto sum = IntegerAddOperation::createNode(32, *callA.output(0), *loadX[0]).output(0);
2510
2511 auto lambdaOutput =
2512 lambda->finalize({ sum, &CallOperation::GetIOStateOutput(callA), loadX[1] });
2513
2514 return std::make_tuple(
2515 lambdaOutput,
2516 &callA,
2517 jlm::util::assertedCast<jlm::rvsdg::SimpleNode>(
2519 };
2520
2521 auto SetupD = [&](jlm::rvsdg::Region & region, jlm::rvsdg::Output & functionA)
2522 {
2523 auto lambda = rvsdg::LambdaNode::Create(
2524 region,
2525 llvm::LlvmLambdaOperation::Create(recFunctionType, "d", Linkage::externalLinkage));
2526 auto xArgument = lambda->GetFunctionArguments()[0];
2527 auto iOStateArgument = lambda->GetFunctionArguments()[1];
2528 auto memoryStateArgument = lambda->GetFunctionArguments()[2];
2529
2530 auto functionACv = lambda->AddContextVar(functionA).inner;
2531
2532 auto four = IntegerConstantOperation::Create(*lambda->subregion(), { 32, 4 }).output(0);
2533 auto storeNode = StoreNonVolatileOperation::Create(xArgument, four, { memoryStateArgument }, 4);
2534
2535 auto constantOne = IntegerConstantOperation::Create(*lambda->subregion(), { 32, 1 }).output(0);
2536 auto pdAlloca = AllocaOperation::create(jlm::rvsdg::BitType::Create(32), constantOne, 4);
2537 auto pdMerge = MemoryStateMergeOperation::Create(
2538 std::vector<jlm::rvsdg::Output *>({ pdAlloca[1], storeNode[0] }));
2539
2540 auto & callA = CallOperation::CreateNode(
2541 functionACv,
2542 recFunctionType,
2543 { pdAlloca[0], iOStateArgument, pdMerge });
2544
2545 auto lambdaOutput = lambda->finalize(outputs(&callA));
2546
2547 return std::make_tuple(
2548 lambdaOutput,
2549 &callA,
2550 jlm::util::assertedCast<jlm::rvsdg::SimpleNode>(
2552 };
2553
2554 auto SetupPhi = [&](rvsdg::Output & lambdaEight, rvsdg::Output & lambdaI)
2555 {
2556 jlm::rvsdg::PhiBuilder phiBuilder;
2557 phiBuilder.begin(&graph->GetRootRegion());
2558 auto lambdaARv = phiBuilder.AddFixVar(recFunctionType);
2559 auto lambdaBRv = phiBuilder.AddFixVar(recFunctionType);
2560 auto lambdaCRv = phiBuilder.AddFixVar(recFunctionType);
2561 auto lambdaDRv = phiBuilder.AddFixVar(recFunctionType);
2562 auto lambdaEightCv = phiBuilder.AddContextVar(lambdaEight);
2563 auto lambdaICv = phiBuilder.AddContextVar(lambdaI);
2564
2565 auto [lambdaAOutput, callB, callD, paAlloca] =
2566 SetupA(*phiBuilder.subregion(), *lambdaBRv.recref, *lambdaDRv.recref);
2567
2568 auto [lambdaBOutput, callI, callC, pbAlloca] =
2569 SetupB(*phiBuilder.subregion(), *lambdaICv.inner, *lambdaCRv.recref, *lambdaEightCv.inner);
2570
2571 auto [lambdaCOutput, callAFromC, pcAlloca] = SetupC(*phiBuilder.subregion(), *lambdaARv.recref);
2572
2573 auto [lambdaDOutput, callAFromD, pdAlloca] = SetupD(*phiBuilder.subregion(), *lambdaARv.recref);
2574
2575 lambdaARv.result->divert_to(lambdaAOutput);
2576 lambdaBRv.result->divert_to(lambdaBOutput);
2577 lambdaCRv.result->divert_to(lambdaCOutput);
2578 lambdaDRv.result->divert_to(lambdaDOutput);
2579
2580 phiBuilder.end();
2581
2582 return std::make_tuple(
2583 lambdaARv,
2584 lambdaBRv,
2585 lambdaCRv,
2586 lambdaDRv,
2587 callB,
2588 callD,
2589 callI,
2590 callC,
2591 callAFromC,
2592 callAFromD,
2593 paAlloca,
2594 pbAlloca,
2595 pcAlloca,
2596 pdAlloca);
2597 };
2598
2599 auto SetupTest = [&](rvsdg::Output & functionA)
2600 {
2601 auto pointerType = PointerType::Create();
2602
2603 auto functionType = rvsdg::FunctionType::Create(
2604 { IOStateType::Create(), MemoryStateType::Create() },
2605 { jlm::rvsdg::BitType::Create(32), IOStateType::Create(), MemoryStateType::Create() });
2606
2607 auto lambda = rvsdg::LambdaNode::Create(
2608 graph->GetRootRegion(),
2609 llvm::LlvmLambdaOperation::Create(functionType, "test", Linkage::externalLinkage));
2610 auto iOStateArgument = lambda->GetFunctionArguments()[0];
2611 auto memoryStateArgument = lambda->GetFunctionArguments()[1];
2612
2613 auto functionACv = lambda->AddContextVar(functionA).inner;
2614
2615 auto constantOne = IntegerConstantOperation::Create(*lambda->subregion(), { 32, 1 }).output(0);
2616 auto pTestAlloca = AllocaOperation::create(jlm::rvsdg::BitType::Create(32), constantOne, 4);
2617 auto pTestMerge = MemoryStateMergeOperation::Create(
2618 std::vector<jlm::rvsdg::Output *>({ pTestAlloca[1], memoryStateArgument }));
2619
2620 auto & callA = CallOperation::CreateNode(
2621 functionACv,
2622 recFunctionType,
2623 { pTestAlloca[0], iOStateArgument, pTestMerge });
2624
2625 auto lambdaOutput = lambda->finalize(outputs(&callA));
2626 GraphExport::Create(*lambdaOutput, "test");
2627
2628 return std::make_tuple(
2629 lambdaOutput,
2630 &callA,
2631 jlm::util::assertedCast<jlm::rvsdg::SimpleNode>(
2632 rvsdg::TryGetOwnerNode<rvsdg::Node>(*pTestAlloca[0])));
2633 };
2634
2635 auto lambdaEight = SetupEight();
2636 auto [lambdaI, indirectCall] = SetupI();
2637
2638 auto
2639 [lambdaA,
2640 lambdaB,
2641 lambdaC,
2642 lambdaD,
2643 callB,
2644 callD,
2645 callI,
2646 callC,
2647 callAFromC,
2648 callAFromD,
2649 paAlloca,
2650 pbAlloca,
2651 pcAlloca,
2652 pdAlloca] = SetupPhi(*lambdaEight, *lambdaI);
2653
2654 auto [lambdaTest, callAFromTest, pTestAlloca] = SetupTest(*lambdaA.output);
2655
2656 /*
2657 * Assign nodes
2658 */
2659 this->LambdaEight_ = &rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(*lambdaEight);
2660 this->LambdaI_ = &rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(*lambdaI);
2661 this->LambdaA_ = &rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(*lambdaA.result->origin());
2662 this->LambdaB_ = &rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(*lambdaB.result->origin());
2663 this->LambdaC_ = &rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(*lambdaC.result->origin());
2664 this->LambdaD_ = &rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(*lambdaD.result->origin());
2665 this->LambdaTest_ = &rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(*lambdaTest);
2666
2667 this->CallAFromTest_ = callAFromTest;
2668 this->CallAFromC_ = callAFromC;
2669 this->CallAFromD_ = callAFromD;
2670 this->CallB_ = callB;
2671 this->CallC_ = callC;
2672 this->CallD_ = callD;
2673 this->CallI_ = callI;
2674 this->IndirectCall_ = indirectCall;
2675
2676 this->PTestAlloca_ = pTestAlloca;
2677 this->PaAlloca_ = paAlloca;
2678 this->PbAlloca_ = pbAlloca;
2679 this->PcAlloca_ = pcAlloca;
2680 this->PdAlloca_ = pdAlloca;
2681
2682 return module;
2683}
2684
2685std::unique_ptr<jlm::llvm::LlvmRvsdgModule>
2686PhiWithDeltaTest::SetupRvsdg()
2687{
2688 using namespace jlm::llvm;
2689 using namespace jlm::rvsdg;
2690
2691 auto rvsdgModule = llvm::LlvmRvsdgModule::Create(jlm::util::FilePath(""), "", "");
2692 auto & rvsdg = rvsdgModule->Rvsdg();
2693
2694 auto pointerType = PointerType::Create();
2695 auto structType = StructType::CreateIdentified("myStruct", { PointerType::Create() }, false);
2696 auto arrayType = ArrayType::Create(structType, 2);
2697
2699 pb.begin(&rvsdg.GetRootRegion());
2700 auto myArrayRecVar = pb.AddFixVar(pointerType);
2701
2702 auto delta = jlm::rvsdg::DeltaNode::Create(
2703 pb.subregion(),
2704 LlvmDeltaOperation::Create(arrayType, "myArray", Linkage::externalLinkage, "", false, 4));
2705 auto myArrayArgument = delta->AddContextVar(*myArrayRecVar.recref).inner;
2706
2707 auto aggregateZero = ConstantAggregateZeroOperation::Create(*delta->subregion(), structType);
2708 auto & constantStruct =
2709 ConstantStructOperation::Create(*delta->subregion(), { myArrayArgument }, structType);
2710 auto constantArray = ConstantArrayOperation::Create({ aggregateZero, &constantStruct });
2711
2712 auto deltaOutput = &delta->finalize(constantArray);
2713 Delta_ = &rvsdg::AssertGetOwnerNode<rvsdg::DeltaNode>(*deltaOutput);
2714 myArrayRecVar.result->divert_to(deltaOutput);
2715
2716 auto phiNode = pb.end();
2717 GraphExport::Create(*phiNode->output(0), "myArray");
2718
2719 return rvsdgModule;
2720}
2721
2722std::unique_ptr<jlm::llvm::LlvmRvsdgModule>
2723ExternalMemoryTest::SetupRvsdg()
2724{
2725 using namespace jlm::llvm;
2726 using namespace jlm::rvsdg;
2727
2728 auto mt = MemoryStateType::Create();
2729 auto pointerType = PointerType::Create();
2731 { PointerType::Create(), PointerType::Create(), MemoryStateType::Create() },
2732 { MemoryStateType::Create() });
2733
2734 auto module = llvm::LlvmRvsdgModule::Create(jlm::util::FilePath(""), "", "");
2735 auto graph = &module->Rvsdg();
2736
2740 LambdaF = rvsdg::LambdaNode::Create(
2741 graph->GetRootRegion(),
2742 llvm::LlvmLambdaOperation::Create(ft, "f", Linkage::externalLinkage));
2743 auto x = LambdaF->GetFunctionArguments()[0];
2744 auto y = LambdaF->GetFunctionArguments()[1];
2745 auto state = LambdaF->GetFunctionArguments()[2];
2746
2747 auto one = IntegerConstantOperation::Create(*LambdaF->subregion(), { 32, 1 }).output(0);
2748 auto two = IntegerConstantOperation::Create(*LambdaF->subregion(), { 32, 2 }).output(0);
2749
2750 auto storeOne = StoreNonVolatileOperation::Create(x, one, { state }, 4);
2751 auto storeTwo = StoreNonVolatileOperation::Create(y, two, { storeOne[0] }, 4);
2752
2753 LambdaF->finalize(storeTwo);
2754 GraphExport::Create(*LambdaF->output(), "f");
2755
2756 return module;
2757}
2758
2759std::unique_ptr<jlm::llvm::LlvmRvsdgModule>
2760EscapedMemoryTest1::SetupRvsdg()
2761{
2762 using namespace jlm::llvm;
2763 using namespace jlm::rvsdg;
2764
2765 auto rvsdgModule = llvm::LlvmRvsdgModule::Create(jlm::util::FilePath(""), "", "");
2766 auto rvsdg = &rvsdgModule->Rvsdg();
2767
2768 auto SetupDeltaA = [&]()
2769 {
2770 auto deltaNode = jlm::rvsdg::DeltaNode::Create(
2771 &rvsdg->GetRootRegion(),
2772 LlvmDeltaOperation::Create(
2774 "a",
2775 Linkage::externalLinkage,
2776 "",
2777 false,
2778 4));
2779
2780 auto constant = IntegerConstantOperation::Create(*deltaNode->subregion(), { 32, 1 }).output(0);
2781
2782 return &deltaNode->finalize(constant);
2783 };
2784
2785 auto SetupDeltaB = [&]()
2786 {
2787 auto deltaNode = jlm::rvsdg::DeltaNode::Create(
2788 &rvsdg->GetRootRegion(),
2789 LlvmDeltaOperation::Create(
2791 "b",
2792 Linkage::externalLinkage,
2793 "",
2794 false,
2795 4));
2796
2797 auto constant = IntegerConstantOperation::Create(*deltaNode->subregion(), { 32, 2 }).output(0);
2798
2799 return &deltaNode->finalize(constant);
2800 };
2801
2802 auto SetupDeltaX = [&](rvsdg::Output & deltaA)
2803 {
2804 auto pointerType = PointerType::Create();
2805
2806 auto deltaNode = jlm::rvsdg::DeltaNode::Create(
2807 &rvsdg->GetRootRegion(),
2808 LlvmDeltaOperation::Create(pointerType, "x", Linkage::externalLinkage, "", false, 4));
2809
2810 auto contextVariableA = deltaNode->AddContextVar(deltaA).inner;
2811
2812 return &deltaNode->finalize(contextVariableA);
2813 };
2814
2815 auto SetupDeltaY = [&](rvsdg::Output & deltaX)
2816 {
2817 auto pointerType = PointerType::Create();
2818
2819 auto deltaNode = jlm::rvsdg::DeltaNode::Create(
2820 &rvsdg->GetRootRegion(),
2821 LlvmDeltaOperation::Create(pointerType, "y", Linkage::externalLinkage, "", false, 4));
2822
2823 auto contextVariableX = deltaNode->AddContextVar(deltaX).inner;
2824
2825 auto deltaOutput = &deltaNode->finalize(contextVariableX);
2826 GraphExport::Create(*deltaOutput, "y");
2827
2828 return deltaOutput;
2829 };
2830
2831 auto SetupLambdaTest = [&](rvsdg::Output & deltaB)
2832 {
2833 auto pointerType = PointerType::Create();
2834 auto iOStateType = IOStateType::Create();
2835 auto memoryStateType = MemoryStateType::Create();
2836 auto functionType = rvsdg::FunctionType::Create(
2837 { PointerType::Create(), IOStateType::Create(), MemoryStateType::Create() },
2838 { jlm::rvsdg::BitType::Create(32), IOStateType::Create(), MemoryStateType::Create() });
2839
2840 auto lambda = rvsdg::LambdaNode::Create(
2841 rvsdg->GetRootRegion(),
2842 llvm::LlvmLambdaOperation::Create(functionType, "test", Linkage::externalLinkage));
2843 auto pointerArgument = lambda->GetFunctionArguments()[0];
2844 auto iOStateArgument = lambda->GetFunctionArguments()[1];
2845 auto memoryStateArgument = lambda->GetFunctionArguments()[2];
2846
2847 auto contextVariableB = lambda->AddContextVar(deltaB).inner;
2848
2849 auto loadResults1 =
2850 LoadNonVolatileOperation::Create(pointerArgument, { memoryStateArgument }, pointerType, 4);
2851 auto loadResults2 = LoadNonVolatileOperation::Create(
2852 loadResults1[0],
2853 { loadResults1[1] },
2855 4);
2856
2857 auto five = IntegerConstantOperation::Create(*lambda->subregion(), { 32, 5 }).output(0);
2858 auto storeResults =
2859 StoreNonVolatileOperation::Create(contextVariableB, five, { loadResults2[1] }, 4);
2860
2861 auto lambdaOutput = lambda->finalize({ loadResults2[0], iOStateArgument, storeResults[0] });
2862
2863 GraphExport::Create(*lambdaOutput, "test");
2864
2865 return std::make_tuple(
2866 lambdaOutput,
2867 jlm::util::assertedCast<rvsdg::SimpleNode>(
2869 };
2870
2871 auto deltaA = SetupDeltaA();
2872 auto deltaB = SetupDeltaB();
2873 auto deltaX = SetupDeltaX(*deltaA);
2874 auto deltaY = SetupDeltaY(*deltaX);
2875 auto [lambdaTest, loadNode1] = SetupLambdaTest(*deltaB);
2876
2877 /*
2878 * Assign nodes
2879 */
2880 this->LambdaTest = &rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(*lambdaTest);
2881
2882 this->DeltaA = &rvsdg::AssertGetOwnerNode<rvsdg::DeltaNode>(*deltaA);
2883 this->DeltaB = &rvsdg::AssertGetOwnerNode<rvsdg::DeltaNode>(*deltaB);
2884 this->DeltaX = &rvsdg::AssertGetOwnerNode<rvsdg::DeltaNode>(*deltaX);
2885 this->DeltaY = &rvsdg::AssertGetOwnerNode<rvsdg::DeltaNode>(*deltaY);
2886
2887 this->LoadNode1 = loadNode1;
2888
2889 return rvsdgModule;
2890}
2891
2892std::unique_ptr<jlm::llvm::LlvmRvsdgModule>
2893EscapedMemoryTest2::SetupRvsdg()
2894{
2895 using namespace jlm::llvm;
2896 using namespace jlm::rvsdg;
2897
2898 auto rvsdgModule = llvm::LlvmRvsdgModule::Create(jlm::util::FilePath(""), "", "");
2899 auto rvsdg = &rvsdgModule->Rvsdg();
2900
2901 auto pointerType = PointerType::Create();
2902 auto iOStateType = IOStateType::Create();
2903 auto memoryStateType = MemoryStateType::Create();
2904
2905 auto externalFunction1Type = rvsdg::FunctionType::Create(
2906 { PointerType::Create(), IOStateType::Create(), MemoryStateType::Create() },
2907 { IOStateType::Create(), MemoryStateType::Create() });
2908
2909 auto externalFunction2Type = rvsdg::FunctionType::Create(
2910 { IOStateType::Create(), MemoryStateType::Create() },
2911 { PointerType::Create(), IOStateType::Create(), MemoryStateType::Create() });
2912
2913 auto SetupExternalFunction1Declaration = [&]()
2914 {
2916 *rvsdg,
2917 externalFunction1Type,
2918 "ExternalFunction1",
2919 Linkage::externalLinkage,
2921 };
2922
2923 auto SetupExternalFunction2Declaration = [&]()
2924 {
2926 *rvsdg,
2927 externalFunction2Type,
2928 "ExternalFunction2",
2929 Linkage::externalLinkage,
2931 };
2932
2933 auto SetupReturnAddressFunction = [&]()
2934 {
2935 PointerType p8;
2936 auto iOStateType = IOStateType::Create();
2937 auto memoryStateType = MemoryStateType::Create();
2938 auto functionType = rvsdg::FunctionType::Create(
2939 { IOStateType::Create(), MemoryStateType::Create() },
2940 { PointerType::Create(), IOStateType::Create(), MemoryStateType::Create() });
2941
2942 auto lambda = rvsdg::LambdaNode::Create(
2943 rvsdg->GetRootRegion(),
2944 llvm::LlvmLambdaOperation::Create(functionType, "ReturnAddress", Linkage::externalLinkage));
2945 auto iOStateArgument = lambda->GetFunctionArguments()[0];
2946 auto memoryStateArgument = lambda->GetFunctionArguments()[1];
2947
2948 auto eight = IntegerConstantOperation::Create(*lambda->subregion(), { 32, 8 }).output(0);
2949
2950 auto & mallocNode = MallocOperation::createNode(*eight, *iOStateArgument);
2951 auto mergeResults = MemoryStateMergeOperation::Create(
2952 std::vector({ memoryStateArgument, &MallocOperation::memoryStateOutput(mallocNode) }));
2953
2954 auto lambdaOutput = lambda->finalize({ &MallocOperation::addressOutput(mallocNode),
2955 &MallocOperation::ioStateOutput(mallocNode),
2956 mergeResults });
2957
2958 GraphExport::Create(*lambdaOutput, "ReturnAddress");
2959
2960 return std::make_tuple(lambdaOutput, &mallocNode);
2961 };
2962
2963 auto SetupCallExternalFunction1 = [&](jlm::rvsdg::RegionArgument * externalFunction1Argument)
2964 {
2965 auto iOStateType = IOStateType::Create();
2966 auto memoryStateType = MemoryStateType::Create();
2967 auto functionType = rvsdg::FunctionType::Create(
2968 { IOStateType::Create(), MemoryStateType::Create() },
2969 { IOStateType::Create(), MemoryStateType::Create() });
2970
2971 auto lambda = rvsdg::LambdaNode::Create(
2972 rvsdg->GetRootRegion(),
2974 functionType,
2975 "CallExternalFunction1",
2976 Linkage::externalLinkage));
2977 auto iOStateArgument = lambda->GetFunctionArguments()[0];
2978 auto memoryStateArgument = lambda->GetFunctionArguments()[1];
2979
2980 auto externalFunction1 = lambda->AddContextVar(*externalFunction1Argument).inner;
2981
2982 auto eight = IntegerConstantOperation::Create(*lambda->subregion(), { 32, 8 }).output(0);
2983
2984 auto & mallocNode = MallocOperation::createNode(*eight, *iOStateArgument);
2985 auto mergeResult = MemoryStateMergeOperation::Create(
2986 std::vector({ memoryStateArgument, &MallocOperation::memoryStateOutput(mallocNode) }));
2987
2988 auto & call = CallOperation::CreateNode(
2989 externalFunction1,
2990 externalFunction1Type,
2991 { &MallocOperation::addressOutput(mallocNode),
2992 &MallocOperation::ioStateOutput(mallocNode),
2993 mergeResult });
2994
2995 auto lambdaOutput = lambda->finalize(outputs(&call));
2996
2997 GraphExport::Create(*lambdaOutput, "CallExternalFunction1");
2998
2999 return std::make_tuple(lambdaOutput, &call, &mallocNode);
3000 };
3001
3002 auto SetupCallExternalFunction2 = [&](jlm::rvsdg::RegionArgument * externalFunction2Argument)
3003 {
3004 auto iOStateType = IOStateType::Create();
3005 auto memoryStateType = MemoryStateType::Create();
3006 auto functionType = rvsdg::FunctionType::Create(
3007 { IOStateType::Create(), MemoryStateType::Create() },
3008 { jlm::rvsdg::BitType::Create(32), IOStateType::Create(), MemoryStateType::Create() });
3009
3010 auto lambda = rvsdg::LambdaNode::Create(
3011 rvsdg->GetRootRegion(),
3013 functionType,
3014 "CallExternalFunction2",
3015 Linkage::externalLinkage));
3016 auto iOStateArgument = lambda->GetFunctionArguments()[0];
3017 auto memoryStateArgument = lambda->GetFunctionArguments()[1];
3018
3019 auto externalFunction2 = lambda->AddContextVar(*externalFunction2Argument).inner;
3020
3021 auto & call = CallOperation::CreateNode(
3022 externalFunction2,
3023 externalFunction2Type,
3024 { iOStateArgument, memoryStateArgument });
3025
3026 auto loadResults = LoadNonVolatileOperation::Create(
3027 call.output(0),
3028 { &CallOperation::GetMemoryStateOutput(call) },
3030 4);
3031
3032 auto lambdaOutput = lambda->finalize(
3033 { loadResults[0], &CallOperation::GetIOStateOutput(call), loadResults[1] });
3034
3035 GraphExport::Create(*lambdaOutput, "CallExternalFunction2");
3036
3037 return std::make_tuple(
3038 lambdaOutput,
3039 &call,
3040 jlm::util::assertedCast<rvsdg::SimpleNode>(
3041 rvsdg::TryGetOwnerNode<rvsdg::Node>(*loadResults[0])));
3042 };
3043
3044 auto externalFunction1 = SetupExternalFunction1Declaration();
3045 auto externalFunction2 = SetupExternalFunction2Declaration();
3046 auto [returnAddressFunction, returnAddressMalloc] = SetupReturnAddressFunction();
3047 auto [callExternalFunction1, externalFunction1Call, callExternalFunction1Malloc] =
3048 SetupCallExternalFunction1(externalFunction1);
3049 auto [callExternalFunction2, externalFunction2Call, loadNode] =
3050 SetupCallExternalFunction2(externalFunction2);
3051
3052 /*
3053 * Assign nodes
3054 */
3055 this->ReturnAddressFunction =
3056 &rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(*returnAddressFunction);
3057 this->CallExternalFunction1 =
3058 &rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(*callExternalFunction1);
3059 this->CallExternalFunction2 =
3060 &rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(*callExternalFunction2);
3061
3062 this->ExternalFunction1Call = externalFunction1Call;
3063 this->ExternalFunction2Call = externalFunction2Call;
3064
3065 this->ReturnAddressMalloc = returnAddressMalloc;
3066 this->CallExternalFunction1Malloc = callExternalFunction1Malloc;
3067
3068 this->ExternalFunction1Import = externalFunction1;
3069 this->ExternalFunction2Import = externalFunction2;
3070
3071 this->LoadNode = loadNode;
3072
3073 return rvsdgModule;
3074}
3075
3076std::unique_ptr<jlm::llvm::LlvmRvsdgModule>
3077EscapedMemoryTest3::SetupRvsdg()
3078{
3079 using namespace jlm::llvm;
3080 using namespace jlm::rvsdg;
3081
3082 auto rvsdgModule = llvm::LlvmRvsdgModule::Create(jlm::util::FilePath(""), "", "");
3083 auto rvsdg = &rvsdgModule->Rvsdg();
3084
3085 auto pointerType = PointerType::Create();
3086 auto iOStateType = IOStateType::Create();
3087 auto memoryStateType = MemoryStateType::Create();
3088 auto externalFunctionType = rvsdg::FunctionType::Create(
3089 { IOStateType::Create(), MemoryStateType::Create() },
3090 { PointerType::Create(), IOStateType::Create(), MemoryStateType::Create() });
3091
3092 auto SetupExternalFunctionDeclaration = [&]()
3093 {
3094 return &LlvmGraphImport::createFunctionImport(
3095 *rvsdg,
3096 externalFunctionType,
3097 "externalFunction",
3098 Linkage::externalLinkage,
3100 };
3101
3102 auto SetupGlobal = [&]()
3103 {
3104 auto delta = jlm::rvsdg::DeltaNode::Create(
3105 &rvsdg->GetRootRegion(),
3106 LlvmDeltaOperation::Create(
3108 "global",
3109 Linkage::externalLinkage,
3110 "",
3111 false,
3112 4));
3113
3114 auto constant = IntegerConstantOperation::Create(*delta->subregion(), { 32, 4 }).output(0);
3115
3116 auto deltaOutput = &delta->finalize(constant);
3117
3118 GraphExport::Create(*deltaOutput, "global");
3119
3120 return deltaOutput;
3121 };
3122
3123 auto SetupTestFunction = [&](jlm::rvsdg::RegionArgument * externalFunctionArgument)
3124 {
3125 auto iOStateType = IOStateType::Create();
3126 auto memoryStateType = MemoryStateType::Create();
3127 auto functionType = rvsdg::FunctionType::Create(
3128 { IOStateType::Create(), MemoryStateType::Create() },
3129 { jlm::rvsdg::BitType::Create(32), IOStateType::Create(), MemoryStateType::Create() });
3130
3131 auto lambda = rvsdg::LambdaNode::Create(
3132 rvsdg->GetRootRegion(),
3133 llvm::LlvmLambdaOperation::Create(functionType, "test", Linkage::externalLinkage));
3134 auto iOStateArgument = lambda->GetFunctionArguments()[0];
3135 auto memoryStateArgument = lambda->GetFunctionArguments()[1];
3136
3137 auto externalFunction = lambda->AddContextVar(*externalFunctionArgument).inner;
3138
3139 auto & call = CallOperation::CreateNode(
3140 externalFunction,
3141 externalFunctionType,
3142 { iOStateArgument, memoryStateArgument });
3143
3144 auto loadResults = LoadNonVolatileOperation::Create(
3145 call.output(0),
3146 { &CallOperation::GetMemoryStateOutput(call) },
3148 4);
3149
3150 auto lambdaOutput = lambda->finalize(
3151 { loadResults[0], &CallOperation::GetIOStateOutput(call), loadResults[1] });
3152
3153 GraphExport::Create(*lambdaOutput, "test");
3154
3155 return std::make_tuple(
3156 lambdaOutput,
3157 &call,
3158 jlm::util::assertedCast<rvsdg::SimpleNode>(
3159 rvsdg::TryGetOwnerNode<rvsdg::Node>(*loadResults[0])));
3160 };
3161
3162 auto importExternalFunction = SetupExternalFunctionDeclaration();
3163 auto deltaGlobal = SetupGlobal();
3164 auto [lambdaTest, callExternalFunction, loadNode] = SetupTestFunction(importExternalFunction);
3165
3166 // Assign nodes
3167 this->LambdaTest = &rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(*lambdaTest);
3168 this->DeltaGlobal = &rvsdg::AssertGetOwnerNode<rvsdg::DeltaNode>(*deltaGlobal);
3169 this->ImportExternalFunction = importExternalFunction;
3170 this->CallExternalFunction = callExternalFunction;
3171 this->LoadNode = loadNode;
3172
3173 return rvsdgModule;
3174}
3175
3176std::unique_ptr<jlm::llvm::LlvmRvsdgModule>
3177MemcpyTest::SetupRvsdg()
3178{
3179 using namespace jlm::llvm;
3180 using namespace jlm::rvsdg;
3181
3182 auto rvsdgModule = llvm::LlvmRvsdgModule::Create(jlm::util::FilePath(""), "", "");
3183 auto rvsdg = &rvsdgModule->Rvsdg();
3184
3185 auto arrayType = ArrayType::Create(jlm::rvsdg::BitType::Create(32), 5);
3186
3187 auto SetupInitArray = [&]()
3188 {
3189 auto delta = jlm::rvsdg::DeltaNode::Create(
3190 &rvsdg->GetRootRegion(),
3191 LlvmDeltaOperation::Create(arrayType, "initArray", Linkage::externalLinkage, "", false, 4));
3192
3193 auto zero = IntegerConstantOperation::Create(*delta->subregion(), { 32, 0 }).output(0);
3194 auto one = IntegerConstantOperation::Create(*delta->subregion(), { 32, 1 }).output(0);
3195 auto two = IntegerConstantOperation::Create(*delta->subregion(), { 32, 2 }).output(0);
3196 auto three = IntegerConstantOperation::Create(*delta->subregion(), { 32, 3 }).output(0);
3197 auto four = IntegerConstantOperation::Create(*delta->subregion(), { 32, 4 }).output(0);
3198
3199 auto constantDataArray = ConstantDataArrayOperation::Create({ zero, one, two, three, four });
3200
3201 auto deltaOutput = &delta->finalize(constantDataArray);
3202
3203 GraphExport::Create(*deltaOutput, "initArray");
3204
3205 return deltaOutput;
3206 };
3207
3208 auto SetupGlobalArray = [&]()
3209 {
3210 auto delta = jlm::rvsdg::DeltaNode::Create(
3211 &rvsdg->GetRootRegion(),
3212 LlvmDeltaOperation::Create(
3213 arrayType,
3214 "globalArray",
3215 Linkage::externalLinkage,
3216 "",
3217 false,
3218 4));
3219
3220 auto constantAggregateZero =
3221 ConstantAggregateZeroOperation::Create(*delta->subregion(), arrayType);
3222
3223 auto deltaOutput = &delta->finalize(constantAggregateZero);
3224
3225 GraphExport::Create(*deltaOutput, "globalArray");
3226
3227 return deltaOutput;
3228 };
3229
3230 auto SetupFunctionF = [&](rvsdg::Output & globalArray)
3231 {
3232 auto iOStateType = IOStateType::Create();
3233 auto memoryStateType = MemoryStateType::Create();
3234 auto functionType = rvsdg::FunctionType::Create(
3235 { IOStateType::Create(), MemoryStateType::Create() },
3236 { jlm::rvsdg::BitType::Create(32), IOStateType::Create(), MemoryStateType::Create() });
3237
3238 auto lambda = rvsdg::LambdaNode::Create(
3239 rvsdg->GetRootRegion(),
3240 llvm::LlvmLambdaOperation::Create(functionType, "f", Linkage::externalLinkage));
3241 auto iOStateArgument = lambda->GetFunctionArguments()[0];
3242 auto memoryStateArgument = lambda->GetFunctionArguments()[1];
3243
3244 auto globalArrayArgument = lambda->AddContextVar(globalArray).inner;
3245
3246 auto zero = IntegerConstantOperation::Create(*lambda->subregion(), { 32, 0 }).output(0);
3247 auto two = IntegerConstantOperation::Create(*lambda->subregion(), { 32, 2 }).output(0);
3248 auto six = IntegerConstantOperation::Create(*lambda->subregion(), { 32, 6 }).output(0);
3249
3250 auto gep = GetElementPtrOperation::create(globalArrayArgument, { zero, two }, arrayType);
3251
3252 auto storeResults = StoreNonVolatileOperation::Create(gep, six, { memoryStateArgument }, 8);
3253
3254 auto loadResults = LoadNonVolatileOperation::Create(
3255 gep,
3256 { storeResults[0] },
3258 8);
3259
3260 auto lambdaOutput = lambda->finalize({ loadResults[0], iOStateArgument, loadResults[1] });
3261
3262 GraphExport::Create(*lambdaOutput, "f");
3263
3264 return lambdaOutput;
3265 };
3266
3267 auto SetupFunctionG =
3268 [&](rvsdg::Output & localArray, rvsdg::Output & globalArray, rvsdg::Output & lambdaF)
3269 {
3270 auto iOStateType = IOStateType::Create();
3271 auto memoryStateType = MemoryStateType::Create();
3272 auto functionType = rvsdg::FunctionType::Create(
3273 { IOStateType::Create(), MemoryStateType::Create() },
3274 { jlm::rvsdg::BitType::Create(32), IOStateType::Create(), MemoryStateType::Create() });
3275
3276 auto lambda = rvsdg::LambdaNode::Create(
3277 rvsdg->GetRootRegion(),
3278 llvm::LlvmLambdaOperation::Create(functionType, "g", Linkage::externalLinkage));
3279 auto iOStateArgument = lambda->GetFunctionArguments()[0];
3280 auto memoryStateArgument = lambda->GetFunctionArguments()[1];
3281
3282 auto localArrayArgument = lambda->AddContextVar(localArray).inner;
3283 auto globalArrayArgument = lambda->AddContextVar(globalArray).inner;
3284 auto functionFArgument = lambda->AddContextVar(lambdaF).inner;
3285
3286 auto bcLocalArray = BitCastOperation::create(localArrayArgument, PointerType::Create());
3287 auto bcGlobalArray = BitCastOperation::create(globalArrayArgument, PointerType::Create());
3288
3289 auto twenty = IntegerConstantOperation::Create(*lambda->subregion(), { 32, 20 }).output(0);
3290
3291 auto memcpyResults = MemCpyNonVolatileOperation::create(
3292 bcGlobalArray,
3293 bcLocalArray,
3294 twenty,
3295 { memoryStateArgument });
3296
3297 auto & call = CallOperation::CreateNode(
3298 functionFArgument,
3299 rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(lambdaF).GetOperation().Type(),
3300 { iOStateArgument, memcpyResults[0] });
3301
3302 auto lambdaOutput = lambda->finalize(outputs(&call));
3303
3304 GraphExport::Create(*lambdaOutput, "g");
3305
3306 return std::make_tuple(
3307 lambdaOutput,
3308 &call,
3310 };
3311
3312 auto initArray = SetupInitArray();
3313 auto globalArray = SetupGlobalArray();
3314 auto lambdaF = SetupFunctionF(*globalArray);
3315 auto [lambdaG, callF, memcpyNode] = SetupFunctionG(*initArray, *globalArray, *lambdaF);
3316
3317 /*
3318 * Assign nodes
3319 */
3320 this->LambdaF_ = &rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(*lambdaF);
3321 this->LambdaG_ = &rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(*lambdaG);
3322 this->InitArray_ = &rvsdg::AssertGetOwnerNode<rvsdg::DeltaNode>(*initArray);
3323 this->GlobalArray_ = &rvsdg::AssertGetOwnerNode<rvsdg::DeltaNode>(*globalArray);
3324 this->CallF_ = callF;
3325 this->Memcpy_ = memcpyNode;
3326
3327 return rvsdgModule;
3328}
3329
3330std::unique_ptr<jlm::llvm::LlvmRvsdgModule>
3331MemcpyTest2::SetupRvsdg()
3332{
3333 using namespace jlm::llvm;
3334 using namespace jlm::rvsdg;
3335
3336 auto rvsdgModule = llvm::LlvmRvsdgModule::Create(jlm::util::FilePath(""), "", "");
3337 auto rvsdg = &rvsdgModule->Rvsdg();
3338
3339 auto pointerType = PointerType::Create();
3340 auto arrayType = ArrayType::Create(PointerType::Create(), 32);
3341 auto structTypeB = StructType::CreateIdentified("structTypeB", { arrayType }, false);
3342
3343 auto SetupFunctionG = [&]()
3344 {
3345 auto iOStateType = IOStateType::Create();
3346 auto memoryStateType = MemoryStateType::Create();
3347 auto functionType = rvsdg::FunctionType::Create(
3348 { PointerType::Create(),
3349 PointerType::Create(),
3350 IOStateType::Create(),
3351 MemoryStateType::Create() },
3352 { IOStateType::Create(), MemoryStateType::Create() });
3353
3354 auto lambda = rvsdg::LambdaNode::Create(
3355 rvsdg->GetRootRegion(),
3356 llvm::LlvmLambdaOperation::Create(functionType, "g", Linkage::internalLinkage));
3357 auto s1Argument = lambda->GetFunctionArguments()[0];
3358 auto s2Argument = lambda->GetFunctionArguments()[1];
3359 auto iOStateArgument = lambda->GetFunctionArguments()[2];
3360 auto memoryStateArgument = lambda->GetFunctionArguments()[3];
3361
3362 auto c0 = IntegerConstantOperation::Create(*lambda->subregion(), { 32, 0 }).output(0);
3363 auto c128 = IntegerConstantOperation::Create(*lambda->subregion(), { 64, 128 }).output(0);
3364
3365 auto gepS21 = GetElementPtrOperation::create(s2Argument, { c0, c0 }, structTypeB);
3366 auto gepS22 = GetElementPtrOperation::create(gepS21, { c0, c0 }, arrayType);
3367 auto ldS2 = LoadNonVolatileOperation::Create(gepS22, { memoryStateArgument }, pointerType, 8);
3368
3369 auto gepS11 = GetElementPtrOperation::create(s1Argument, { c0, c0 }, structTypeB);
3370 auto gepS12 = GetElementPtrOperation::create(gepS11, { c0, c0 }, arrayType);
3371 auto ldS1 = LoadNonVolatileOperation::Create(gepS12, { ldS2[1] }, pointerType, 8);
3372
3373 auto memcpyResults = MemCpyNonVolatileOperation::create(ldS2[0], ldS1[0], c128, { ldS1[1] });
3374
3375 auto lambdaOutput = lambda->finalize({ iOStateArgument, memcpyResults[0] });
3376
3377 return std::make_tuple(lambdaOutput, rvsdg::TryGetOwnerNode<rvsdg::Node>(*memcpyResults[0]));
3378 };
3379
3380 auto SetupFunctionF = [&](rvsdg::Output & functionF)
3381 {
3382 auto iOStateType = IOStateType::Create();
3383 auto memoryStateType = MemoryStateType::Create();
3384 auto functionType = rvsdg::FunctionType::Create(
3385 { PointerType::Create(),
3386 PointerType::Create(),
3387 IOStateType::Create(),
3388 MemoryStateType::Create() },
3389 { IOStateType::Create(), MemoryStateType::Create() });
3390
3391 auto lambda = rvsdg::LambdaNode::Create(
3392 rvsdg->GetRootRegion(),
3393 llvm::LlvmLambdaOperation::Create(functionType, "f", Linkage::externalLinkage));
3394 auto s1Argument = lambda->GetFunctionArguments()[0];
3395 auto s2Argument = lambda->GetFunctionArguments()[1];
3396 auto iOStateArgument = lambda->GetFunctionArguments()[2];
3397 auto memoryStateArgument = lambda->GetFunctionArguments()[3];
3398
3399 auto functionFArgument = lambda->AddContextVar(functionF).inner;
3400
3401 auto c0 = IntegerConstantOperation::Create(*lambda->subregion(), { 32, 0 }).output(0);
3402
3403 auto gepS1 = GetElementPtrOperation::create(s1Argument, { c0, c0 }, structTypeB);
3404 auto ldS1 = LoadNonVolatileOperation::Create(gepS1, { memoryStateArgument }, pointerType, 8);
3405
3406 auto gepS2 = GetElementPtrOperation::create(s2Argument, { c0, c0 }, structTypeB);
3407 auto ldS2 = LoadNonVolatileOperation::Create(gepS2, { ldS1[1] }, pointerType, 8);
3408
3409 auto & call = CallOperation::CreateNode(
3410 functionFArgument,
3411 rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(functionF).GetOperation().Type(),
3412 { ldS1[0], ldS2[0], iOStateArgument, ldS2[1] });
3413
3414 auto lambdaOutput = lambda->finalize(outputs(&call));
3415
3416 GraphExport::Create(*lambdaOutput, "f");
3417
3418 return std::make_tuple(lambdaOutput, &call);
3419 };
3420
3421 auto [lambdaG, memcpyNode] = SetupFunctionG();
3422 auto [lambdaF, callG] = SetupFunctionF(*lambdaG);
3423
3424 this->LambdaF_ = &rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(*lambdaF);
3425 this->LambdaG_ = &rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(*lambdaG);
3426 this->CallG_ = callG;
3427 this->Memcpy_ = memcpyNode;
3428
3429 return rvsdgModule;
3430}
3431
3432std::unique_ptr<jlm::llvm::LlvmRvsdgModule>
3433MemcpyTest3::SetupRvsdg()
3434{
3435 using namespace jlm::llvm;
3436 using namespace jlm::rvsdg;
3437
3438 auto rvsdgModule = llvm::LlvmRvsdgModule::Create(jlm::util::FilePath(""), "", "");
3439 auto rvsdg = &rvsdgModule->Rvsdg();
3440
3441 auto pointerType = PointerType::Create();
3442 auto structType = StructType::CreateIdentified("myStruct", { PointerType::Create() }, false);
3443
3444 auto iOStateType = IOStateType::Create();
3445 auto memoryStateType = MemoryStateType::Create();
3446 auto functionType = rvsdg::FunctionType::Create(
3447 { PointerType::Create(), IOStateType::Create(), MemoryStateType::Create() },
3448 { IOStateType::Create(), MemoryStateType::Create() });
3449
3450 Lambda_ = rvsdg::LambdaNode::Create(
3451 rvsdg->GetRootRegion(),
3452 llvm::LlvmLambdaOperation::Create(functionType, "f", Linkage::internalLinkage));
3453 auto pArgument = Lambda_->GetFunctionArguments()[0];
3454 auto iOStateArgument = Lambda_->GetFunctionArguments()[1];
3455 auto memoryStateArgument = Lambda_->GetFunctionArguments()[2];
3456
3457 auto eight = IntegerConstantOperation::Create(*Lambda_->subregion(), { 64, 8 }).output(0);
3458 auto zero = IntegerConstantOperation::Create(*Lambda_->subregion(), { 32, 0 }).output(0);
3459 auto minusFive = IntegerConstantOperation::Create(*Lambda_->subregion(), { 64, -5 }).output(0);
3460 auto three = IntegerConstantOperation::Create(*Lambda_->subregion(), { 64, 3 }).output(0);
3461
3462 auto constantOne = IntegerConstantOperation::Create(*Lambda_->subregion(), { 64, 1 }).output(0);
3463 auto allocaResults = AllocaOperation::create(structType, constantOne, 8);
3464 auto memoryState = MemoryStateMergeOperation::Create(
3465 std::vector<jlm::rvsdg::Output *>{ allocaResults[1], memoryStateArgument });
3466
3467 auto memcpyResults =
3468 MemCpyNonVolatileOperation::create(allocaResults[0], pArgument, eight, { memoryState });
3469
3470 auto gep1 = GetElementPtrOperation::create(allocaResults[0], { zero, zero }, structType);
3471 auto ld = LoadNonVolatileOperation::Create(gep1, { memcpyResults[0] }, pointerType, 8);
3472
3473 auto gep2 = GetElementPtrOperation::create(allocaResults[0], { minusFive }, structType);
3474
3475 memcpyResults = MemCpyNonVolatileOperation::create(ld[0], gep2, three, { ld[1] });
3476
3477 auto lambdaOutput = Lambda_->finalize({ iOStateArgument, memcpyResults[0] });
3478
3479 GraphExport::Create(*lambdaOutput, "f");
3480
3481 Alloca_ = rvsdg::TryGetOwnerNode<rvsdg::Node>(*allocaResults[0]);
3482 Memcpy_ = rvsdg::TryGetOwnerNode<rvsdg::Node>(*memcpyResults[0]);
3483
3484 return rvsdgModule;
3485}
3486
3487std::unique_ptr<jlm::llvm::LlvmRvsdgModule>
3488LinkedListTest::SetupRvsdg()
3489{
3490 using namespace jlm::llvm;
3491 using namespace jlm::rvsdg;
3492
3493 auto rvsdgModule = llvm::LlvmRvsdgModule::Create(jlm::util::FilePath(""), "", "");
3494 auto & rvsdg = rvsdgModule->Rvsdg();
3495
3496 auto pointerType = PointerType::Create();
3497 auto structType = StructType::CreateIdentified("list", { PointerType::Create() }, false);
3498
3499 auto SetupDeltaMyList = [&]()
3500 {
3501 auto delta = jlm::rvsdg::DeltaNode::Create(
3502 &rvsdg.GetRootRegion(),
3503 LlvmDeltaOperation::Create(pointerType, "MyList", Linkage::externalLinkage, "", false, 4));
3504
3505 auto constantPointerNullResult =
3506 ConstantPointerNullOperation::createNode(*delta->subregion()).output(0);
3507
3508 auto deltaOutput = &delta->finalize(constantPointerNullResult);
3509 GraphExport::Create(*deltaOutput, "myList");
3510
3511 return deltaOutput;
3512 };
3513
3514 auto SetupFunctionNext = [&](rvsdg::Output & myList)
3515 {
3516 auto iOStateType = IOStateType::Create();
3517 auto memoryStateType = MemoryStateType::Create();
3518 auto functionType = rvsdg::FunctionType::Create(
3519 { IOStateType::Create(), MemoryStateType::Create() },
3520 { PointerType::Create(), IOStateType::Create(), MemoryStateType::Create() });
3521
3522 auto lambda = rvsdg::LambdaNode::Create(
3523 rvsdg.GetRootRegion(),
3524 llvm::LlvmLambdaOperation::Create(functionType, "next", Linkage::externalLinkage));
3525 auto iOStateArgument = lambda->GetFunctionArguments()[0];
3526 auto memoryStateArgument = lambda->GetFunctionArguments()[1];
3527
3528 auto myListArgument = lambda->AddContextVar(myList).inner;
3529
3530 auto zero = IntegerConstantOperation::Create(*lambda->subregion(), { 32, 0 }).output(0);
3531 auto constantOne = IntegerConstantOperation::Create(*lambda->subregion(), { 32, 1 }).output(0);
3532
3533 auto alloca = AllocaOperation::create(pointerType, constantOne, 4);
3534 auto mergedMemoryState = MemoryStateMergeOperation::Create(
3535 std::vector<jlm::rvsdg::Output *>{ alloca[1], memoryStateArgument });
3536
3537 auto load1 =
3538 LoadNonVolatileOperation::Create(myListArgument, { mergedMemoryState }, pointerType, 4);
3539 auto store1 = StoreNonVolatileOperation::Create(alloca[0], load1[0], { load1[1] }, 4);
3540
3541 auto load2 = LoadNonVolatileOperation::Create(alloca[0], { store1[0] }, pointerType, 4);
3542 auto gep = GetElementPtrOperation::create(load2[0], { zero, zero }, structType);
3543
3544 auto load3 = LoadNonVolatileOperation::Create(gep, { load2[1] }, pointerType, 4);
3545 auto store2 = StoreNonVolatileOperation::Create(alloca[0], load3[0], { load3[1] }, 4);
3546
3547 auto load4 = LoadNonVolatileOperation::Create(alloca[0], { store2[0] }, pointerType, 4);
3548
3549 auto lambdaOutput = lambda->finalize({ load4[0], iOStateArgument, load4[1] });
3550 GraphExport::Create(*lambdaOutput, "next");
3551
3552 return std::make_tuple(rvsdg::TryGetOwnerNode<rvsdg::SimpleNode>(*alloca[0]), lambdaOutput);
3553 };
3554
3555 auto deltaMyList = SetupDeltaMyList();
3556 auto [alloca, lambdaNext] = SetupFunctionNext(*deltaMyList);
3557
3558 /*
3559 * Assign nodes
3560 */
3561 this->DeltaMyList_ = &rvsdg::AssertGetOwnerNode<rvsdg::DeltaNode>(*deltaMyList);
3562 this->LambdaNext_ = &rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(*lambdaNext);
3563 this->Alloca_ = alloca;
3564
3565 return rvsdgModule;
3566}
3567
3568std::unique_ptr<jlm::llvm::LlvmRvsdgModule>
3569AllMemoryNodesTest::SetupRvsdg()
3570{
3571 using namespace jlm::llvm;
3572 using namespace jlm::rvsdg;
3573
3574 auto mt = MemoryStateType::Create();
3575 auto pointerType = PointerType::Create();
3576 auto ioStateType = IOStateType::Create();
3577 auto functionType = rvsdg::FunctionType::Create(
3578 { MemoryStateType::Create(), ioStateType },
3579 { MemoryStateType::Create(), ioStateType });
3580
3581 auto module = llvm::LlvmRvsdgModule::Create(jlm::util::FilePath(""), "", "");
3582 auto graph = &module->Rvsdg();
3583
3584 // Create imported symbol "imported"
3585 Import_ = &LlvmGraphImport::createGlobalImport(
3586 *graph,
3587 BitType::Create(32),
3588 PointerType::Create(),
3589 "imported",
3590 Linkage::externalLinkage,
3591 false,
3592 4);
3593
3594 // Create global variable "global"
3596 &graph->GetRootRegion(),
3597 LlvmDeltaOperation::Create(pointerType, "global", Linkage::externalLinkage, "", false, 4));
3598 auto constantPointerNullResult =
3599 ConstantPointerNullOperation::createNode(*Delta_->subregion()).output(0);
3600 Delta_->finalize(constantPointerNullResult);
3601
3602 // Start of function "f"
3603 Lambda_ = rvsdg::LambdaNode::Create(
3604 graph->GetRootRegion(),
3605 llvm::LlvmLambdaOperation::Create(functionType, "f", Linkage::externalLinkage));
3606 auto entryMemoryState = Lambda_->GetFunctionArguments()[0];
3607 auto ioStateArgument = Lambda_->GetFunctionArguments()[1];
3608 auto deltaContextVar = Lambda_->AddContextVar(Delta_->output()).inner;
3609 auto importContextVar = Lambda_->AddContextVar(*Import_).inner;
3610
3611 // Create alloca node
3612 auto allocaSize = IntegerConstantOperation::Create(*Lambda_->subregion(), { 32, 1 }).output(0);
3613 auto allocaOutputs = AllocaOperation::create(pointerType, allocaSize, 8);
3614 Alloca_ = rvsdg::TryGetOwnerNode<rvsdg::SimpleNode>(*allocaOutputs[0]);
3615
3616 auto afterAllocaMemoryState = MemoryStateMergeOperation::Create(
3617 std::vector<jlm::rvsdg::Output *>{ entryMemoryState, allocaOutputs[1] });
3618
3619 // Create malloc node
3620 auto mallocSize = IntegerConstantOperation::Create(*Lambda_->subregion(), { 32, 4 }).output(0);
3621 Malloc_ = &MallocOperation::createNode(*mallocSize, *ioStateArgument);
3622
3623 auto afterMallocMemoryState = MemoryStateMergeOperation::Create(
3624 std::vector{ afterAllocaMemoryState, &MallocOperation::memoryStateOutput(*Malloc_) });
3625
3626 // Store the result of malloc into the alloca'd memory
3627 auto storeAllocaOutputs = StoreNonVolatileOperation::Create(
3628 allocaOutputs[0],
3629 &MallocOperation::addressOutput(*Malloc_),
3630 { afterMallocMemoryState },
3631 8);
3632
3633 // load the value in the alloca again
3634 auto loadAllocaOutputs =
3635 LoadNonVolatileOperation::Create(allocaOutputs[0], { storeAllocaOutputs[0] }, pointerType, 8);
3636
3637 // Load the value of the imported symbol "imported"
3638 auto loadImportedOutputs = LoadNonVolatileOperation::Create(
3639 importContextVar,
3640 { loadAllocaOutputs[1] },
3642 4);
3643
3644 // Store the loaded value from imported, into the address loaded from the alloca (aka. the malloc
3645 // result)
3646 auto storeImportedOutputs = StoreNonVolatileOperation::Create(
3647 loadAllocaOutputs[0],
3648 loadImportedOutputs[0],
3649 { loadImportedOutputs[1] },
3650 4);
3651
3652 // store the loaded alloca value in the global variable
3653 auto storeOutputs = StoreNonVolatileOperation::Create(
3654 deltaContextVar,
3655 loadAllocaOutputs[0],
3656 { storeImportedOutputs[0] },
3657 8);
3658
3659 Lambda_->finalize({ storeOutputs[0], &MallocOperation::ioStateOutput(*Malloc_) });
3660
3661 GraphExport::Create(Delta_->output(), "global");
3662 GraphExport::Create(*Lambda_->output(), "f");
3663
3664 return module;
3665}
3666
3667std::unique_ptr<jlm::llvm::LlvmRvsdgModule>
3668NAllocaNodesTest::SetupRvsdg()
3669{
3670 using namespace jlm::llvm;
3671 using namespace jlm::rvsdg;
3672
3673 auto mt = MemoryStateType::Create();
3674 auto pointerType = PointerType::Create();
3675 auto fcttype =
3676 rvsdg::FunctionType::Create({ MemoryStateType::Create() }, { MemoryStateType::Create() });
3677
3678 auto module = llvm::LlvmRvsdgModule::Create(jlm::util::FilePath(""), "", "");
3679 auto graph = &module->Rvsdg();
3680
3681 Function_ = rvsdg::LambdaNode::Create(
3682 graph->GetRootRegion(),
3683 llvm::LlvmLambdaOperation::Create(fcttype, "f", Linkage::externalLinkage));
3684
3685 auto constantOne = IntegerConstantOperation::Create(*Function_->subregion(), { 32, 1 }).output(0);
3686
3687 jlm::rvsdg::Output * latestMemoryState = Function_->GetFunctionArguments()[0];
3688
3689 for (size_t i = 0; i < NumAllocaNodes_; i++)
3690 {
3691 auto allocaOutputs = AllocaOperation::create(jlm::rvsdg::BitType::Create(32), constantOne, 4);
3692 auto allocaNode = rvsdg::TryGetOwnerNode<rvsdg::SimpleNode>(*allocaOutputs[0]);
3693
3694 AllocaNodes_.push_back(allocaNode);
3695
3696 // Update latestMemoryState to include the alloca memory state output
3697 latestMemoryState =
3698 MemoryStateMergeOperation::Create(std::vector{ latestMemoryState, allocaOutputs[1] });
3699 }
3700
3701 Function_->finalize({ latestMemoryState });
3702
3703 GraphExport::Create(*Function_->output(), "f");
3704
3705 return module;
3706}
3707
3708std::unique_ptr<jlm::llvm::LlvmRvsdgModule>
3709EscapingLocalFunctionTest::SetupRvsdg()
3710{
3711 using namespace jlm::llvm;
3712 using namespace jlm::rvsdg;
3713
3714 auto uint32Type = rvsdg::BitType::Create(32);
3715 auto mt = MemoryStateType::Create();
3716 auto pointerType = PointerType::Create();
3717 auto localFuncType = rvsdg::FunctionType::Create(
3718 { PointerType::Create(), MemoryStateType::Create() },
3719 { PointerType::Create(), MemoryStateType::Create() });
3720 auto exportedFuncType = rvsdg::FunctionType::Create(
3721 { MemoryStateType::Create() },
3722 { PointerType::Create(), MemoryStateType::Create() });
3723
3724 auto module = llvm::LlvmRvsdgModule::Create(util::FilePath(""), "", "");
3725 const auto graph = &module->Rvsdg();
3726
3728 &graph->GetRootRegion(),
3729 LlvmDeltaOperation::Create(uint32Type, "global", Linkage::internalLinkage, "", false, 4));
3730 const auto constantZero =
3731 IntegerConstantOperation::Create(*Global_->subregion(), { 32, 0 }).output(0);
3732 const auto deltaOutput = &Global_->finalize(constantZero);
3733
3734 LocalFunc_ = rvsdg::LambdaNode::Create(
3735 graph->GetRootRegion(),
3736 llvm::LlvmLambdaOperation::Create(localFuncType, "localFunction", Linkage::internalLinkage));
3737
3738 LocalFuncParam_ = LocalFunc_->GetFunctionArguments()[0];
3739
3740 const auto constantOne =
3741 IntegerConstantOperation::Create(*LocalFunc_->subregion(), { 32, 1 }).output(0);
3742 const auto allocaOutputs = AllocaOperation::create(uint32Type, constantOne, 4);
3743 LocalFuncParamAllocaNode_ = rvsdg::TryGetOwnerNode<rvsdg::Node>(*allocaOutputs[0]);
3744
3745 // Merge function's input Memory State and alloca node's memory state
3746 rvsdg::Output * mergedMemoryState = MemoryStateMergeOperation::Create(
3747 std::vector<rvsdg::Output *>{ LocalFunc_->GetFunctionArguments()[1], allocaOutputs[1] });
3748
3749 // Store the function parameter into the alloca node
3750 auto storeOutputs = StoreNonVolatileOperation::Create(
3751 allocaOutputs[0],
3752 LocalFuncParam_,
3753 { mergedMemoryState },
3754 4);
3755
3756 // Bring in deltaOuput as a context variable
3757 const auto deltaOutputCtxVar = LocalFunc_->AddContextVar(*deltaOutput).inner;
3758
3759 // Return &global
3760 LocalFunc_->finalize({ deltaOutputCtxVar, storeOutputs[0] });
3761
3762 LocalFuncRegister_ =
3763 rvsdg::CreateOpNode<FunctionToPointerOperation>({ LocalFunc_->output() }, localFuncType)
3764 .output(0);
3765
3766 ExportedFunc_ = rvsdg::LambdaNode::Create(
3767 graph->GetRootRegion(),
3769 exportedFuncType,
3770 "exportedFunc",
3771 Linkage::externalLinkage));
3772
3773 const auto localFuncCtxVar = ExportedFunc_->AddContextVar(*LocalFuncRegister_).inner;
3774
3775 // Return &localFunc, pass memory state directly through
3776 ExportedFunc_->finalize({ localFuncCtxVar, ExportedFunc_->GetFunctionArguments()[0] });
3777
3778 GraphExport::Create(*ExportedFunc_->output(), "exportedFunc");
3779
3780 return module;
3781}
3782
3783std::unique_ptr<llvm::LlvmRvsdgModule>
3784FreeNullTest::SetupRvsdg()
3785{
3786 using namespace jlm::llvm;
3787 using namespace jlm::rvsdg;
3788
3789 auto functionType = rvsdg::FunctionType::Create(
3790 { IOStateType::Create(), MemoryStateType::Create() },
3791 { IOStateType::Create(), MemoryStateType::Create() });
3792
3793 auto module = llvm::LlvmRvsdgModule::Create(jlm::util::FilePath(""), "", "");
3794 auto graph = &module->Rvsdg();
3795
3796 LambdaMain_ = rvsdg::LambdaNode::Create(
3797 graph->GetRootRegion(),
3798 llvm::LlvmLambdaOperation::Create(functionType, "main", Linkage::externalLinkage));
3799 auto iOStateArgument = LambdaMain_->GetFunctionArguments()[0];
3800 auto memoryStateArgument = LambdaMain_->GetFunctionArguments()[1];
3801
3802 auto constantPointerNullResult =
3803 ConstantPointerNullOperation::createNode(*LambdaMain_->subregion()).output(0);
3804
3805 auto & freeNode = FreeOperation::createNode(
3806 *constantPointerNullResult,
3807 *iOStateArgument,
3808 { memoryStateArgument });
3809
3810 LambdaMain_->finalize({ &FreeOperation::getIOStateOutput(freeNode),
3811 &*FreeOperation::memoryStateOutputs(freeNode).begin() });
3812
3813 GraphExport::Create(*LambdaMain_->output(), "main");
3814
3815 return module;
3816}
3817
3818std::unique_ptr<llvm::LlvmRvsdgModule>
3819LambdaCallArgumentMismatch::SetupRvsdg()
3820{
3821 using namespace jlm::llvm;
3822 using namespace jlm::rvsdg;
3823
3824 auto rvsdgModule = llvm::LlvmRvsdgModule::Create(util::FilePath(""), "", "");
3825 auto & rvsdg = rvsdgModule->Rvsdg();
3826
3827 auto functionType = rvsdg::FunctionType::Create(
3828 { IOStateType::Create(), MemoryStateType::Create() },
3829 { rvsdg::BitType::Create(32), IOStateType::Create(), MemoryStateType::Create() });
3830 auto variableArgumentType = VariableArgumentType::Create();
3831 auto functionTypeCall = rvsdg::FunctionType::Create(
3833 variableArgumentType,
3834 IOStateType::Create(),
3835 MemoryStateType::Create() },
3836 { rvsdg::BitType::Create(32), IOStateType::Create(), MemoryStateType::Create() });
3837
3838 auto setupLambdaG = [&]()
3839 {
3840 auto iOStateType = IOStateType::Create();
3841 auto memoryStateType = MemoryStateType::Create();
3842
3843 auto lambda = rvsdg::LambdaNode::Create(
3844 rvsdg.GetRootRegion(),
3845 llvm::LlvmLambdaOperation::Create(functionType, "g", Linkage::internalLinkage));
3846 auto iOStateArgument = lambda->GetFunctionArguments()[0];
3847 auto memoryStateArgument = lambda->GetFunctionArguments()[1];
3848
3849 auto five = IntegerConstantOperation::Create(*lambda->subregion(), { 32, 5 }).output(0);
3850
3851 return lambda->finalize({ five, iOStateArgument, memoryStateArgument });
3852 };
3853
3854 auto setupLambdaMain = [&](rvsdg::Output & lambdaG)
3855 {
3856 auto pointerType = PointerType::Create();
3857 auto iOStateType = IOStateType::Create();
3858 auto memoryStateType = MemoryStateType::Create();
3859 auto functionTypeMain = rvsdg::FunctionType::Create(
3860 { IOStateType::Create(), MemoryStateType::Create() },
3861 { rvsdg::BitType::Create(32), IOStateType::Create(), MemoryStateType::Create() });
3862
3863 auto lambda = rvsdg::LambdaNode::Create(
3864 rvsdg.GetRootRegion(),
3865 llvm::LlvmLambdaOperation::Create(functionTypeMain, "main", Linkage::externalLinkage));
3866 auto iOStateArgument = lambda->GetFunctionArguments()[0];
3867 auto memoryStateArgument = lambda->GetFunctionArguments()[1];
3868 auto lambdaGArgument = lambda->AddContextVar(lambdaG).inner;
3869
3870 auto one = IntegerConstantOperation::Create(*lambda->subregion(), { 32, 1 }).output(0);
3871 auto six = IntegerConstantOperation::Create(*lambda->subregion(), { 32, 6 }).output(0);
3872
3873 auto vaList = VariadicArgumentListOperation::Create(*lambda->subregion(), {});
3874
3875 auto allocaResults = AllocaOperation::create(rvsdg::BitType::Create(32), one, 4);
3876
3877 auto memoryState = MemoryStateMergeOperation::Create(
3878 std::vector<rvsdg::Output *>{ memoryStateArgument, allocaResults[1] });
3879
3880 auto storeResults =
3881 StoreNonVolatileOperation::Create(allocaResults[0], six, { memoryState }, 4);
3882
3883 auto loadResults = LoadNonVolatileOperation::Create(
3884 allocaResults[0],
3885 storeResults,
3887 4);
3888
3889 auto & call = CallOperation::CreateNode(
3890 lambdaGArgument,
3891 functionTypeCall,
3892 { loadResults[0], vaList, iOStateArgument, loadResults[1] });
3893
3894 auto lambdaOutput = lambda->finalize(outputs(&call));
3895
3896 GraphExport::Create(*lambdaOutput, "main");
3897
3898 return std::make_tuple(lambdaOutput, &call);
3899 };
3900
3901 LambdaG_ = &rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(*setupLambdaG());
3902
3903 // Formal arguments and call arguments do not match. Force conversion through pointer
3904 // to hide the mismatch, the call operator would complain otherwise.
3905 // The semantic of this is llvm-specific.
3906 auto ptr =
3907 jlm::rvsdg::CreateOpNode<FunctionToPointerOperation>({ LambdaG_->output() }, functionType)
3908 .output(0);
3909 auto fn =
3910 jlm::rvsdg::CreateOpNode<PointerToFunctionOperation>({ ptr }, functionTypeCall).output(0);
3911 auto [lambdaMainOutput, call] = setupLambdaMain(*fn);
3912 LambdaMain_ = &rvsdg::AssertGetOwnerNode<rvsdg::LambdaNode>(*lambdaMainOutput);
3913 Call_ = call;
3914
3915 return rvsdgModule;
3916}
3917
3918std::unique_ptr<llvm::LlvmRvsdgModule>
3919VariadicFunctionTest1::SetupRvsdg()
3920{
3921 using namespace jlm::llvm;
3922
3923 auto rvsdgModule = LlvmRvsdgModule::Create(util::FilePath(""), "", "");
3924 auto & rvsdg = rvsdgModule->Rvsdg();
3925
3926 auto pointerType = PointerType::Create();
3927 auto iOStateType = IOStateType::Create();
3928 auto memoryStateType = MemoryStateType::Create();
3929 auto varArgType = VariableArgumentType::Create();
3930 auto lambdaHType = rvsdg::FunctionType::Create(
3932 varArgType,
3933 IOStateType::Create(),
3934 MemoryStateType::Create() },
3935 { PointerType::Create(), IOStateType::Create(), MemoryStateType::Create() });
3936 auto lambdaFType = rvsdg::FunctionType::Create(
3937 { PointerType::Create(), IOStateType::Create(), MemoryStateType::Create() },
3938 { IOStateType::Create(), MemoryStateType::Create() });
3939 auto lambdaGType = rvsdg::FunctionType::Create(
3940 { IOStateType::Create(), MemoryStateType::Create() },
3941 { IOStateType::Create(), MemoryStateType::Create() });
3942
3943 // Setup h()
3944 ImportH_ = &LlvmGraphImport::createFunctionImport(
3945 rvsdg,
3946 lambdaHType,
3947 "h",
3948 Linkage::externalLinkage,
3950
3951 // Setup f()
3952 {
3953 LambdaF_ = rvsdg::LambdaNode::Create(
3954 rvsdg.GetRootRegion(),
3955 llvm::LlvmLambdaOperation::Create(lambdaFType, "f", Linkage::internalLinkage));
3956 auto iArgument = LambdaF_->GetFunctionArguments()[0];
3957 auto iOStateArgument = LambdaF_->GetFunctionArguments()[1];
3958 auto memoryStateArgument = LambdaF_->GetFunctionArguments()[2];
3959 auto lambdaHArgument = LambdaF_->AddContextVar(*ImportH_).inner;
3960
3961 auto one = IntegerConstantOperation::Create(*LambdaF_->subregion(), { 32, 1 }).output(0);
3962 auto three = IntegerConstantOperation::Create(*LambdaF_->subregion(), { 32, 3 }).output(0);
3963
3964 auto varArgList = VariadicArgumentListOperation::Create(*LambdaF_->subregion(), { iArgument });
3965
3966 CallH_ = &CallOperation::CreateNode(
3967 lambdaHArgument,
3968 lambdaHType,
3969 { one, varArgList, iOStateArgument, memoryStateArgument });
3970
3971 auto storeResults = StoreNonVolatileOperation::Create(
3972 CallH_->output(0),
3973 three,
3974 { &CallOperation::GetMemoryStateOutput(*CallH_) },
3975 4);
3976
3977 LambdaF_->finalize({ &CallOperation::GetIOStateOutput(*CallH_), storeResults[0] });
3978 }
3979
3980 // Setup g()
3981 {
3982 LambdaG_ = rvsdg::LambdaNode::Create(
3983 rvsdg.GetRootRegion(),
3984 llvm::LlvmLambdaOperation::Create(lambdaGType, "g", Linkage::externalLinkage));
3985 auto iOStateArgument = LambdaG_->GetFunctionArguments()[0];
3986 auto memoryStateArgument = LambdaG_->GetFunctionArguments()[1];
3987 auto lambdaFArgument = LambdaG_->AddContextVar(*LambdaF_->output()).inner;
3988
3989 auto one = IntegerConstantOperation::Create(*LambdaG_->subregion(), { 32, 1 }).output(0);
3990 auto five = IntegerConstantOperation::Create(*LambdaG_->subregion(), { 32, 5 }).output(0);
3991
3992 auto allocaResults = AllocaOperation::create(jlm::rvsdg::BitType::Create(32), one, 4);
3993 auto merge = MemoryStateMergeOperation::Create(
3994 std::vector<jlm::rvsdg::Output *>{ allocaResults[1], memoryStateArgument });
3995 AllocaNode_ = rvsdg::TryGetOwnerNode<rvsdg::Node>(*allocaResults[0]);
3996
3997 auto storeResults = StoreNonVolatileOperation::Create(allocaResults[0], five, { merge }, 4);
3998
3999 auto & callF = CallOperation::CreateNode(
4000 lambdaFArgument,
4001 lambdaFType,
4002 { allocaResults[0], iOStateArgument, storeResults[0] });
4003
4004 LambdaG_->finalize(outputs(&callF));
4005 }
4006
4007 return rvsdgModule;
4008}
4009
4010std::unique_ptr<jlm::llvm::LlvmRvsdgModule>
4011VariadicFunctionTest2::SetupRvsdg()
4012{
4013 using namespace jlm::llvm;
4014
4015 auto rvsdgModule = LlvmRvsdgModule::Create(jlm::util::FilePath(""), "", "");
4016 auto & rvsdg = rvsdgModule->Rvsdg();
4017
4018 auto pointerType = PointerType::Create();
4019 auto structType = StructType::CreateIdentified(
4020 "struct.__va_list_tag",
4023 PointerType::Create(),
4024 PointerType::Create() },
4025 false);
4026 auto arrayType = ArrayType::Create(structType, 1);
4027 auto iOStateType = IOStateType::Create();
4028 auto memoryStateType = MemoryStateType::Create();
4029 auto varArgType = VariableArgumentType::Create();
4030 auto lambdaLlvmLifetimeStartType = rvsdg::FunctionType::Create(
4032 PointerType::Create(),
4033 IOStateType::Create(),
4034 MemoryStateType::Create() },
4035 { IOStateType::Create(), MemoryStateType::Create() });
4036 auto lambdaLlvmLifetimeEndType = rvsdg::FunctionType::Create(
4038 PointerType::Create(),
4039 IOStateType::Create(),
4040 MemoryStateType::Create() },
4041 { IOStateType::Create(), MemoryStateType::Create() });
4042 auto lambdaVaStartType = rvsdg::FunctionType::Create(
4043 { PointerType::Create(), IOStateType::Create(), MemoryStateType::Create() },
4044 { IOStateType::Create(), MemoryStateType::Create() });
4045 auto lambdaVaEndType = rvsdg::FunctionType::Create(
4046 { PointerType::Create(), IOStateType::Create(), MemoryStateType::Create() },
4047 { IOStateType::Create(), MemoryStateType::Create() });
4048 auto lambdaFstType = rvsdg::FunctionType::Create(
4049 { rvsdg::BitType::Create(32), varArgType, IOStateType::Create(), MemoryStateType::Create() },
4050 { rvsdg::BitType::Create(32), IOStateType::Create(), MemoryStateType::Create() });
4051 auto lambdaGType = rvsdg::FunctionType::Create(
4052 { IOStateType::Create(), MemoryStateType::Create() },
4053 { rvsdg::BitType::Create(32), IOStateType::Create(), MemoryStateType::Create() });
4054
4055 auto llvmLifetimeStart = &LlvmGraphImport::createFunctionImport(
4056 rvsdg,
4057 lambdaLlvmLifetimeStartType,
4058 "llvm.lifetime.start.p0",
4059 Linkage::externalLinkage,
4061 auto llvmLifetimeEnd = &LlvmGraphImport::createFunctionImport(
4062 rvsdg,
4063 lambdaLlvmLifetimeEndType,
4064 "llvm.lifetime.end.p0",
4065 Linkage::externalLinkage,
4067 auto llvmVaStart = &LlvmGraphImport::createFunctionImport(
4068 rvsdg,
4069 lambdaVaStartType,
4070 "llvm.va_start",
4071 Linkage::externalLinkage,
4073 auto llvmVaEnd = &LlvmGraphImport::createFunctionImport(
4074 rvsdg,
4075 lambdaVaEndType,
4076 "llvm.va_end",
4077 Linkage::externalLinkage,
4079
4080 // Setup function fst()
4081 {
4082 LambdaFst_ = rvsdg::LambdaNode::Create(
4083 rvsdg.GetRootRegion(),
4084 llvm::LlvmLambdaOperation::Create(lambdaFstType, "fst", Linkage::internalLinkage));
4085 auto iOStateArgument = LambdaFst_->GetFunctionArguments()[2];
4086 auto memoryStateArgument = LambdaFst_->GetFunctionArguments()[3];
4087 auto llvmLifetimeStartArgument = LambdaFst_->AddContextVar(*llvmLifetimeStart).inner;
4088 auto llvmLifetimeEndArgument = LambdaFst_->AddContextVar(*llvmLifetimeEnd).inner;
4089 auto llvmVaStartArgument = LambdaFst_->AddContextVar(*llvmVaStart).inner;
4090 auto llvmVaEndArgument = LambdaFst_->AddContextVar(*llvmVaEnd).inner;
4091
4092 auto one = IntegerConstantOperation::Create(*LambdaFst_->subregion(), { 32, 1 }).output(0);
4093 auto twentyFour =
4094 IntegerConstantOperation::Create(*LambdaFst_->subregion(), { 64, 24 }).output(0);
4095 auto fortyOne =
4096 IntegerConstantOperation::Create(*LambdaFst_->subregion(), { 32, 41 }).output(0);
4097
4098 auto allocaResults = AllocaOperation::create(arrayType, one, 16);
4099 auto memoryState = MemoryStateMergeOperation::Create(
4100 std::vector<jlm::rvsdg::Output *>{ allocaResults[1], memoryStateArgument });
4101 AllocaNode_ = rvsdg::TryGetOwnerNode<rvsdg::Node>(*allocaResults[0]);
4102
4103 auto & callLLvmLifetimeStart = CallOperation::CreateNode(
4104 llvmLifetimeStartArgument,
4105 lambdaLlvmLifetimeStartType,
4106 { twentyFour, allocaResults[0], iOStateArgument, memoryState });
4107 auto & callVaStart = CallOperation::CreateNode(
4108 llvmVaStartArgument,
4109 lambdaVaStartType,
4110 { allocaResults[0],
4111 &CallOperation::GetIOStateOutput(callLLvmLifetimeStart),
4112 &CallOperation::GetMemoryStateOutput(callLLvmLifetimeStart) });
4113
4114 auto loadResults = LoadNonVolatileOperation::Create(
4115 allocaResults[0],
4116 { &CallOperation::GetMemoryStateOutput(callVaStart) },
4118 16);
4119 auto icmpResult = IntegerUltOperation::createNode(32, *loadResults[0], *fortyOne).output(0);
4120 auto matchResult = rvsdg::MatchOperation::Create(*icmpResult, { { 1, 1 } }, 0, 2);
4121
4122 auto gammaNode = rvsdg::GammaNode::create(matchResult, 2);
4123 auto gammaVaAddress = gammaNode->AddEntryVar(allocaResults[0]);
4124 auto gammaLoadResult = gammaNode->AddEntryVar(loadResults[0]);
4125 auto gammaMemoryState = gammaNode->AddEntryVar(loadResults[1]);
4126
4127 // gamma subregion 0
4128 auto zero = IntegerConstantOperation::Create(*gammaNode->subregion(0), { 64, 0 }).output(0);
4129 auto two = IntegerConstantOperation::Create(*gammaNode->subregion(0), { 32, 2 }).output(0);
4130 auto eight = IntegerConstantOperation::Create(*gammaNode->subregion(0), { 64, 8 }).output(0);
4131 auto gepResult1 =
4132 GetElementPtrOperation::create(gammaVaAddress.branchArgument[0], { zero, two }, structType);
4133 auto loadResultsGamma0 = LoadNonVolatileOperation::Create(
4134 gepResult1,
4135 { gammaMemoryState.branchArgument[0] },
4136 pointerType,
4137 8);
4138 auto gepResult2 =
4139 GetElementPtrOperation::create(loadResultsGamma0[0], { eight }, rvsdg::BitType::Create(8));
4140 auto storeResultsGamma0 =
4141 StoreNonVolatileOperation::Create(gepResult1, gepResult2, { loadResultsGamma0[1] }, 8);
4142
4143 // gamma subregion 1
4144 zero = IntegerConstantOperation::Create(*gammaNode->subregion(1), { 64, 0 }).output(0);
4145 auto eightBit32 =
4146 IntegerConstantOperation::Create(*gammaNode->subregion(1), { 32, 8 }).output(0);
4147 auto three = IntegerConstantOperation::Create(*gammaNode->subregion(1), { 32, 3 }).output(0);
4148 gepResult1 = GetElementPtrOperation::create(
4149 gammaVaAddress.branchArgument[1],
4150 { zero, three },
4151 structType);
4152 auto loadResultsGamma1 = LoadNonVolatileOperation::Create(
4153 gepResult1,
4154 { gammaMemoryState.branchArgument[1] },
4155 pointerType,
4156 16);
4157 auto & zextResult = ZExtOperation::create(64, *gammaLoadResult.branchArgument[1]);
4158 gepResult2 = GetElementPtrOperation::create(
4159 loadResultsGamma1[0],
4160 { &zextResult },
4162 auto addResult =
4163 IntegerAddOperation::createNode(32, *gammaLoadResult.branchArgument[1], *eightBit32)
4164 .output(0);
4165 auto storeResultsGamma1 = StoreNonVolatileOperation::Create(
4166 gammaVaAddress.branchArgument[1],
4167 addResult,
4168 { loadResultsGamma1[1] },
4169 16);
4170
4171 auto gammaAddress = gammaNode->AddExitVar({ loadResultsGamma0[0], gepResult2 });
4172 auto gammaOutputMemoryState =
4173 gammaNode->AddExitVar({ storeResultsGamma0[0], storeResultsGamma1[0] });
4174
4175 loadResults = LoadNonVolatileOperation::Create(
4176 gammaAddress.output,
4177 { gammaOutputMemoryState.output },
4179 4);
4180 auto & callVaEnd = CallOperation::CreateNode(
4181 llvmVaEndArgument,
4182 lambdaVaEndType,
4183 { allocaResults[0], &CallOperation::GetIOStateOutput(callVaStart), loadResults[1] });
4184 auto & callLLvmLifetimeEnd = CallOperation::CreateNode(
4185 llvmLifetimeEndArgument,
4186 lambdaLlvmLifetimeEndType,
4187 { twentyFour,
4188 allocaResults[0],
4189 &CallOperation::GetIOStateOutput(callVaEnd),
4190 &CallOperation::GetMemoryStateOutput(callVaEnd) });
4191
4192 LambdaFst_->finalize({ loadResults[0],
4193 &CallOperation::GetIOStateOutput(callLLvmLifetimeEnd),
4194 &CallOperation::GetMemoryStateOutput(callLLvmLifetimeEnd) });
4195 }
4196
4197 // Setup function g()
4198 {
4199 LambdaG_ = rvsdg::LambdaNode::Create(
4200 rvsdg.GetRootRegion(),
4201 llvm::LlvmLambdaOperation::Create(lambdaGType, "g", Linkage::externalLinkage));
4202 auto iOStateArgument = LambdaG_->GetFunctionArguments()[0];
4203 auto memoryStateArgument = LambdaG_->GetFunctionArguments()[1];
4204 auto lambdaFstArgument = LambdaG_->AddContextVar(*LambdaFst_->output()).inner;
4205
4206 auto zero = IntegerConstantOperation::Create(*LambdaG_->subregion(), { 32, 0 }).output(0);
4207 auto one = IntegerConstantOperation::Create(*LambdaG_->subregion(), { 32, 1 }).output(0);
4208 auto two = IntegerConstantOperation::Create(*LambdaG_->subregion(), { 32, 2 }).output(0);
4209 auto three = IntegerConstantOperation::Create(*LambdaG_->subregion(), { 32, 3 }).output(0);
4210
4211 auto vaListResult =
4212 VariadicArgumentListOperation::Create(*LambdaG_->subregion(), { zero, one, two });
4213
4214 auto & callFst = CallOperation::CreateNode(
4215 lambdaFstArgument,
4216 lambdaFstType,
4217 { three, vaListResult, iOStateArgument, memoryStateArgument });
4218
4219 LambdaG_->finalize(outputs(&callFst));
4220 }
4221
4222 return rvsdgModule;
4223}
4224
4225}
static std::vector< rvsdg::Output * > create(std::shared_ptr< const rvsdg::Type > allocatedType, rvsdg::Output *count, const size_t alignment)
Definition alloca.hpp:131
static jlm::rvsdg::Output * create(jlm::rvsdg::Output *operand, std::shared_ptr< const jlm::rvsdg::Type > rtype)
jlm::rvsdg::LambdaNode * lambda
std::unique_ptr< jlm::llvm::LlvmRvsdgModule > SetupRvsdg() override
Create RVSDG for this test.
jlm::rvsdg::LambdaNode * LambdaTest_
rvsdg::SimpleNode * CallNode_
std::unique_ptr< jlm::llvm::LlvmRvsdgModule > SetupRvsdg() override
Create RVSDG for this test.
rvsdg::Node * BitsToPtrNode_
jlm::rvsdg::LambdaNode * LambdaBits2Ptr_
static rvsdg::Output & GetMemoryStateOutput(const rvsdg::Node &node) noexcept
Definition call.hpp:378
static rvsdg::SimpleNode & CreateNode(rvsdg::Region &region, std::unique_ptr< CallOperation > callOperation, const std::vector< rvsdg::Output * > &operands)
Definition call.hpp:507
static rvsdg::Output & GetIOStateOutput(const rvsdg::Node &node) noexcept
Definition call.hpp:345
rvsdg::SimpleNode * CallF_
std::unique_ptr< jlm::llvm::LlvmRvsdgModule > SetupRvsdg() override
Create RVSDG for this test.
rvsdg::SimpleNode * CallG_
rvsdg::SimpleNode * alloca_y
rvsdg::SimpleNode * alloca_z
jlm::rvsdg::LambdaNode * lambda_g
jlm::rvsdg::LambdaNode * lambda_f
rvsdg::SimpleNode * alloca_x
jlm::rvsdg::LambdaNode * lambda_h
jlm::rvsdg::LambdaNode * lambda_test
rvsdg::SimpleNode * CallCreate1_
std::unique_ptr< jlm::llvm::LlvmRvsdgModule > SetupRvsdg() override
Create RVSDG for this test.
rvsdg::SimpleNode * CallDestroy1_
rvsdg::SimpleNode * CallCreate2_
jlm::rvsdg::LambdaNode * lambda_create
jlm::rvsdg::LambdaNode * lambda_destroy
rvsdg::SimpleNode * free
rvsdg::SimpleNode * malloc
rvsdg::SimpleNode * CallDestroy2_
static rvsdg::Node & createNode(rvsdg::Region &region)
jlm::rvsdg::LambdaNode * lambda
std::unique_ptr< jlm::llvm::LlvmRvsdgModule > SetupRvsdg() override
Create RVSDG for this test.
jlm::rvsdg::GraphImport * ExternalGArgument_
std::unique_ptr< jlm::llvm::LlvmRvsdgModule > SetupRvsdg() override
Create RVSDG for this test.
jlm::rvsdg::LambdaNode * LambdaF_
rvsdg::SimpleNode * CallG_
jlm::rvsdg::LambdaNode * LambdaG_
std::unique_ptr< jlm::llvm::LlvmRvsdgModule > SetupRvsdg() override
Create RVSDG for this test.
jlm::rvsdg::RegionArgument * ExternalFArgument_
rvsdg::SimpleNode * CallF_
static rvsdg::Node::OutputIteratorRange memoryStateOutputs(const rvsdg::Node &node) noexcept
static rvsdg::Output & getIOStateOutput(const rvsdg::Node &node) noexcept
static rvsdg::SimpleNode & createNode(rvsdg::Output &pointer, rvsdg::Output &iOState, const std::vector< rvsdg::Output * > &memoryStates)
std::unique_ptr< llvm::LlvmRvsdgModule > SetupRvsdg() override
Create RVSDG for this test.
rvsdg::GammaNode * gamma
jlm::rvsdg::LambdaNode * lambda
std::unique_ptr< jlm::llvm::LlvmRvsdgModule > SetupRvsdg() override
Create RVSDG for this test.
static rvsdg::Output * create(rvsdg::Output *baseAddress, const std::vector< rvsdg::Output * > &indices, std::shared_ptr< const rvsdg::Type > gepType)
std::unique_ptr< jlm::llvm::LlvmRvsdgModule > SetupRvsdg() override
Create RVSDG for this test.
jlm::rvsdg::LambdaNode * lambda
static std::shared_ptr< const IOStateType > Create()
Definition types.cpp:343
jlm::rvsdg::LambdaNode * LambdaIndcall_
rvsdg::SimpleNode * CallFour_
std::unique_ptr< jlm::llvm::LlvmRvsdgModule > SetupRvsdg() override
Create RVSDG for this test.
jlm::rvsdg::LambdaNode * LambdaFour_
rvsdg::SimpleNode * CallIndcall_
jlm::rvsdg::LambdaNode * LambdaTest_
jlm::rvsdg::LambdaNode * LambdaThree_
rvsdg::SimpleNode * CallThree_
rvsdg::SimpleNode * CallIWithThree_
rvsdg::SimpleNode * IndirectCall_
jlm::rvsdg::SimpleNode * AllocaPx_
rvsdg::SimpleNode * CallIWithFour_
jlm::rvsdg::DeltaNode * DeltaG1_
jlm::rvsdg::SimpleNode * AllocaPy_
jlm::rvsdg::LambdaNode * LambdaThree_
rvsdg::SimpleNode * TestCallX_
rvsdg::SimpleNode * CallY_
rvsdg::SimpleNode * Test2CallX_
jlm::rvsdg::LambdaNode * LambdaY_
jlm::rvsdg::SimpleNode * AllocaPz_
jlm::rvsdg::LambdaNode * LambdaFour_
std::unique_ptr< jlm::llvm::LlvmRvsdgModule > SetupRvsdg() override
Create RVSDG for this test.
jlm::rvsdg::LambdaNode * LambdaTest_
jlm::rvsdg::LambdaNode * LambdaTest2_
jlm::rvsdg::LambdaNode * LambdaX_
jlm::rvsdg::LambdaNode * LambdaI_
jlm::rvsdg::DeltaNode * DeltaG2_
static std::unique_ptr< ThreeAddressCode > create(const Variable *argument)
static rvsdg::Node & createNode(const size_t numBits, rvsdg::Output &operand1, rvsdg::Output &operand2)
static rvsdg::Node & Create(rvsdg::Region &region, IntegerValueRepresentation representation)
static rvsdg::Node & createNode(const size_t numBits, rvsdg::Output &operand1, rvsdg::Output &operand2)
static rvsdg::Node & createNode(const size_t numBits, rvsdg::Output &operand1, rvsdg::Output &operand2)
static rvsdg::Node & createNode(const size_t numBits, rvsdg::Output &operand1, rvsdg::Output &operand2)
static std::unique_ptr< LlvmDeltaOperation > Create(std::shared_ptr< const rvsdg::Type > type, const std::string &name, const Linkage &linkage, std::string section, bool constant, const size_t alignment)
Definition delta.hpp:82
static LlvmGraphImport & createGlobalImport(rvsdg::Graph &graph, std::shared_ptr< const rvsdg::Type > valueType, std::shared_ptr< const rvsdg::Type > importedType, std::string name, Linkage linkage, const bool isConstant, const size_t alignment)
static LlvmGraphImport & createFunctionImport(rvsdg::Graph &graph, std::shared_ptr< const rvsdg::FunctionType > functionType, std::string name, Linkage linkage, CallingConvention callingConvention)
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)
jlm::rvsdg::LambdaNode * Lambda_
std::unique_ptr< jlm::llvm::LlvmRvsdgModule > SetupRvsdg() override
Create RVSDG for this test.
static std::unique_ptr< llvm::ThreeAddressCode > Create(const Variable *address, const Variable *state, std::shared_ptr< const rvsdg::Type > loadedType, size_t alignment)
Definition Load.hpp:448
jlm::rvsdg::LambdaNode * lambda
rvsdg::Node * load_p
std::unique_ptr< jlm::llvm::LlvmRvsdgModule > SetupRvsdg() override
Create RVSDG for this test.
rvsdg::Node * load_x
rvsdg::SimpleNode * load_a
rvsdg::SimpleNode * alloca_p
std::unique_ptr< jlm::llvm::LlvmRvsdgModule > SetupRvsdg() override
Create RVSDG for this test.
jlm::rvsdg::LambdaNode * lambda
rvsdg::SimpleNode * alloca_y
rvsdg::SimpleNode * load_x
rvsdg::SimpleNode * alloca_a
rvsdg::SimpleNode * alloca_x
rvsdg::SimpleNode * alloca_b
static rvsdg::Output & addressOutput(const rvsdg::Node &node)
static rvsdg::Output & memoryStateOutput(const rvsdg::Node &node)
static rvsdg::SimpleNode & createNode(rvsdg::Output &size, rvsdg::Output &ioState)
static rvsdg::Output & ioStateOutput(const rvsdg::Node &node)
static rvsdg::Output * Create(const std::vector< rvsdg::Output * > &operands)
static std::shared_ptr< const MemoryStateType > Create()
Definition types.cpp:379
PointerType class.
Definition types.hpp:25
static std::shared_ptr< const PointerType > Create()
Definition types.cpp:45
const rvsdg::Graph & graph()
static std::unique_ptr< llvm::ThreeAddressCode > Create(const Variable *address, const Variable *value, const Variable *state, size_t alignment)
Definition Store.hpp:341
rvsdg::SimpleNode * alloca_c
rvsdg::SimpleNode * alloca_a
rvsdg::SimpleNode * alloca_d
std::unique_ptr< jlm::llvm::LlvmRvsdgModule > SetupRvsdg() override
Create RVSDG for this test.
rvsdg::SimpleNode * size
jlm::rvsdg::LambdaNode * lambda
rvsdg::SimpleNode * alloca_b
rvsdg::SimpleNode * alloca_p
jlm::rvsdg::LambdaNode * lambda
rvsdg::SimpleNode * alloca_y
std::unique_ptr< jlm::llvm::LlvmRvsdgModule > SetupRvsdg() override
Create RVSDG for this test.
rvsdg::SimpleNode * alloca_x
rvsdg::SimpleNode * alloca_b
rvsdg::SimpleNode * size
rvsdg::SimpleNode * alloca_a
static std::shared_ptr< const StructType > CreateIdentified(const std::string &name, std::vector< std::shared_ptr< const Type > > types, bool isPacked)
Definition types.hpp:307
static jlm::rvsdg::Output * Create(rvsdg::Region &region, std::shared_ptr< const jlm::rvsdg::Type > type)
static std::shared_ptr< const BitType > Create(std::size_t nbits)
Creates bit type of specified width.
Definition type.cpp:45
static DeltaNode * Create(rvsdg::Region *parent, std::unique_ptr< DeltaOperation > op)
Definition delta.hpp:313
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 GammaNode * create(jlm::rvsdg::Output *predicate, size_t nalternatives)
Definition gamma.hpp:161
Region & GetRootRegion() const noexcept
Definition graph.hpp:99
rvsdg::Output * finalize(const std::vector< jlm::rvsdg::Output * > &results)
Definition lambda.cpp:147
std::vector< rvsdg::Output * > GetFunctionArguments() const
Definition lambda.cpp:58
ContextVar AddContextVar(jlm::rvsdg::Output &origin)
Adds a context/free variable to the lambda node.
Definition lambda.cpp:132
static LambdaNode * Create(rvsdg::Region &parent, std::unique_ptr< LambdaOperation > operation)
Definition lambda.cpp:141
rvsdg::Output * output() const noexcept
Definition lambda.cpp:177
rvsdg::Region * subregion() const noexcept
Definition lambda.hpp:138
LambdaOperation & GetOperation() const noexcept override
Definition lambda.cpp:52
const std::shared_ptr< const FunctionType > & Type() const noexcept
Definition lambda.hpp:42
static Output * Create(Output &predicate, const std::unordered_map< uint64_t, uint64_t > &mapping, const uint64_t defaultAlternative, const size_t numAlternatives)
Definition control.hpp:278
NodeOutput * output(size_t index) const noexcept
Definition node.hpp:650
PhiNode * end()
Definition Phi.cpp:270
PhiNode::ContextVar AddContextVar(jlm::rvsdg::Output &origin)
Definition Phi.cpp:251
PhiNode::FixVar AddFixVar(std::shared_ptr< const jlm::rvsdg::Type > type)
Definition Phi.cpp:257
void begin(rvsdg::Region *parent)
Definition Phi.hpp:355
rvsdg::Region * subregion() const noexcept
Definition Phi.hpp:349
A phi node represents the fixpoint of mutually recursive definitions.
Definition Phi.hpp:46
Represents the argument of a region.
Definition region.hpp:41
Represent acyclic RVSDG subgraphs.
Definition region.hpp:213
static ThetaNode * create(rvsdg::Region *parent)
Definition theta.hpp:84
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
rvsdg::Output * inner
Access to bound object in subregion.
Definition lambda.hpp:117