IntelJITEventListener.cpp revision 61b1851a205cb8dd29c1d3d4231efb8f8f7da283
161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky//===-- IntelJITEventListener.cpp - Tell Intel profiler about JITed code --===// 261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky// 361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky// The LLVM Compiler Infrastructure 461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky// 561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky// This file is distributed under the University of Illinois Open Source 661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky// License. See LICENSE.TXT for details. 761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky// 861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky//===----------------------------------------------------------------------===// 961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky// 1061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky// This file defines a JITEventListener object to tell Intel(R) VTune(TM) 1161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky// Amplifier XE 2011 about JITted functions. 1261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky// 1361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky//===----------------------------------------------------------------------===// 1461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 1561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky#include "llvm/Config/config.h" 1661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky#include "llvm/ExecutionEngine/JITEventListener.h" 1761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 1861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky#define DEBUG_TYPE "amplifier-jit-event-listener" 1961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky#include "llvm/Function.h" 2061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky#include "llvm/Metadata.h" 2161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky#include "llvm/ADT/DenseMap.h" 2261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky#include "llvm/ADT/OwningPtr.h" 2361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky#include "llvm/Analysis/DebugInfo.h" 2461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky#include "llvm/CodeGen/MachineFunction.h" 2561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky#include "llvm/ExecutionEngine/IntelJITEventsWrapper.h" 2661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky#include "llvm/Support/Debug.h" 2761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky#include "llvm/Support/raw_ostream.h" 2861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky#include "llvm/Support/Errno.h" 2961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky#include "llvm/Support/ValueHandle.h" 3061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky#include "EventListenerCommon.h" 3161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 3261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Benderskyusing namespace llvm; 3361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Benderskyusing namespace llvm::jitprofiling; 3461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 3561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Benderskynamespace { 3661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 3761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Benderskyclass IntelJITEventListener : public JITEventListener { 3861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky typedef DenseMap<void*, unsigned int> MethodIDMap; 3961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 4061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky IntelJITEventsWrapper& Wrapper; 4161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky MethodIDMap MethodIDs; 4261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky FilenameCache Filenames; 4361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 4461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Benderskypublic: 4561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky IntelJITEventListener(IntelJITEventsWrapper& libraryWrapper) 4661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky : Wrapper(libraryWrapper) { 4761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky } 4861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 4961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky ~IntelJITEventListener() { 5061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky } 5161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 5261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky virtual void NotifyFunctionEmitted(const Function &F, 5361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky void *FnStart, size_t FnSize, 5461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky const EmittedFunctionDetails &Details); 5561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 5661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky virtual void NotifyFreeingMachineCode(void *OldPtr); 5761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky}; 5861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 5961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Benderskystatic LineNumberInfo LineStartToIntelJITFormat( 6061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky uintptr_t StartAddress, 6161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky uintptr_t Address, 6261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky DebugLoc Loc) { 6361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky LineNumberInfo Result; 6461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 6561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky Result.Offset = Address - StartAddress; 6661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky Result.LineNumber = Loc.getLine(); 6761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 6861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky return Result; 6961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky} 7061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 7161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Benderskystatic iJIT_Method_Load FunctionDescToIntelJITFormat( 7261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky IntelJITEventsWrapper& Wrapper, 7361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky const char* FnName, 7461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky uintptr_t FnStart, 7561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky size_t FnSize) { 7661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky iJIT_Method_Load Result; 7761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky memset(&Result, 0, sizeof(iJIT_Method_Load)); 7861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 7961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky Result.method_id = Wrapper.iJIT_GetNewMethodID(); 8061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky Result.method_name = const_cast<char*>(FnName); 8161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky Result.method_load_address = reinterpret_cast<void*>(FnStart); 8261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky Result.method_size = FnSize; 8361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 8461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky Result.class_id = 0; 8561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky Result.class_file_name = NULL; 8661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky Result.user_data = NULL; 8761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky Result.user_data_size = 0; 8861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky Result.env = iJDE_JittingAPI; 8961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 9061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky return Result; 9161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky} 9261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 9361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky// Adds the just-emitted function to the symbol table. 9461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Benderskyvoid IntelJITEventListener::NotifyFunctionEmitted( 9561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky const Function &F, void *FnStart, size_t FnSize, 9661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky const EmittedFunctionDetails &Details) { 9761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky iJIT_Method_Load FunctionMessage = FunctionDescToIntelJITFormat(Wrapper, 9861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky F.getName().data(), 9961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky reinterpret_cast<uint64_t>(FnStart), 10061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky FnSize); 10161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 10261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky std::vector<LineNumberInfo> LineInfo; 10361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 10461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky if (!Details.LineStarts.empty()) { 10561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky // Now convert the line number information from the address/DebugLoc 10661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky // format in Details to the offset/lineno in Intel JIT API format. 10761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 10861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky LineInfo.reserve(Details.LineStarts.size() + 1); 10961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 11061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky DebugLoc FirstLoc = Details.LineStarts[0].Loc; 11161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky assert(!FirstLoc.isUnknown() 11261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky && "LineStarts should not contain unknown DebugLocs"); 11361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 11461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky MDNode *FirstLocScope = FirstLoc.getScope(F.getContext()); 11561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky DISubprogram FunctionDI = getDISubprogram(FirstLocScope); 11661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky if (FunctionDI.Verify()) { 11761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky FunctionMessage.source_file_name = const_cast<char*>( 11861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky Filenames.getFullPath(FirstLocScope)); 11961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 12061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky LineNumberInfo FirstLine; 12161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky FirstLine.Offset = 0; 12261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky FirstLine.LineNumber = FunctionDI.getLineNumber(); 12361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky LineInfo.push_back(FirstLine); 12461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky } 12561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 12661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky for (std::vector<EmittedFunctionDetails::LineStart>::const_iterator I = 12761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky Details.LineStarts.begin(), E = Details.LineStarts.end(); 12861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky I != E; ++I) { 12961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky // This implementation ignores the DebugLoc filename because the Intel 13061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky // JIT API does not support multiple source files associated with a single 13161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky // JIT function 13261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky LineInfo.push_back(LineStartToIntelJITFormat( 13361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky reinterpret_cast<uintptr_t>(FnStart), 13461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky I->Address, 13561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky I->Loc)); 13661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 13761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky // If we have no file name yet for the function, use the filename from 13861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky // the first instruction that has one 13961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky if (FunctionMessage.source_file_name == 0) { 14061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky MDNode *scope = I->Loc.getScope( 14161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky Details.MF->getFunction()->getContext()); 14261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky FunctionMessage.source_file_name = const_cast<char*>( 14361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky Filenames.getFullPath(scope)); 14461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky } 14561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky } 14661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 14761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky FunctionMessage.line_number_size = LineInfo.size(); 14861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky FunctionMessage.line_number_table = &*LineInfo.begin(); 14961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky } else { 15061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky FunctionMessage.line_number_size = 0; 15161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky FunctionMessage.line_number_table = 0; 15261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky } 15361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 15461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky Wrapper.iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, 15561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky &FunctionMessage); 15661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky MethodIDs[FnStart] = FunctionMessage.method_id; 15761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky} 15861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 15961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Benderskyvoid IntelJITEventListener::NotifyFreeingMachineCode(void *FnStart) { 16061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky MethodIDMap::iterator I = MethodIDs.find(FnStart); 16161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky if (I != MethodIDs.end()) { 16261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky Wrapper.iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_UNLOAD_START, &I->second); 16361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky MethodIDs.erase(I); 16461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky } 16561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky} 16661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 16761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky} // anonymous namespace. 16861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 16961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Benderskynamespace llvm { 17061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli BenderskyJITEventListener *JITEventListener::createIntelJITEventListener() { 17161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky static OwningPtr<IntelJITEventsWrapper> JITProfilingWrapper( 17261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky new IntelJITEventsWrapper); 17361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky return new IntelJITEventListener(*JITProfilingWrapper); 17461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky} 17561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 17661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky// for testing 17761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli BenderskyJITEventListener *JITEventListener::createIntelJITEventListener( 17861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky IntelJITEventsWrapper* TestImpl) { 17961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky return new IntelJITEventListener(*TestImpl); 18061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky} 18161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 18261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky} // namespace llvm 18361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky 184