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