brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.4 KiB · 8793d6f Raw
187 lines · cpp
1//===--- VTuneSupportPlugin.cpp -- Support for VTune profiler --*- 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// Handles support for registering code with VIntel Tune's Amplfiier JIT API.10//11//===----------------------------------------------------------------------===//12#include "llvm/ExecutionEngine/Orc/Debugging/VTuneSupportPlugin.h"13#include "llvm/DebugInfo/DWARF/DWARFContext.h"14#include "llvm/ExecutionEngine/Orc/Debugging/DebugInfoSupport.h"15 16using namespace llvm;17using namespace llvm::orc;18using namespace llvm::jitlink;19 20static constexpr StringRef RegisterVTuneImplName = "llvm_orc_registerVTuneImpl";21static constexpr StringRef UnregisterVTuneImplName =22    "llvm_orc_unregisterVTuneImpl";23static constexpr StringRef RegisterTestVTuneImplName =24    "llvm_orc_test_registerVTuneImpl";25 26static VTuneMethodBatch getMethodBatch(LinkGraph &G, bool EmitDebugInfo) {27  VTuneMethodBatch Batch;28  std::unique_ptr<DWARFContext> DC;29  StringMap<std::unique_ptr<MemoryBuffer>> DCBacking;30  if (EmitDebugInfo) {31    auto EDC = createDWARFContext(G);32    if (!EDC) {33      EmitDebugInfo = false;34    } else {35      DC = std::move(EDC->first);36      DCBacking = std::move(EDC->second);37    }38  }39 40  auto GetStringIdx = [Deduplicator = StringMap<uint32_t>(),41                       &Batch](StringRef S) mutable {42    auto [I, Inserted] = Deduplicator.try_emplace(S);43    if (Inserted) {44      Batch.Strings.push_back(S.str());45      I->second = Batch.Strings.size();46    }47    return I->second;48  };49  for (auto Sym : G.defined_symbols()) {50    if (!Sym->isCallable())51      continue;52 53    Batch.Methods.push_back(VTuneMethodInfo());54    auto &Method = Batch.Methods.back();55    Method.MethodID = 0;56    Method.ParentMI = 0;57    Method.LoadAddr = Sym->getAddress();58    Method.LoadSize = Sym->getSize();59    Method.NameSI = GetStringIdx(*Sym->getName());60    Method.ClassFileSI = 0;61    Method.SourceFileSI = 0;62 63    if (!EmitDebugInfo)64      continue;65 66    auto &Section = Sym->getSection();67    auto Addr = Sym->getAddress();68    auto SAddr =69        object::SectionedAddress{Addr.getValue(), Section.getOrdinal()};70    DILineInfoTable LinesInfo = DC->getLineInfoForAddressRange(71        SAddr, Sym->getSize(),72        DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath);73    Method.SourceFileSI = Batch.Strings.size();74    Batch.Strings.push_back(75        DC->getLineInfoForAddress(SAddr).value_or(DILineInfo()).FileName);76    for (auto &LInfo : LinesInfo) {77      Method.LineTable.push_back(78          std::pair<unsigned, unsigned>{/*unsigned*/ Sym->getOffset(),79                                        /*DILineInfo*/ LInfo.second.Line});80    }81  }82  return Batch;83}84 85void VTuneSupportPlugin::modifyPassConfig(MaterializationResponsibility &MR,86                                          LinkGraph &G,87                                          PassConfiguration &Config) {88  Config.PostFixupPasses.push_back([this, MR = &MR](LinkGraph &G) {89    // the object file is generated but not linked yet90    auto Batch = getMethodBatch(G, EmitDebugInfo);91    if (Batch.Methods.empty()) {92      return Error::success();93    }94    {95      std::lock_guard<std::mutex> Lock(PluginMutex);96      uint64_t Allocated = Batch.Methods.size();97      uint64_t Start = NextMethodID;98      NextMethodID += Allocated;99      for (size_t i = Start; i < NextMethodID; ++i) {100        Batch.Methods[i - Start].MethodID = i;101      }102      this->PendingMethodIDs[MR] = {Start, Allocated};103    }104    G.allocActions().push_back(105        {cantFail(shared::WrapperFunctionCall::Create<106                  shared::SPSArgList<shared::SPSVTuneMethodBatch>>(107             RegisterVTuneImplAddr, Batch)),108         {}});109    return Error::success();110  });111}112 113Error VTuneSupportPlugin::notifyEmitted(MaterializationResponsibility &MR) {114  if (auto Err = MR.withResourceKeyDo([this, MR = &MR](ResourceKey K) {115        std::lock_guard<std::mutex> Lock(PluginMutex);116        auto I = PendingMethodIDs.find(MR);117        if (I == PendingMethodIDs.end())118          return;119 120        LoadedMethodIDs[K].push_back(I->second);121        PendingMethodIDs.erase(I);122      })) {123    return Err;124  }125  return Error::success();126}127 128Error VTuneSupportPlugin::notifyFailed(MaterializationResponsibility &MR) {129  std::lock_guard<std::mutex> Lock(PluginMutex);130  PendingMethodIDs.erase(&MR);131  return Error::success();132}133 134Error VTuneSupportPlugin::notifyRemovingResources(JITDylib &JD, ResourceKey K) {135  // Unregistration not required if not provided136  if (!UnregisterVTuneImplAddr) {137    return Error::success();138  }139  VTuneUnloadedMethodIDs UnloadedIDs;140  {141    std::lock_guard<std::mutex> Lock(PluginMutex);142    auto I = LoadedMethodIDs.find(K);143    if (I == LoadedMethodIDs.end())144      return Error::success();145 146    UnloadedIDs = std::move(I->second);147    LoadedMethodIDs.erase(I);148  }149  if (auto Err = EPC.callSPSWrapper<void(shared::SPSVTuneUnloadedMethodIDs)>(150          UnregisterVTuneImplAddr, UnloadedIDs))151    return Err;152 153  return Error::success();154}155 156void VTuneSupportPlugin::notifyTransferringResources(JITDylib &JD,157                                                     ResourceKey DstKey,158                                                     ResourceKey SrcKey) {159  std::lock_guard<std::mutex> Lock(PluginMutex);160  auto I = LoadedMethodIDs.find(SrcKey);161  if (I == LoadedMethodIDs.end())162    return;163 164  auto &Dest = LoadedMethodIDs[DstKey];165  llvm::append_range(Dest, I->second);166  LoadedMethodIDs.erase(SrcKey);167}168 169Expected<std::unique_ptr<VTuneSupportPlugin>>170VTuneSupportPlugin::Create(ExecutorProcessControl &EPC, JITDylib &JD,171                           bool EmitDebugInfo, bool TestMode) {172  auto &ES = EPC.getExecutionSession();173  auto RegisterImplName =174      ES.intern(TestMode ? RegisterTestVTuneImplName : RegisterVTuneImplName);175  auto UnregisterImplName = ES.intern(UnregisterVTuneImplName);176  SymbolLookupSet SLS{RegisterImplName, UnregisterImplName};177  auto Res = ES.lookup(makeJITDylibSearchOrder({&JD}), std::move(SLS));178  if (!Res)179    return Res.takeError();180  ExecutorAddr RegisterImplAddr(181      Res->find(RegisterImplName)->second.getAddress());182  ExecutorAddr UnregisterImplAddr(183      Res->find(UnregisterImplName)->second.getAddress());184  return std::make_unique<VTuneSupportPlugin>(185      EPC, RegisterImplAddr, UnregisterImplAddr, EmitDebugInfo);186}187