Current Path : /usr/src/contrib/llvm/lib/ExecutionEngine/IntelJITEvents/ |
FreeBSD hs32.drive.ne.jp 9.1-RELEASE FreeBSD 9.1-RELEASE #1: Wed Jan 14 12:18:08 JST 2015 root@hs32.drive.ne.jp:/sys/amd64/compile/hs32 amd64 |
Current File : //usr/src/contrib/llvm/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp |
//===-- 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<void*, unsigned int> 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<char*>(FnName); Result.method_load_address = reinterpret_cast<void*>(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<uint64_t>(FnStart), FnSize); std::vector<LineNumberInfo> 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<char*>( Filenames.getFullPath(FirstLocScope)); LineNumberInfo FirstLine; FirstLine.Offset = 0; FirstLine.LineNumber = FunctionDI.getLineNumber(); LineInfo.push_back(FirstLine); } for (std::vector<EmittedFunctionDetails::LineStart>::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<uintptr_t>(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<char*>( 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<IntelJITEventsWrapper> JITProfilingWrapper( new IntelJITEventsWrapper); return new IntelJITEventListener(*JITProfilingWrapper); } // for testing JITEventListener *JITEventListener::createIntelJITEventListener( IntelJITEventsWrapper* TestImpl) { return new IntelJITEventListener(*TestImpl); } } // namespace llvm