Path: blob/main/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/TargetProcess/JITLoaderVTune.cpp
35323 views
//===------- JITLoaderVTune.cpp - Register profiler objects -----*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// Register objects for access by profilers via the VTune JIT interface.9//===----------------------------------------------------------------------===//1011#include "llvm/ExecutionEngine/Orc/TargetProcess/JITLoaderVTune.h"12#include "llvm/ExecutionEngine/Orc/Shared/VTuneSharedStructs.h"13#include <map>1415#if LLVM_USE_INTEL_JITEVENTS16#include "IntelJITEventsWrapper.h"17#include "ittnotify.h"1819using namespace llvm;20using namespace llvm::orc;2122namespace {23class JITEventWrapper {24public:25static std::unique_ptr<IntelJITEventsWrapper> Wrapper;26};27std::unique_ptr<IntelJITEventsWrapper> JITEventWrapper::Wrapper;28} // namespace2930static Error registerJITLoaderVTuneRegisterImpl(const VTuneMethodBatch &MB) {31const size_t StringsSize = MB.Strings.size();3233for (const auto &MethodInfo : MB.Methods) {34iJIT_Method_Load MethodMessage;35memset(&MethodMessage, 0, sizeof(iJIT_Method_Load));3637MethodMessage.method_id = MethodInfo.MethodID;38if (MethodInfo.NameSI != 0 && MethodInfo.NameSI < StringsSize) {39MethodMessage.method_name =40const_cast<char *>(MB.Strings.at(MethodInfo.NameSI).data());41} else {42MethodMessage.method_name = NULL;43}44if (MethodInfo.ClassFileSI != 0 && MethodInfo.ClassFileSI < StringsSize) {45MethodMessage.class_file_name =46const_cast<char *>(MB.Strings.at(MethodInfo.ClassFileSI).data());47} else {48MethodMessage.class_file_name = NULL;49}50if (MethodInfo.SourceFileSI != 0 && MethodInfo.SourceFileSI < StringsSize) {51MethodMessage.source_file_name =52const_cast<char *>(MB.Strings.at(MethodInfo.SourceFileSI).data());53} else {54MethodMessage.source_file_name = NULL;55}5657MethodMessage.method_load_address = MethodInfo.LoadAddr.toPtr<void *>();58MethodMessage.method_size = MethodInfo.LoadSize;59MethodMessage.class_id = 0;6061MethodMessage.user_data = NULL;62MethodMessage.user_data_size = 0;63MethodMessage.env = iJDE_JittingAPI;6465std::vector<LineNumberInfo> LineInfo;66for (const auto &LInfo : MethodInfo.LineTable) {67LineInfo.push_back(LineNumberInfo{LInfo.first, LInfo.second});68}6970if (LineInfo.size() == 0) {71MethodMessage.line_number_size = 0;72MethodMessage.line_number_table = 0;73} else {74MethodMessage.line_number_size = LineInfo.size();75MethodMessage.line_number_table = &*LineInfo.begin();76}77JITEventWrapper::Wrapper->iJIT_NotifyEvent(78iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, &MethodMessage);79}8081return Error::success();82}8384static void registerJITLoaderVTuneUnregisterImpl(85const std::vector<std::pair<uint64_t, uint64_t>> &UM) {86for (auto &Method : UM) {87JITEventWrapper::Wrapper->iJIT_NotifyEvent(88iJVM_EVENT_TYPE_METHOD_UNLOAD_START,89const_cast<uint64_t *>(&Method.first));90}91}9293extern "C" llvm::orc::shared::CWrapperFunctionResult94llvm_orc_registerVTuneImpl(const char *Data, uint64_t Size) {95using namespace orc::shared;96if (!JITEventWrapper::Wrapper)97JITEventWrapper::Wrapper.reset(new IntelJITEventsWrapper);9899return WrapperFunction<SPSError(SPSVTuneMethodBatch)>::handle(100Data, Size, registerJITLoaderVTuneRegisterImpl)101.release();102}103104extern "C" llvm::orc::shared::CWrapperFunctionResult105llvm_orc_unregisterVTuneImpl(const char *Data, uint64_t Size) {106using namespace orc::shared;107return WrapperFunction<void(SPSVTuneUnloadedMethodIDs)>::handle(108Data, Size, registerJITLoaderVTuneUnregisterImpl)109.release();110}111112// For Testing: following code comes from llvm-jitlistener.cpp in llvm tools113namespace {114using SourceLocations = std::vector<std::pair<std::string, unsigned int>>;115using NativeCodeMap = std::map<uint64_t, SourceLocations>;116NativeCodeMap ReportedDebugFuncs;117} // namespace118119static int NotifyEvent(iJIT_JVM_EVENT EventType, void *EventSpecificData) {120switch (EventType) {121case iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED: {122if (!EventSpecificData) {123errs() << "Error: The JIT event listener did not provide a event data.";124return -1;125}126iJIT_Method_Load *msg = static_cast<iJIT_Method_Load *>(EventSpecificData);127128ReportedDebugFuncs[msg->method_id];129130outs() << "Method load [" << msg->method_id << "]: " << msg->method_name131<< ", Size = " << msg->method_size << "\n";132133for (unsigned int i = 0; i < msg->line_number_size; ++i) {134if (!msg->line_number_table) {135errs() << "A function with a non-zero line count had no line table.";136return -1;137}138std::pair<std::string, unsigned int> loc(139std::string(msg->source_file_name),140msg->line_number_table[i].LineNumber);141ReportedDebugFuncs[msg->method_id].push_back(loc);142outs() << " Line info @ " << msg->line_number_table[i].Offset << ": "143<< msg->source_file_name << ", line "144<< msg->line_number_table[i].LineNumber << "\n";145}146outs() << "\n";147} break;148case iJVM_EVENT_TYPE_METHOD_UNLOAD_START: {149if (!EventSpecificData) {150errs() << "Error: The JIT event listener did not provide a event data.";151return -1;152}153unsigned int UnloadId =154*reinterpret_cast<unsigned int *>(EventSpecificData);155assert(1 == ReportedDebugFuncs.erase(UnloadId));156outs() << "Method unload [" << UnloadId << "]\n";157} break;158default:159break;160}161return 0;162}163164static iJIT_IsProfilingActiveFlags IsProfilingActive(void) {165// for testing, pretend we have an Intel Parallel Amplifier XE 2011166// instance attached167return iJIT_SAMPLING_ON;168}169170static unsigned int GetNewMethodID(void) {171static unsigned int id = 0;172return ++id;173}174175extern "C" llvm::orc::shared::CWrapperFunctionResult176llvm_orc_test_registerVTuneImpl(const char *Data, uint64_t Size) {177using namespace orc::shared;178JITEventWrapper::Wrapper.reset(new IntelJITEventsWrapper(179NotifyEvent, NULL, NULL, IsProfilingActive, 0, 0, GetNewMethodID));180return WrapperFunction<SPSError(SPSVTuneMethodBatch)>::handle(181Data, Size, registerJITLoaderVTuneRegisterImpl)182.release();183}184185#else186187using namespace llvm;188using namespace llvm::orc;189190static Error unsupportedBatch(const VTuneMethodBatch &MB) {191return llvm::make_error<StringError>("unsupported for Intel VTune",192inconvertibleErrorCode());193}194195static void unsuppported(const std::vector<std::pair<uint64_t, uint64_t>> &UM) {196197}198199extern "C" llvm::orc::shared::CWrapperFunctionResult200llvm_orc_registerVTuneImpl(const char *Data, uint64_t Size) {201using namespace orc::shared;202return WrapperFunction<SPSError(SPSVTuneMethodBatch)>::handle(203Data, Size, unsupportedBatch)204.release();205}206207extern "C" llvm::orc::shared::CWrapperFunctionResult208llvm_orc_unregisterVTuneImpl(const char *Data, uint64_t Size) {209using namespace orc::shared;210return WrapperFunction<void(SPSVTuneUnloadedMethodIDs)>::handle(Data, Size,211unsuppported)212.release();213}214215extern "C" llvm::orc::shared::CWrapperFunctionResult216llvm_orc_test_registerVTuneImpl(const char *Data, uint64_t Size) {217using namespace orc::shared;218return WrapperFunction<SPSError(SPSVTuneMethodBatch)>::handle(219Data, Size, unsupportedBatch)220.release();221}222223#endif224225226