Jlm
RvsdgTreePrinterTests.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2024 Nico Reißmann <nico.reissmann@gmail.com>
3  * See COPYING for terms of redistribution.
4  */
5 
6 #include <gtest/gtest.h>
7 
13 #include <jlm/rvsdg/TestNodes.hpp>
15 #include <jlm/rvsdg/TestType.hpp>
16 #include <jlm/util/Statistics.hpp>
17 
18 #include <fstream>
19 
20 static std::string
21 ReadFile(const jlm::util::FilePath & outputFilePath)
22 {
23  std::ifstream file(outputFilePath.to_str());
24  std::stringstream buffer;
25  buffer << file.rdbuf();
26 
27  return buffer.str();
28 }
29 
33 static std::string
35 {
36  using namespace jlm::util;
37 
38  const auto tmpDir = FilePath::TempDirectoryPath();
39  StatisticsCollectorSettings settings({}, tmpDir, "TestTreePrinter");
40  StatisticsCollector collector(settings);
41 
42  printer.Run(module, collector);
43 
44  auto fileName = tmpDir.Join("TestTreePrinter-" + settings.GetUniqueString() + "-rvsdgTree-0.txt");
45  auto result = ReadFile(fileName);
46 
47  // Cleanup
48  std::filesystem::remove(fileName.to_str());
49 
50  return result;
51 }
52 
53 TEST(RvsdgTreePrinterTests, PrintRvsdgTree)
54 {
55  using namespace jlm::llvm;
56  using namespace jlm::util;
57 
58  // Arrange
59  auto rvsdgModule = LlvmRvsdgModule::Create(FilePath(""), "", "");
60 
61  auto functionType = jlm::rvsdg::FunctionType::Create(
64  auto lambda = jlm::rvsdg::LambdaNode::Create(
65  rvsdgModule->Rvsdg().GetRootRegion(),
67  auto lambdaOutput = lambda->finalize({ lambda->GetFunctionArguments()[0] });
68  jlm::rvsdg::GraphExport::Create(*lambdaOutput, "f");
69 
70  RvsdgTreePrinter::Configuration configuration({});
71  RvsdgTreePrinter printer(configuration);
72 
73  // Act
74  auto tree = RunAndExtractFile(*rvsdgModule, printer);
75  std::cout << tree;
76 
77  // Assert
78  auto expectedTree =
79  "{\"StructuralNodes\":[{\"DebugString\":\"LAMBDA[f]\",\"Subregions\":[{}]}]}\n";
80 
81  EXPECT_EQ(tree, expectedTree);
82 }
83 
84 TEST(RvsdgTreePrinterTests, PrintNumRvsdgNodesAnnotation)
85 {
86  using namespace jlm::llvm;
87  using namespace jlm::rvsdg;
88  using namespace jlm::util;
89 
90  // Arrange
91  auto rvsdgModule = jlm::llvm::LlvmRvsdgModule::Create(FilePath(""), "", "");
92  auto rootRegion = &rvsdgModule->Rvsdg().GetRootRegion();
93 
94  auto structuralNode = TestStructuralNode::create(rootRegion, 2);
95  TestOperation::createNode(structuralNode->subregion(0), {}, {});
96  TestOperation::createNode(structuralNode->subregion(1), {}, {});
97 
98  TestOperation::createNode(rootRegion, {}, {});
99 
100  RvsdgTreePrinter::Configuration configuration(
102  RvsdgTreePrinter printer(configuration);
103 
104  // Act
105  auto tree = RunAndExtractFile(*rvsdgModule, printer);
106  std::cout << tree;
107 
108  // Assert
109  auto expectedTree =
110  "{\"NumRvsdgNodes\":2,\"StructuralNodes\":[{\"DebugString\":\"TestStructuralOperation\","
111  "\"NumRvsdgNodes\":2,\"Subregions\":[{\"NumRvsdgNodes\":1},{\"NumRvsdgNodes\":1}]}]}\n";
112 
113  EXPECT_EQ(tree, expectedTree);
114 }
115 
116 TEST(RvsdgTreePrinterTests, PrintNumLoadNodesAnnotation)
117 {
118  using namespace jlm::llvm;
119  using namespace jlm::rvsdg;
120  using namespace jlm::util;
121 
122  // Arrange
123  const auto pointerType = PointerType::Create();
124  const auto memoryStateType = MemoryStateType::Create();
125  const auto valueType = jlm::rvsdg::TestType::createValueType();
126 
127  auto rvsdgModule = jlm::llvm::LlvmRvsdgModule::Create(FilePath(""), "", "");
128  auto & rvsdg = rvsdgModule->Rvsdg();
129  auto rootRegion = &rvsdg.GetRootRegion();
130 
131  auto & address = jlm::rvsdg::GraphImport::Create(rvsdg, pointerType, "a");
132  auto & memoryState = jlm::rvsdg::GraphImport::Create(rvsdg, memoryStateType, "m");
133 
134  auto structuralNode = TestStructuralNode::create(rootRegion, 3);
135  const auto addressInput = structuralNode->addInputWithArguments(address);
136  const auto memoryStateInput = structuralNode->addInputWithArguments(memoryState);
138  addressInput.argument[0],
139  { memoryStateInput.argument[0] },
140  valueType,
141  4);
142  TestOperation::createNode(structuralNode->subregion(1), {}, {});
144  addressInput.argument[2],
145  { memoryStateInput.argument[2] },
146  valueType,
147  4);
148 
149  TestOperation::createNode(rootRegion, {}, {});
150 
151  RvsdgTreePrinter::Configuration configuration(
153  RvsdgTreePrinter printer(configuration);
154 
155  // Act
156  auto tree = RunAndExtractFile(*rvsdgModule, printer);
157  std::cout << tree;
158 
159  // Assert
160  auto expectedTree = "{\"NumLoadNodes\":0,\"StructuralNodes\":[{\"DebugString\":"
161  "\"TestStructuralOperation\",\"NumLoadNodes\":2,\"Subregions\":"
162  "[{\"NumLoadNodes\":1},{\"NumLoadNodes\":0},{\"NumLoadNodes\":1}]}]}\n";
163 
164  EXPECT_EQ(tree, expectedTree);
165 }
166 
167 TEST(RvsdgTreePrinterTests, PrintNumMemoryStateInputsOutputsAnnotation)
168 {
169  using namespace jlm::llvm;
170  using namespace jlm::rvsdg;
171  using namespace jlm::util;
172 
173  // Arrange
174  auto memoryStateType = MemoryStateType::Create();
175  auto valueType = jlm::rvsdg::TestType::createValueType();
176 
177  auto rvsdgModule = jlm::llvm::LlvmRvsdgModule::Create(FilePath(""), "", "");
178  auto & rvsdg = rvsdgModule->Rvsdg();
179 
180  auto & x = jlm::rvsdg::GraphImport::Create(rvsdg, memoryStateType, "x");
181  auto & y = jlm::rvsdg::GraphImport::Create(rvsdg, valueType, "y");
182 
183  auto structuralNode = TestStructuralNode::create(&rvsdg.GetRootRegion(), 2);
184  const auto inputVarX = structuralNode->addInputWithArguments(x);
185  const auto inputVarY = structuralNode->addInputWithArguments(y);
186 
187  auto outputVarX =
188  structuralNode->addOutputWithResults({ inputVarX.argument[0], inputVarX.argument[1] });
189  auto outputVarY =
190  structuralNode->addOutputWithResults({ inputVarY.argument[0], inputVarY.argument[1] });
191 
192  jlm::rvsdg::GraphExport::Create(*outputVarX.output, "x");
193  jlm::rvsdg::GraphExport::Create(*outputVarY.output, "y");
194 
195  RvsdgTreePrinter::Configuration configuration(
197  RvsdgTreePrinter printer(configuration);
198 
199  // Act
200  auto tree = RunAndExtractFile(*rvsdgModule, printer);
201  std::cout << tree;
202 
203  // Assert
204  auto expectedTree =
205  "{\"NumMemoryStateTypeArguments\":1,\"NumMemoryStateTypeResults\":1,\"StructuralNodes\":"
206  "[{\"DebugString\":\"TestStructuralOperation\",\"NumMemoryStateTypeInputs\":1,"
207  "\"NumMemoryStateTypeOutputs\":1,\"Subregions\":[{\"NumMemoryStateTypeArguments\":"
208  "1,\"NumMemoryStateTypeResults\":1},{\"NumMemoryStateTypeArguments\":"
209  "1,\"NumMemoryStateTypeResults\":1}]}]}\n";
210 
211  EXPECT_EQ(tree, expectedTree);
212 }
213 
214 TEST(RvsdgTreePrinterTests, printDebugIds)
215 {
216  using namespace jlm::llvm;
217  using namespace jlm::rvsdg;
218  using namespace jlm::util;
219 
220  // Arrange
221  auto valueType = TestType::createValueType();
222 
223  auto rvsdgModule = LlvmRvsdgModule::Create(FilePath(""), "", "");
224  auto & rvsdg = rvsdgModule->Rvsdg();
225 
226  TestStructuralNode::create(&rvsdg.GetRootRegion(), 2);
227 
228  const RvsdgTreePrinter::Configuration configuration(
230  RvsdgTreePrinter printer(configuration);
231 
232  // Act
233  auto tree = RunAndExtractFile(*rvsdgModule, printer);
234  std::cout << tree;
235 
236  // Assert
237  const auto expectedTree =
238  "{\"RegionId\":0,\"StructuralNodes\":[{\"DebugString\":\"TestStructuralOperation\","
239  "\"NodeId\":0,\"Subregions\":[{\"RegionId\":1},{\"RegionId\":2}]}]}\n";
240 
241  EXPECT_EQ(tree, expectedTree);
242 }
243 
244 TEST(RvsdgTreePrinterTests, printAllocaNodes)
245 {
246  using namespace jlm::llvm;
247  using namespace jlm::rvsdg;
248  using namespace jlm::util;
249 
250  // Arrange
251  auto valueType = TestType::createValueType();
252  auto structType = StructType::CreateIdentified({ valueType, valueType }, false);
253 
254  auto rvsdgModule = LlvmRvsdgModule::Create(FilePath(""), "", "");
255  auto & rvsdg = rvsdgModule->Rvsdg();
256 
257  auto & one = IntegerConstantOperation::Create(rvsdg.GetRootRegion(), 32, 1);
258 
259  auto allocaResults = AllocaOperation::create(valueType, one.output(0), 4);
260  auto aggregatedAllocaResults = AllocaOperation::create(structType, one.output(0), 4);
261 
262  const RvsdgTreePrinter::Configuration configuration(
265  RvsdgTreePrinter printer(configuration);
266 
267  // Act
268  auto tree = RunAndExtractFile(*rvsdgModule, printer);
269  std::cout << tree;
270 
271  // Assert
272  const auto expectedTree = "{\"NumAllocaNodes\":2,\"NumAggregateAllocaNodes\":1}\n";
273 
274  EXPECT_EQ(tree, expectedTree);
275 }
static std::string ReadFile(const jlm::util::FilePath &outputFilePath)
static std::string RunAndExtractFile(jlm::llvm::LlvmRvsdgModule &module, jlm::llvm::RvsdgTreePrinter &printer)
TEST(RvsdgTreePrinterTests, PrintRvsdgTree)
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 rvsdg::Node & Create(rvsdg::Region &region, IntegerValueRepresentation representation)
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)
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
static std::shared_ptr< const MemoryStateType > Create()
Definition: types.cpp:379
static std::shared_ptr< const PointerType > Create()
Definition: types.cpp:45
RVSDG tree printer debug pass.
void Run(rvsdg::RvsdgModule &rvsdgModule, util::StatisticsCollector &statisticsCollector) override
Perform RVSDG transformation.
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
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 GraphExport & Create(Output &origin, std::string name)
Definition: graph.cpp:62
static GraphImport & Create(Graph &graph, std::shared_ptr< const rvsdg::Type > type, std::string name)
Definition: graph.cpp:36
static LambdaNode * Create(rvsdg::Region &parent, std::unique_ptr< LambdaOperation > operation)
Definition: lambda.cpp:140
static std::shared_ptr< const TestType > createValueType()
Definition: TestType.cpp:67
static FilePath TempDirectoryPath()
Definition: file.hpp:317
const std::string & to_str() const noexcept
Definition: file.hpp:275
Global memory state passed between functions.
static void remove(Node *node)
Definition: region.hpp:978