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