From 61b1851a205cb8dd29c1d3d4231efb8f8f7da283 Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Tue, 13 Mar 2012 08:33:15 +0000 Subject: Add profiling support for Intel Parallel Amplifier XE (VTune) for JITted code in LLVM. Also refactor the existing OProfile profiling code to reuse the same interfaces with the VTune profiling code. In addition, unit tests for the profiling interfaces were added. This patch was prepared by Andrew Kaylor and Daniel Malea, and reviewed in the llvm-commits list by Jim Grosbach git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@152620 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/ExecutionEngine/IntelJITEvents/CMakeLists.txt | 11 ++ .../IntelJITEvents/IntelJITEventListener.cpp | 183 +++++++++++++++++++++ lib/ExecutionEngine/IntelJITEvents/LLVMBuild.txt | 23 +++ lib/ExecutionEngine/IntelJITEvents/Makefile | 17 ++ 4 files changed, 234 insertions(+) create mode 100644 lib/ExecutionEngine/IntelJITEvents/CMakeLists.txt create mode 100644 lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp create mode 100644 lib/ExecutionEngine/IntelJITEvents/LLVMBuild.txt create mode 100644 lib/ExecutionEngine/IntelJITEvents/Makefile (limited to 'lib/ExecutionEngine/IntelJITEvents') diff --git a/lib/ExecutionEngine/IntelJITEvents/CMakeLists.txt b/lib/ExecutionEngine/IntelJITEvents/CMakeLists.txt new file mode 100644 index 0000000000..7d67d0d8be --- /dev/null +++ b/lib/ExecutionEngine/IntelJITEvents/CMakeLists.txt @@ -0,0 +1,11 @@ + +include_directories( ${LLVM_INTEL_JITEVENTS_INCDIR} ${CMAKE_CURRENT_SOURCE_DIR}/.. ) + +set(system_libs + ${system_libs} + jitprofiling + ) + +add_llvm_library(LLVMIntelJITEvents + IntelJITEventListener.cpp + ) diff --git a/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp b/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp new file mode 100644 index 0000000000..5dfa78f34a --- /dev/null +++ b/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp @@ -0,0 +1,183 @@ +//===-- IntelJITEventListener.cpp - Tell Intel profiler about JITed code --===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines a JITEventListener object to tell Intel(R) VTune(TM) +// Amplifier XE 2011 about JITted functions. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Config/config.h" +#include "llvm/ExecutionEngine/JITEventListener.h" + +#define DEBUG_TYPE "amplifier-jit-event-listener" +#include "llvm/Function.h" +#include "llvm/Metadata.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/OwningPtr.h" +#include "llvm/Analysis/DebugInfo.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/ExecutionEngine/IntelJITEventsWrapper.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/Errno.h" +#include "llvm/Support/ValueHandle.h" +#include "EventListenerCommon.h" + +using namespace llvm; +using namespace llvm::jitprofiling; + +namespace { + +class IntelJITEventListener : public JITEventListener { + typedef DenseMap MethodIDMap; + + IntelJITEventsWrapper& Wrapper; + MethodIDMap MethodIDs; + FilenameCache Filenames; + +public: + IntelJITEventListener(IntelJITEventsWrapper& libraryWrapper) + : Wrapper(libraryWrapper) { + } + + ~IntelJITEventListener() { + } + + virtual void NotifyFunctionEmitted(const Function &F, + void *FnStart, size_t FnSize, + const EmittedFunctionDetails &Details); + + virtual void NotifyFreeingMachineCode(void *OldPtr); +}; + +static LineNumberInfo LineStartToIntelJITFormat( + uintptr_t StartAddress, + uintptr_t Address, + DebugLoc Loc) { + LineNumberInfo Result; + + Result.Offset = Address - StartAddress; + Result.LineNumber = Loc.getLine(); + + return Result; +} + +static iJIT_Method_Load FunctionDescToIntelJITFormat( + IntelJITEventsWrapper& Wrapper, + const char* FnName, + uintptr_t FnStart, + size_t FnSize) { + iJIT_Method_Load Result; + memset(&Result, 0, sizeof(iJIT_Method_Load)); + + Result.method_id = Wrapper.iJIT_GetNewMethodID(); + Result.method_name = const_cast(FnName); + Result.method_load_address = reinterpret_cast(FnStart); + Result.method_size = FnSize; + + Result.class_id = 0; + Result.class_file_name = NULL; + Result.user_data = NULL; + Result.user_data_size = 0; + Result.env = iJDE_JittingAPI; + + return Result; +} + +// Adds the just-emitted function to the symbol table. +void IntelJITEventListener::NotifyFunctionEmitted( + const Function &F, void *FnStart, size_t FnSize, + const EmittedFunctionDetails &Details) { + iJIT_Method_Load FunctionMessage = FunctionDescToIntelJITFormat(Wrapper, + F.getName().data(), + reinterpret_cast(FnStart), + FnSize); + + std::vector LineInfo; + + if (!Details.LineStarts.empty()) { + // Now convert the line number information from the address/DebugLoc + // format in Details to the offset/lineno in Intel JIT API format. + + LineInfo.reserve(Details.LineStarts.size() + 1); + + DebugLoc FirstLoc = Details.LineStarts[0].Loc; + assert(!FirstLoc.isUnknown() + && "LineStarts should not contain unknown DebugLocs"); + + MDNode *FirstLocScope = FirstLoc.getScope(F.getContext()); + DISubprogram FunctionDI = getDISubprogram(FirstLocScope); + if (FunctionDI.Verify()) { + FunctionMessage.source_file_name = const_cast( + Filenames.getFullPath(FirstLocScope)); + + LineNumberInfo FirstLine; + FirstLine.Offset = 0; + FirstLine.LineNumber = FunctionDI.getLineNumber(); + LineInfo.push_back(FirstLine); + } + + for (std::vector::const_iterator I = + Details.LineStarts.begin(), E = Details.LineStarts.end(); + I != E; ++I) { + // This implementation ignores the DebugLoc filename because the Intel + // JIT API does not support multiple source files associated with a single + // JIT function + LineInfo.push_back(LineStartToIntelJITFormat( + reinterpret_cast(FnStart), + I->Address, + I->Loc)); + + // If we have no file name yet for the function, use the filename from + // the first instruction that has one + if (FunctionMessage.source_file_name == 0) { + MDNode *scope = I->Loc.getScope( + Details.MF->getFunction()->getContext()); + FunctionMessage.source_file_name = const_cast( + Filenames.getFullPath(scope)); + } + } + + FunctionMessage.line_number_size = LineInfo.size(); + FunctionMessage.line_number_table = &*LineInfo.begin(); + } else { + FunctionMessage.line_number_size = 0; + FunctionMessage.line_number_table = 0; + } + + Wrapper.iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, + &FunctionMessage); + MethodIDs[FnStart] = FunctionMessage.method_id; +} + +void IntelJITEventListener::NotifyFreeingMachineCode(void *FnStart) { + MethodIDMap::iterator I = MethodIDs.find(FnStart); + if (I != MethodIDs.end()) { + Wrapper.iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_UNLOAD_START, &I->second); + MethodIDs.erase(I); + } +} + +} // anonymous namespace. + +namespace llvm { +JITEventListener *JITEventListener::createIntelJITEventListener() { + static OwningPtr JITProfilingWrapper( + new IntelJITEventsWrapper); + return new IntelJITEventListener(*JITProfilingWrapper); +} + +// for testing +JITEventListener *JITEventListener::createIntelJITEventListener( + IntelJITEventsWrapper* TestImpl) { + return new IntelJITEventListener(*TestImpl); +} + +} // namespace llvm + diff --git a/lib/ExecutionEngine/IntelJITEvents/LLVMBuild.txt b/lib/ExecutionEngine/IntelJITEvents/LLVMBuild.txt new file mode 100644 index 0000000000..80d2273264 --- /dev/null +++ b/lib/ExecutionEngine/IntelJITEvents/LLVMBuild.txt @@ -0,0 +1,23 @@ +;===- ./lib/ExecutionEngine/JITProfileAmplifier/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 +; +;===------------------------------------------------------------------------===; + +[common] + +[component_0] +type = Library +name = IntelJITEvents +parent = ExecutionEngine diff --git a/lib/ExecutionEngine/IntelJITEvents/Makefile b/lib/ExecutionEngine/IntelJITEvents/Makefile new file mode 100644 index 0000000000..ba75ac6f64 --- /dev/null +++ b/lib/ExecutionEngine/IntelJITEvents/Makefile @@ -0,0 +1,17 @@ +##===- lib/ExecutionEngine/JITProfile/Makefile -------------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## +LEVEL = ../../.. +LIBRARYNAME = LLVMIntelJITEvents + +include $(LEVEL)/Makefile.config + +SOURCES := IntelJITEventListener.cpp +CPPFLAGS += -I$(INTEL_JITEVENTS_INCDIR) -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/.. + +include $(LLVM_SRC_ROOT)/Makefile.rules -- cgit v1.2.3