Jlm
Loading...
Searching...
No Matches
ThreeAddressCodeConversionTests.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
15
16#include <jlm/rvsdg/view.hpp>
17
19
20static std::unique_ptr<jlm::llvm::ControlFlowGraph>
23 const jlm::rvsdg::SimpleOperation & operation)
24{
25 using namespace jlm::llvm;
26
27 auto cfg = ControlFlowGraph::create(ipgModule);
28
29 std::vector<const Variable *> operands;
30 for (size_t n = 0; n < operation.narguments(); n++)
31 {
32 auto & operandType = operation.argument(n);
33 auto operand = cfg->entry()->append_argument(Argument::create("", operandType));
34 operands.emplace_back(operand);
35 }
36
37 auto basicBlock = BasicBlock::create(*cfg);
38 auto threeAddressCode = basicBlock->append_last(ThreeAddressCode::create(
39 std::unique_ptr<jlm::rvsdg::SimpleOperation>(
40 jlm::util::assertedCast<jlm::rvsdg::SimpleOperation>(operation.copy().release())),
41 operands));
42
43 for (size_t n = 0; n < threeAddressCode->nresults(); n++)
44 {
45 auto result = threeAddressCode->result(n);
46 cfg->exit()->append_result(result);
47 }
48
49 cfg->exit()->divert_inedges(basicBlock);
50 basicBlock->add_outedge(cfg->exit());
51
52 return cfg;
53}
54
55static std::unique_ptr<jlm::llvm::InterProceduralGraphModule>
57{
58 using namespace jlm::llvm;
59
60 auto ipgModule = InterProceduralGraphModule::create(jlm::util::FilePath(""), "", "");
61 auto & ipgraph = ipgModule->ipgraph();
62
63 std::vector<std::shared_ptr<const jlm::rvsdg::Type>> operandTypes;
64 for (size_t n = 0; n < operation.narguments(); n++)
65 {
66 operandTypes.emplace_back(operation.argument(n));
67 }
68
69 std::vector<std::shared_ptr<const jlm::rvsdg::Type>> resultTypes;
70 for (size_t n = 0; n < operation.nresults(); n++)
71 {
72 resultTypes.emplace_back(operation.result(n));
73 }
74
75 auto functionType = jlm::rvsdg::FunctionType::Create(operandTypes, resultTypes);
76
77 auto functionNode = FunctionNode::create(ipgraph, "test", functionType, Linkage::externalLinkage);
78 auto cfg = SetupControlFlowGraph(*ipgModule, operation);
79 functionNode->add_cfg(std::move(cfg));
80 ipgModule->create_variable(functionNode);
81
82 return ipgModule;
83}
84
85TEST(ThreeAddressCodeConversionTests, LoadVolatileConversion)
86{
87 using namespace jlm::llvm;
88
89 // Arrange
91 LoadVolatileOperation operation(valueType, 3, 4);
92 auto ipgModule = SetupFunctionWithThreeAddressCode(operation);
93
94 // Act
96 auto rvsdgModule = ConvertInterProceduralGraphModule(*ipgModule, statisticsCollector);
97 std::cout << jlm::rvsdg::view(&rvsdgModule->Rvsdg().GetRootRegion()) << std::flush;
98
99 // Assert
100 auto lambdaOutput = rvsdgModule->Rvsdg().GetRootRegion().result(0)->origin();
101 auto lambda = jlm::rvsdg::TryGetOwnerNode<jlm::rvsdg::LambdaNode>(*lambdaOutput);
102
103 auto loadVolatileNode = lambda->subregion()->Nodes().begin().ptr();
104 EXPECT_TRUE(is<LoadVolatileOperation>(loadVolatileNode));
105}
106
107TEST(ThreeAddressCodeConversionTests, StoreVolatileConversion)
108{
109 using namespace jlm::llvm;
110
111 // Arrange
112 auto valueType = jlm::rvsdg::TestType::createValueType();
113 StoreVolatileOperation operation(valueType, 3, 4);
114 auto ipgModule = SetupFunctionWithThreeAddressCode(operation);
115
116 // Act
118 auto rvsdgModule = ConvertInterProceduralGraphModule(*ipgModule, statisticsCollector);
119 std::cout << jlm::rvsdg::view(&rvsdgModule->Rvsdg().GetRootRegion()) << std::flush;
120
121 // Assert
122 auto lambdaOutput = rvsdgModule->Rvsdg().GetRootRegion().result(0)->origin();
123 auto lambda = jlm::rvsdg::TryGetOwnerNode<jlm::rvsdg::LambdaNode>(*lambdaOutput);
124
125 auto storeVolatileNode = lambda->subregion()->Nodes().begin().ptr();
126 EXPECT_TRUE(is<StoreVolatileOperation>(storeVolatileNode));
127}
static jlm::util::StatisticsCollector statisticsCollector
static std::unique_ptr< jlm::llvm::ControlFlowGraph > SetupControlFlowGraph(jlm::llvm::InterProceduralGraphModule &ipgModule, const jlm::rvsdg::SimpleOperation &operation)
TEST(ThreeAddressCodeConversionTests, LoadVolatileConversion)
static std::unique_ptr< jlm::llvm::InterProceduralGraphModule > SetupFunctionWithThreeAddressCode(const jlm::rvsdg::SimpleOperation &operation)
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)
virtual std::unique_ptr< Operation > copy() const =0
const std::shared_ptr< const rvsdg::Type > & argument(size_t index) const noexcept
Definition operation.cpp:23
const std::shared_ptr< const rvsdg::Type > & result(size_t index) const noexcept
Definition operation.cpp:36
size_t nresults() const noexcept
Definition operation.cpp:30
size_t narguments() const noexcept
Definition operation.cpp:17
static std::shared_ptr< const TestType > createValueType()
Definition TestType.cpp:67
Global memory state passed between functions.
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