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