aboutsummaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/CMakeLists.txt3
-rw-r--r--tools/LLVMBuild.txt2
-rw-r--r--tools/Makefile2
-rw-r--r--tools/llvm-jitlistener/CMakeLists.txt20
-rw-r--r--tools/llvm-jitlistener/LLVMBuild.txt22
-rw-r--r--tools/llvm-jitlistener/Makefile27
-rw-r--r--tools/llvm-jitlistener/llvm-jitlistener.cpp207
7 files changed, 281 insertions, 2 deletions
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
index d444473ebf..144e8ec3ea 100644
--- a/tools/CMakeLists.txt
+++ b/tools/CMakeLists.txt
@@ -31,6 +31,9 @@ add_subdirectory(llvm-objdump)
add_subdirectory(llvm-readobj)
add_subdirectory(llvm-rtdyld)
add_subdirectory(llvm-dwarfdump)
+if( LLVM_USE_INTEL_JITEVENTS )
+ add_subdirectory(llvm-jitlistener)
+endif( LLVM_USE_INTEL_JITEVENTS )
add_subdirectory(bugpoint)
add_subdirectory(bugpoint-passes)
diff --git a/tools/LLVMBuild.txt b/tools/LLVMBuild.txt
index 64164792a7..25aa177b35 100644
--- a/tools/LLVMBuild.txt
+++ b/tools/LLVMBuild.txt
@@ -16,7 +16,7 @@
;===------------------------------------------------------------------------===;
[common]
-subdirectories = bugpoint llc lli llvm-ar llvm-as llvm-bcanalyzer llvm-cov llvm-diff llvm-dis llvm-dwarfdump llvm-extract llvm-link llvm-mc llvm-nm llvm-objdump llvm-prof llvm-ranlib llvm-rtdyld llvm-size macho-dump opt llvm-mcmarkup
+subdirectories = bugpoint llc lli llvm-ar llvm-as llvm-bcanalyzer llvm-cov llvm-diff llvm-dis llvm-dwarfdump llvm-extract llvm-jitlistener llvm-link llvm-mc llvm-nm llvm-objdump llvm-prof llvm-ranlib llvm-rtdyld llvm-size macho-dump opt llvm-mcmarkup
[component_0]
type = Group
diff --git a/tools/Makefile b/tools/Makefile
index 7c273a281d..7872267d17 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -33,7 +33,7 @@ PARALLEL_DIRS := opt llvm-as llvm-dis \
lli llvm-extract llvm-mc \
bugpoint llvm-bcanalyzer \
llvm-diff macho-dump llvm-objdump llvm-readobj \
- llvm-rtdyld llvm-dwarfdump llvm-cov \
+ llvm-rtdyld llvm-dwarfdump llvm-cov llvm-jitlistener \
llvm-size llvm-stress llvm-mcmarkup \
llvm-symbolizer
diff --git a/tools/llvm-jitlistener/CMakeLists.txt b/tools/llvm-jitlistener/CMakeLists.txt
new file mode 100644
index 0000000000..57a4a0cbe1
--- /dev/null
+++ b/tools/llvm-jitlistener/CMakeLists.txt
@@ -0,0 +1,20 @@
+# This tool is excluded from the CMake build if Intel JIT events are disabled.
+
+link_directories( ${LLVM_INTEL_JITEVENTS_LIBDIR} )
+include_directories( ${LLVM_INTEL_JITEVENTS_INCDIR} )
+
+set(LLVM_LINK_COMPONENTS
+ asmparser
+ bitreader
+ inteljitevents
+ interpreter
+ jit
+ mcjit
+ nativecodegen
+ object
+ selectiondag
+ )
+
+add_llvm_tool(llvm-jitlistener
+ llvm-jitlistener.cpp
+ )
diff --git a/tools/llvm-jitlistener/LLVMBuild.txt b/tools/llvm-jitlistener/LLVMBuild.txt
new file mode 100644
index 0000000000..c436dd90f9
--- /dev/null
+++ b/tools/llvm-jitlistener/LLVMBuild.txt
@@ -0,0 +1,22 @@
+;===- ./tools/llvm-jitlistener/LLVMBuild.txt -------------------*- Conf -*--===;
+;
+; The LLVM Compiler Infrastructure
+;
+; This file is distributed under the University of Illinois Open Source
+; License. See LICENSE.TXT for details.
+;
+;===------------------------------------------------------------------------===;
+;
+; This is an LLVMBuild description file for the components in this subdirectory.
+;
+; For more information on the LLVMBuild system, please see:
+;
+; http://llvm.org/docs/LLVMBuild.html
+;
+;===------------------------------------------------------------------------===;
+
+[component_0]
+type = Tool
+name = llvm-jitlistener
+parent = Tools
+required_libraries = AsmParser BitReader Interpreter JIT MCJIT NativeCodeGen Object SelectionDAG Native
diff --git a/tools/llvm-jitlistener/Makefile b/tools/llvm-jitlistener/Makefile
new file mode 100644
index 0000000000..0971e6a252
--- /dev/null
+++ b/tools/llvm-jitlistener/Makefile
@@ -0,0 +1,27 @@
+##===- tools/llvm-jitlistener/Makefile ---------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL := ../..
+TOOLNAME := llvm-jitlistener
+
+include $(LEVEL)/Makefile.config
+
+LINK_COMPONENTS := mcjit jit interpreter nativecodegen bitreader asmparser selectiondag Object
+
+# If Intel JIT Events support is configured, link against the LLVM Intel JIT
+# Events interface library. If not, this tool will do nothing useful, but it
+# will build correctly.
+ifeq ($(USE_INTEL_JITEVENTS), 1)
+ LINK_COMPONENTS += inteljitevents
+endif
+
+# This tool has no plugins, optimize startup time.
+TOOL_NO_EXPORTS := 1
+
+include $(LLVM_SRC_ROOT)/Makefile.rules
diff --git a/tools/llvm-jitlistener/llvm-jitlistener.cpp b/tools/llvm-jitlistener/llvm-jitlistener.cpp
new file mode 100644
index 0000000000..2b05e66e98
--- /dev/null
+++ b/tools/llvm-jitlistener/llvm-jitlistener.cpp
@@ -0,0 +1,207 @@
+//===-- llvm-jitlistener.cpp - Utility for testing MCJIT event listener ---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This program is a used by lit tests to verify the MCJIT JITEventListener
+// interface. It registers a mock JIT event listener, generates a module from
+// an input IR file and dumps the reported event information to stdout.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/Triple.h"
+#include "../../lib/ExecutionEngine/IntelJITEvents/IntelJITEventsWrapper.h"
+#include "llvm/ExecutionEngine/JITEventListener.h"
+#include "llvm/ExecutionEngine/JITMemoryManager.h"
+#include "llvm/ExecutionEngine/MCJIT.h"
+#include "llvm/ExecutionEngine/ObjectImage.h"
+#include "llvm/LLVMContext.h"
+#include "llvm/Module.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/IRReader.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/TargetSelect.h"
+#include <string>
+
+using namespace llvm;
+
+namespace {
+
+typedef std::vector<std::pair<std::string, unsigned int> > SourceLocations;
+typedef std::map<uint64_t, SourceLocations> NativeCodeMap;
+
+NativeCodeMap ReportedDebugFuncs;
+
+int NotifyEvent(iJIT_JVM_EVENT EventType, void *EventSpecificData) {
+ switch (EventType) {
+ case iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED: {
+ if (!EventSpecificData) {
+ errs() <<
+ "Error: The JIT event listener did not provide a event data.";
+ return -1;
+ }
+ iJIT_Method_Load* msg = static_cast<iJIT_Method_Load*>(EventSpecificData);
+
+ ReportedDebugFuncs[msg->method_id];
+
+ outs() << "Method load [" << msg->method_id << "]: " << msg->method_name
+ << ", Size = " << msg->method_size << "\n";
+
+ for(unsigned int i = 0; i < msg->line_number_size; ++i) {
+ if (!msg->line_number_table) {
+ errs() << "A function with a non-zero line count had no line table.";
+ return -1;
+ }
+ 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);
+ outs() << " Line info @ " << msg->line_number_table[i].Offset
+ << ": " << msg->source_file_name
+ << ", line " << msg->line_number_table[i].LineNumber << "\n";
+ }
+ outs() << "\n";
+ }
+ break;
+ case iJVM_EVENT_TYPE_METHOD_UNLOAD_START: {
+ if (!EventSpecificData) {
+ errs() <<
+ "Error: The JIT event listener did not provide a event data.";
+ return -1;
+ }
+ unsigned int UnloadId
+ = *reinterpret_cast<unsigned int*>(EventSpecificData);
+ assert(1 == ReportedDebugFuncs.erase(UnloadId));
+ outs() << "Method unload [" << UnloadId << "]\n";
+ }
+ break;
+ 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;
+}
+
+class JitEventListenerTest {
+protected:
+ void InitEE(const std::string &IRFile) {
+ LLVMContext &Context = getGlobalContext();
+
+ // If we have a native target, initialize it to ensure it is linked in and
+ // usable by the JIT.
+ InitializeNativeTarget();
+ InitializeNativeTargetAsmPrinter();
+
+ // Parse the bitcode...
+ SMDiagnostic Err;
+ TheModule = ParseIRFile(IRFile, Err, Context);
+ if (!TheModule) {
+ errs() << Err.getMessage();
+ return;
+ }
+
+ // FIXME: This is using the default legacy JITMemoryManager because it
+ // supports poison memory. At some point, we'll need to update this to
+ // use an MCJIT-specific memory manager. It might be nice to have the
+ // poison memory option there too.
+ JITMemoryManager *MemMgr = JITMemoryManager::CreateDefaultMemManager();
+ if (!MemMgr) {
+ errs() << "Unable to create memory manager.";
+ return;
+ }
+
+ // Tell the memory manager to poison freed memory so that accessing freed
+ // memory is more easily tested.
+ MemMgr->setPoisonMemory(true);
+
+ // Override the triple to generate ELF on Windows since that's supported
+ Triple Tuple(TheModule->getTargetTriple());
+ if (Tuple.getTriple().empty())
+ Tuple.setTriple(LLVM_HOSTTRIPLE);
+
+ if (Tuple.isOSWindows() && Triple::ELF != Tuple.getEnvironment()) {
+ Tuple.setEnvironment(Triple::ELF);
+ TheModule->setTargetTriple(Tuple.getTriple());
+ }
+
+ // Compile the IR
+ std::string Error;
+ TheJIT.reset(EngineBuilder(TheModule)
+ .setEngineKind(EngineKind::JIT)
+ .setErrorStr(&Error)
+ .setJITMemoryManager(MemMgr)
+ .setUseMCJIT(true)
+ .create());
+ if (Error.empty() == false)
+ errs() << Error;
+ }
+
+ void DestroyEE() {
+ TheJIT.reset();
+ }
+
+ LLVMContext Context; // Global ownership
+ Module *TheModule; // Owned by ExecutionEngine.
+ JITMemoryManager *JMM; // Owned by ExecutionEngine.
+ OwningPtr<ExecutionEngine> TheJIT;
+
+public:
+ void ProcessInput(const std::string &Filename) {
+ InitEE(Filename);
+
+ llvm::OwningPtr<llvm::JITEventListener> Listener(JITEventListener::createIntelJITEventListener(
+ new IntelJITEventsWrapper(NotifyEvent, 0,
+ IsProfilingActive, 0, 0,
+ GetNewMethodID)));
+
+ TheJIT->RegisterJITEventListener(Listener.get());
+
+ TheJIT->finalizeObject();
+
+ // Destroy the JIT engine instead of unregistering to get unload events.
+ DestroyEE();
+ }
+};
+
+
+
+} // end anonymous namespace
+
+static cl::opt<std::string>
+InputFilename(cl::Positional, cl::desc("<input IR file>"),
+ cl::Required);
+
+int main(int argc, char **argv) {
+ // Print a stack trace if we signal out.
+ sys::PrintStackTraceOnErrorSignal();
+ PrettyStackTraceProgram X(argc, argv);
+ llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
+
+ cl::ParseCommandLineOptions(argc, argv, "llvm jit event listener test utility\n");
+
+ JitEventListenerTest Test;
+
+ Test.ProcessInput(InputFilename);
+
+ return 0;
+}