Follow-up to r152620: restore JIT event listener tests to unittest/ExecutionEngine/JIT
authorEli Bendersky <eli.bendersky@intel.com>
Thu, 15 Mar 2012 06:49:31 +0000 (06:49 +0000)
committerEli Bendersky <eli.bendersky@intel.com>
Thu, 15 Mar 2012 06:49:31 +0000 (06:49 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@152780 91177308-0d34-0410-b5e6-96231b3b80d8

unittests/CMakeLists.txt
unittests/ExecutionEngine/IntelJITEventListenerTest.cpp [deleted file]
unittests/ExecutionEngine/JIT/IntelJITEventListenerTest.cpp [new file with mode: 0644]
unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp [new file with mode: 0644]
unittests/ExecutionEngine/JIT/JITEventListenerTestCommon.h [new file with mode: 0644]
unittests/ExecutionEngine/JIT/Makefile
unittests/ExecutionEngine/JIT/OProfileJITEventListenerTest.cpp [new file with mode: 0644]
unittests/ExecutionEngine/JITEventListenerTest.cpp [deleted file]
unittests/ExecutionEngine/JITEventListenerTestCommon.h [deleted file]
unittests/ExecutionEngine/Makefile
unittests/ExecutionEngine/OProfileJITEventListenerTest.cpp [deleted file]

index 648a1d86254bfdb50906853aee368ea8f8b03d43..60423f25c25a41b591997e0809191c44c5e14085 100644 (file)
@@ -83,11 +83,15 @@ add_llvm_unittest(Analysis
   Analysis/ScalarEvolutionTest.cpp
   )
 
+add_llvm_unittest(ExecutionEngine
+  ExecutionEngine/ExecutionEngineTest.cpp
+  )
+
 if( LLVM_USE_INTEL_JITEVENTS )
   include_directories( ${LLVM_INTEL_JITEVENTS_INCDIR} )
   link_directories( ${LLVM_INTEL_JITEVENTS_LIBDIR} )
   set(ProfileTestSources
-    ExecutionEngine/IntelJITEventListenerTest.cpp
+    ExecutionEngine/JIT/IntelJITEventListenerTest.cpp
     )
   set(LLVM_LINK_COMPONENTS
     ${LLVM_LINK_COMPONENTS}
@@ -98,7 +102,7 @@ endif( LLVM_USE_INTEL_JITEVENTS )
 if( LLVM_USE_OPROFILE )
   set(ProfileTestSources
     ${ProfileTestSources}
-    ExecutionEngine/OProfileJITEventListenerTest.cpp
+    ExecutionEngine/JIT/OProfileJITEventListenerTest.cpp
     )
   set(LLVM_LINK_COMPONENTS
     ${LLVM_LINK_COMPONENTS}
@@ -106,16 +110,12 @@ if( LLVM_USE_OPROFILE )
     )
 endif( LLVM_USE_OPROFILE )
 
-add_llvm_unittest(ExecutionEngine
-  ExecutionEngine/ExecutionEngineTest.cpp
-  ExecutionEngine/JITEventListenerTest.cpp
-  ${ProfileTestSources}
-  )
-
 set(JITTestsSources
+  ExecutionEngine/JIT/JITEventListenerTest.cpp
   ExecutionEngine/JIT/JITMemoryManagerTest.cpp
   ExecutionEngine/JIT/JITTest.cpp
   ExecutionEngine/JIT/MultiJITTest.cpp
+  ${ProfileTestSources}
   )
 
 if(MSVC)
diff --git a/unittests/ExecutionEngine/IntelJITEventListenerTest.cpp b/unittests/ExecutionEngine/IntelJITEventListenerTest.cpp
deleted file mode 100644 (file)
index 8ed7a15..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-//===- JITEventListenerTest.cpp - Tests for Intel JITEventListener --------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "JITEventListenerTestCommon.h"
-
-using namespace llvm;
-
-#include "llvm/ExecutionEngine/IntelJITEventsWrapper.h"
-
-#include <map>
-#include <list>
-
-namespace {
-
-// map of function ("method") IDs to source locations
-NativeCodeMap ReportedDebugFuncs;
-
-} // namespace
-
-/// Mock implementaion of Intel JIT API jitprofiling library
-namespace test_jitprofiling {
-
-int NotifyEvent(iJIT_JVM_EVENT EventType, void *EventSpecificData) {
-  switch (EventType) {
-    case iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED: {
-      EXPECT_TRUE(0 != EventSpecificData);
-      iJIT_Method_Load* msg = static_cast<iJIT_Method_Load*>(EventSpecificData);
-
-      ReportedDebugFuncs[msg->method_id];
-
-      for(unsigned int i = 0; i < msg->line_number_size; ++i) {
-        EXPECT_TRUE(0 != msg->line_number_table);
-        std::pair<std::string, unsigned int> loc(
-          std::string(msg->source_file_name),
-          msg->line_number_table[i].LineNumber);
-        ReportedDebugFuncs[msg->method_id].push_back(loc);
-      }
-    }
-    break;
-    case iJVM_EVENT_TYPE_METHOD_UNLOAD_START: {
-      EXPECT_TRUE(0 != EventSpecificData);
-      unsigned int UnloadId
-        = *reinterpret_cast<unsigned int*>(EventSpecificData);
-      EXPECT_TRUE(1 == ReportedDebugFuncs.erase(UnloadId));
-    }
-    default:
-      break;
-  }
-  return 0;
-}
-
-iJIT_IsProfilingActiveFlags IsProfilingActive(void) {
-  // for testing, pretend we have an Intel Parallel Amplifier XE 2011
-  // instance attached
-  return iJIT_SAMPLING_ON;
-}
-
-unsigned int GetNewMethodID(void) {
-  static unsigned int id = 0;
-  return ++id;
-}
-
-} //namespace test_jitprofiling
-
-class IntelJITEventListenerTest
-  : public JITEventListenerTestBase<IntelJITEventsWrapper> {
-public:
-  IntelJITEventListenerTest()
-  : JITEventListenerTestBase<IntelJITEventsWrapper>(
-      new IntelJITEventsWrapper(test_jitprofiling::NotifyEvent, 0,
-        test_jitprofiling::IsProfilingActive, 0, 0,
-        test_jitprofiling::GetNewMethodID))
-  {
-    EXPECT_TRUE(0 != MockWrapper);
-
-    Listener.reset(JITEventListener::createIntelJITEventListener(
-      MockWrapper.get()));
-    EXPECT_TRUE(0 != Listener);
-    EE->RegisterJITEventListener(Listener.get());
-  }
-};
-
-TEST_F(IntelJITEventListenerTest, NoDebugInfo) {
-  TestNoDebugInfo(ReportedDebugFuncs);
-}
-
-TEST_F(IntelJITEventListenerTest, SingleLine) {
-  TestSingleLine(ReportedDebugFuncs);
-}
-
-TEST_F(IntelJITEventListenerTest, MultipleLines) {
-  TestMultipleLines(ReportedDebugFuncs);
-}
-
-// This testcase is disabled because the Intel JIT API does not support a single
-// JITted function with source lines associated with multiple files
-/*
-TEST_F(IntelJITEventListenerTest, MultipleFiles) {
-  TestMultipleFiles(ReportedDebugFuncs);
-}
-*/
-
-testing::Environment* const jit_env =
-  testing::AddGlobalTestEnvironment(new JITEnvironment);
diff --git a/unittests/ExecutionEngine/JIT/IntelJITEventListenerTest.cpp b/unittests/ExecutionEngine/JIT/IntelJITEventListenerTest.cpp
new file mode 100644 (file)
index 0000000..8ed7a15
--- /dev/null
@@ -0,0 +1,110 @@
+//===- JITEventListenerTest.cpp - Tests for Intel JITEventListener --------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "JITEventListenerTestCommon.h"
+
+using namespace llvm;
+
+#include "llvm/ExecutionEngine/IntelJITEventsWrapper.h"
+
+#include <map>
+#include <list>
+
+namespace {
+
+// map of function ("method") IDs to source locations
+NativeCodeMap ReportedDebugFuncs;
+
+} // namespace
+
+/// Mock implementaion of Intel JIT API jitprofiling library
+namespace test_jitprofiling {
+
+int NotifyEvent(iJIT_JVM_EVENT EventType, void *EventSpecificData) {
+  switch (EventType) {
+    case iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED: {
+      EXPECT_TRUE(0 != EventSpecificData);
+      iJIT_Method_Load* msg = static_cast<iJIT_Method_Load*>(EventSpecificData);
+
+      ReportedDebugFuncs[msg->method_id];
+
+      for(unsigned int i = 0; i < msg->line_number_size; ++i) {
+        EXPECT_TRUE(0 != msg->line_number_table);
+        std::pair<std::string, unsigned int> loc(
+          std::string(msg->source_file_name),
+          msg->line_number_table[i].LineNumber);
+        ReportedDebugFuncs[msg->method_id].push_back(loc);
+      }
+    }
+    break;
+    case iJVM_EVENT_TYPE_METHOD_UNLOAD_START: {
+      EXPECT_TRUE(0 != EventSpecificData);
+      unsigned int UnloadId
+        = *reinterpret_cast<unsigned int*>(EventSpecificData);
+      EXPECT_TRUE(1 == ReportedDebugFuncs.erase(UnloadId));
+    }
+    default:
+      break;
+  }
+  return 0;
+}
+
+iJIT_IsProfilingActiveFlags IsProfilingActive(void) {
+  // for testing, pretend we have an Intel Parallel Amplifier XE 2011
+  // instance attached
+  return iJIT_SAMPLING_ON;
+}
+
+unsigned int GetNewMethodID(void) {
+  static unsigned int id = 0;
+  return ++id;
+}
+
+} //namespace test_jitprofiling
+
+class IntelJITEventListenerTest
+  : public JITEventListenerTestBase<IntelJITEventsWrapper> {
+public:
+  IntelJITEventListenerTest()
+  : JITEventListenerTestBase<IntelJITEventsWrapper>(
+      new IntelJITEventsWrapper(test_jitprofiling::NotifyEvent, 0,
+        test_jitprofiling::IsProfilingActive, 0, 0,
+        test_jitprofiling::GetNewMethodID))
+  {
+    EXPECT_TRUE(0 != MockWrapper);
+
+    Listener.reset(JITEventListener::createIntelJITEventListener(
+      MockWrapper.get()));
+    EXPECT_TRUE(0 != Listener);
+    EE->RegisterJITEventListener(Listener.get());
+  }
+};
+
+TEST_F(IntelJITEventListenerTest, NoDebugInfo) {
+  TestNoDebugInfo(ReportedDebugFuncs);
+}
+
+TEST_F(IntelJITEventListenerTest, SingleLine) {
+  TestSingleLine(ReportedDebugFuncs);
+}
+
+TEST_F(IntelJITEventListenerTest, MultipleLines) {
+  TestMultipleLines(ReportedDebugFuncs);
+}
+
+// This testcase is disabled because the Intel JIT API does not support a single
+// JITted function with source lines associated with multiple files
+/*
+TEST_F(IntelJITEventListenerTest, MultipleFiles) {
+  TestMultipleFiles(ReportedDebugFuncs);
+}
+*/
+
+testing::Environment* const jit_env =
+  testing::AddGlobalTestEnvironment(new JITEnvironment);
diff --git a/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp b/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp
new file mode 100644 (file)
index 0000000..f8d8830
--- /dev/null
@@ -0,0 +1,238 @@
+//===- JITEventListenerTest.cpp - Unit tests for JITEventListeners --------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ExecutionEngine/JITEventListener.h"
+
+#include "llvm/LLVMContext.h"
+#include "llvm/Instructions.h"
+#include "llvm/Module.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/CodeGen/MachineCodeInfo.h"
+#include "llvm/ExecutionEngine/JIT.h"
+#include "llvm/Support/TypeBuilder.h"
+#include "llvm/Support/TargetSelect.h"
+#include "gtest/gtest.h"
+#include <vector>
+
+using namespace llvm;
+
+int dummy;
+
+namespace {
+
+struct FunctionEmittedEvent {
+  // Indices are local to the RecordingJITEventListener, since the
+  // JITEventListener interface makes no guarantees about the order of
+  // calls between Listeners.
+  unsigned Index;
+  const Function *F;
+  void *Code;
+  size_t Size;
+  JITEvent_EmittedFunctionDetails Details;
+};
+struct FunctionFreedEvent {
+  unsigned Index;
+  void *Code;
+};
+
+struct RecordingJITEventListener : public JITEventListener {
+  std::vector<FunctionEmittedEvent> EmittedEvents;
+  std::vector<FunctionFreedEvent> FreedEvents;
+
+  unsigned NextIndex;
+
+  RecordingJITEventListener() : NextIndex(0) {}
+
+  virtual void NotifyFunctionEmitted(const Function &F,
+                                     void *Code, size_t Size,
+                                     const EmittedFunctionDetails &Details) {
+    FunctionEmittedEvent Event = {NextIndex++, &F, Code, Size, Details};
+    EmittedEvents.push_back(Event);
+  }
+
+  virtual void NotifyFreeingMachineCode(void *OldPtr) {
+    FunctionFreedEvent Event = {NextIndex++, OldPtr};
+    FreedEvents.push_back(Event);
+  }
+};
+
+class JITEventListenerTest : public testing::Test {
+ protected:
+  JITEventListenerTest()
+      : M(new Module("module", getGlobalContext())),
+        EE(EngineBuilder(M)
+           .setEngineKind(EngineKind::JIT)
+           .create()) {
+  }
+
+  Module *M;
+  const OwningPtr<ExecutionEngine> EE;
+};
+
+Function *buildFunction(Module *M) {
+  Function *Result = Function::Create(
+      TypeBuilder<int32_t(int32_t), false>::get(getGlobalContext()),
+      GlobalValue::ExternalLinkage, "id", M);
+  Value *Arg = Result->arg_begin();
+  BasicBlock *BB = BasicBlock::Create(M->getContext(), "entry", Result);
+  ReturnInst::Create(M->getContext(), Arg, BB);
+  return Result;
+}
+
+// Tests that a single JITEventListener follows JIT events accurately.
+TEST_F(JITEventListenerTest, Simple) {
+  RecordingJITEventListener Listener;
+  EE->RegisterJITEventListener(&Listener);
+  Function *F1 = buildFunction(M);
+  Function *F2 = buildFunction(M);
+
+  void *F1_addr = EE->getPointerToFunction(F1);
+  void *F2_addr = EE->getPointerToFunction(F2);
+  EE->getPointerToFunction(F1);  // Should do nothing.
+  EE->freeMachineCodeForFunction(F1);
+  EE->freeMachineCodeForFunction(F2);
+
+  ASSERT_EQ(2U, Listener.EmittedEvents.size());
+  ASSERT_EQ(2U, Listener.FreedEvents.size());
+
+  EXPECT_EQ(0U, Listener.EmittedEvents[0].Index);
+  EXPECT_EQ(F1, Listener.EmittedEvents[0].F);
+  EXPECT_EQ(F1_addr, Listener.EmittedEvents[0].Code);
+  EXPECT_LT(0U, Listener.EmittedEvents[0].Size)
+      << "We don't know how big the function will be, but it had better"
+      << " contain some bytes.";
+
+  EXPECT_EQ(1U, Listener.EmittedEvents[1].Index);
+  EXPECT_EQ(F2, Listener.EmittedEvents[1].F);
+  EXPECT_EQ(F2_addr, Listener.EmittedEvents[1].Code);
+  EXPECT_LT(0U, Listener.EmittedEvents[1].Size)
+      << "We don't know how big the function will be, but it had better"
+      << " contain some bytes.";
+
+  EXPECT_EQ(2U, Listener.FreedEvents[0].Index);
+  EXPECT_EQ(F1_addr, Listener.FreedEvents[0].Code);
+
+  EXPECT_EQ(3U, Listener.FreedEvents[1].Index);
+  EXPECT_EQ(F2_addr, Listener.FreedEvents[1].Code);
+
+  F1->eraseFromParent();
+  F2->eraseFromParent();
+}
+
+// Tests that a single JITEventListener follows JIT events accurately.
+TEST_F(JITEventListenerTest, MultipleListenersDontInterfere) {
+  RecordingJITEventListener Listener1;
+  RecordingJITEventListener Listener2;
+  RecordingJITEventListener Listener3;
+  Function *F1 = buildFunction(M);
+  Function *F2 = buildFunction(M);
+
+  EE->RegisterJITEventListener(&Listener1);
+  EE->RegisterJITEventListener(&Listener2);
+  void *F1_addr = EE->getPointerToFunction(F1);
+  EE->RegisterJITEventListener(&Listener3);
+  EE->UnregisterJITEventListener(&Listener1);
+  void *F2_addr = EE->getPointerToFunction(F2);
+  EE->UnregisterJITEventListener(&Listener2);
+  EE->UnregisterJITEventListener(&Listener3);
+  EE->freeMachineCodeForFunction(F1);
+  EE->RegisterJITEventListener(&Listener2);
+  EE->RegisterJITEventListener(&Listener3);
+  EE->RegisterJITEventListener(&Listener1);
+  EE->freeMachineCodeForFunction(F2);
+  EE->UnregisterJITEventListener(&Listener1);
+  EE->UnregisterJITEventListener(&Listener2);
+  EE->UnregisterJITEventListener(&Listener3);
+
+  // Listener 1.
+  ASSERT_EQ(1U, Listener1.EmittedEvents.size());
+  ASSERT_EQ(1U, Listener1.FreedEvents.size());
+
+  EXPECT_EQ(0U, Listener1.EmittedEvents[0].Index);
+  EXPECT_EQ(F1, Listener1.EmittedEvents[0].F);
+  EXPECT_EQ(F1_addr, Listener1.EmittedEvents[0].Code);
+  EXPECT_LT(0U, Listener1.EmittedEvents[0].Size)
+      << "We don't know how big the function will be, but it had better"
+      << " contain some bytes.";
+
+  EXPECT_EQ(1U, Listener1.FreedEvents[0].Index);
+  EXPECT_EQ(F2_addr, Listener1.FreedEvents[0].Code);
+
+  // Listener 2.
+  ASSERT_EQ(2U, Listener2.EmittedEvents.size());
+  ASSERT_EQ(1U, Listener2.FreedEvents.size());
+
+  EXPECT_EQ(0U, Listener2.EmittedEvents[0].Index);
+  EXPECT_EQ(F1, Listener2.EmittedEvents[0].F);
+  EXPECT_EQ(F1_addr, Listener2.EmittedEvents[0].Code);
+  EXPECT_LT(0U, Listener2.EmittedEvents[0].Size)
+      << "We don't know how big the function will be, but it had better"
+      << " contain some bytes.";
+
+  EXPECT_EQ(1U, Listener2.EmittedEvents[1].Index);
+  EXPECT_EQ(F2, Listener2.EmittedEvents[1].F);
+  EXPECT_EQ(F2_addr, Listener2.EmittedEvents[1].Code);
+  EXPECT_LT(0U, Listener2.EmittedEvents[1].Size)
+      << "We don't know how big the function will be, but it had better"
+      << " contain some bytes.";
+
+  EXPECT_EQ(2U, Listener2.FreedEvents[0].Index);
+  EXPECT_EQ(F2_addr, Listener2.FreedEvents[0].Code);
+
+  // Listener 3.
+  ASSERT_EQ(1U, Listener3.EmittedEvents.size());
+  ASSERT_EQ(1U, Listener3.FreedEvents.size());
+
+  EXPECT_EQ(0U, Listener3.EmittedEvents[0].Index);
+  EXPECT_EQ(F2, Listener3.EmittedEvents[0].F);
+  EXPECT_EQ(F2_addr, Listener3.EmittedEvents[0].Code);
+  EXPECT_LT(0U, Listener3.EmittedEvents[0].Size)
+      << "We don't know how big the function will be, but it had better"
+      << " contain some bytes.";
+
+  EXPECT_EQ(1U, Listener3.FreedEvents[0].Index);
+  EXPECT_EQ(F2_addr, Listener3.FreedEvents[0].Code);
+
+  F1->eraseFromParent();
+  F2->eraseFromParent();
+}
+
+TEST_F(JITEventListenerTest, MatchesMachineCodeInfo) {
+  RecordingJITEventListener Listener;
+  MachineCodeInfo MCI;
+  Function *F = buildFunction(M);
+
+  EE->RegisterJITEventListener(&Listener);
+  EE->runJITOnFunction(F, &MCI);
+  void *F_addr = EE->getPointerToFunction(F);
+  EE->freeMachineCodeForFunction(F);
+
+  ASSERT_EQ(1U, Listener.EmittedEvents.size());
+  ASSERT_EQ(1U, Listener.FreedEvents.size());
+
+  EXPECT_EQ(0U, Listener.EmittedEvents[0].Index);
+  EXPECT_EQ(F, Listener.EmittedEvents[0].F);
+  EXPECT_EQ(F_addr, Listener.EmittedEvents[0].Code);
+  EXPECT_EQ(MCI.address(), Listener.EmittedEvents[0].Code);
+  EXPECT_EQ(MCI.size(), Listener.EmittedEvents[0].Size);
+
+  EXPECT_EQ(1U, Listener.FreedEvents[0].Index);
+  EXPECT_EQ(F_addr, Listener.FreedEvents[0].Code);
+}
+
+class JITEnvironment : public testing::Environment {
+  virtual void SetUp() {
+    // Required to create a JIT.
+    InitializeNativeTarget();
+  }
+};
+testing::Environment* const jit_env =
+  testing::AddGlobalTestEnvironment(new JITEnvironment);
+
+}  // anonymous namespace
diff --git a/unittests/ExecutionEngine/JIT/JITEventListenerTestCommon.h b/unittests/ExecutionEngine/JIT/JITEventListenerTestCommon.h
new file mode 100644 (file)
index 0000000..53608cb
--- /dev/null
@@ -0,0 +1,209 @@
+//===- JITEventListenerTestCommon.h - Helper for JITEventListener tests ------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===-------------------------------------------------------------------------------===//
+
+#ifndef JIT_EVENT_LISTENER_TEST_COMMON_H
+#define JIT_EVENT_LISTENER_TEST_COMMON_H
+
+#include "llvm/Analysis/DIBuilder.h"
+#include "llvm/Analysis/DebugInfo.h"
+#include "llvm/CodeGen/MachineCodeInfo.h"
+#include "llvm/Config/config.h"
+#include "llvm/ExecutionEngine/JIT.h"
+#include "llvm/ExecutionEngine/JITEventListener.h"
+#include "llvm/Instructions.h"
+#include "llvm/Module.h"
+#include "llvm/Support/IRBuilder.h"
+#include "llvm/Support/Dwarf.h"
+#include "llvm/Support/TypeBuilder.h"
+#include "llvm/Support/TargetSelect.h"
+
+#include "gtest/gtest.h"
+
+#include <vector>
+#include <string>
+#include <utility>
+
+typedef std::vector<std::pair<std::string, unsigned int> > SourceLocations;
+typedef std::map<uint64_t, SourceLocations> NativeCodeMap;
+
+class JITEnvironment : public testing::Environment {
+  virtual void SetUp() {
+    // Required to create a JIT.
+    llvm::InitializeNativeTarget();
+  }
+};
+
+inline unsigned int getLine() {
+  return 12;
+}
+
+inline unsigned int getCol() {
+  return 0;
+}
+
+inline const char* getFilename() {
+  return "mock_source_file.cpp";
+}
+
+// Test fixture shared by tests for listener implementations
+template<typename WrapperT>
+class JITEventListenerTestBase : public testing::Test {
+protected:
+  llvm::OwningPtr<WrapperT> MockWrapper;
+  llvm::OwningPtr<llvm::JITEventListener> Listener;
+
+public:
+  llvm::Module* M;
+  llvm::MDNode* Scope;
+  llvm::ExecutionEngine* EE;
+  llvm::DIBuilder* DebugBuilder;
+  llvm::IRBuilder<> Builder;
+
+  JITEventListenerTestBase(WrapperT* w)
+  : MockWrapper(w)
+  , M(new llvm::Module("module", llvm::getGlobalContext()))
+  , EE(llvm::EngineBuilder(M)
+    .setEngineKind(llvm::EngineKind::JIT)
+    .setOptLevel(llvm::CodeGenOpt::None)
+    .create())
+  , DebugBuilder(new llvm::DIBuilder(*M))
+  , Builder(llvm::getGlobalContext())
+  {
+    DebugBuilder->createCompileUnit(llvm::dwarf::DW_LANG_C_plus_plus,
+                                    "JIT",
+                                    "JIT",
+                                    "JIT",
+                                    true,
+                                    "",
+                                    1);
+
+    Scope = DebugBuilder->createFile(getFilename(), ".");
+  }
+
+  llvm::Function *buildFunction(const SourceLocations& DebugLocations) {
+    using namespace llvm;
+
+    LLVMContext& GlobalContext = getGlobalContext();
+
+    SourceLocations::const_iterator CurrentDebugLocation
+      = DebugLocations.begin();
+
+    if (CurrentDebugLocation != DebugLocations.end()) {
+      DebugLoc DebugLocation = DebugLoc::get(getLine(), getCol(),
+          DebugBuilder->createFile(CurrentDebugLocation->first, "."));
+      Builder.SetCurrentDebugLocation(DebugLocation);
+      CurrentDebugLocation++;
+    }
+
+    Function *Result = Function::Create(
+        TypeBuilder<int32_t(int32_t), false>::get(GlobalContext),
+        GlobalValue::ExternalLinkage, "id", M);
+    Value *Arg = Result->arg_begin();
+    BasicBlock *BB = BasicBlock::Create(M->getContext(), "entry", Result);
+    Builder.SetInsertPoint(BB);
+    Value* one = ConstantInt::get(GlobalContext, APInt(32, 1));
+    for(; CurrentDebugLocation != DebugLocations.end();
+        ++CurrentDebugLocation) {
+      Arg = Builder.CreateMul(Arg, Builder.CreateAdd(Arg, one));
+      Builder.SetCurrentDebugLocation(
+        DebugLoc::get(CurrentDebugLocation->second, 0,
+                      DebugBuilder->createFile(CurrentDebugLocation->first, ".")));
+    }
+    Builder.CreateRet(Arg);
+    return Result;
+  }
+
+  void TestNoDebugInfo(NativeCodeMap& ReportedDebugFuncs) {
+    SourceLocations DebugLocations;
+    llvm::Function* f = buildFunction(DebugLocations);
+    EXPECT_TRUE(0 != f);
+
+    //Cause JITting and callbacks to our listener
+    EXPECT_TRUE(0 != EE->getPointerToFunction(f));
+    EXPECT_TRUE(1 == ReportedDebugFuncs.size());
+
+    EE->freeMachineCodeForFunction(f);
+    EXPECT_TRUE(ReportedDebugFuncs.size() == 0);
+  }
+
+  void TestSingleLine(NativeCodeMap& ReportedDebugFuncs) {
+    SourceLocations DebugLocations;
+    DebugLocations.push_back(std::make_pair(std::string(getFilename()),
+                                            getLine()));
+    llvm::Function* f = buildFunction(DebugLocations);
+    EXPECT_TRUE(0 != f);
+
+    EXPECT_TRUE(0 != EE->getPointerToFunction(f));
+    EXPECT_TRUE(1 == ReportedDebugFuncs.size());
+    EXPECT_STREQ(ReportedDebugFuncs.begin()->second.begin()->first.c_str(),
+                 getFilename());
+    EXPECT_EQ(ReportedDebugFuncs.begin()->second.begin()->second, getLine());
+
+    EE->freeMachineCodeForFunction(f);
+    EXPECT_TRUE(ReportedDebugFuncs.size() == 0);
+  }
+
+  void TestMultipleLines(NativeCodeMap& ReportedDebugFuncs) {
+    using namespace std;
+
+    SourceLocations DebugLocations;
+    unsigned int c = 5;
+    for(unsigned int i = 0; i < c; ++i) {
+      DebugLocations.push_back(make_pair(string(getFilename()), getLine() + i));
+    }
+
+    llvm::Function* f = buildFunction(DebugLocations);
+    EXPECT_TRUE(0 != f);
+
+    EXPECT_TRUE(0 != EE->getPointerToFunction(f));
+    EXPECT_TRUE(1 == ReportedDebugFuncs.size());
+    SourceLocations& FunctionInfo = ReportedDebugFuncs.begin()->second;
+    EXPECT_EQ(c, FunctionInfo.size());
+
+    int VerifyCount = 0;
+    for(SourceLocations::iterator i = FunctionInfo.begin();
+        i != FunctionInfo.end();
+        ++i) {
+      EXPECT_STREQ(i->first.c_str(), getFilename());
+      EXPECT_EQ(i->second, getLine() + VerifyCount);
+      VerifyCount++;
+    }
+
+    EE->freeMachineCodeForFunction(f);
+    EXPECT_TRUE(ReportedDebugFuncs.size() == 0);
+  }
+
+  void TestMultipleFiles(NativeCodeMap& ReportedDebugFuncs) {
+
+    std::string secondFilename("another_file.cpp");
+
+    SourceLocations DebugLocations;
+    DebugLocations.push_back(std::make_pair(std::string(getFilename()),
+                                            getLine()));
+    DebugLocations.push_back(std::make_pair(secondFilename, getLine()));
+    llvm::Function* f = buildFunction(DebugLocations);
+    EXPECT_TRUE(0 != f);
+
+    EXPECT_TRUE(0 != EE->getPointerToFunction(f));
+    EXPECT_TRUE(1 == ReportedDebugFuncs.size());
+    SourceLocations& FunctionInfo = ReportedDebugFuncs.begin()->second;
+    EXPECT_TRUE(2 == FunctionInfo.size());
+
+    EXPECT_STREQ(FunctionInfo.at(0).first.c_str(), getFilename());
+    EXPECT_STREQ(FunctionInfo.at(1).first.c_str(), secondFilename.c_str());
+
+    EXPECT_EQ(FunctionInfo.at(0).second, getLine());
+    EXPECT_EQ(FunctionInfo.at(1).second, getLine());
+
+    EE->freeMachineCodeForFunction(f);
+    EXPECT_TRUE(ReportedDebugFuncs.size() == 0);
+  }
+};
+
+#endif //JIT_EVENT_LISTENER_TEST_COMMON_H
index f5abe75a8f6839bcdaf67093ec7b06666feb3571..b429033b19bb9e97e337a5c3de09970666ca5847 100644 (file)
@@ -12,6 +12,29 @@ TESTNAME = JIT
 LINK_COMPONENTS := asmparser bitreader bitwriter core jit native support
 
 include $(LEVEL)/Makefile.config
+
+SOURCES := JITEventListenerTest.cpp
+
+ifeq ($(USE_INTEL_JITEVENTS), 1)
+  # Build the Intel JIT Events interface tests
+  SOURCES += IntelJITEventListenerTest.cpp
+
+  # Add the Intel JIT Events include directory
+  CPPFLAGS += -I$(INTEL_JITEVENTS_INCDIR)
+
+  # Link against the LLVM Intel JIT Evens interface library
+  LINK_COMPONENTS += inteljitevents
+endif
+
+ifeq ($(USE_OPROFILE), 1)
+  # Build the OProfile JIT interface tests
+  SOURCES += OProfileJITEventListenerTest.cpp
+
+  # Link against the LLVM oprofile interface library
+  LINK_COMPONENTS += oprofilejit
+endif
+
+
 include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
 
 # Permit these tests to use the JIT's symbolic lookup.
diff --git a/unittests/ExecutionEngine/JIT/OProfileJITEventListenerTest.cpp b/unittests/ExecutionEngine/JIT/OProfileJITEventListenerTest.cpp
new file mode 100644 (file)
index 0000000..9b0ee60
--- /dev/null
@@ -0,0 +1,166 @@
+//===- OProfileJITEventListenerTest.cpp - Unit tests for OProfileJITEventsListener --------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--------------------------------------------------------------------------------------===//
+
+#include "llvm/ExecutionEngine/JITEventListener.h"
+#include "llvm/ExecutionEngine/OProfileWrapper.h"
+#include "JITEventListenerTestCommon.h"
+
+#include <map>
+#include <list>
+
+using namespace llvm;
+
+namespace {
+
+struct OprofileNativeFunction {
+  const char* Name;
+  uint64_t Addr;
+  const void* CodePtr;
+  unsigned int CodeSize;
+
+  OprofileNativeFunction(const char* name,
+                         uint64_t addr,
+                         const void* code,
+                         unsigned int size)
+  : Name(name)
+  , Addr(addr)
+  , CodePtr(code)
+  , CodeSize(size) {
+  }
+};
+
+typedef std::list<OprofileNativeFunction> NativeFunctionList;
+typedef std::list<debug_line_info> NativeDebugList;
+NativeFunctionList NativeFunctions;
+
+NativeCodeMap ReportedDebugFuncs;
+
+} // namespace
+
+/// Mock implementaion of opagent library
+namespace test_opagent {
+
+op_agent_t globalAgent = reinterpret_cast<op_agent_t>(42);
+
+op_agent_t open_agent()
+{
+  // return non-null op_agent_t
+  return globalAgent;
+}
+
+int close_agent(op_agent_t agent)
+{
+  EXPECT_EQ(globalAgent, agent);
+  return 0;
+}
+
+int write_native_code(op_agent_t agent,
+                      const char* name,
+                      uint64_t addr,
+                      void const* code,
+                      unsigned int size)
+{
+  EXPECT_EQ(globalAgent, agent);
+  OprofileNativeFunction func(name, addr, code, size);
+  NativeFunctions.push_back(func);
+
+  // Verify no other registration has take place for the same address
+  EXPECT_TRUE(ReportedDebugFuncs.find(addr) == ReportedDebugFuncs.end());
+
+  ReportedDebugFuncs[addr];
+  return 0;
+}
+
+int write_debug_line_info(op_agent_t agent,
+                          void const* code,
+                          size_t num_entries,
+                          struct debug_line_info const* info)
+{
+  EXPECT_EQ(globalAgent, agent);
+
+  //verify code has been loaded first
+  uint64_t addr = reinterpret_cast<uint64_t>(code);
+  NativeCodeMap::iterator i = ReportedDebugFuncs.find(addr);
+  EXPECT_TRUE(i != ReportedDebugFuncs.end());
+
+  NativeDebugList NativeInfo(info, info + num_entries);
+
+  SourceLocations locs;
+  for(NativeDebugList::iterator i = NativeInfo.begin();
+      i != NativeInfo.end();
+      ++i) {
+    locs.push_back(std::make_pair(std::string(i->filename), i->lineno));
+  }
+  ReportedDebugFuncs[addr] = locs;
+
+  return 0;
+}
+
+int unload_native_code(op_agent_t agent, uint64_t addr) {
+  EXPECT_EQ(globalAgent, agent);
+
+  //verify that something for the given JIT addr has been loaded first
+  NativeCodeMap::iterator i = ReportedDebugFuncs.find(addr);
+  EXPECT_TRUE(i != ReportedDebugFuncs.end());
+  ReportedDebugFuncs.erase(i);
+  return 0;
+}
+
+int version() {
+  return 1;
+}
+
+bool is_oprofile_running() {
+  return true;
+}
+
+} //namespace test_opagent
+
+class OProfileJITEventListenerTest
+: public JITEventListenerTestBase<OProfileWrapper>
+{
+public:
+  OProfileJITEventListenerTest()
+  : JITEventListenerTestBase<OProfileWrapper>(
+    new OProfileWrapper(test_opagent::open_agent,
+      test_opagent::close_agent,
+      test_opagent::write_native_code,
+      test_opagent::write_debug_line_info,
+      test_opagent::unload_native_code,
+      test_opagent::version,
+      test_opagent::version,
+      test_opagent::is_oprofile_running))
+  {
+    EXPECT_TRUE(0 != MockWrapper);
+
+    Listener.reset(JITEventListener::createOProfileJITEventListener(
+      MockWrapper.get()));
+    EXPECT_TRUE(0 != Listener);
+    EE->RegisterJITEventListener(Listener.get());
+  }
+};
+
+TEST_F(OProfileJITEventListenerTest, NoDebugInfo) {
+  TestNoDebugInfo(ReportedDebugFuncs);
+}
+
+TEST_F(OProfileJITEventListenerTest, SingleLine) {
+  TestSingleLine(ReportedDebugFuncs);
+}
+
+TEST_F(OProfileJITEventListenerTest, MultipleLines) {
+  TestMultipleLines(ReportedDebugFuncs);
+}
+
+TEST_F(OProfileJITEventListenerTest, MultipleFiles) {
+  TestMultipleFiles(ReportedDebugFuncs);
+}
+
+testing::Environment* const jit_env =
+  testing::AddGlobalTestEnvironment(new JITEnvironment);
diff --git a/unittests/ExecutionEngine/JITEventListenerTest.cpp b/unittests/ExecutionEngine/JITEventListenerTest.cpp
deleted file mode 100644 (file)
index f8d8830..0000000
+++ /dev/null
@@ -1,238 +0,0 @@
-//===- JITEventListenerTest.cpp - Unit tests for JITEventListeners --------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/ExecutionEngine/JITEventListener.h"
-
-#include "llvm/LLVMContext.h"
-#include "llvm/Instructions.h"
-#include "llvm/Module.h"
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/CodeGen/MachineCodeInfo.h"
-#include "llvm/ExecutionEngine/JIT.h"
-#include "llvm/Support/TypeBuilder.h"
-#include "llvm/Support/TargetSelect.h"
-#include "gtest/gtest.h"
-#include <vector>
-
-using namespace llvm;
-
-int dummy;
-
-namespace {
-
-struct FunctionEmittedEvent {
-  // Indices are local to the RecordingJITEventListener, since the
-  // JITEventListener interface makes no guarantees about the order of
-  // calls between Listeners.
-  unsigned Index;
-  const Function *F;
-  void *Code;
-  size_t Size;
-  JITEvent_EmittedFunctionDetails Details;
-};
-struct FunctionFreedEvent {
-  unsigned Index;
-  void *Code;
-};
-
-struct RecordingJITEventListener : public JITEventListener {
-  std::vector<FunctionEmittedEvent> EmittedEvents;
-  std::vector<FunctionFreedEvent> FreedEvents;
-
-  unsigned NextIndex;
-
-  RecordingJITEventListener() : NextIndex(0) {}
-
-  virtual void NotifyFunctionEmitted(const Function &F,
-                                     void *Code, size_t Size,
-                                     const EmittedFunctionDetails &Details) {
-    FunctionEmittedEvent Event = {NextIndex++, &F, Code, Size, Details};
-    EmittedEvents.push_back(Event);
-  }
-
-  virtual void NotifyFreeingMachineCode(void *OldPtr) {
-    FunctionFreedEvent Event = {NextIndex++, OldPtr};
-    FreedEvents.push_back(Event);
-  }
-};
-
-class JITEventListenerTest : public testing::Test {
- protected:
-  JITEventListenerTest()
-      : M(new Module("module", getGlobalContext())),
-        EE(EngineBuilder(M)
-           .setEngineKind(EngineKind::JIT)
-           .create()) {
-  }
-
-  Module *M;
-  const OwningPtr<ExecutionEngine> EE;
-};
-
-Function *buildFunction(Module *M) {
-  Function *Result = Function::Create(
-      TypeBuilder<int32_t(int32_t), false>::get(getGlobalContext()),
-      GlobalValue::ExternalLinkage, "id", M);
-  Value *Arg = Result->arg_begin();
-  BasicBlock *BB = BasicBlock::Create(M->getContext(), "entry", Result);
-  ReturnInst::Create(M->getContext(), Arg, BB);
-  return Result;
-}
-
-// Tests that a single JITEventListener follows JIT events accurately.
-TEST_F(JITEventListenerTest, Simple) {
-  RecordingJITEventListener Listener;
-  EE->RegisterJITEventListener(&Listener);
-  Function *F1 = buildFunction(M);
-  Function *F2 = buildFunction(M);
-
-  void *F1_addr = EE->getPointerToFunction(F1);
-  void *F2_addr = EE->getPointerToFunction(F2);
-  EE->getPointerToFunction(F1);  // Should do nothing.
-  EE->freeMachineCodeForFunction(F1);
-  EE->freeMachineCodeForFunction(F2);
-
-  ASSERT_EQ(2U, Listener.EmittedEvents.size());
-  ASSERT_EQ(2U, Listener.FreedEvents.size());
-
-  EXPECT_EQ(0U, Listener.EmittedEvents[0].Index);
-  EXPECT_EQ(F1, Listener.EmittedEvents[0].F);
-  EXPECT_EQ(F1_addr, Listener.EmittedEvents[0].Code);
-  EXPECT_LT(0U, Listener.EmittedEvents[0].Size)
-      << "We don't know how big the function will be, but it had better"
-      << " contain some bytes.";
-
-  EXPECT_EQ(1U, Listener.EmittedEvents[1].Index);
-  EXPECT_EQ(F2, Listener.EmittedEvents[1].F);
-  EXPECT_EQ(F2_addr, Listener.EmittedEvents[1].Code);
-  EXPECT_LT(0U, Listener.EmittedEvents[1].Size)
-      << "We don't know how big the function will be, but it had better"
-      << " contain some bytes.";
-
-  EXPECT_EQ(2U, Listener.FreedEvents[0].Index);
-  EXPECT_EQ(F1_addr, Listener.FreedEvents[0].Code);
-
-  EXPECT_EQ(3U, Listener.FreedEvents[1].Index);
-  EXPECT_EQ(F2_addr, Listener.FreedEvents[1].Code);
-
-  F1->eraseFromParent();
-  F2->eraseFromParent();
-}
-
-// Tests that a single JITEventListener follows JIT events accurately.
-TEST_F(JITEventListenerTest, MultipleListenersDontInterfere) {
-  RecordingJITEventListener Listener1;
-  RecordingJITEventListener Listener2;
-  RecordingJITEventListener Listener3;
-  Function *F1 = buildFunction(M);
-  Function *F2 = buildFunction(M);
-
-  EE->RegisterJITEventListener(&Listener1);
-  EE->RegisterJITEventListener(&Listener2);
-  void *F1_addr = EE->getPointerToFunction(F1);
-  EE->RegisterJITEventListener(&Listener3);
-  EE->UnregisterJITEventListener(&Listener1);
-  void *F2_addr = EE->getPointerToFunction(F2);
-  EE->UnregisterJITEventListener(&Listener2);
-  EE->UnregisterJITEventListener(&Listener3);
-  EE->freeMachineCodeForFunction(F1);
-  EE->RegisterJITEventListener(&Listener2);
-  EE->RegisterJITEventListener(&Listener3);
-  EE->RegisterJITEventListener(&Listener1);
-  EE->freeMachineCodeForFunction(F2);
-  EE->UnregisterJITEventListener(&Listener1);
-  EE->UnregisterJITEventListener(&Listener2);
-  EE->UnregisterJITEventListener(&Listener3);
-
-  // Listener 1.
-  ASSERT_EQ(1U, Listener1.EmittedEvents.size());
-  ASSERT_EQ(1U, Listener1.FreedEvents.size());
-
-  EXPECT_EQ(0U, Listener1.EmittedEvents[0].Index);
-  EXPECT_EQ(F1, Listener1.EmittedEvents[0].F);
-  EXPECT_EQ(F1_addr, Listener1.EmittedEvents[0].Code);
-  EXPECT_LT(0U, Listener1.EmittedEvents[0].Size)
-      << "We don't know how big the function will be, but it had better"
-      << " contain some bytes.";
-
-  EXPECT_EQ(1U, Listener1.FreedEvents[0].Index);
-  EXPECT_EQ(F2_addr, Listener1.FreedEvents[0].Code);
-
-  // Listener 2.
-  ASSERT_EQ(2U, Listener2.EmittedEvents.size());
-  ASSERT_EQ(1U, Listener2.FreedEvents.size());
-
-  EXPECT_EQ(0U, Listener2.EmittedEvents[0].Index);
-  EXPECT_EQ(F1, Listener2.EmittedEvents[0].F);
-  EXPECT_EQ(F1_addr, Listener2.EmittedEvents[0].Code);
-  EXPECT_LT(0U, Listener2.EmittedEvents[0].Size)
-      << "We don't know how big the function will be, but it had better"
-      << " contain some bytes.";
-
-  EXPECT_EQ(1U, Listener2.EmittedEvents[1].Index);
-  EXPECT_EQ(F2, Listener2.EmittedEvents[1].F);
-  EXPECT_EQ(F2_addr, Listener2.EmittedEvents[1].Code);
-  EXPECT_LT(0U, Listener2.EmittedEvents[1].Size)
-      << "We don't know how big the function will be, but it had better"
-      << " contain some bytes.";
-
-  EXPECT_EQ(2U, Listener2.FreedEvents[0].Index);
-  EXPECT_EQ(F2_addr, Listener2.FreedEvents[0].Code);
-
-  // Listener 3.
-  ASSERT_EQ(1U, Listener3.EmittedEvents.size());
-  ASSERT_EQ(1U, Listener3.FreedEvents.size());
-
-  EXPECT_EQ(0U, Listener3.EmittedEvents[0].Index);
-  EXPECT_EQ(F2, Listener3.EmittedEvents[0].F);
-  EXPECT_EQ(F2_addr, Listener3.EmittedEvents[0].Code);
-  EXPECT_LT(0U, Listener3.EmittedEvents[0].Size)
-      << "We don't know how big the function will be, but it had better"
-      << " contain some bytes.";
-
-  EXPECT_EQ(1U, Listener3.FreedEvents[0].Index);
-  EXPECT_EQ(F2_addr, Listener3.FreedEvents[0].Code);
-
-  F1->eraseFromParent();
-  F2->eraseFromParent();
-}
-
-TEST_F(JITEventListenerTest, MatchesMachineCodeInfo) {
-  RecordingJITEventListener Listener;
-  MachineCodeInfo MCI;
-  Function *F = buildFunction(M);
-
-  EE->RegisterJITEventListener(&Listener);
-  EE->runJITOnFunction(F, &MCI);
-  void *F_addr = EE->getPointerToFunction(F);
-  EE->freeMachineCodeForFunction(F);
-
-  ASSERT_EQ(1U, Listener.EmittedEvents.size());
-  ASSERT_EQ(1U, Listener.FreedEvents.size());
-
-  EXPECT_EQ(0U, Listener.EmittedEvents[0].Index);
-  EXPECT_EQ(F, Listener.EmittedEvents[0].F);
-  EXPECT_EQ(F_addr, Listener.EmittedEvents[0].Code);
-  EXPECT_EQ(MCI.address(), Listener.EmittedEvents[0].Code);
-  EXPECT_EQ(MCI.size(), Listener.EmittedEvents[0].Size);
-
-  EXPECT_EQ(1U, Listener.FreedEvents[0].Index);
-  EXPECT_EQ(F_addr, Listener.FreedEvents[0].Code);
-}
-
-class JITEnvironment : public testing::Environment {
-  virtual void SetUp() {
-    // Required to create a JIT.
-    InitializeNativeTarget();
-  }
-};
-testing::Environment* const jit_env =
-  testing::AddGlobalTestEnvironment(new JITEnvironment);
-
-}  // anonymous namespace
diff --git a/unittests/ExecutionEngine/JITEventListenerTestCommon.h b/unittests/ExecutionEngine/JITEventListenerTestCommon.h
deleted file mode 100644 (file)
index 53608cb..0000000
+++ /dev/null
@@ -1,209 +0,0 @@
-//===- JITEventListenerTestCommon.h - Helper for JITEventListener tests ------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===-------------------------------------------------------------------------------===//
-
-#ifndef JIT_EVENT_LISTENER_TEST_COMMON_H
-#define JIT_EVENT_LISTENER_TEST_COMMON_H
-
-#include "llvm/Analysis/DIBuilder.h"
-#include "llvm/Analysis/DebugInfo.h"
-#include "llvm/CodeGen/MachineCodeInfo.h"
-#include "llvm/Config/config.h"
-#include "llvm/ExecutionEngine/JIT.h"
-#include "llvm/ExecutionEngine/JITEventListener.h"
-#include "llvm/Instructions.h"
-#include "llvm/Module.h"
-#include "llvm/Support/IRBuilder.h"
-#include "llvm/Support/Dwarf.h"
-#include "llvm/Support/TypeBuilder.h"
-#include "llvm/Support/TargetSelect.h"
-
-#include "gtest/gtest.h"
-
-#include <vector>
-#include <string>
-#include <utility>
-
-typedef std::vector<std::pair<std::string, unsigned int> > SourceLocations;
-typedef std::map<uint64_t, SourceLocations> NativeCodeMap;
-
-class JITEnvironment : public testing::Environment {
-  virtual void SetUp() {
-    // Required to create a JIT.
-    llvm::InitializeNativeTarget();
-  }
-};
-
-inline unsigned int getLine() {
-  return 12;
-}
-
-inline unsigned int getCol() {
-  return 0;
-}
-
-inline const char* getFilename() {
-  return "mock_source_file.cpp";
-}
-
-// Test fixture shared by tests for listener implementations
-template<typename WrapperT>
-class JITEventListenerTestBase : public testing::Test {
-protected:
-  llvm::OwningPtr<WrapperT> MockWrapper;
-  llvm::OwningPtr<llvm::JITEventListener> Listener;
-
-public:
-  llvm::Module* M;
-  llvm::MDNode* Scope;
-  llvm::ExecutionEngine* EE;
-  llvm::DIBuilder* DebugBuilder;
-  llvm::IRBuilder<> Builder;
-
-  JITEventListenerTestBase(WrapperT* w)
-  : MockWrapper(w)
-  , M(new llvm::Module("module", llvm::getGlobalContext()))
-  , EE(llvm::EngineBuilder(M)
-    .setEngineKind(llvm::EngineKind::JIT)
-    .setOptLevel(llvm::CodeGenOpt::None)
-    .create())
-  , DebugBuilder(new llvm::DIBuilder(*M))
-  , Builder(llvm::getGlobalContext())
-  {
-    DebugBuilder->createCompileUnit(llvm::dwarf::DW_LANG_C_plus_plus,
-                                    "JIT",
-                                    "JIT",
-                                    "JIT",
-                                    true,
-                                    "",
-                                    1);
-
-    Scope = DebugBuilder->createFile(getFilename(), ".");
-  }
-
-  llvm::Function *buildFunction(const SourceLocations& DebugLocations) {
-    using namespace llvm;
-
-    LLVMContext& GlobalContext = getGlobalContext();
-
-    SourceLocations::const_iterator CurrentDebugLocation
-      = DebugLocations.begin();
-
-    if (CurrentDebugLocation != DebugLocations.end()) {
-      DebugLoc DebugLocation = DebugLoc::get(getLine(), getCol(),
-          DebugBuilder->createFile(CurrentDebugLocation->first, "."));
-      Builder.SetCurrentDebugLocation(DebugLocation);
-      CurrentDebugLocation++;
-    }
-
-    Function *Result = Function::Create(
-        TypeBuilder<int32_t(int32_t), false>::get(GlobalContext),
-        GlobalValue::ExternalLinkage, "id", M);
-    Value *Arg = Result->arg_begin();
-    BasicBlock *BB = BasicBlock::Create(M->getContext(), "entry", Result);
-    Builder.SetInsertPoint(BB);
-    Value* one = ConstantInt::get(GlobalContext, APInt(32, 1));
-    for(; CurrentDebugLocation != DebugLocations.end();
-        ++CurrentDebugLocation) {
-      Arg = Builder.CreateMul(Arg, Builder.CreateAdd(Arg, one));
-      Builder.SetCurrentDebugLocation(
-        DebugLoc::get(CurrentDebugLocation->second, 0,
-                      DebugBuilder->createFile(CurrentDebugLocation->first, ".")));
-    }
-    Builder.CreateRet(Arg);
-    return Result;
-  }
-
-  void TestNoDebugInfo(NativeCodeMap& ReportedDebugFuncs) {
-    SourceLocations DebugLocations;
-    llvm::Function* f = buildFunction(DebugLocations);
-    EXPECT_TRUE(0 != f);
-
-    //Cause JITting and callbacks to our listener
-    EXPECT_TRUE(0 != EE->getPointerToFunction(f));
-    EXPECT_TRUE(1 == ReportedDebugFuncs.size());
-
-    EE->freeMachineCodeForFunction(f);
-    EXPECT_TRUE(ReportedDebugFuncs.size() == 0);
-  }
-
-  void TestSingleLine(NativeCodeMap& ReportedDebugFuncs) {
-    SourceLocations DebugLocations;
-    DebugLocations.push_back(std::make_pair(std::string(getFilename()),
-                                            getLine()));
-    llvm::Function* f = buildFunction(DebugLocations);
-    EXPECT_TRUE(0 != f);
-
-    EXPECT_TRUE(0 != EE->getPointerToFunction(f));
-    EXPECT_TRUE(1 == ReportedDebugFuncs.size());
-    EXPECT_STREQ(ReportedDebugFuncs.begin()->second.begin()->first.c_str(),
-                 getFilename());
-    EXPECT_EQ(ReportedDebugFuncs.begin()->second.begin()->second, getLine());
-
-    EE->freeMachineCodeForFunction(f);
-    EXPECT_TRUE(ReportedDebugFuncs.size() == 0);
-  }
-
-  void TestMultipleLines(NativeCodeMap& ReportedDebugFuncs) {
-    using namespace std;
-
-    SourceLocations DebugLocations;
-    unsigned int c = 5;
-    for(unsigned int i = 0; i < c; ++i) {
-      DebugLocations.push_back(make_pair(string(getFilename()), getLine() + i));
-    }
-
-    llvm::Function* f = buildFunction(DebugLocations);
-    EXPECT_TRUE(0 != f);
-
-    EXPECT_TRUE(0 != EE->getPointerToFunction(f));
-    EXPECT_TRUE(1 == ReportedDebugFuncs.size());
-    SourceLocations& FunctionInfo = ReportedDebugFuncs.begin()->second;
-    EXPECT_EQ(c, FunctionInfo.size());
-
-    int VerifyCount = 0;
-    for(SourceLocations::iterator i = FunctionInfo.begin();
-        i != FunctionInfo.end();
-        ++i) {
-      EXPECT_STREQ(i->first.c_str(), getFilename());
-      EXPECT_EQ(i->second, getLine() + VerifyCount);
-      VerifyCount++;
-    }
-
-    EE->freeMachineCodeForFunction(f);
-    EXPECT_TRUE(ReportedDebugFuncs.size() == 0);
-  }
-
-  void TestMultipleFiles(NativeCodeMap& ReportedDebugFuncs) {
-
-    std::string secondFilename("another_file.cpp");
-
-    SourceLocations DebugLocations;
-    DebugLocations.push_back(std::make_pair(std::string(getFilename()),
-                                            getLine()));
-    DebugLocations.push_back(std::make_pair(secondFilename, getLine()));
-    llvm::Function* f = buildFunction(DebugLocations);
-    EXPECT_TRUE(0 != f);
-
-    EXPECT_TRUE(0 != EE->getPointerToFunction(f));
-    EXPECT_TRUE(1 == ReportedDebugFuncs.size());
-    SourceLocations& FunctionInfo = ReportedDebugFuncs.begin()->second;
-    EXPECT_TRUE(2 == FunctionInfo.size());
-
-    EXPECT_STREQ(FunctionInfo.at(0).first.c_str(), getFilename());
-    EXPECT_STREQ(FunctionInfo.at(1).first.c_str(), secondFilename.c_str());
-
-    EXPECT_EQ(FunctionInfo.at(0).second, getLine());
-    EXPECT_EQ(FunctionInfo.at(1).second, getLine());
-
-    EE->freeMachineCodeForFunction(f);
-    EXPECT_TRUE(ReportedDebugFuncs.size() == 0);
-  }
-};
-
-#endif //JIT_EVENT_LISTENER_TEST_COMMON_H
index ffa05be87d282426864ff3fba50ca3a771dce3c7..a0395cdad3bfa5ddc73f0e0459ffb7d1ec8116c4 100644 (file)
 LEVEL = ../..
 TESTNAME = ExecutionEngine
 LINK_COMPONENTS := engine interpreter
-
-include $(LEVEL)/Makefile.config
-
-SOURCES := ExecutionEngineTest.cpp \
-  JITEventListenerTest.cpp
-
-ifeq ($(USE_INTEL_JITEVENTS), 1)
-  # Build the Intel JIT Events interface tests
-  SOURCES += IntelJITEventListenerTest.cpp
-
-  # Add the Intel JIT Events include directory
-  CPPFLAGS += -I$(INTEL_JITEVENTS_INCDIR)
-
-  # Link against the LLVM Intel JIT Evens interface library
-  LINK_COMPONENTS += inteljitevents
-endif
-
-ifeq ($(USE_OPROFILE), 1)
-  # Build the OProfile JIT interface tests
-  SOURCES += OProfileJITEventListenerTest.cpp
-
-  # Link against the LLVM oprofile interface library
-  LINK_COMPONENTS += oprofilejit
-endif
-
-
 PARALLEL_DIRS = JIT
 
+include $(LEVEL)/Makefile.config
 include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
diff --git a/unittests/ExecutionEngine/OProfileJITEventListenerTest.cpp b/unittests/ExecutionEngine/OProfileJITEventListenerTest.cpp
deleted file mode 100644 (file)
index 9b0ee60..0000000
+++ /dev/null
@@ -1,166 +0,0 @@
-//===- OProfileJITEventListenerTest.cpp - Unit tests for OProfileJITEventsListener --------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===--------------------------------------------------------------------------------------===//
-
-#include "llvm/ExecutionEngine/JITEventListener.h"
-#include "llvm/ExecutionEngine/OProfileWrapper.h"
-#include "JITEventListenerTestCommon.h"
-
-#include <map>
-#include <list>
-
-using namespace llvm;
-
-namespace {
-
-struct OprofileNativeFunction {
-  const char* Name;
-  uint64_t Addr;
-  const void* CodePtr;
-  unsigned int CodeSize;
-
-  OprofileNativeFunction(const char* name,
-                         uint64_t addr,
-                         const void* code,
-                         unsigned int size)
-  : Name(name)
-  , Addr(addr)
-  , CodePtr(code)
-  , CodeSize(size) {
-  }
-};
-
-typedef std::list<OprofileNativeFunction> NativeFunctionList;
-typedef std::list<debug_line_info> NativeDebugList;
-NativeFunctionList NativeFunctions;
-
-NativeCodeMap ReportedDebugFuncs;
-
-} // namespace
-
-/// Mock implementaion of opagent library
-namespace test_opagent {
-
-op_agent_t globalAgent = reinterpret_cast<op_agent_t>(42);
-
-op_agent_t open_agent()
-{
-  // return non-null op_agent_t
-  return globalAgent;
-}
-
-int close_agent(op_agent_t agent)
-{
-  EXPECT_EQ(globalAgent, agent);
-  return 0;
-}
-
-int write_native_code(op_agent_t agent,
-                      const char* name,
-                      uint64_t addr,
-                      void const* code,
-                      unsigned int size)
-{
-  EXPECT_EQ(globalAgent, agent);
-  OprofileNativeFunction func(name, addr, code, size);
-  NativeFunctions.push_back(func);
-
-  // Verify no other registration has take place for the same address
-  EXPECT_TRUE(ReportedDebugFuncs.find(addr) == ReportedDebugFuncs.end());
-
-  ReportedDebugFuncs[addr];
-  return 0;
-}
-
-int write_debug_line_info(op_agent_t agent,
-                          void const* code,
-                          size_t num_entries,
-                          struct debug_line_info const* info)
-{
-  EXPECT_EQ(globalAgent, agent);
-
-  //verify code has been loaded first
-  uint64_t addr = reinterpret_cast<uint64_t>(code);
-  NativeCodeMap::iterator i = ReportedDebugFuncs.find(addr);
-  EXPECT_TRUE(i != ReportedDebugFuncs.end());
-
-  NativeDebugList NativeInfo(info, info + num_entries);
-
-  SourceLocations locs;
-  for(NativeDebugList::iterator i = NativeInfo.begin();
-      i != NativeInfo.end();
-      ++i) {
-    locs.push_back(std::make_pair(std::string(i->filename), i->lineno));
-  }
-  ReportedDebugFuncs[addr] = locs;
-
-  return 0;
-}
-
-int unload_native_code(op_agent_t agent, uint64_t addr) {
-  EXPECT_EQ(globalAgent, agent);
-
-  //verify that something for the given JIT addr has been loaded first
-  NativeCodeMap::iterator i = ReportedDebugFuncs.find(addr);
-  EXPECT_TRUE(i != ReportedDebugFuncs.end());
-  ReportedDebugFuncs.erase(i);
-  return 0;
-}
-
-int version() {
-  return 1;
-}
-
-bool is_oprofile_running() {
-  return true;
-}
-
-} //namespace test_opagent
-
-class OProfileJITEventListenerTest
-: public JITEventListenerTestBase<OProfileWrapper>
-{
-public:
-  OProfileJITEventListenerTest()
-  : JITEventListenerTestBase<OProfileWrapper>(
-    new OProfileWrapper(test_opagent::open_agent,
-      test_opagent::close_agent,
-      test_opagent::write_native_code,
-      test_opagent::write_debug_line_info,
-      test_opagent::unload_native_code,
-      test_opagent::version,
-      test_opagent::version,
-      test_opagent::is_oprofile_running))
-  {
-    EXPECT_TRUE(0 != MockWrapper);
-
-    Listener.reset(JITEventListener::createOProfileJITEventListener(
-      MockWrapper.get()));
-    EXPECT_TRUE(0 != Listener);
-    EE->RegisterJITEventListener(Listener.get());
-  }
-};
-
-TEST_F(OProfileJITEventListenerTest, NoDebugInfo) {
-  TestNoDebugInfo(ReportedDebugFuncs);
-}
-
-TEST_F(OProfileJITEventListenerTest, SingleLine) {
-  TestSingleLine(ReportedDebugFuncs);
-}
-
-TEST_F(OProfileJITEventListenerTest, MultipleLines) {
-  TestMultipleLines(ReportedDebugFuncs);
-}
-
-TEST_F(OProfileJITEventListenerTest, MultipleFiles) {
-  TestMultipleFiles(ReportedDebugFuncs);
-}
-
-testing::Environment* const jit_env =
-  testing::AddGlobalTestEnvironment(new JITEnvironment);