Jlm
RvsdgToIpGraphConverterTests.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2018, 2025 Nico Reißmann <nico.reissmann@gmail.com>
3  * See COPYING for terms of redistribution.
4  */
5 
6 #include <gtest/gtest.h>
7 
17 #include <jlm/llvm/ir/print.hpp>
18 #include <jlm/rvsdg/gamma.hpp>
19 #include <jlm/rvsdg/Phi.hpp>
21 #include <jlm/rvsdg/TestType.hpp>
22 #include <jlm/rvsdg/view.hpp>
23 #include <jlm/util/Statistics.hpp>
24 
25 TEST(RvsdgToIpGraphConverterTests, GammaWithMatch)
26 {
27  using namespace jlm::llvm;
28  using namespace jlm::rvsdg;
29  using namespace jlm::util;
30 
31  // Arrange
32  auto valueType = TestType::createValueType();
33  auto functionType = jlm::rvsdg::FunctionType::Create(
34  { jlm::rvsdg::BitType::Create(1), valueType, valueType },
35  { valueType });
36 
37  jlm::llvm::LlvmRvsdgModule rvsdgModule(FilePath(""), "", "");
38 
39  auto lambdaNode = jlm::rvsdg::LambdaNode::Create(
40  rvsdgModule.Rvsdg().GetRootRegion(),
42 
43  auto & matchNode =
44  MatchOperation::CreateNode(*lambdaNode->GetFunctionArguments()[0], { { 0, 0 } }, 1, 2);
45  auto gamma = GammaNode::create(matchNode.output(0), 2);
46  auto gammaInput1 = gamma->AddEntryVar(lambdaNode->GetFunctionArguments()[1]);
47  auto gammaInput2 = gamma->AddEntryVar(lambdaNode->GetFunctionArguments()[2]);
48  auto gammaOutput =
49  gamma->AddExitVar({ gammaInput1.branchArgument[0], gammaInput2.branchArgument[1] });
50 
51  auto lambdaOutput = lambdaNode->finalize({ gammaOutput.output });
52  GraphExport::Create(*lambdaOutput, "");
53 
54  view(rvsdgModule.Rvsdg(), stdout);
55 
56  // Act
59  print(*module, stdout);
60 
61  // Assert
62  auto & ipg = module->ipgraph();
63  EXPECT_EQ(ipg.nnodes(), 1u);
64 
65  auto cfg = dynamic_cast<const FunctionNode &>(*ipg.begin()).cfg();
66  EXPECT_EQ(cfg->nnodes(), 4u);
67 }
68 
69 TEST(RvsdgToIpGraphConverterTests, GammaWithoutMatch)
70 {
71  using namespace jlm::llvm;
72  using namespace jlm::rvsdg;
73  using namespace jlm::util;
74 
75  // Arrange
76  auto valueType = jlm::rvsdg::TestType::createValueType();
77  auto functionType = jlm::rvsdg::FunctionType::Create(
78  { jlm::rvsdg::ControlType::Create(2), valueType, valueType },
79  { valueType });
80 
81  jlm::llvm::LlvmRvsdgModule rvsdgModule(FilePath(""), "", "");
82 
83  auto lambdaNode = jlm::rvsdg::LambdaNode::Create(
84  rvsdgModule.Rvsdg().GetRootRegion(),
86 
87  auto gammaNode = jlm::rvsdg::GammaNode::create(lambdaNode->GetFunctionArguments()[0], 2);
88  auto gammaInput1 = gammaNode->AddEntryVar(lambdaNode->GetFunctionArguments()[1]);
89  auto gammaInput2 = gammaNode->AddEntryVar(lambdaNode->GetFunctionArguments()[2]);
90  auto gammaOutput =
91  gammaNode->AddExitVar({ gammaInput1.branchArgument[0], gammaInput2.branchArgument[1] });
92 
93  auto lambdaOutput = lambdaNode->finalize({ gammaOutput.output });
94  GraphExport::Create(*lambdaOutput, "");
95 
96  jlm::rvsdg::view(rvsdgModule.Rvsdg(), stdout);
97 
98  // Act
101  print(*module, stdout);
102 
103  // Assert
104  auto & ipg = module->ipgraph();
105  EXPECT_EQ(ipg.nnodes(), 1u);
106 
107  auto cfg = dynamic_cast<const FunctionNode &>(*ipg.begin()).cfg();
108  EXPECT_EQ(cfg->nnodes(), 4u);
109 }
110 
111 TEST(RvsdgToIpGraphConverterTests, EmptyGammaWithTwoSubregionsAndMatch)
112 {
113  using namespace jlm::llvm;
114  using namespace jlm::rvsdg;
115  using namespace jlm::util;
116 
117  // Arrange
118  auto valueType = jlm::rvsdg::TestType::createValueType();
119  const auto functionType = jlm::rvsdg::FunctionType::Create(
120  { jlm::rvsdg::BitType::Create(32), valueType, valueType },
121  { valueType });
122 
123  jlm::llvm::LlvmRvsdgModule rvsdgModule(FilePath(""), "", "");
124 
125  const auto lambdaNode = jlm::rvsdg::LambdaNode::Create(
126  rvsdgModule.Rvsdg().GetRootRegion(),
128  const auto conditionValue = lambdaNode->GetFunctionArguments()[0];
129  const auto trueValue = lambdaNode->GetFunctionArguments()[1];
130  const auto falseValue = lambdaNode->GetFunctionArguments()[2];
131 
132  auto caseValue = 24;
133  auto & matchNode = MatchOperation::CreateNode(*conditionValue, { { caseValue, 0 } }, 1, 2);
134 
135  const auto gammaNode = jlm::rvsdg::GammaNode::create(matchNode.output(0), 2);
136  auto [inputTrue, branchArgumentTrue] = gammaNode->AddEntryVar(trueValue);
137  auto [inputFalse, branchArgumentFalse] = gammaNode->AddEntryVar(falseValue);
138  auto [_, gammaOutput] = gammaNode->AddExitVar({ branchArgumentTrue[0], branchArgumentFalse[1] });
139 
140  const auto lambdaOutput = lambdaNode->finalize({ gammaOutput });
141  GraphExport::Create(*lambdaOutput, "");
142 
143  view(rvsdgModule.Rvsdg(), stdout);
144 
145  // Act
147  const auto module =
149  print(*module, stdout);
150 
151  // Assert
152  const auto & ipGraph = module->ipgraph();
153  EXPECT_EQ(ipGraph.nnodes(), 1u);
154 
155  const auto controlFlowGraph = dynamic_cast<const FunctionNode &>(*ipGraph.begin()).cfg();
156  EXPECT_TRUE(is_closed(*controlFlowGraph));
157 }
158 
159 TEST(RvsdgToIpGraphConverterTests, EmptyGammaWithTwoSubregions)
160 {
161  using namespace jlm::llvm;
162  using namespace jlm::rvsdg;
163  using namespace jlm::util;
164 
165  // Arrange
166  auto valueType = jlm::rvsdg::TestType::createValueType();
167  auto functionType = jlm::rvsdg::FunctionType::Create(
168  { jlm::rvsdg::BitType::Create(32), valueType, valueType },
169  { valueType });
170 
171  jlm::llvm::LlvmRvsdgModule rvsdgModule(FilePath(""), "", "");
172 
173  const auto lambdaNode = jlm::rvsdg::LambdaNode::Create(
174  rvsdgModule.Rvsdg().GetRootRegion(),
176  const auto trueValue = lambdaNode->GetFunctionArguments()[1];
177  const auto falseValue = lambdaNode->GetFunctionArguments()[2];
178 
179  auto & matchNode =
180  MatchOperation::CreateNode(*lambdaNode->GetFunctionArguments()[0], { { 0, 0 } }, 1, 2);
181 
182  const auto gammaNode0 = jlm::rvsdg::GammaNode::create(matchNode.output(0), 2);
183  const auto & c0 = jlm::rvsdg::CreateOpNode<ControlConstantOperation>(
184  *gammaNode0->subregion(0),
186  const auto & c1 = jlm::rvsdg::CreateOpNode<ControlConstantOperation>(
187  *gammaNode0->subregion(1),
189  auto c = gammaNode0->AddExitVar({ c0.output(0), c1.output(0) });
190 
191  const auto gammaNode1 = jlm::rvsdg::GammaNode::create(c.output, 2);
192  auto [inputTrue, branchArgumentTrue] = gammaNode1->AddEntryVar(trueValue);
193  auto [inputFalse, branchArgumentFalse] = gammaNode1->AddEntryVar(falseValue);
194  auto [_, gammaOutput] = gammaNode1->AddExitVar({ branchArgumentFalse[0], branchArgumentTrue[1] });
195 
196  const auto lambdaOutput = lambdaNode->finalize({ gammaOutput });
197  GraphExport::Create(*lambdaOutput, "");
198 
199  view(rvsdgModule.Rvsdg(), stdout);
200 
201  // Act
203  const auto module =
205  print(*module, stdout);
206 
207  // Assert
208  const auto & ipGraph = module->ipgraph();
209  EXPECT_EQ(ipGraph.nnodes(), 1u);
210 
211  const auto controlFlowGraph = dynamic_cast<const FunctionNode &>(*ipGraph.begin()).cfg();
212  EXPECT_TRUE(is_closed(*controlFlowGraph));
213 }
214 
215 TEST(RvsdgToIpGraphConverterTests, EmptyGammaWithThreeSubregions)
216 {
217  using namespace jlm::llvm;
218  using namespace jlm::rvsdg;
219  using namespace jlm::util;
220 
221  // Arrange
222  auto valueType = jlm::rvsdg::TestType::createValueType();
223  auto functionType = jlm::rvsdg::FunctionType::Create(
224  { jlm::rvsdg::BitType::Create(32), valueType, valueType },
225  { valueType });
226 
227  jlm::llvm::LlvmRvsdgModule rvsdgModule(FilePath(""), "", "");
228 
229  auto lambdaNode = jlm::rvsdg::LambdaNode::Create(
230  rvsdgModule.Rvsdg().GetRootRegion(),
232 
233  auto & matchNode = MatchOperation::CreateNode(
234  *lambdaNode->GetFunctionArguments()[0],
235  { { 0, 0 }, { 1, 1 } },
236  2,
237  3);
238 
239  auto gammaNode = jlm::rvsdg::GammaNode::create(matchNode.output(0), 3);
240  auto gammaInput1 = gammaNode->AddEntryVar(lambdaNode->GetFunctionArguments()[1]);
241  auto gammaInput2 = gammaNode->AddEntryVar(lambdaNode->GetFunctionArguments()[2]);
242  auto gammaOutput = gammaNode->AddExitVar({ gammaInput1.branchArgument[0],
243  gammaInput1.branchArgument[1],
244  gammaInput2.branchArgument[2] });
245 
246  auto lambdaOutput = lambdaNode->finalize({ gammaOutput.output });
247  GraphExport::Create(*lambdaOutput, "");
248 
249  jlm::rvsdg::view(rvsdgModule.Rvsdg(), stdout);
250 
251  // Act
254  print(*module, stdout);
255 
256  // Assert
257  auto & ipg = module->ipgraph();
258  EXPECT_EQ(ipg.nnodes(), 1u);
259 
260  auto cfg = dynamic_cast<const FunctionNode &>(*ipg.begin()).cfg();
261  EXPECT_TRUE(is_closed(*cfg));
262 }
263 
264 TEST(RvsdgToIpGraphConverterTests, PartialEmptyGamma)
265 {
266  using namespace jlm::llvm;
267  using namespace jlm::rvsdg;
268  using namespace jlm::util;
269 
270  // Arrange
271  auto valueType = jlm::rvsdg::TestType::createValueType();
272  auto functionType = jlm::rvsdg::FunctionType::Create(
273  { jlm::rvsdg::BitType::Create(1), valueType },
274  { valueType });
275 
276  jlm::llvm::LlvmRvsdgModule rvsdgModule(FilePath(""), "", "");
277 
278  auto lambdaNode = jlm::rvsdg::LambdaNode::Create(
279  rvsdgModule.Rvsdg().GetRootRegion(),
281 
282  auto & matchNode =
283  MatchOperation::CreateNode(*lambdaNode->GetFunctionArguments()[0], { { 0, 0 } }, 1, 2);
284  auto gammaNode = GammaNode::create(matchNode.output(0), 2);
285  auto gammaInput = gammaNode->AddEntryVar(lambdaNode->GetFunctionArguments()[1]);
286  auto output = TestOperation::createNode(
287  gammaNode->subregion(1),
288  { gammaInput.branchArgument[1] },
289  { valueType })
290  ->output(0);
291  auto gammaOutput = gammaNode->AddExitVar({ gammaInput.branchArgument[0], output });
292 
293  auto lambdaOutput = lambdaNode->finalize({ gammaOutput.output });
294 
295  GraphExport::Create(*lambdaOutput, "");
296 
297  jlm::rvsdg::view(rvsdgModule.Rvsdg(), stdout);
298 
299  // Act
302 
303  // Assert
304  auto & ipg = module->ipgraph();
305  EXPECT_EQ(ipg.nnodes(), 1u);
306 
307  auto cfg = dynamic_cast<const FunctionNode &>(*ipg.begin()).cfg();
308  std::cout << ControlFlowGraph::ToAscii(*cfg) << std::flush;
309 
310  EXPECT_TRUE(is_proper_structured(*cfg));
311 }
312 
313 TEST(RvsdgToIpGraphConverterTests, RecursiveData)
314 {
315  using namespace jlm::llvm;
316  using namespace jlm::rvsdg;
317 
318  // Arrange
319  auto vt = TestType::createValueType();
320  auto pt = PointerType::Create();
321 
322  LlvmRvsdgModule rm(jlm::util::FilePath(""), "", "");
323 
325  rm.Rvsdg(),
326  vt,
327  pt,
328  "import",
330  false,
331  4);
332 
333  PhiBuilder phiBuilder;
334  phiBuilder.begin(&rm.Rvsdg().GetRootRegion());
335  auto region = phiBuilder.subregion();
336  auto fixVar1 = phiBuilder.AddFixVar(pt);
337  auto fixVar2 = phiBuilder.AddFixVar(pt);
338  auto dep = phiBuilder.AddContextVar(*imp);
339 
340  Output *delta1 = nullptr, *delta2 = nullptr;
341  {
342  auto delta = DeltaNode::Create(
343  region,
345  auto dep1 = delta->AddContextVar(*fixVar2.recref).inner;
346  auto dep2 = delta->AddContextVar(*dep.inner).inner;
347  delta1 = &delta->finalize(
348  TestOperation::createNode(delta->subregion(), { dep1, dep2 }, { vt })->output(0));
349  }
350 
351  {
352  auto delta = DeltaNode::Create(
353  region,
355  auto dep1 = delta->AddContextVar(*fixVar1.recref).inner;
356  auto dep2 = delta->AddContextVar(*dep.inner).inner;
357  delta2 = &delta->finalize(
358  TestOperation::createNode(delta->subregion(), { dep1, dep2 }, { vt })->output(0));
359  }
360 
361  fixVar1.result->divert_to(delta1);
362  fixVar2.result->divert_to(delta2);
363 
364  auto phi = phiBuilder.end();
365  GraphExport::Create(*phi->output(0), "");
366 
367  view(rm.Rvsdg(), stdout);
368 
369  // Act
372  print(*module, stdout);
373 
374  // Assert
375  auto & ipGraph = module->ipgraph();
376  EXPECT_EQ(ipGraph.nnodes(), 3u);
377 
378  auto delta1Node = ipGraph.find("delta1");
379  auto delta2Node = ipGraph.find("delta2");
380  auto importNode = ipGraph.find("import");
381  EXPECT_EQ(delta1Node->numDependencies(), 2u);
382  for (auto depNode : *delta1Node)
383  {
384  EXPECT_TRUE(depNode == delta2Node || depNode == importNode);
385  }
386 
387  EXPECT_EQ(delta2Node->numDependencies(), 2u);
388  for (auto depNode : *delta2Node)
389  {
390  EXPECT_TRUE(depNode == delta1Node || depNode == importNode);
391  }
392 
393  EXPECT_EQ(importNode->numDependencies(), 0u);
394 }
395 
396 static size_t
398 {
399  using namespace jlm::llvm;
400  using namespace jlm::rvsdg;
401 
402  size_t numSsaPhiOperations = 0;
403  for (const auto tac : basicBlock.tacs())
404  {
405  if (is<SsaPhiOperation>(tac))
407  }
408 
409  return numSsaPhiOperations;
410 }
411 
412 TEST(RvsdgToIpGraphConverterTests, NestedLoopWithCall)
413 {
414  using namespace jlm::llvm;
415  using namespace jlm::rvsdg;
416  using namespace jlm::util;
417 
418  // Arrange
419  auto ioStateType = IOStateType::Create();
420  auto memoryStateType = MemoryStateType::Create();
421  auto pointerType = PointerType::Create();
422  auto functionType =
423  FunctionType::Create({ ioStateType, memoryStateType }, { ioStateType, memoryStateType });
424 
425  LlvmRvsdgModule rvsdgModule(FilePath(""), "", "");
426  auto & rvsdg = rvsdgModule.Rvsdg();
427 
429  rvsdg,
430  functionType,
431  "opaque",
434 
435  auto lambdaNode = LambdaNode::Create(
436  rvsdg.GetRootRegion(),
438  auto ioStateArgument = lambdaNode->GetFunctionArguments()[0];
439  auto memoryStateArgument = lambdaNode->GetFunctionArguments()[1];
440  auto opaqueCtxVar = lambdaNode->AddContextVar(opaque);
441 
442  auto outerThetaNode = ThetaNode::create(lambdaNode->subregion());
443  auto outerIOStateLoopVar = outerThetaNode->AddLoopVar(ioStateArgument);
444  auto outerMemoryStateLoopVar = outerThetaNode->AddLoopVar(memoryStateArgument);
445  auto outerOpaque = outerThetaNode->AddLoopVar(opaqueCtxVar.inner);
446 
447  auto innerThetaNode = ThetaNode::create(outerThetaNode->subregion());
448  auto innerIOStateLoopVar = innerThetaNode->AddLoopVar(outerIOStateLoopVar.pre);
449  auto innerMemoryStateLoopVar = innerThetaNode->AddLoopVar(outerMemoryStateLoopVar.pre);
450  auto innerOpaque = innerThetaNode->AddLoopVar(outerOpaque.pre);
451 
452  auto & callNode = CallOperation::CreateNode(
453  innerOpaque.pre,
454  functionType,
455  { innerIOStateLoopVar.pre, innerMemoryStateLoopVar.pre });
456 
457  innerIOStateLoopVar.post->divert_to(callNode.output(0));
458  innerMemoryStateLoopVar.post->divert_to(callNode.output(1));
459 
460  outerIOStateLoopVar.post->divert_to(innerIOStateLoopVar.output);
461  outerMemoryStateLoopVar.post->divert_to(innerMemoryStateLoopVar.output);
462  outerOpaque.post->divert_to(innerOpaque.output);
463 
464  auto lambdaOutput =
465  lambdaNode->finalize({ outerIOStateLoopVar.output, outerMemoryStateLoopVar.output });
466 
467  GraphExport::Create(*lambdaOutput, "f");
468 
469  view(rvsdgModule.Rvsdg(), stdout);
470 
471  // Act
473  auto ipGraphModule =
475 
476  print(*ipGraphModule, stdout);
477 
478  // Assert
479  // We expect that we only create SSA phi operations for the IO and memory state edges, but NOT
480  // for the context variable in the inner loop. Ultimately, this means that every basic block
481  // should either have zero or two SSA phi operations.
482  auto & ipGraph = ipGraphModule->ipgraph();
483  EXPECT_EQ(ipGraph.nnodes(), 2u);
484 
485  auto functionNode = ipGraph.find("f");
486  auto importNode = ipGraph.find("opaque");
487  EXPECT_EQ(functionNode->numDependencies(), 1u);
488  EXPECT_EQ(importNode->numDependencies(), 0u);
489  EXPECT_EQ(*functionNode->begin(), importNode);
490 
491  auto controlFlowGraph = dynamic_cast<const FunctionNode *>(ipGraph.find("f"))->cfg();
492  EXPECT_EQ(controlFlowGraph->nnodes(), 5u);
493 
494  for (auto & basicBlock : *controlFlowGraph)
495  {
496  auto numSsaPhis = numSsaPhiOperations(basicBlock);
497  EXPECT_TRUE(numSsaPhis == 2 || numSsaPhis == 0);
498  }
499 }
500 
501 class DataImportConversionTest : public testing::TestWithParam<std::tuple<
502  std::shared_ptr<const jlm::rvsdg::Type>,
503  std::string,
504  jlm::llvm::Linkage,
505  bool,
506  size_t>>
507 {
508 };
509 
511 {
512  using namespace jlm::llvm;
513  using namespace jlm::rvsdg;
514  using namespace jlm::util;
515 
516  // Arrange
517  auto [valueType, name, linkage, isConstant, alignment] = GetParam();
518 
519  const auto pointerType = PointerType::Create();
520 
521  LlvmRvsdgModule rvsdgModule(FilePath(""), "", "");
522  [[maybe_unused]] auto & import = LlvmGraphImport::createGlobalImport(
523  rvsdgModule.Rvsdg(),
524  valueType,
525  pointerType,
526  name,
527  linkage,
528  isConstant,
529  alignment);
530 
531  view(rvsdgModule.Rvsdg(), stdout);
532 
533  // Act
535  const auto ipGraphModule =
537 
538  print(*ipGraphModule, stdout);
539 
540  // Assert
541  const auto & ipGraph = ipGraphModule->ipgraph();
542  EXPECT_EQ(ipGraph.nnodes(), 1u);
543 
544  const auto dataNode = dynamic_cast<const DataNode *>(&*ipGraph.begin());
545  EXPECT_NE(dataNode, nullptr);
546 
547  EXPECT_EQ(dataNode->GetValueType(), valueType);
548  EXPECT_EQ(dataNode->name(), name);
549  EXPECT_EQ(dataNode->linkage(), linkage);
550  EXPECT_EQ(dataNode->constant(), isConstant);
551  EXPECT_EQ(dataNode->getAlignment(), alignment);
552 }
553 
555  Test1,
557  ::testing::Values(std::make_tuple(
559  "name",
561  false,
562  4)));
564  Test2,
566  ::testing::Values(std::make_tuple(
568  "name",
570  true,
571  8)));
573  Test3,
575  ::testing::Values(std::make_tuple(
577  "foo",
579  false,
580  1)));
static jlm::util::StatisticsCollector statisticsCollector
static const auto vt
Definition: PullTests.cpp:16
INSTANTIATE_TEST_SUITE_P(Test1, DataImportConversionTest, ::testing::Values(std::make_tuple(jlm::rvsdg::TestType::createValueType(), "name", jlm::llvm::Linkage::externalLinkage, false, 4)))
static size_t numSsaPhiOperations(const jlm::llvm::BasicBlock &basicBlock)
TEST_P(DataImportConversionTest, Test)
TEST(RvsdgToIpGraphConverterTests, GammaWithMatch)
const ThreeAddressCodeList & tacs() const noexcept
Definition: basic-block.hpp:38
static rvsdg::SimpleNode & CreateNode(rvsdg::Region &region, std::unique_ptr< CallOperation > callOperation, const std::vector< rvsdg::Output * > &operands)
Definition: call.hpp:489
static std::string ToAscii(const ControlFlowGraph &controlFlowGraph)
Definition: cfg.cpp:151
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
static std::shared_ptr< const IOStateType > Create()
Definition: types.cpp:343
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::shared_ptr< const MemoryStateType > Create()
Definition: types.cpp:379
static std::shared_ptr< const PointerType > Create()
Definition: types.cpp:45
static std::unique_ptr< InterProceduralGraphModule > CreateAndConvertModule(LlvmRvsdgModule &rvsdgModule, util::StatisticsCollector &statisticsCollector)
static std::shared_ptr< const BitType > Create(std::size_t nbits)
Creates bit type of specified width.
Definition: type.cpp:45
static std::shared_ptr< const ControlType > Create(std::size_t nalternatives)
Instantiates control type.
Definition: control.cpp:50
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
static LambdaNode * Create(rvsdg::Region &parent, std::unique_ptr< LambdaOperation > operation)
Definition: lambda.cpp:140
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
Graph & Rvsdg() noexcept
Definition: RvsdgModule.hpp:57
static std::shared_ptr< const TestType > createValueType()
Definition: TestType.cpp:67
Global memory state passed between functions.
void print(const AggregationNode &n, const AnnotationMap &dm, FILE *out)
Definition: print.cpp:120
bool is_proper_structured(const ControlFlowGraph &cfg)
bool is_closed(const ControlFlowGraph &cfg)
std::string view(const rvsdg::Region *region)
Definition: view.cpp:142