1919#include < clang/Basic/TargetOptions.h>
2020#include < clang/Frontend/CompilerInstance.h>
2121
22+ #include < llvm/ExecutionEngine/Orc/Debugging/DebugInfoSupport.h>
23+ #include < llvm/ExecutionEngine/Orc/Debugging/DebuggerSupport.h>
24+ #include < llvm/ExecutionEngine/Orc/Debugging/PerfSupportPlugin.h>
2225#include < llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h>
2326#include < llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h>
2427#include < llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h>
28+ #include < llvm/ExecutionEngine/Orc/TargetProcess/JITLoaderPerf.h>
2529#include < llvm/ExecutionEngine/SectionMemoryManager.h>
2630#include < llvm/IR/LLVMContext.h>
2731#include < llvm/MC/TargetRegistry.h>
@@ -40,7 +44,57 @@ using namespace llvm;
4044using namespace llvm ::jitlink;
4145using namespace llvm ::orc;
4246
47+ static LLVM_ATTRIBUTE_USED void linkComponents () {
48+ errs () << " Linking in runtime functions\n "
49+ << (void *)&llvm_orc_registerJITLoaderPerfStart << ' \n '
50+ << (void *)&llvm_orc_registerJITLoaderPerfEnd << ' \n '
51+ << (void *)&llvm_orc_registerJITLoaderPerfImpl << ' \n ' ;
52+ }
53+
4354namespace {
55+ // This could potentially be upstreamed, similar to enableDebuggerSupport()
56+ Error enablePerfSupport (LLJIT& J) {
57+ auto * ObjLinkingLayer =
58+ dyn_cast<ObjectLinkingLayer>(&J.getObjLinkingLayer ());
59+ if (!ObjLinkingLayer)
60+ return make_error<StringError>(" Cannot enable LLJIT perf support: "
61+ " perf support requires JITLink" ,
62+ inconvertibleErrorCode ());
63+ auto ProcessSymsJD = J.getProcessSymbolsJITDylib ();
64+ if (!ProcessSymsJD)
65+ return make_error<StringError>(" Cannot enable LLJIT perf support: "
66+ " Process symbols are not available" ,
67+ inconvertibleErrorCode ());
68+
69+ auto & ES = J.getExecutionSession ();
70+ const auto & TT = J.getTargetTriple ();
71+
72+ switch (TT.getObjectFormat ()) {
73+ case Triple::ELF: {
74+ auto debugInfoPreservationPlugin =
75+ DebugInfoPreservationPlugin::Create ();
76+ if (!debugInfoPreservationPlugin)
77+ return debugInfoPreservationPlugin.takeError ();
78+
79+ auto perfSupportPlugin =
80+ PerfSupportPlugin::Create (ES.getExecutorProcessControl (),
81+ *ProcessSymsJD, true , true );
82+ if (!perfSupportPlugin)
83+ return perfSupportPlugin.takeError ();
84+
85+ ObjLinkingLayer->addPlugin (std::move (*debugInfoPreservationPlugin));
86+ ObjLinkingLayer->addPlugin (std::move (*perfSupportPlugin));
87+
88+ return Error::success ();
89+ }
90+ default :
91+ return make_error<StringError>(" Cannot enable LLJIT perf support: " +
92+ Triple::getObjectFormatTypeName (
93+ TT.getObjectFormat ()) +
94+ " is not supported" ,
95+ inconvertibleErrorCode ());
96+ }
97+ }
4498
4599 class ClingMMapper final : public SectionMemoryManager::MemoryMapper {
46100 public:
@@ -491,6 +545,20 @@ IncrementalJIT::IncrementalJIT(
491545 Builder.setDataLayout (m_TM->createDataLayout ());
492546 Builder.setExecutorProcessControl (std::move (EPC));
493547
548+ if (m_JITLink) {
549+ Builder.setPrePlatformSetup ([](llvm::orc::LLJIT& J) {
550+ // Try to enable debugging of JIT'd code (only works with JITLink for
551+ // ELF and MachO).
552+ if (cling::utils::ConvertEnvValueToBool (std::getenv (" CLING_DEBUG" )))
553+ consumeError (enableDebuggerSupport (J));
554+ #ifdef __linux__
555+ if (cling::utils::ConvertEnvValueToBool (std::getenv (" CLING_PROFILE" )))
556+ consumeError (enablePerfSupport (J));
557+ #endif
558+ return llvm::Error::success ();
559+ });
560+ }
561+
494562 // Create ObjectLinkingLayer with our own MemoryManager.
495563 Builder.setObjectLinkingLayerCreator ([&](ExecutionSession& ES,
496564 const Triple& TT)
0 commit comments