brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.5 KiB · 8f988c9 Raw
225 lines · cpp
1//===------- JITLoaderVTune.cpp - Register profiler objects -----*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// Register objects for access by profilers via the VTune JIT interface.10//===----------------------------------------------------------------------===//11 12#include "llvm/ExecutionEngine/Orc/TargetProcess/JITLoaderVTune.h"13#include "llvm/ExecutionEngine/Orc/Shared/VTuneSharedStructs.h"14 15#if LLVM_USE_INTEL_JITEVENTS16#include "IntelJITEventsWrapper.h"17#include "ittnotify.h"18#include <map>19 20using namespace llvm;21using namespace llvm::orc;22 23namespace {24class JITEventWrapper {25public:26  static std::unique_ptr<IntelJITEventsWrapper> Wrapper;27};28std::unique_ptr<IntelJITEventsWrapper> JITEventWrapper::Wrapper;29} // namespace30 31static Error registerJITLoaderVTuneRegisterImpl(const VTuneMethodBatch &MB) {32  const size_t StringsSize = MB.Strings.size();33 34  for (const auto &MethodInfo : MB.Methods) {35    iJIT_Method_Load MethodMessage;36    memset(&MethodMessage, 0, sizeof(iJIT_Method_Load));37 38    MethodMessage.method_id = MethodInfo.MethodID;39    if (MethodInfo.NameSI != 0 && MethodInfo.NameSI < StringsSize) {40      MethodMessage.method_name =41          const_cast<char *>(MB.Strings.at(MethodInfo.NameSI).data());42    } else {43      MethodMessage.method_name = NULL;44    }45    if (MethodInfo.ClassFileSI != 0 && MethodInfo.ClassFileSI < StringsSize) {46      MethodMessage.class_file_name =47          const_cast<char *>(MB.Strings.at(MethodInfo.ClassFileSI).data());48    } else {49      MethodMessage.class_file_name = NULL;50    }51    if (MethodInfo.SourceFileSI != 0 && MethodInfo.SourceFileSI < StringsSize) {52      MethodMessage.source_file_name =53          const_cast<char *>(MB.Strings.at(MethodInfo.SourceFileSI).data());54    } else {55      MethodMessage.source_file_name = NULL;56    }57 58    MethodMessage.method_load_address = MethodInfo.LoadAddr.toPtr<void *>();59    MethodMessage.method_size = MethodInfo.LoadSize;60    MethodMessage.class_id = 0;61 62    MethodMessage.user_data = NULL;63    MethodMessage.user_data_size = 0;64    MethodMessage.env = iJDE_JittingAPI;65 66    std::vector<LineNumberInfo> LineInfo;67    for (const auto &LInfo : MethodInfo.LineTable) {68      LineInfo.push_back(LineNumberInfo{LInfo.first, LInfo.second});69    }70 71    if (LineInfo.size() == 0) {72      MethodMessage.line_number_size = 0;73      MethodMessage.line_number_table = 0;74    } else {75      MethodMessage.line_number_size = LineInfo.size();76      MethodMessage.line_number_table = &*LineInfo.begin();77    }78    JITEventWrapper::Wrapper->iJIT_NotifyEvent(79        iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, &MethodMessage);80  }81 82  return Error::success();83}84 85static void registerJITLoaderVTuneUnregisterImpl(86    const std::vector<std::pair<uint64_t, uint64_t>> &UM) {87  for (auto &Method : UM) {88    JITEventWrapper::Wrapper->iJIT_NotifyEvent(89        iJVM_EVENT_TYPE_METHOD_UNLOAD_START,90        const_cast<uint64_t *>(&Method.first));91  }92}93 94extern "C" llvm::orc::shared::CWrapperFunctionResult95llvm_orc_registerVTuneImpl(const char *ArgData, size_t ArgSize) {96  using namespace orc::shared;97  if (!JITEventWrapper::Wrapper)98    JITEventWrapper::Wrapper.reset(new IntelJITEventsWrapper);99 100  return WrapperFunction<SPSError(SPSVTuneMethodBatch)>::handle(101             ArgData, ArgSize, registerJITLoaderVTuneRegisterImpl)102      .release();103}104 105extern "C" llvm::orc::shared::CWrapperFunctionResult106llvm_orc_unregisterVTuneImpl(const char *ArgData, size_t ArgSize) {107  using namespace orc::shared;108  return WrapperFunction<void(SPSVTuneUnloadedMethodIDs)>::handle(109             ArgData, ArgSize, registerJITLoaderVTuneUnregisterImpl)110      .release();111}112 113// For Testing: following code comes from llvm-jitlistener.cpp in llvm tools114namespace {115using SourceLocations = std::vector<std::pair<std::string, unsigned int>>;116using NativeCodeMap = std::map<uint64_t, SourceLocations>;117NativeCodeMap ReportedDebugFuncs;118} // namespace119 120static int NotifyEvent(iJIT_JVM_EVENT EventType, void *EventSpecificData) {121  switch (EventType) {122  case iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED: {123    if (!EventSpecificData) {124      errs() << "Error: The JIT event listener did not provide a event data.";125      return -1;126    }127    iJIT_Method_Load *msg = static_cast<iJIT_Method_Load *>(EventSpecificData);128 129    ReportedDebugFuncs[msg->method_id];130 131    outs() << "Method load [" << msg->method_id << "]: " << msg->method_name132           << ", Size = " << msg->method_size << "\n";133 134    for (unsigned int i = 0; i < msg->line_number_size; ++i) {135      if (!msg->line_number_table) {136        errs() << "A function with a non-zero line count had no line table.";137        return -1;138      }139      std::pair<std::string, unsigned int> loc(140          std::string(msg->source_file_name),141          msg->line_number_table[i].LineNumber);142      ReportedDebugFuncs[msg->method_id].push_back(loc);143      outs() << "  Line info @ " << msg->line_number_table[i].Offset << ": "144             << msg->source_file_name << ", line "145             << msg->line_number_table[i].LineNumber << "\n";146    }147    outs() << "\n";148  } break;149  case iJVM_EVENT_TYPE_METHOD_UNLOAD_START: {150    if (!EventSpecificData) {151      errs() << "Error: The JIT event listener did not provide a event data.";152      return -1;153    }154    unsigned int UnloadId =155        *reinterpret_cast<unsigned int *>(EventSpecificData);156    assert(1 == ReportedDebugFuncs.erase(UnloadId));157    outs() << "Method unload [" << UnloadId << "]\n";158  } break;159  default:160    break;161  }162  return 0;163}164 165static iJIT_IsProfilingActiveFlags IsProfilingActive(void) {166  // for testing, pretend we have an Intel Parallel Amplifier XE 2011167  // instance attached168  return iJIT_SAMPLING_ON;169}170 171static unsigned int GetNewMethodID(void) {172  static unsigned int id = 0;173  return ++id;174}175 176extern "C" llvm::orc::shared::CWrapperFunctionResult177llvm_orc_test_registerVTuneImpl(const char *ArgData, size_t ArgSize) {178  using namespace orc::shared;179  JITEventWrapper::Wrapper.reset(new IntelJITEventsWrapper(180      NotifyEvent, NULL, NULL, IsProfilingActive, 0, 0, GetNewMethodID));181  return WrapperFunction<SPSError(SPSVTuneMethodBatch)>::handle(182             ArgData, ArgSize, registerJITLoaderVTuneRegisterImpl)183      .release();184}185 186#else187 188using namespace llvm;189using namespace llvm::orc;190 191static Error unsupportedBatch(const VTuneMethodBatch &MB) {192  return llvm::make_error<StringError>("unsupported for Intel VTune",193                                       inconvertibleErrorCode());194}195 196static void unsuppported(const std::vector<std::pair<uint64_t, uint64_t>> &UM) {197 198}199 200extern "C" llvm::orc::shared::CWrapperFunctionResult201llvm_orc_registerVTuneImpl(const char *ArgData, size_t ArgSize) {202  using namespace orc::shared;203  return WrapperFunction<SPSError(SPSVTuneMethodBatch)>::handle(204             ArgData, ArgSize, unsupportedBatch)205      .release();206}207 208extern "C" llvm::orc::shared::CWrapperFunctionResult209llvm_orc_unregisterVTuneImpl(const char *ArgData, size_t ArgSize) {210  using namespace orc::shared;211  return WrapperFunction<void(SPSVTuneUnloadedMethodIDs)>::handle(212             ArgData, ArgSize, unsuppported)213      .release();214}215 216extern "C" llvm::orc::shared::CWrapperFunctionResult217llvm_orc_test_registerVTuneImpl(const char *ArgData, size_t ArgSize) {218  using namespace orc::shared;219  return WrapperFunction<SPSError(SPSVTuneMethodBatch)>::handle(220             ArgData, ArgSize, unsupportedBatch)221      .release();222}223 224#endif225