Jlm
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 
14 #include <jlm/rvsdg/TestType.hpp>
15 
16 #include <jlm/rvsdg/view.hpp>
17 
18 #include <jlm/util/Statistics.hpp>
19 
20 static 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 
55 static 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 
85 TEST(ThreeAddressCodeConversionTests, LoadVolatileConversion)
86 {
87  using namespace jlm::llvm;
88 
89  // Arrange
90  auto valueType = jlm::rvsdg::TestType::createValueType();
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 
107 TEST(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::InterProceduralGraphModule > SetupFunctionWithThreeAddressCode(const jlm::rvsdg::SimpleOperation &operation)
TEST(ThreeAddressCodeConversionTests, LoadVolatileConversion)
static std::unique_ptr< jlm::llvm::ControlFlowGraph > SetupControlFlowGraph(jlm::llvm::InterProceduralGraphModule &ipgModule, const jlm::rvsdg::SimpleOperation &operation)
static std::unique_ptr< Argument > create(const std::string &name, std::shared_ptr< const jlm::rvsdg::Type > type, const AttributeSet &attributes)
Definition: cfg.hpp:59
static BasicBlock * create(ControlFlowGraph &cfg)
Definition: basic-block.cpp:37
static std::unique_ptr< ControlFlowGraph > create(InterProceduralGraphModule &im)
Definition: cfg.hpp:267
static FunctionNode * create(InterProceduralGraph &ipg, const std::string &name, std::shared_ptr< const rvsdg::FunctionType > type, const llvm::Linkage &linkage, const CallingConvention &callingConvention, const AttributeSet &attributes)
Definition: ipgraph.hpp:242
static std::unique_ptr< InterProceduralGraphModule > create(const jlm::util::FilePath &sourceFilename, const std::string &targetTriple, const std::string &dataLayout)
static std::unique_ptr< llvm::ThreeAddressCode > create(std::unique_ptr< rvsdg::SimpleOperation > operation, const std::vector< const Variable * > &operands)
Definition: tac.hpp:135
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.
static std::unique_ptr< LlvmRvsdgModule > ConvertInterProceduralGraphModule(InterProceduralGraphModule &interProceduralGraphModule, InterProceduralGraphToRvsdgStatisticsCollector &statisticsCollector)
std::string view(const rvsdg::Region *region)
Definition: view.cpp:142
static std::vector< jlm::rvsdg::Output * > operands(const Node *node)
Definition: node.hpp:1049