Make it explicit that ExecutionEngine takes ownership of the modules.
[oota-llvm.git] / unittests / ExecutionEngine / JIT / JITEventListenerTest.cpp
1 //===- JITEventListenerTest.cpp - Unit tests for JITEventListeners --------===//
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 "llvm/ExecutionEngine/JITEventListener.h"
11 #include "llvm/CodeGen/MachineCodeInfo.h"
12 #include "llvm/ExecutionEngine/JIT.h"
13 #include "llvm/IR/Instructions.h"
14 #include "llvm/IR/LLVMContext.h"
15 #include "llvm/IR/Module.h"
16 #include "llvm/IR/TypeBuilder.h"
17 #include "llvm/Support/TargetSelect.h"
18 #include "gtest/gtest.h"
19 #include <vector>
20
21 using namespace llvm;
22
23 namespace {
24
25 struct FunctionEmittedEvent {
26   // Indices are local to the RecordingJITEventListener, since the
27   // JITEventListener interface makes no guarantees about the order of
28   // calls between Listeners.
29   unsigned Index;
30   const Function *F;
31   void *Code;
32   size_t Size;
33   JITEvent_EmittedFunctionDetails Details;
34 };
35 struct FunctionFreedEvent {
36   unsigned Index;
37   void *Code;
38 };
39
40 struct RecordingJITEventListener : public JITEventListener {
41   std::vector<FunctionEmittedEvent> EmittedEvents;
42   std::vector<FunctionFreedEvent> FreedEvents;
43
44   unsigned NextIndex;
45
46   RecordingJITEventListener() : NextIndex(0) {}
47
48   virtual void NotifyFunctionEmitted(const Function &F,
49                                      void *Code, size_t Size,
50                                      const EmittedFunctionDetails &Details) {
51     FunctionEmittedEvent Event = {NextIndex++, &F, Code, Size, Details};
52     EmittedEvents.push_back(Event);
53   }
54
55   virtual void NotifyFreeingMachineCode(void *OldPtr) {
56     FunctionFreedEvent Event = {NextIndex++, OldPtr};
57     FreedEvents.push_back(Event);
58   }
59 };
60
61 class JITEventListenerTest : public testing::Test {
62  protected:
63    JITEventListenerTest() {
64      auto Owner = make_unique<Module>("module", getGlobalContext());
65      M = Owner.get();
66      EE.reset(EngineBuilder(std::move(Owner))
67                   .setEngineKind(EngineKind::JIT)
68                   .create());
69    }
70
71   Module *M;
72   std::unique_ptr<ExecutionEngine> EE;
73 };
74
75 // Tests on SystemZ disabled as we're running the old JIT
76 #if !defined(__s390__) && !defined(__aarch64__)
77 Function *buildFunction(Module *M) {
78   Function *Result = Function::Create(
79       TypeBuilder<int32_t(int32_t), false>::get(getGlobalContext()),
80       GlobalValue::ExternalLinkage, "id", M);
81   Value *Arg = Result->arg_begin();
82   BasicBlock *BB = BasicBlock::Create(M->getContext(), "entry", Result);
83   ReturnInst::Create(M->getContext(), Arg, BB);
84   return Result;
85 }
86
87 // Tests that a single JITEventListener follows JIT events accurately.
88 TEST_F(JITEventListenerTest, Simple) {
89   RecordingJITEventListener Listener;
90   EE->RegisterJITEventListener(&Listener);
91   Function *F1 = buildFunction(M);
92   Function *F2 = buildFunction(M);
93
94   void *F1_addr = EE->getPointerToFunction(F1);
95   void *F2_addr = EE->getPointerToFunction(F2);
96   EE->getPointerToFunction(F1);  // Should do nothing.
97   EE->freeMachineCodeForFunction(F1);
98   EE->freeMachineCodeForFunction(F2);
99
100   ASSERT_EQ(2U, Listener.EmittedEvents.size());
101   ASSERT_EQ(2U, Listener.FreedEvents.size());
102
103   EXPECT_EQ(0U, Listener.EmittedEvents[0].Index);
104   EXPECT_EQ(F1, Listener.EmittedEvents[0].F);
105   EXPECT_EQ(F1_addr, Listener.EmittedEvents[0].Code);
106   EXPECT_LT(0U, Listener.EmittedEvents[0].Size)
107       << "We don't know how big the function will be, but it had better"
108       << " contain some bytes.";
109
110   EXPECT_EQ(1U, Listener.EmittedEvents[1].Index);
111   EXPECT_EQ(F2, Listener.EmittedEvents[1].F);
112   EXPECT_EQ(F2_addr, Listener.EmittedEvents[1].Code);
113   EXPECT_LT(0U, Listener.EmittedEvents[1].Size)
114       << "We don't know how big the function will be, but it had better"
115       << " contain some bytes.";
116
117   EXPECT_EQ(2U, Listener.FreedEvents[0].Index);
118   EXPECT_EQ(F1_addr, Listener.FreedEvents[0].Code);
119
120   EXPECT_EQ(3U, Listener.FreedEvents[1].Index);
121   EXPECT_EQ(F2_addr, Listener.FreedEvents[1].Code);
122
123   F1->eraseFromParent();
124   F2->eraseFromParent();
125 }
126
127 // Tests that a single JITEventListener follows JIT events accurately.
128 TEST_F(JITEventListenerTest, MultipleListenersDontInterfere) {
129   RecordingJITEventListener Listener1;
130   RecordingJITEventListener Listener2;
131   RecordingJITEventListener Listener3;
132   Function *F1 = buildFunction(M);
133   Function *F2 = buildFunction(M);
134
135   EE->RegisterJITEventListener(&Listener1);
136   EE->RegisterJITEventListener(&Listener2);
137   void *F1_addr = EE->getPointerToFunction(F1);
138   EE->RegisterJITEventListener(&Listener3);
139   EE->UnregisterJITEventListener(&Listener1);
140   void *F2_addr = EE->getPointerToFunction(F2);
141   EE->UnregisterJITEventListener(&Listener2);
142   EE->UnregisterJITEventListener(&Listener3);
143   EE->freeMachineCodeForFunction(F1);
144   EE->RegisterJITEventListener(&Listener2);
145   EE->RegisterJITEventListener(&Listener3);
146   EE->RegisterJITEventListener(&Listener1);
147   EE->freeMachineCodeForFunction(F2);
148   EE->UnregisterJITEventListener(&Listener1);
149   EE->UnregisterJITEventListener(&Listener2);
150   EE->UnregisterJITEventListener(&Listener3);
151
152   // Listener 1.
153   ASSERT_EQ(1U, Listener1.EmittedEvents.size());
154   ASSERT_EQ(1U, Listener1.FreedEvents.size());
155
156   EXPECT_EQ(0U, Listener1.EmittedEvents[0].Index);
157   EXPECT_EQ(F1, Listener1.EmittedEvents[0].F);
158   EXPECT_EQ(F1_addr, Listener1.EmittedEvents[0].Code);
159   EXPECT_LT(0U, Listener1.EmittedEvents[0].Size)
160       << "We don't know how big the function will be, but it had better"
161       << " contain some bytes.";
162
163   EXPECT_EQ(1U, Listener1.FreedEvents[0].Index);
164   EXPECT_EQ(F2_addr, Listener1.FreedEvents[0].Code);
165
166   // Listener 2.
167   ASSERT_EQ(2U, Listener2.EmittedEvents.size());
168   ASSERT_EQ(1U, Listener2.FreedEvents.size());
169
170   EXPECT_EQ(0U, Listener2.EmittedEvents[0].Index);
171   EXPECT_EQ(F1, Listener2.EmittedEvents[0].F);
172   EXPECT_EQ(F1_addr, Listener2.EmittedEvents[0].Code);
173   EXPECT_LT(0U, Listener2.EmittedEvents[0].Size)
174       << "We don't know how big the function will be, but it had better"
175       << " contain some bytes.";
176
177   EXPECT_EQ(1U, Listener2.EmittedEvents[1].Index);
178   EXPECT_EQ(F2, Listener2.EmittedEvents[1].F);
179   EXPECT_EQ(F2_addr, Listener2.EmittedEvents[1].Code);
180   EXPECT_LT(0U, Listener2.EmittedEvents[1].Size)
181       << "We don't know how big the function will be, but it had better"
182       << " contain some bytes.";
183
184   EXPECT_EQ(2U, Listener2.FreedEvents[0].Index);
185   EXPECT_EQ(F2_addr, Listener2.FreedEvents[0].Code);
186
187   // Listener 3.
188   ASSERT_EQ(1U, Listener3.EmittedEvents.size());
189   ASSERT_EQ(1U, Listener3.FreedEvents.size());
190
191   EXPECT_EQ(0U, Listener3.EmittedEvents[0].Index);
192   EXPECT_EQ(F2, Listener3.EmittedEvents[0].F);
193   EXPECT_EQ(F2_addr, Listener3.EmittedEvents[0].Code);
194   EXPECT_LT(0U, Listener3.EmittedEvents[0].Size)
195       << "We don't know how big the function will be, but it had better"
196       << " contain some bytes.";
197
198   EXPECT_EQ(1U, Listener3.FreedEvents[0].Index);
199   EXPECT_EQ(F2_addr, Listener3.FreedEvents[0].Code);
200
201   F1->eraseFromParent();
202   F2->eraseFromParent();
203 }
204
205 TEST_F(JITEventListenerTest, MatchesMachineCodeInfo) {
206   RecordingJITEventListener Listener;
207   MachineCodeInfo MCI;
208   Function *F = buildFunction(M);
209
210   EE->RegisterJITEventListener(&Listener);
211   EE->runJITOnFunction(F, &MCI);
212   void *F_addr = EE->getPointerToFunction(F);
213   EE->freeMachineCodeForFunction(F);
214
215   ASSERT_EQ(1U, Listener.EmittedEvents.size());
216   ASSERT_EQ(1U, Listener.FreedEvents.size());
217
218   EXPECT_EQ(0U, Listener.EmittedEvents[0].Index);
219   EXPECT_EQ(F, Listener.EmittedEvents[0].F);
220   EXPECT_EQ(F_addr, Listener.EmittedEvents[0].Code);
221   EXPECT_EQ(MCI.address(), Listener.EmittedEvents[0].Code);
222   EXPECT_EQ(MCI.size(), Listener.EmittedEvents[0].Size);
223
224   EXPECT_EQ(1U, Listener.FreedEvents[0].Index);
225   EXPECT_EQ(F_addr, Listener.FreedEvents[0].Code);
226 }
227 #endif
228
229 class JITEnvironment : public testing::Environment {
230   virtual void SetUp() {
231     // Required to create a JIT.
232     InitializeNativeTarget();
233   }
234 };
235 testing::Environment* const jit_env =
236   testing::AddGlobalTestEnvironment(new JITEnvironment);
237
238 }  // anonymous namespace