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