Also renames CWrapperFunctionResult to CWrapperFunctionBuffer. These types are used as argument buffers, as well as result buffers. The new name better reflects their purpose, and is consistent with naming in the new ORC runtime (llvm-project/orc-rt).
225 lines
7.5 KiB
C++
225 lines
7.5 KiB
C++
//===------- JITLoaderVTune.cpp - Register profiler objects -----*- C++ -*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Register objects for access by profilers via the VTune JIT interface.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/ExecutionEngine/Orc/TargetProcess/JITLoaderVTune.h"
|
|
#include "llvm/ExecutionEngine/Orc/Shared/VTuneSharedStructs.h"
|
|
|
|
#if LLVM_USE_INTEL_JITEVENTS
|
|
#include "IntelJITEventsWrapper.h"
|
|
#include "ittnotify.h"
|
|
#include <map>
|
|
|
|
using namespace llvm;
|
|
using namespace llvm::orc;
|
|
|
|
namespace {
|
|
class JITEventWrapper {
|
|
public:
|
|
static std::unique_ptr<IntelJITEventsWrapper> Wrapper;
|
|
};
|
|
std::unique_ptr<IntelJITEventsWrapper> JITEventWrapper::Wrapper;
|
|
} // namespace
|
|
|
|
static Error registerJITLoaderVTuneRegisterImpl(const VTuneMethodBatch &MB) {
|
|
const size_t StringsSize = MB.Strings.size();
|
|
|
|
for (const auto &MethodInfo : MB.Methods) {
|
|
iJIT_Method_Load MethodMessage;
|
|
memset(&MethodMessage, 0, sizeof(iJIT_Method_Load));
|
|
|
|
MethodMessage.method_id = MethodInfo.MethodID;
|
|
if (MethodInfo.NameSI != 0 && MethodInfo.NameSI < StringsSize) {
|
|
MethodMessage.method_name =
|
|
const_cast<char *>(MB.Strings.at(MethodInfo.NameSI).data());
|
|
} else {
|
|
MethodMessage.method_name = NULL;
|
|
}
|
|
if (MethodInfo.ClassFileSI != 0 && MethodInfo.ClassFileSI < StringsSize) {
|
|
MethodMessage.class_file_name =
|
|
const_cast<char *>(MB.Strings.at(MethodInfo.ClassFileSI).data());
|
|
} else {
|
|
MethodMessage.class_file_name = NULL;
|
|
}
|
|
if (MethodInfo.SourceFileSI != 0 && MethodInfo.SourceFileSI < StringsSize) {
|
|
MethodMessage.source_file_name =
|
|
const_cast<char *>(MB.Strings.at(MethodInfo.SourceFileSI).data());
|
|
} else {
|
|
MethodMessage.source_file_name = NULL;
|
|
}
|
|
|
|
MethodMessage.method_load_address = MethodInfo.LoadAddr.toPtr<void *>();
|
|
MethodMessage.method_size = MethodInfo.LoadSize;
|
|
MethodMessage.class_id = 0;
|
|
|
|
MethodMessage.user_data = NULL;
|
|
MethodMessage.user_data_size = 0;
|
|
MethodMessage.env = iJDE_JittingAPI;
|
|
|
|
std::vector<LineNumberInfo> LineInfo;
|
|
for (const auto &LInfo : MethodInfo.LineTable) {
|
|
LineInfo.push_back(LineNumberInfo{LInfo.first, LInfo.second});
|
|
}
|
|
|
|
if (LineInfo.size() == 0) {
|
|
MethodMessage.line_number_size = 0;
|
|
MethodMessage.line_number_table = 0;
|
|
} else {
|
|
MethodMessage.line_number_size = LineInfo.size();
|
|
MethodMessage.line_number_table = &*LineInfo.begin();
|
|
}
|
|
JITEventWrapper::Wrapper->iJIT_NotifyEvent(
|
|
iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, &MethodMessage);
|
|
}
|
|
|
|
return Error::success();
|
|
}
|
|
|
|
static void registerJITLoaderVTuneUnregisterImpl(
|
|
const std::vector<std::pair<uint64_t, uint64_t>> &UM) {
|
|
for (auto &Method : UM) {
|
|
JITEventWrapper::Wrapper->iJIT_NotifyEvent(
|
|
iJVM_EVENT_TYPE_METHOD_UNLOAD_START,
|
|
const_cast<uint64_t *>(&Method.first));
|
|
}
|
|
}
|
|
|
|
extern "C" llvm::orc::shared::CWrapperFunctionBuffer
|
|
llvm_orc_registerVTuneImpl(const char *ArgData, size_t ArgSize) {
|
|
using namespace orc::shared;
|
|
if (!JITEventWrapper::Wrapper)
|
|
JITEventWrapper::Wrapper.reset(new IntelJITEventsWrapper);
|
|
|
|
return WrapperFunction<SPSError(SPSVTuneMethodBatch)>::handle(
|
|
ArgData, ArgSize, registerJITLoaderVTuneRegisterImpl)
|
|
.release();
|
|
}
|
|
|
|
extern "C" llvm::orc::shared::CWrapperFunctionBuffer
|
|
llvm_orc_unregisterVTuneImpl(const char *ArgData, size_t ArgSize) {
|
|
using namespace orc::shared;
|
|
return WrapperFunction<void(SPSVTuneUnloadedMethodIDs)>::handle(
|
|
ArgData, ArgSize, registerJITLoaderVTuneUnregisterImpl)
|
|
.release();
|
|
}
|
|
|
|
// For Testing: following code comes from llvm-jitlistener.cpp in llvm tools
|
|
namespace {
|
|
using SourceLocations = std::vector<std::pair<std::string, unsigned int>>;
|
|
using NativeCodeMap = std::map<uint64_t, SourceLocations>;
|
|
NativeCodeMap ReportedDebugFuncs;
|
|
} // namespace
|
|
|
|
static int NotifyEvent(iJIT_JVM_EVENT EventType, void *EventSpecificData) {
|
|
switch (EventType) {
|
|
case iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED: {
|
|
if (!EventSpecificData) {
|
|
errs() << "Error: The JIT event listener did not provide a event data.";
|
|
return -1;
|
|
}
|
|
iJIT_Method_Load *msg = static_cast<iJIT_Method_Load *>(EventSpecificData);
|
|
|
|
ReportedDebugFuncs[msg->method_id];
|
|
|
|
outs() << "Method load [" << msg->method_id << "]: " << msg->method_name
|
|
<< ", Size = " << msg->method_size << "\n";
|
|
|
|
for (unsigned int i = 0; i < msg->line_number_size; ++i) {
|
|
if (!msg->line_number_table) {
|
|
errs() << "A function with a non-zero line count had no line table.";
|
|
return -1;
|
|
}
|
|
std::pair<std::string, unsigned int> loc(
|
|
std::string(msg->source_file_name),
|
|
msg->line_number_table[i].LineNumber);
|
|
ReportedDebugFuncs[msg->method_id].push_back(loc);
|
|
outs() << " Line info @ " << msg->line_number_table[i].Offset << ": "
|
|
<< msg->source_file_name << ", line "
|
|
<< msg->line_number_table[i].LineNumber << "\n";
|
|
}
|
|
outs() << "\n";
|
|
} break;
|
|
case iJVM_EVENT_TYPE_METHOD_UNLOAD_START: {
|
|
if (!EventSpecificData) {
|
|
errs() << "Error: The JIT event listener did not provide a event data.";
|
|
return -1;
|
|
}
|
|
unsigned int UnloadId =
|
|
*reinterpret_cast<unsigned int *>(EventSpecificData);
|
|
assert(1 == ReportedDebugFuncs.erase(UnloadId));
|
|
outs() << "Method unload [" << UnloadId << "]\n";
|
|
} break;
|
|
default:
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static iJIT_IsProfilingActiveFlags IsProfilingActive(void) {
|
|
// for testing, pretend we have an Intel Parallel Amplifier XE 2011
|
|
// instance attached
|
|
return iJIT_SAMPLING_ON;
|
|
}
|
|
|
|
static unsigned int GetNewMethodID(void) {
|
|
static unsigned int id = 0;
|
|
return ++id;
|
|
}
|
|
|
|
extern "C" llvm::orc::shared::CWrapperFunctionBuffer
|
|
llvm_orc_test_registerVTuneImpl(const char *ArgData, size_t ArgSize) {
|
|
using namespace orc::shared;
|
|
JITEventWrapper::Wrapper.reset(new IntelJITEventsWrapper(
|
|
NotifyEvent, NULL, NULL, IsProfilingActive, 0, 0, GetNewMethodID));
|
|
return WrapperFunction<SPSError(SPSVTuneMethodBatch)>::handle(
|
|
ArgData, ArgSize, registerJITLoaderVTuneRegisterImpl)
|
|
.release();
|
|
}
|
|
|
|
#else
|
|
|
|
using namespace llvm;
|
|
using namespace llvm::orc;
|
|
|
|
static Error unsupportedBatch(const VTuneMethodBatch &MB) {
|
|
return llvm::make_error<StringError>("unsupported for Intel VTune",
|
|
inconvertibleErrorCode());
|
|
}
|
|
|
|
static void unsuppported(const std::vector<std::pair<uint64_t, uint64_t>> &UM) {
|
|
|
|
}
|
|
|
|
extern "C" llvm::orc::shared::CWrapperFunctionBuffer
|
|
llvm_orc_registerVTuneImpl(const char *ArgData, size_t ArgSize) {
|
|
using namespace orc::shared;
|
|
return WrapperFunction<SPSError(SPSVTuneMethodBatch)>::handle(
|
|
ArgData, ArgSize, unsupportedBatch)
|
|
.release();
|
|
}
|
|
|
|
extern "C" llvm::orc::shared::CWrapperFunctionBuffer
|
|
llvm_orc_unregisterVTuneImpl(const char *ArgData, size_t ArgSize) {
|
|
using namespace orc::shared;
|
|
return WrapperFunction<void(SPSVTuneUnloadedMethodIDs)>::handle(
|
|
ArgData, ArgSize, unsuppported)
|
|
.release();
|
|
}
|
|
|
|
extern "C" llvm::orc::shared::CWrapperFunctionBuffer
|
|
llvm_orc_test_registerVTuneImpl(const char *ArgData, size_t ArgSize) {
|
|
using namespace orc::shared;
|
|
return WrapperFunction<SPSError(SPSVTuneMethodBatch)>::handle(
|
|
ArgData, ArgSize, unsupportedBatch)
|
|
.release();
|
|
}
|
|
|
|
#endif
|