Jlm
StoreTests.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(StoreTests, StoreConversion)
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  auto voidType = Type::getVoidTy(context);
28 
29  auto functionType =
30  FunctionType::get(voidType, ArrayRef<Type *>({ int64Type, pointerType }), false);
31  auto function =
32  Function::Create(functionType, GlobalValue::ExternalLinkage, "f", llvmModule.get());
33  auto valueArgument = function->getArg(0);
34  auto addressArgument = function->getArg(1);
35 
36  auto basicBlock = BasicBlock::Create(context, "BasicBlock", function);
37 
38  IRBuilder<> builder(basicBlock);
39  builder.CreateStore(valueArgument, addressArgument, true);
40  builder.CreateStore(valueArgument, addressArgument, false);
41  builder.CreateStore(valueArgument, addressArgument, true);
42  builder.CreateRetVoid();
43 
44  llvmModule->print(llvm::errs(), nullptr);
45 
46  // Act
47  auto ipgModule = jlm::llvm::ConvertLlvmModule(*llvmModule);
48  print(*ipgModule, stdout);
49 
50  // Assert
51  {
52  using namespace jlm::llvm;
53 
54  auto controlFlowGraph =
55  dynamic_cast<const FunctionNode *>(ipgModule->ipgraph().find("f"))->cfg();
56  auto basicBlock =
57  dynamic_cast<const jlm::llvm::BasicBlock *>(controlFlowGraph->entry()->OutEdge(0)->sink());
58 
59  size_t numStoreThreeAddressCodes = 0;
60  size_t numStoreVolatileThreeAddressCodes = 0;
61  for (auto it = basicBlock->begin(); it != basicBlock->end(); it++)
62  {
63  if (is<StoreVolatileOperation>(*it))
64  {
65  numStoreVolatileThreeAddressCodes++;
66  auto ioStateAssignment = *std::next(it);
67  auto memoryStateAssignment = *std::next(it, 2);
68 
69  EXPECT_TRUE(is<AssignmentOperation>(ioStateAssignment->operation()));
70  EXPECT_TRUE(is<IOStateType>(ioStateAssignment->operand(0)->type()));
71 
72  EXPECT_TRUE(is<AssignmentOperation>(memoryStateAssignment->operation()));
73  EXPECT_TRUE(is<MemoryStateType>(memoryStateAssignment->operand(0)->type()));
74  }
75  else if (is<StoreNonVolatileOperation>(*it))
76  {
77  numStoreThreeAddressCodes++;
78  auto memoryStateAssignment = *std::next(it, 1);
79 
80  EXPECT_TRUE(is<AssignmentOperation>(memoryStateAssignment->operation()));
81  EXPECT_TRUE(is<MemoryStateType>(memoryStateAssignment->operand(0)->type()));
82  }
83  }
84 
85  EXPECT_EQ(numStoreThreeAddressCodes, 1u);
86  EXPECT_EQ(numStoreVolatileThreeAddressCodes, 2u);
87  }
88 }
TEST(StoreTests, StoreConversion)
Definition: StoreTests.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)