Jlm
DotWriterTests.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2024 HÃ¥vard Krogstie <krogstie.havard@gmail.com>
3  * See COPYING for terms of redistribution.
4  */
5 
6 #include <gtest/gtest.h>
7 
8 #include <jlm/llvm/DotWriter.hpp>
10 #include <jlm/rvsdg/gamma.hpp>
11 
12 TEST(DotWriterTests, TestWriteGraphs)
13 {
14  using namespace jlm::llvm;
15  using namespace jlm::util;
16  using namespace jlm::util::graph;
17 
18  // Arrange
19  GammaTest gammaTest;
20 
21  // Act
22  Writer writer;
23  LlvmDotWriter dotWriter;
24  dotWriter.WriteGraphs(writer, gammaTest.graph().GetRootRegion(), false);
25 
26  writer.outputAllGraphs(std::cout, OutputFormat::Dot);
27 
28  // Assert
29  auto & rootGraph = writer.GetGraph(0);
30  EXPECT_EQ(
31  rootGraph.GetProgramObject(),
32  reinterpret_cast<uintptr_t>(&gammaTest.graph().GetRootRegion()));
33  EXPECT_EQ(rootGraph.NumNodes(), 1u); // Only the lambda node for "f"
34  EXPECT_EQ(rootGraph.NumResultNodes(), 1u); // Exporting the function "f"
35  auto & lambdaNode = *assertedCast<InOutNode>(&rootGraph.GetNode(0));
36 
37  // The lambda only has one output, and a single subgraph
38  EXPECT_EQ(lambdaNode.GetLabel(), gammaTest.lambda->DebugString());
39  EXPECT_EQ(lambdaNode.NumInputPorts(), 0u);
40  EXPECT_EQ(lambdaNode.NumOutputPorts(), 1u);
41  EXPECT_EQ(lambdaNode.NumSubgraphs(), 1u);
42 
43  auto & fctBody = lambdaNode.GetSubgraph(0);
44  EXPECT_EQ(fctBody.NumArgumentNodes(), 6u);
45  EXPECT_EQ(fctBody.NumResultNodes(), 2u);
46 
47  // Argument a1 leads to the gamma node
48  auto & connections = fctBody.GetArgumentNode(1).GetConnections();
49  EXPECT_EQ(connections.size(), 1u);
50  auto & gammaNode = *assertedCast<InOutNode>(&connections[0]->GetTo().GetNode());
51  EXPECT_EQ(gammaNode.GetLabel(), gammaTest.gamma->DebugString());
52  EXPECT_EQ(gammaNode.NumInputPorts(), 5u);
53  EXPECT_EQ(gammaNode.NumOutputPorts(), 2u);
54  EXPECT_EQ(gammaNode.NumSubgraphs(), 2u);
55 
56  // The second argument of the first region of the gamma references the second gamma input
57  auto & argument = gammaNode.GetSubgraph(0).GetArgumentNode(1);
58  auto & input = gammaNode.GetInputPort(1);
59  EXPECT_EQ(argument.GetAttributeGraphElement("input"), &input);
60  // The label also includes the attribute index and input index
61  EXPECT_EQ(argument.GetLabel(), "a1 <- i1");
62  auto & result = argument.GetConnections().front()->GetOtherEnd(argument);
63  EXPECT_EQ(result.GetLabel(), "r0 -> o0");
64 
65  // Check that the last argument is colored red to represent the memory state type
66  auto & stateConnections = fctBody.GetArgumentNode(5).GetConnections();
67  EXPECT_EQ(stateConnections.size(), 1u);
68  EXPECT_EQ(stateConnections.front()->GetAttributeString("color"), "#FF0000");
69 
70  // Check that the output of the lambda leads to a graph export
71  auto & lambdaConnections = lambdaNode.GetOutputPort(0).GetConnections();
72  EXPECT_EQ(lambdaConnections.size(), 1u);
73  auto & graphExport = lambdaConnections.front()->GetTo().GetNode();
74  EXPECT_EQ(graphExport.GetLabel(), "export[f]");
75 }
76 
77 TEST(DotWriterTests, TestWriteGraph)
78 {
79  using namespace jlm::llvm;
80  using namespace jlm::util;
81  using namespace jlm::util::graph;
82 
83  // Arrange
84  GammaTest gammaTest;
85 
86  // Act
87  Writer writer;
88  LlvmDotWriter dotWriter;
89  dotWriter.WriteGraph(writer, gammaTest.graph().GetRootRegion());
90 
91  // Assert
92  auto & rootGraph = writer.GetGraph(0);
93  EXPECT_EQ(
94  rootGraph.GetProgramObject(),
95  reinterpret_cast<uintptr_t>(&gammaTest.graph().GetRootRegion()));
96  EXPECT_EQ(rootGraph.NumNodes(), 1u); // Only the lambda node for "f"
97  EXPECT_EQ(rootGraph.NumResultNodes(), 1u); // Exporting the function "f"
98  auto & lambdaNode = *assertedCast<InOutNode>(&rootGraph.GetNode(0));
99 
100  // The lambda only has one output, and a single subgraph
101  EXPECT_EQ(lambdaNode.GetLabel(), gammaTest.lambda->DebugString());
102  EXPECT_EQ(lambdaNode.NumInputPorts(), 0u);
103  EXPECT_EQ(lambdaNode.NumOutputPorts(), 1u);
104  EXPECT_EQ(lambdaNode.NumSubgraphs(), 0u);
105 
106  // Check that the output of the lambda leads to a graph export
107  auto & lambdaConnections = lambdaNode.GetOutputPort(0).GetConnections();
108  EXPECT_EQ(lambdaConnections.size(), 1u);
109  auto & graphExport = lambdaConnections.front()->GetTo().GetNode();
110  EXPECT_EQ(graphExport.GetLabel(), "export[f]");
111 }
112 
113 TEST(DotWriterTests, TestTypeGraph)
114 {
115  using namespace jlm::llvm;
116  using namespace jlm::util;
117  using namespace jlm::util::graph;
118 
119  // Arrange
120  GammaTest gammaTest;
121  auto ptrType = PointerType::Create();
122  auto bit32Type = jlm::rvsdg::BitType::Create(32);
123  auto memType = MemoryStateType::Create();
124 
125  // Act
126  Writer writer;
127  LlvmDotWriter dotWriter;
128  dotWriter.WriteGraphs(writer, gammaTest.graph().GetRootRegion(), true);
129 
130  writer.Finalize();
131  writer.outputAllGraphs(std::cout, OutputFormat::Dot);
132 
133  // Assert
134  auto & typeGraph = writer.GetGraph(0);
135  EXPECT_EQ(typeGraph.GetProgramObject(), 0u);
136 
137  // Check that nodes exist for the given types
138  [[maybe_unused]] auto & ptrNode = typeGraph.GetFromProgramObject<Node>(*ptrType);
139  [[maybe_unused]] auto & bit32Node = typeGraph.GetFromProgramObject<Node>(*ptrType);
140  auto & memNode = typeGraph.GetFromProgramObject<Node>(*memType);
141 
142  // Check that the rightmost argument of the function references the memNode type
143  auto & fGraph = writer.GetGraph(2);
144  EXPECT_EQ(writer.GetElementFromProgramObject(*gammaTest.lambda->subregion()), &fGraph);
145  EXPECT_EQ(fGraph.GetArgumentNode(5).GetAttributeGraphElement("type"), &memNode);
146 }
TEST(DotWriterTests, TestWriteGraphs)
GammaTest class.
Definition: TestRvsdgs.hpp:961
rvsdg::GammaNode * gamma
Definition: TestRvsdgs.hpp:969
jlm::rvsdg::LambdaNode * lambda
Definition: TestRvsdgs.hpp:967
static std::shared_ptr< const MemoryStateType > Create()
Definition: types.cpp:379
static std::shared_ptr< const PointerType > Create()
Definition: types.cpp:45
const rvsdg::Graph & graph()
Definition: TestRvsdgs.hpp:41
static std::shared_ptr< const BitType > Create(std::size_t nbits)
Creates bit type of specified width.
Definition: type.cpp:45
util::graph::Graph & WriteGraphs(util::graph::Writer &writer, const Region &region, bool emitTypeGraph)
Definition: DotWriter.cpp:198
util::graph::Graph & WriteGraph(util::graph::Writer &writer, const Region &region)
Definition: DotWriter.cpp:217
Region & GetRootRegion() const noexcept
Definition: graph.hpp:99
rvsdg::Region * subregion() const noexcept
Definition: lambda.hpp:138
std::string DebugString() const override
GraphElement * GetElementFromProgramObject(uintptr_t object) const
void outputAllGraphs(std::ostream &out, OutputFormat format)
Graph & GetGraph(size_t index)
Global memory state passed between functions.