Lang Hames 558760009c
[ORC] Rename WrapperFunctionResult to WrapperFunctionBuffer. NFCI. (#172633)
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).
2025-12-18 07:57:06 +11:00

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