Jlm
Loading...
Searching...
No Matches
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>
22#include <jlm/rvsdg/view.hpp>
24
25TEST(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(),
41 LlvmLambdaOperation::Create(functionType, "f", Linkage::externalLinkage));
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
58 auto module = RvsdgToIpGraphConverter::CreateAndConvertModule(rvsdgModule, statisticsCollector);
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
69TEST(RvsdgToIpGraphConverterTests, GammaWithoutMatch)
70{
71 using namespace jlm::llvm;
72 using namespace jlm::rvsdg;
73 using namespace jlm::util;
74
75 // Arrange
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(),
85 LlvmLambdaOperation::Create(functionType, "f", Linkage::externalLinkage));
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
100 auto module = RvsdgToIpGraphConverter::CreateAndConvertModule(rvsdgModule, statisticsCollector);
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
111TEST(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(),
127 LlvmLambdaOperation::Create(functionType, "f", Linkage::externalLinkage));
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 =
148 RvsdgToIpGraphConverter::CreateAndConvertModule(rvsdgModule, statisticsCollector);
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
159TEST(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(),
175 LlvmLambdaOperation::Create(functionType, "f", Linkage::externalLinkage));
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);
184 *gammaNode0->subregion(0),
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 =
204 RvsdgToIpGraphConverter::CreateAndConvertModule(rvsdgModule, statisticsCollector);
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
215TEST(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(),
231 LlvmLambdaOperation::Create(functionType, "f", Linkage::externalLinkage));
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
253 auto module = RvsdgToIpGraphConverter::CreateAndConvertModule(rvsdgModule, statisticsCollector);
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
264TEST(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(),
280 LlvmLambdaOperation::Create(functionType, "f", Linkage::externalLinkage));
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
301 auto module = RvsdgToIpGraphConverter::CreateAndConvertModule(rvsdgModule, statisticsCollector);
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
313TEST(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
324 auto imp = &LlvmGraphImport::createGlobalImport(
325 rm.Rvsdg(),
326 vt,
327 pt,
328 "import",
329 Linkage::externalLinkage,
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,
344 LlvmDeltaOperation::Create(vt, "delta1", Linkage::externalLinkage, "", false, 4));
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,
354 LlvmDeltaOperation::Create(vt, "delta2", Linkage::externalLinkage, "", false, 4));
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
371 auto module = RvsdgToIpGraphConverter::CreateAndConvertModule(rm, statisticsCollector);
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
396static 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
412TEST(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
428 auto & opaque = LlvmGraphImport::createFunctionImport(
429 rvsdg,
430 functionType,
431 "opaque",
432 Linkage::externalLinkage,
433 CallingConvention::Default);
434
435 auto lambdaNode = LambdaNode::Create(
436 rvsdg.GetRootRegion(),
437 LlvmLambdaOperation::Create(functionType, "f", Linkage::externalLinkage));
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 =
474 RvsdgToIpGraphConverter::CreateAndConvertModule(rvsdgModule, statisticsCollector);
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
501class 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 =
536 RvsdgToIpGraphConverter::CreateAndConvertModule(rvsdgModule, statisticsCollector);
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 void print(const jlm::util::DisjointSet< int >::Set &set)
std::int64_t c1
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
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:141
PhiNode * end()
Definition Phi.cpp:270
PhiNode::ContextVar AddContextVar(jlm::rvsdg::Output &origin)
Definition Phi.cpp:251
PhiNode::FixVar AddFixVar(std::shared_ptr< const jlm::rvsdg::Type > type)
Definition Phi.cpp:257
void begin(rvsdg::Region *parent)
Definition Phi.hpp:355
rvsdg::Region * subregion() const noexcept
Definition Phi.hpp:349
Graph & Rvsdg() noexcept
static std::shared_ptr< const TestType > createValueType()
Definition TestType.cpp:67
Global memory state passed between functions.
bool is_proper_structured(const ControlFlowGraph &cfg)
bool is_closed(const ControlFlowGraph &cfg)
std::string view(const rvsdg::Region *region)
Definition view.cpp:142
NodeType * TryGetOwnerNode(const rvsdg::Input &input) noexcept
Checks if this is an input to a node of specified type.
Definition node.hpp:872