59ee01f36010c29abb81ba959135aeaf8d3e640c
[oota-llvm.git] / unittests / ExecutionEngine / Orc / ObjectLinkingLayerTest.cpp
1 //===-- ObjectLinkingLayerTest.cpp - Unit tests for object linking layer --===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "OrcTestCommon.h"
11 #include "llvm/ExecutionEngine/ExecutionEngine.h"
12 #include "llvm/ExecutionEngine/SectionMemoryManager.h"
13 #include "llvm/ExecutionEngine/Orc/CompileUtils.h"
14 #include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
15 #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
16 #include "llvm/IR/Constants.h"
17 #include "llvm/IR/LLVMContext.h"
18 #include "gtest/gtest.h"
19
20 using namespace llvm;
21 using namespace llvm::orc;
22
23 namespace {
24
25 class ObjectLinkingLayerExecutionTest : public testing::Test,
26                                         public OrcExecutionTest {
27 };
28
29 class SectionMemoryManagerWrapper : public SectionMemoryManager {
30 public:
31   int FinalizationCount = 0;
32   bool finalizeMemory(std::string *ErrMsg = 0) override {
33     ++FinalizationCount;
34     return SectionMemoryManager::finalizeMemory(ErrMsg);
35   }
36 };
37
38 TEST(ObjectLinkingLayerTest, TestSetProcessAllSections) {
39
40   class SectionMemoryManagerWrapper : public SectionMemoryManager {
41   public:
42     SectionMemoryManagerWrapper(bool &DebugSeen) : DebugSeen(DebugSeen) {}
43     uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
44                                  unsigned SectionID,
45                                  StringRef SectionName,
46                                  bool IsReadOnly) override {
47       if (SectionName == ".debug_str")
48         DebugSeen = true;
49       return SectionMemoryManager::allocateDataSection(Size, Alignment,
50                                                          SectionID,
51                                                          SectionName,
52                                                          IsReadOnly);
53     }
54   private:
55     bool DebugSeen;
56   };
57
58   ObjectLinkingLayer<> ObjLayer;
59
60   auto M = llvm::make_unique<Module>("", getGlobalContext());
61   M->setTargetTriple("x86_64-unknown-linux-gnu");
62   Type *Int32Ty = IntegerType::get(getGlobalContext(), 32);
63   GlobalVariable *GV =
64     new GlobalVariable(*M, Int32Ty, false, GlobalValue::ExternalLinkage,
65                          ConstantInt::get(Int32Ty, 42), "foo");
66
67   GV->setSection(".debug_str");
68
69   std::unique_ptr<TargetMachine> TM(
70     EngineBuilder().selectTarget(Triple(M->getTargetTriple()), "", "",
71                                  SmallVector<std::string, 1>()));
72   if (!TM)
73     return;
74
75   auto OwningObj = SimpleCompiler(*TM)(*M);
76   std::vector<object::ObjectFile*> Objs;
77   Objs.push_back(OwningObj.getBinary());
78
79   bool DebugSectionSeen = false;
80   SectionMemoryManagerWrapper SMMW(DebugSectionSeen);
81   auto Resolver =
82     createLambdaResolver(
83       [](const std::string &Name) {
84         return RuntimeDyld::SymbolInfo(nullptr);
85       },
86       [](const std::string &Name) {
87         return RuntimeDyld::SymbolInfo(nullptr);
88       });
89
90   {
91     // Test with ProcessAllSections = false (the default).
92     auto H = ObjLayer.addObjectSet(Objs, &SMMW, &*Resolver);
93     EXPECT_EQ(DebugSectionSeen, false)
94       << "Unexpected debug info section";
95     ObjLayer.removeObjectSet(H);
96   }
97
98   {
99     // Test with ProcessAllSections = true.
100     ObjLayer.setProcessAllSections(true);
101     auto H = ObjLayer.addObjectSet(Objs, &SMMW, &*Resolver);
102     EXPECT_EQ(DebugSectionSeen, true)
103       << "Expected debug info section not seen";
104     ObjLayer.removeObjectSet(H);
105   }
106 }
107
108
109 TEST_F(ObjectLinkingLayerExecutionTest, NoDuplicateFinalization) {
110
111   if (!TM)
112     return;
113
114   ObjectLinkingLayer<> ObjLayer;
115   SimpleCompiler Compile(*TM);
116
117   // Create a pair of modules that will trigger recursive finalization:
118   // Module 1:
119   //   int bar() { return 42; }
120   // Module 2:
121   //   int bar();
122   //   int foo() { return bar(); }
123
124   ModuleBuilder MB1(getGlobalContext(), "", "dummy");
125   {
126     MB1.getModule()->setDataLayout(TM->createDataLayout());
127     Function *BarImpl = MB1.createFunctionDecl<int32_t(void)>("bar");
128     BasicBlock *BarEntry = BasicBlock::Create(getGlobalContext(), "entry",
129                                               BarImpl);
130     IRBuilder<> Builder(BarEntry);
131     IntegerType *Int32Ty = IntegerType::get(getGlobalContext(), 32);
132     Value *FourtyTwo = ConstantInt::getSigned(Int32Ty, 42);
133     Builder.CreateRet(FourtyTwo);
134   }
135
136   auto Obj1 = Compile(*MB1.getModule());
137   std::vector<object::ObjectFile*> Obj1Set;
138   Obj1Set.push_back(Obj1.getBinary());
139
140   ModuleBuilder MB2(getGlobalContext(), "", "dummy");
141   {
142     MB2.getModule()->setDataLayout(TM->createDataLayout());
143     Function *BarDecl = MB2.createFunctionDecl<int32_t(void)>("bar");
144     Function *FooImpl = MB2.createFunctionDecl<int32_t(void)>("foo");
145     BasicBlock *FooEntry = BasicBlock::Create(getGlobalContext(), "entry",
146                                               FooImpl);
147     IRBuilder<> Builder(FooEntry);
148     Builder.CreateRet(Builder.CreateCall(BarDecl));
149   }
150   auto Obj2 = Compile(*MB2.getModule());
151   std::vector<object::ObjectFile*> Obj2Set;
152   Obj2Set.push_back(Obj2.getBinary());
153
154   auto Resolver =
155     createLambdaResolver(
156       [&](const std::string &Name) {
157         if (auto Sym = ObjLayer.findSymbol(Name, true))
158           return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags());
159         return RuntimeDyld::SymbolInfo(nullptr);
160       },
161       [](const std::string &Name) {
162         return RuntimeDyld::SymbolInfo(nullptr);
163       });
164
165   SectionMemoryManagerWrapper SMMW;
166   ObjLayer.addObjectSet(std::move(Obj1Set), &SMMW, &*Resolver);
167   auto H = ObjLayer.addObjectSet(std::move(Obj2Set), &SMMW, &*Resolver);
168   ObjLayer.emitAndFinalize(H);
169
170   // Finalization of module 2 should trigger finalization of module 1.
171   // Verify that finalize on SMMW is only called once.
172   EXPECT_EQ(SMMW.FinalizationCount, 1)
173       << "Extra call to finalize";
174 }
175
176 }