Jlm
LoadTests.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 
11 #include <jlm/llvm/ir/print.hpp>
12 
13 #include <llvm/IR/BasicBlock.h>
14 #include <llvm/IR/IRBuilder.h>
15 #include <llvm/IR/Module.h>
16 
17 TEST(LoadTests, LoadConversion)
18 {
19  using namespace llvm;
20 
21  // Arrange
22  llvm::LLVMContext context;
23  std::unique_ptr<Module> llvmModule(new Module("module", context));
24 
25  auto int64Type = Type::getInt64Ty(context);
26  auto pointerType = llvm::PointerType::getUnqual(context);
27 
28  auto functionType = FunctionType::get(int64Type, ArrayRef<Type *>({ pointerType }), false);
29  auto function =
30  Function::Create(functionType, GlobalValue::ExternalLinkage, "f", llvmModule.get());
31 
32  auto basicBlock = BasicBlock::Create(context, "BasicBlock", function);
33 
34  IRBuilder<> builder(basicBlock);
35  auto loadedValue1 = builder.CreateLoad(int64Type, function->arg_begin(), true);
36  auto loadedValue2 = builder.CreateLoad(int64Type, function->arg_begin(), false);
37  auto loadedValue3 = builder.CreateLoad(int64Type, function->arg_begin(), true);
38  auto sum1 = builder.CreateAdd(loadedValue1, loadedValue2);
39  auto sum2 = builder.CreateAdd(sum1, loadedValue3);
40  builder.CreateRet(sum2);
41 
42  llvmModule->print(llvm::errs(), nullptr);
43 
44  // Act
45  auto ipgModule = jlm::llvm::ConvertLlvmModule(*llvmModule);
46  print(*ipgModule, stdout);
47 
48  // Assert
49  {
50  using namespace jlm::llvm;
51 
52  auto controlFlowGraph =
53  dynamic_cast<const FunctionNode *>(ipgModule->ipgraph().find("f"))->cfg();
54  auto basicBlock =
55  dynamic_cast<const jlm::llvm::BasicBlock *>(controlFlowGraph->entry()->OutEdge(0)->sink());
56 
57  size_t numLoadThreeAddressCodes = 0;
58  size_t numLoadVolatileThreeAddressCodes = 0;
59  for (auto it = basicBlock->begin(); it != basicBlock->end(); it++)
60  {
61  if (is<LoadVolatileOperation>(*it))
62  {
63  numLoadVolatileThreeAddressCodes++;
64  auto ioStateAssignment = *std::next(it);
65  auto memoryStateAssignment = *std::next(it, 2);
66 
67  EXPECT_TRUE(is<AssignmentOperation>(ioStateAssignment->operation()));
68  EXPECT_TRUE(is<IOStateType>(ioStateAssignment->operand(0)->type()));
69 
70  EXPECT_TRUE(is<AssignmentOperation>(memoryStateAssignment->operation()));
71  EXPECT_TRUE(is<MemoryStateType>(memoryStateAssignment->operand(0)->type()));
72  }
73  else if (is<LoadNonVolatileOperation>(*it))
74  {
75  numLoadThreeAddressCodes++;
76  auto memoryStateAssignment = *std::next(it, 1);
77 
78  EXPECT_TRUE(is<AssignmentOperation>(memoryStateAssignment->operation()));
79  EXPECT_TRUE(is<MemoryStateType>(memoryStateAssignment->operand(0)->type()));
80  }
81  }
82 
83  EXPECT_EQ(numLoadThreeAddressCodes, 1u);
84  EXPECT_EQ(numLoadVolatileThreeAddressCodes, 2u);
85  }
86 }
TEST(LoadTests, LoadConversion)
Definition: LoadTests.cpp:17
Global memory state passed between functions.
void print(const AggregationNode &n, const AnnotationMap &dm, FILE *out)
Definition: print.cpp:120
std::unique_ptr< InterProceduralGraphModule > ConvertLlvmModule(::llvm::Module &llvmModule)