[llvm] [ORC][JITLink] Add Intel VTune support to JITLink (PR #83957)
Hongyu Chen via llvm-commits
llvm-commits at lists.llvm.org
Thu Mar 7 09:29:21 PST 2024
================
@@ -0,0 +1,224 @@
+//===------- 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"
+#include <map>
+
+#if LLVM_USE_INTEL_JITEVENTS
+#include "IntelJITEventsWrapper.h"
+#include "ittnotify.h"
+
+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<unsigned long *>(&Method.first));
+ }
+}
+
+extern "C" llvm::orc::shared::CWrapperFunctionResult
+llvm_orc_registerVTuneImpl(const char *Data, uint64_t Size) {
+ using namespace orc::shared;
+ if (!JITEventWrapper::Wrapper)
+ JITEventWrapper::Wrapper.reset(new IntelJITEventsWrapper);
+
+ return WrapperFunction<SPSError(SPSVTuneMethodBatch)>::handle(
+ Data, Size, registerJITLoaderVTuneRegisterImpl)
+ .release();
+}
+
+extern "C" llvm::orc::shared::CWrapperFunctionResult
+llvm_orc_unregisterVTuneImpl(const char *Data, uint64_t Size) {
+ using namespace orc::shared;
+ return WrapperFunction<void(SPSVTuneUnloadedMethodIDs)>::handle(
+ Data, Size, 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";
----------------
yugier wrote:
No this is not debugging prints. They are outputs will be checked against in the tests.
```
# CHECK: Method load [0]: {{.*}}, Size = {{[0-9]+}}
# CHECK: Method unload [0]
```
in file `llvm/test/ExecutionEngine/JITLink/x86-64/ELF_vtune.s`
https://github.com/llvm/llvm-project/pull/83957
More information about the llvm-commits
mailing list