<div dir="ltr"><div>Hi Eric,</div><div>Sorry for causing the warning :( <br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, 13 Aug 2019 at 06:46, Eric Christopher <<a href="mailto:echristo@gmail.com">echristo@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">FWIW you had a static function in the .h file that isn't used in every<br>
single TU. I fixed it up thusly:<br>
<br>
commit 4acb4ee767d0f450f6b87a68e6c9e483ee0744b6<br>
Author: Eric Christopher <<a href="mailto:echristo@gmail.com" target="_blank">echristo@gmail.com</a>><br>
Date: Tue Aug 13 00:05:01 2019 +0000<br>
<br>
Move findBBwithCalls to the file it's used in to avoid unused function<br>
warnings.<br>
<br>
llvm-svn: 368636<br>
<br>
And I'm surprised that more bots weren't broken. Do try to build with<br>
warnings and errors on by default if you can.<br>
<br>
Thanks!<br>
<br>
-eric<br>
<br>
On Sat, Aug 3, 2019 at 7:41 AM Praveen Velliengiri via llvm-commits<br>
<<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>> wrote:<br>
><br>
> Author: pree-jackie<br>
> Date: Sat Aug 3 07:42:13 2019<br>
> New Revision: 367756<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=367756&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=367756&view=rev</a><br>
> Log:<br>
> Speculative Compilation<br>
><br>
> [ORC] Remove Speculator Variants for Different Program Representations<br>
><br>
> [ORC] Block Freq Analysis<br>
><br>
> Speculative Compilation with Naive Block Frequency<br>
><br>
> Add Applications to OrcSpeculation<br>
><br>
> ORC v2 with Block Freq Query & Example<br>
><br>
> Deleted BenchMark Programs<br>
><br>
> Signed-off-by: preejackie <<a href="mailto:praveenvelliengiri@gmail.com" target="_blank">praveenvelliengiri@gmail.com</a>><br>
><br>
> ORCv2 comments resolved<br>
><br>
> [ORCV2] NFC<br>
><br>
> ORCv2 NFC<br>
><br>
> [ORCv2] Speculative compilation - CFGWalkQuery<br>
><br>
> ORCv2 Adapting IRSpeculationLayer to new locking scheme<br>
><br>
> Added:<br>
> llvm/trunk/examples/SpeculativeJIT/<br>
> llvm/trunk/examples/SpeculativeJIT/CMakeLists.txt<br>
> llvm/trunk/examples/SpeculativeJIT/SpeculativeJIT.cpp<br>
> llvm/trunk/include/llvm/ExecutionEngine/Orc/SpeculateAnalyses.h<br>
> llvm/trunk/include/llvm/ExecutionEngine/Orc/Speculation.h<br>
> llvm/trunk/lib/ExecutionEngine/Orc/SpeculateAnalyses.cpp<br>
> llvm/trunk/lib/ExecutionEngine/Orc/Speculation.cpp<br>
> Modified:<br>
> llvm/trunk/examples/CMakeLists.txt<br>
> llvm/trunk/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h<br>
> llvm/trunk/include/llvm/ExecutionEngine/Orc/LazyReexports.h<br>
> llvm/trunk/lib/ExecutionEngine/Orc/CMakeLists.txt<br>
> llvm/trunk/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp<br>
> llvm/trunk/lib/ExecutionEngine/Orc/LazyReexports.cpp<br>
><br>
> Modified: llvm/trunk/examples/CMakeLists.txt<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/CMakeLists.txt?rev=367756&r1=367755&r2=367756&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/CMakeLists.txt?rev=367756&r1=367755&r2=367756&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/examples/CMakeLists.txt (original)<br>
> +++ llvm/trunk/examples/CMakeLists.txt Sat Aug 3 07:42:13 2019<br>
> @@ -5,6 +5,7 @@ add_subdirectory(HowToUseLLJIT)<br>
> add_subdirectory(LLJITExamples)<br>
> add_subdirectory(Kaleidoscope)<br>
> add_subdirectory(ModuleMaker)<br>
> +add_subdirectory(SpeculativeJIT)<br>
><br>
> if(LLVM_ENABLE_EH AND (NOT WIN32) AND (NOT "${LLVM_NATIVE_ARCH}" STREQUAL "ARM"))<br>
> add_subdirectory(ExceptionDemo)<br>
><br>
> Added: llvm/trunk/examples/SpeculativeJIT/CMakeLists.txt<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/SpeculativeJIT/CMakeLists.txt?rev=367756&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/SpeculativeJIT/CMakeLists.txt?rev=367756&view=auto</a><br>
> ==============================================================================<br>
> --- llvm/trunk/examples/SpeculativeJIT/CMakeLists.txt (added)<br>
> +++ llvm/trunk/examples/SpeculativeJIT/CMakeLists.txt Sat Aug 3 07:42:13 2019<br>
> @@ -0,0 +1,14 @@<br>
> +set(LLVM_LINK_COMPONENTS<br>
> + Core<br>
> + IRReader<br>
> + OrcJIT<br>
> + ExecutionEngine<br>
> + Support<br>
> + nativecodegen<br>
> + Analysis<br>
> + Passes<br>
> + )<br>
> +<br>
> +add_llvm_example(SpeculativeJIT<br>
> + SpeculativeJIT.cpp<br>
> + )<br>
><br>
> Added: llvm/trunk/examples/SpeculativeJIT/SpeculativeJIT.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/SpeculativeJIT/SpeculativeJIT.cpp?rev=367756&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/SpeculativeJIT/SpeculativeJIT.cpp?rev=367756&view=auto</a><br>
> ==============================================================================<br>
> --- llvm/trunk/examples/SpeculativeJIT/SpeculativeJIT.cpp (added)<br>
> +++ llvm/trunk/examples/SpeculativeJIT/SpeculativeJIT.cpp Sat Aug 3 07:42:13 2019<br>
> @@ -0,0 +1,197 @@<br>
> +#include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"<br>
> +#include "llvm/ExecutionEngine/Orc/CompileUtils.h"<br>
> +#include "llvm/ExecutionEngine/Orc/Core.h"<br>
> +#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"<br>
> +#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"<br>
> +#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"<br>
> +#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"<br>
> +#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"<br>
> +#include "llvm/ExecutionEngine/Orc/SpeculateAnalyses.h"<br>
> +#include "llvm/ExecutionEngine/Orc/Speculation.h"<br>
> +#include "llvm/ExecutionEngine/SectionMemoryManager.h"<br>
> +#include "llvm/IRReader/IRReader.h"<br>
> +#include "llvm/Support/CommandLine.h"<br>
> +#include "llvm/Support/Debug.h"<br>
> +#include "llvm/Support/InitLLVM.h"<br>
> +#include "llvm/Support/SourceMgr.h"<br>
> +#include "llvm/Support/TargetSelect.h"<br>
> +#include "llvm/Support/ThreadPool.h"<br>
> +<br>
> +#include <list><br>
> +#include <string><br>
> +<br>
> +using namespace llvm;<br>
> +using namespace llvm::orc;<br>
> +<br>
> +static cl::list<std::string> InputFiles(cl::Positional, cl::OneOrMore,<br>
> + cl::desc("input files"));<br>
> +<br>
> +static cl::list<std::string> InputArgv("args", cl::Positional,<br>
> + cl::desc("<program arguments>..."),<br>
> + cl::ZeroOrMore, cl::PositionalEatsArgs);<br>
> +<br>
> +static cl::opt<unsigned> NumThreads("num-threads", cl::Optional,<br>
> + cl::desc("Number of compile threads"),<br>
> + cl::init(4));<br>
> +<br>
> +ExitOnError ExitOnErr;<br>
> +<br>
> +// Add Layers<br>
> +class SpeculativeJIT {<br>
> +public:<br>
> + static Expected<std::unique_ptr<SpeculativeJIT>> Create() {<br>
> + auto JTMB = orc::JITTargetMachineBuilder::detectHost();<br>
> + if (!JTMB)<br>
> + return JTMB.takeError();<br>
> +<br>
> + auto DL = JTMB->getDefaultDataLayoutForTarget();<br>
> + if (!DL)<br>
> + return DL.takeError();<br>
> +<br>
> + auto ES = llvm::make_unique<ExecutionSession>();<br>
> +<br>
> + auto LCTMgr = createLocalLazyCallThroughManager(<br>
> + JTMB->getTargetTriple(), *ES,<br>
> + pointerToJITTargetAddress(explodeOnLazyCompileFailure));<br>
> + if (!LCTMgr)<br>
> + return LCTMgr.takeError();<br>
> +<br>
> + auto ISMBuilder =<br>
> + createLocalIndirectStubsManagerBuilder(JTMB->getTargetTriple());<br>
> + if (!ISMBuilder)<br>
> + return make_error<StringError>("No indirect stubs manager for target",<br>
> + inconvertibleErrorCode());<br>
> +<br>
> + auto ProcessSymbolsSearchGenerator =<br>
> + DynamicLibrarySearchGenerator::GetForCurrentProcess(<br>
> + DL->getGlobalPrefix());<br>
> + if (!ProcessSymbolsSearchGenerator)<br>
> + return ProcessSymbolsSearchGenerator.takeError();<br>
> +<br>
> + std::unique_ptr<SpeculativeJIT> SJ(new SpeculativeJIT(<br>
> + std::move(ES), std::move(*DL), std::move(*JTMB), std::move(*LCTMgr),<br>
> + std::move(ISMBuilder), std::move(*ProcessSymbolsSearchGenerator)));<br>
> + return std::move(SJ);<br>
> + }<br>
> +<br>
> + ExecutionSession &getES() { return *ES; }<br>
> +<br>
> + Error addModule(JITDylib &JD, ThreadSafeModule TSM) {<br>
> + return CODLayer.add(JD, std::move(TSM));<br>
> + }<br>
> +<br>
> + Expected<JITEvaluatedSymbol> lookup(StringRef UnmangledName) {<br>
> + return ES->lookup({&ES->getMainJITDylib()}, Mangle(UnmangledName));<br>
> + }<br>
> +<br>
> + ~SpeculativeJIT() { CompileThreads.wait(); }<br>
> +<br>
> +private:<br>
> + using IndirectStubsManagerBuilderFunction =<br>
> + std::function<std::unique_ptr<IndirectStubsManager>()>;<br>
> +<br>
> + static void explodeOnLazyCompileFailure() {<br>
> + errs() << "Lazy compilation failed, Symbol Implmentation not found!\n";<br>
> + exit(1);<br>
> + }<br>
> +<br>
> + SpeculativeJIT(std::unique_ptr<ExecutionSession> ES, DataLayout DL,<br>
> + orc::JITTargetMachineBuilder JTMB,<br>
> + std::unique_ptr<LazyCallThroughManager> LCTMgr,<br>
> + IndirectStubsManagerBuilderFunction ISMBuilder,<br>
> + DynamicLibrarySearchGenerator ProcessSymbolsGenerator)<br>
> + : ES(std::move(ES)), DL(std::move(DL)), LCTMgr(std::move(LCTMgr)),<br>
> + CompileLayer(*this->ES, ObjLayer,<br>
> + ConcurrentIRCompiler(std::move(JTMB))),<br>
> + S(Imps, *this->ES),<br>
> + SpeculateLayer(*this->ES, CompileLayer, S, BlockFreqQuery()),<br>
> + CODLayer(*this->ES, SpeculateLayer, *this->LCTMgr,<br>
> + std::move(ISMBuilder)) {<br>
> + this->ES->getMainJITDylib().setGenerator(<br>
> + std::move(ProcessSymbolsGenerator));<br>
> + this->CODLayer.setImplMap(&Imps);<br>
> + this->ES->setDispatchMaterialization(<br>
> +<br>
> + [this](JITDylib &JD, std::unique_ptr<MaterializationUnit> MU) {<br>
> + // FIXME: Switch to move capture once we have c 14.<br>
> + auto SharedMU = std::shared_ptr<MaterializationUnit>(std::move(MU));<br>
> + auto Work = [SharedMU, &JD]() { SharedMU->doMaterialize(JD); };<br>
> + CompileThreads.async(std::move(Work));<br>
> + });<br>
> + JITEvaluatedSymbol SpeculatorSymbol(JITTargetAddress(&S),<br>
> + JITSymbolFlags::Exported);<br>
> + ExitOnErr(this->ES->getMainJITDylib().define(<br>
> + absoluteSymbols({{Mangle("__orc_speculator"), SpeculatorSymbol}})));<br>
> + LocalCXXRuntimeOverrides CXXRuntimeoverrides;<br>
> + ExitOnErr(CXXRuntimeoverrides.enable(this->ES->getMainJITDylib(), Mangle));<br>
> + }<br>
> +<br>
> + static std::unique_ptr<SectionMemoryManager> createMemMgr() {<br>
> + return llvm::make_unique<SectionMemoryManager>();<br>
> + }<br>
> +<br>
> + std::unique_ptr<ExecutionSession> ES;<br>
> + DataLayout DL;<br>
> + MangleAndInterner Mangle{*ES, DL};<br>
> + ThreadPool CompileThreads{NumThreads};<br>
> +<br>
> + Triple TT;<br>
> + std::unique_ptr<LazyCallThroughManager> LCTMgr;<br>
> + IRCompileLayer CompileLayer;<br>
> + ImplSymbolMap Imps;<br>
> + Speculator S;<br>
> + RTDyldObjectLinkingLayer ObjLayer{*ES, createMemMgr};<br>
> + IRSpeculationLayer SpeculateLayer;<br>
> + CompileOnDemandLayer CODLayer;<br>
> +};<br>
> +<br>
> +int main(int argc, char *argv[]) {<br>
> + // Initialize LLVM.<br>
> + InitLLVM X(argc, argv);<br>
> +<br>
> + InitializeNativeTarget();<br>
> + InitializeNativeTargetAsmPrinter();<br>
> +<br>
> + cl::ParseCommandLineOptions(argc, argv, "SpeculativeJIT");<br>
> + ExitOnErr.setBanner(std::string(argv[0]) + ": ");<br>
> +<br>
> + if (NumThreads < 1) {<br>
> + errs() << "Speculative compilation requires one or more dedicated compile "<br>
> + "threads\n";<br>
> + return 1;<br>
> + }<br>
> +<br>
> + // Create a JIT instance.<br>
> + auto SJ = ExitOnErr(SpeculativeJIT::Create());<br>
> +<br>
> + // Load the IR inputs.<br>
> + for (const auto &InputFile : InputFiles) {<br>
> + SMDiagnostic Err;<br>
> + auto Ctx = llvm::make_unique<LLVMContext>();<br>
> + auto M = parseIRFile(InputFile, Err, *Ctx);<br>
> + if (!M) {<br>
> + Err.print(argv[0], errs());<br>
> + return 1;<br>
> + }<br>
> +<br>
> + ExitOnErr(SJ->addModule(SJ->getES().getMainJITDylib(),<br>
> + ThreadSafeModule(std::move(M), std::move(Ctx))));<br>
> + }<br>
> +<br>
> + // Build an argv array for the JIT'd main.<br>
> + std::vector<const char *> ArgV;<br>
> + ArgV.push_back(argv[0]);<br>
> + for (const auto &InputArg : InputArgv)<br>
> + ArgV.push_back(InputArg.data());<br>
> + ArgV.push_back(nullptr);<br>
> +<br>
> + // Look up the JIT'd main, cast it to a function pointer, then call it.<br>
> +<br>
> + auto MainSym = ExitOnErr(SJ->lookup("main"));<br>
> + int (*Main)(int, const char *[]) =<br>
> + (int (*)(int, const char *[]))MainSym.getAddress();<br>
> +<br>
> + Main(ArgV.size() - 1, ArgV.data());<br>
> +<br>
> + return 0;<br>
> +}<br>
><br>
> Modified: llvm/trunk/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h?rev=367756&r1=367755&r2=367756&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h?rev=367756&r1=367755&r2=367756&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h (original)<br>
> +++ llvm/trunk/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h Sat Aug 3 07:42:13 2019<br>
> @@ -26,6 +26,7 @@<br>
> #include "llvm/ExecutionEngine/Orc/LazyReexports.h"<br>
> #include "llvm/ExecutionEngine/Orc/Legacy.h"<br>
> #include "llvm/ExecutionEngine/Orc/OrcError.h"<br>
> +#include "llvm/ExecutionEngine/Orc/Speculation.h"<br>
> #include "llvm/ExecutionEngine/RuntimeDyld.h"<br>
> #include "llvm/IR/Attributes.h"<br>
> #include "llvm/IR/Constant.h"<br>
> @@ -91,6 +92,8 @@ public:<br>
> /// Sets the partition function.<br>
> void setPartitionFunction(PartitionFunction Partition);<br>
><br>
> + /// Sets the ImplSymbolMap<br>
> + void setImplMap(ImplSymbolMap *Imp);<br>
> /// Emits the given module. This should not be called by clients: it will be<br>
> /// called by the JIT when a definition added via the add method is requested.<br>
> void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override;<br>
> @@ -128,6 +131,7 @@ private:<br>
> PerDylibResourcesMap DylibResources;<br>
> PartitionFunction Partition = compileRequested;<br>
> SymbolLinkagePromoter PromoteSymbols;<br>
> + ImplSymbolMap *AliaseeImpls = nullptr;<br>
> };<br>
><br>
> /// Compile-on-demand layer.<br>
><br>
> Modified: llvm/trunk/include/llvm/ExecutionEngine/Orc/LazyReexports.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/LazyReexports.h?rev=367756&r1=367755&r2=367756&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/LazyReexports.h?rev=367756&r1=367755&r2=367756&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/ExecutionEngine/Orc/LazyReexports.h (original)<br>
> +++ llvm/trunk/include/llvm/ExecutionEngine/Orc/LazyReexports.h Sat Aug 3 07:42:13 2019<br>
> @@ -18,6 +18,7 @@<br>
><br>
> #include "llvm/ExecutionEngine/Orc/Core.h"<br>
> #include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"<br>
> +#include "llvm/ExecutionEngine/Orc/Speculation.h"<br>
><br>
> namespace llvm {<br>
><br>
> @@ -159,7 +160,7 @@ public:<br>
> IndirectStubsManager &ISManager,<br>
> JITDylib &SourceJD,<br>
> SymbolAliasMap CallableAliases,<br>
> - VModuleKey K);<br>
> + ImplSymbolMap *SrcJDLoc, VModuleKey K);<br>
><br>
> StringRef getName() const override;<br>
><br>
> @@ -174,6 +175,7 @@ private:<br>
> SymbolAliasMap CallableAliases;<br>
> std::shared_ptr<LazyCallThroughManager::NotifyResolvedFunction><br>
> NotifyResolved;<br>
> + ImplSymbolMap *AliaseeTable;<br>
> };<br>
><br>
> /// Define lazy-reexports based on the given SymbolAliasMap. Each lazy re-export<br>
> @@ -182,9 +184,10 @@ private:<br>
> inline std::unique_ptr<LazyReexportsMaterializationUnit><br>
> lazyReexports(LazyCallThroughManager &LCTManager,<br>
> IndirectStubsManager &ISManager, JITDylib &SourceJD,<br>
> - SymbolAliasMap CallableAliases, VModuleKey K = VModuleKey()) {<br>
> + SymbolAliasMap CallableAliases, ImplSymbolMap *SrcJDLoc = nullptr,<br>
> + VModuleKey K = VModuleKey()) {<br>
> return llvm::make_unique<LazyReexportsMaterializationUnit>(<br>
> - LCTManager, ISManager, SourceJD, std::move(CallableAliases),<br>
> + LCTManager, ISManager, SourceJD, std::move(CallableAliases), SrcJDLoc,<br>
> std::move(K));<br>
> }<br>
><br>
><br>
> Added: llvm/trunk/include/llvm/ExecutionEngine/Orc/SpeculateAnalyses.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/SpeculateAnalyses.h?rev=367756&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/SpeculateAnalyses.h?rev=367756&view=auto</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/ExecutionEngine/Orc/SpeculateAnalyses.h (added)<br>
> +++ llvm/trunk/include/llvm/ExecutionEngine/Orc/SpeculateAnalyses.h Sat Aug 3 07:42:13 2019<br>
> @@ -0,0 +1,72 @@<br>
> +//===-- SpeculateAnalyses.h --*- C++ -*-===//<br>
> +//<br>
> +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.<br>
> +// See <a href="https://llvm.org/LICENSE.txt" rel="noreferrer" target="_blank">https://llvm.org/LICENSE.txt</a> for license information.<br>
> +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception<br>
> +//<br>
> +//===----------------------------------------------------------------------===//<br>
> +// \file<br>
> +/// Contains the Analyses and Result Interpretation to select likely functions<br>
> +/// to Speculatively compile before they are called. [Experimentation]<br>
> +//===----------------------------------------------------------------------===//<br>
> +<br>
> +#ifndef LLVM_EXECUTIONENGINE_ORC_SPECULATEANALYSES_H<br>
> +#define LLVM_EXECUTIONENGINE_ORC_SPECULATEANALYSES_H<br>
> +<br>
> +#include "llvm/ExecutionEngine/Orc/Core.h"<br>
> +#include "llvm/ExecutionEngine/Orc/Speculation.h"<br>
> +<br>
> +#include <vector><br>
> +<br>
> +namespace {<br>
> +using namespace llvm;<br>
> +std::vector<const BasicBlock *> findBBwithCalls(const Function &F,<br>
> + bool IndirectCall = false) {<br>
> + std::vector<const BasicBlock *> BBs;<br>
> +<br>
> + auto findCallInst = [&IndirectCall](const Instruction &I) {<br>
> + if (auto Call = dyn_cast<CallBase>(&I)) {<br>
> + if (Call->isIndirectCall())<br>
> + return IndirectCall;<br>
> + else<br>
> + return true;<br>
> + } else<br>
> + return false;<br>
> + };<br>
> + for (auto &BB : F)<br>
> + if (findCallInst(*BB.getTerminator()) ||<br>
> + llvm::any_of(BB.instructionsWithoutDebug(), findCallInst))<br>
> + BBs.emplace_back(&BB);<br>
> +<br>
> + return BBs;<br>
> +}<br>
> +} // namespace<br>
> +<br>
> +namespace llvm {<br>
> +<br>
> +namespace orc {<br>
> +<br>
> +// Direct calls in high frequency basic blocks are extracted.<br>
> +class BlockFreqQuery {<br>
> +private:<br>
> + void findCalles(const BasicBlock *, DenseSet<StringRef> &);<br>
> + size_t numBBToGet(size_t);<br>
> +<br>
> +public:<br>
> + using ResultTy = Optional<DenseMap<StringRef, DenseSet<StringRef>>>;<br>
> +<br>
> + // Find likely next executables based on IR Block Frequency<br>
> + ResultTy operator()(Function &F, FunctionAnalysisManager &FAM);<br>
> +};<br>
> +<br>
> +// Walk the CFG by exploting BranchProbabilityInfo<br>
> +class CFGWalkQuery {<br>
> +public:<br>
> + using ResultTy = Optional<DenseMap<StringRef, DenseSet<StringRef>>>;<br>
> + ResultTy operator()(Function &F, FunctionAnalysisManager &FAM);<br>
> +};<br>
> +<br>
> +} // namespace orc<br>
> +} // namespace llvm<br>
> +<br>
> +#endif // LLVM_EXECUTIONENGINE_ORC_SPECULATEANALYSES_H<br>
><br>
> Added: llvm/trunk/include/llvm/ExecutionEngine/Orc/Speculation.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/Speculation.h?rev=367756&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/Speculation.h?rev=367756&view=auto</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/ExecutionEngine/Orc/Speculation.h (added)<br>
> +++ llvm/trunk/include/llvm/ExecutionEngine/Orc/Speculation.h Sat Aug 3 07:42:13 2019<br>
> @@ -0,0 +1,208 @@<br>
> +//===-- Speculation.h - Speculative Compilation --*- C++ -*-===//<br>
> +//<br>
> +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.<br>
> +// See <a href="https://llvm.org/LICENSE.txt" rel="noreferrer" target="_blank">https://llvm.org/LICENSE.txt</a> for license information.<br>
> +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception<br>
> +//<br>
> +//===----------------------------------------------------------------------===//<br>
> +//<br>
> +// Contains the definition to support speculative compilation when laziness is<br>
> +// enabled.<br>
> +//===----------------------------------------------------------------------===//<br>
> +<br>
> +#ifndef LLVM_EXECUTIONENGINE_ORC_SPECULATION_H<br>
> +#define LLVM_EXECUTIONENGINE_ORC_SPECULATION_H<br>
> +<br>
> +#include "llvm/ADT/ArrayRef.h"<br>
> +#include "llvm/ADT/DenseMap.h"<br>
> +#include "llvm/ADT/Optional.h"<br>
> +#include "llvm/ExecutionEngine/Orc/Core.h"<br>
> +#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"<br>
> +#include "llvm/IR/PassManager.h"<br>
> +#include "llvm/Passes/PassBuilder.h"<br>
> +<br>
> +#include <mutex><br>
> +#include <type_traits><br>
> +#include <utility><br>
> +#include <vector><br>
> +<br>
> +namespace llvm {<br>
> +namespace orc {<br>
> +<br>
> +class Speculator;<br>
> +<br>
> +// Track the Impls (JITDylib,Symbols) of Symbols while lazy call through<br>
> +// trampolines are created. Operations are guarded by locks tp ensure that Imap<br>
> +// stays in consistent state after read/write<br>
> +<br>
> +class ImplSymbolMap {<br>
> + friend class Speculator;<br>
> +<br>
> +public:<br>
> + using AliaseeDetails = std::pair<SymbolStringPtr, JITDylib *>;<br>
> + using Alias = SymbolStringPtr;<br>
> + using ImapTy = DenseMap<Alias, AliaseeDetails>;<br>
> + void trackImpls(SymbolAliasMap ImplMaps, JITDylib *SrcJD);<br>
> +<br>
> +private:<br>
> + // FIX ME: find a right way to distinguish the pre-compile Symbols, and update<br>
> + // the callsite<br>
> + Optional<AliaseeDetails> getImplFor(const SymbolStringPtr &StubSymbol) {<br>
> + std::lock_guard<std::mutex> Lockit(ConcurrentAccess);<br>
> + auto Position = Maps.find(StubSymbol);<br>
> + if (Position != Maps.end())<br>
> + return Position->getSecond();<br>
> + else<br>
> + return None;<br>
> + }<br>
> +<br>
> + std::mutex ConcurrentAccess;<br>
> + ImapTy Maps;<br>
> +};<br>
> +<br>
> +// Defines Speculator Concept,<br>
> +class Speculator {<br>
> +public:<br>
> + using TargetFAddr = JITTargetAddress;<br>
> + using FunctionCandidatesMap = DenseMap<SymbolStringPtr, SymbolNameSet>;<br>
> + using StubAddrLikelies = DenseMap<TargetFAddr, SymbolNameSet>;<br>
> +<br>
> +private:<br>
> + void registerSymbolsWithAddr(TargetFAddr ImplAddr,<br>
> + SymbolNameSet likelySymbols) {<br>
> + std::lock_guard<std::mutex> Lockit(ConcurrentAccess);<br>
> + GlobalSpecMap.insert({ImplAddr, std::move(likelySymbols)});<br>
> + }<br>
> +<br>
> + void launchCompile(JITTargetAddress FAddr) {<br>
> + SymbolNameSet CandidateSet;<br>
> + // Copy CandidateSet is necessary, to avoid unsynchronized access to<br>
> + // the datastructure.<br>
> + {<br>
> + std::lock_guard<std::mutex> Lockit(ConcurrentAccess);<br>
> + auto It = GlobalSpecMap.find(FAddr);<br>
> + // Kill this when jump on first call instrumentation is in place;<br>
> + auto Iv = AlreadyExecuted.insert(FAddr);<br>
> + if (It == GlobalSpecMap.end() || Iv.second == false)<br>
> + return;<br>
> + else<br>
> + CandidateSet = It->getSecond();<br>
> + }<br>
> +<br>
> + // Try to distinguish pre-compiled symbols!<br>
> + for (auto &Callee : CandidateSet) {<br>
> + auto ImplSymbol = AliaseeImplTable.getImplFor(Callee);<br>
> + if (!ImplSymbol.hasValue())<br>
> + continue;<br>
> + const auto &ImplSymbolName = ImplSymbol.getPointer()->first;<br>
> + auto *ImplJD = ImplSymbol.getPointer()->second;<br>
> + ES.lookup(JITDylibSearchList({{ImplJD, true}}),<br>
> + SymbolNameSet({ImplSymbolName}), SymbolState::Ready,<br>
> + [this](Expected<SymbolMap> Result) {<br>
> + if (auto Err = Result.takeError())<br>
> + ES.reportError(std::move(Err));<br>
> + },<br>
> + NoDependenciesToRegister);<br>
> + }<br>
> + }<br>
> +<br>
> +public:<br>
> + Speculator(ImplSymbolMap &Impl, ExecutionSession &ref)<br>
> + : AliaseeImplTable(Impl), ES(ref), GlobalSpecMap(0) {}<br>
> + Speculator(const Speculator &) = delete;<br>
> + Speculator(Speculator &&) = delete;<br>
> + Speculator &operator=(const Speculator &) = delete;<br>
> + Speculator &operator=(Speculator &&) = delete;<br>
> + ~Speculator() {}<br>
> +<br>
> + // Speculatively compile likely functions for the given Stub Address.<br>
> + // destination of __orc_speculate_for jump<br>
> + void speculateFor(TargetFAddr StubAddr) { launchCompile(StubAddr); }<br>
> +<br>
> + // FIXME : Register with Stub Address, after JITLink Fix.<br>
> + void registerSymbols(FunctionCandidatesMap Candidates, JITDylib *JD) {<br>
> + for (auto &SymPair : Candidates) {<br>
> + auto Target = SymPair.first;<br>
> + auto Likely = SymPair.second;<br>
> +<br>
> + auto OnReadyFixUp = [Likely, Target,<br>
> + this](Expected<SymbolMap> ReadySymbol) {<br>
> + if (ReadySymbol) {<br>
> + auto RAddr = (*ReadySymbol)[Target].getAddress();<br>
> + registerSymbolsWithAddr(RAddr, std::move(Likely));<br>
> + } else<br>
> + this->getES().reportError(ReadySymbol.takeError());<br>
> + };<br>
> + // Include non-exported symbols also.<br>
> + ES.lookup(JITDylibSearchList({{JD, true}}), SymbolNameSet({Target}),<br>
> + SymbolState::Ready, OnReadyFixUp, NoDependenciesToRegister);<br>
> + }<br>
> + }<br>
> +<br>
> + ExecutionSession &getES() { return ES; }<br>
> +<br>
> +private:<br>
> + std::mutex ConcurrentAccess;<br>
> + ImplSymbolMap &AliaseeImplTable;<br>
> + ExecutionSession &ES;<br>
> + DenseSet<TargetFAddr> AlreadyExecuted;<br>
> + StubAddrLikelies GlobalSpecMap;<br>
> +};<br>
> +// replace DenseMap with Pair<br>
> +class IRSpeculationLayer : public IRLayer {<br>
> +public:<br>
> + using IRlikiesStrRef = Optional<DenseMap<StringRef, DenseSet<StringRef>>>;<br>
> + using ResultEval =<br>
> + std::function<IRlikiesStrRef(Function &, FunctionAnalysisManager &)>;<br>
> + using TargetAndLikelies = DenseMap<SymbolStringPtr, SymbolNameSet>;<br>
> +<br>
> + IRSpeculationLayer(ExecutionSession &ES, IRCompileLayer &BaseLayer,<br>
> + Speculator &Spec, ResultEval Interpreter)<br>
> + : IRLayer(ES), NextLayer(BaseLayer), S(Spec), QueryAnalysis(Interpreter) {<br>
> + PB.registerFunctionAnalyses(FAM);<br>
> + }<br>
> +<br>
> + template <<br>
> + typename AnalysisTy,<br>
> + typename std::enable_if<<br>
> + std::is_base_of<AnalysisInfoMixin<AnalysisTy>, AnalysisTy>::value,<br>
> + bool>::type = true><br>
> + void registerAnalysis() {<br>
> + FAM.registerPass([]() { return AnalysisTy(); });<br>
> + }<br>
> +<br>
> + void emit(MaterializationResponsibility R, ThreadSafeModule TSM);<br>
> +<br>
> +private:<br>
> + TargetAndLikelies<br>
> + internToJITSymbols(DenseMap<StringRef, DenseSet<StringRef>> IRNames) {<br>
> + assert(!IRNames.empty() && "No IRNames received to Intern?");<br>
> + TargetAndLikelies InternedNames;<br>
> + DenseSet<SymbolStringPtr> TargetJITNames;<br>
> + ExecutionSession &Es = getExecutionSession();<br>
> + for (auto &NamePair : IRNames) {<br>
> + for (auto &TargetNames : NamePair.second)<br>
> + TargetJITNames.insert(Es.intern(TargetNames));<br>
> +<br>
> + InternedNames.insert(<br>
> + {Es.intern(NamePair.first), std::move(TargetJITNames)});<br>
> + }<br>
> + return InternedNames;<br>
> + }<br>
> +<br>
> + IRCompileLayer &NextLayer;<br>
> + Speculator &S;<br>
> + PassBuilder PB;<br>
> + FunctionAnalysisManager FAM;<br>
> + ResultEval QueryAnalysis;<br>
> +};<br>
> +<br>
> +// Runtime Function Interface<br>
> +extern "C" {<br>
> +void __orc_speculate_for(Speculator *, uint64_t stub_id);<br>
> +}<br>
> +<br>
> +} // namespace orc<br>
> +} // namespace llvm<br>
> +<br>
> +#endif // LLVM_EXECUTIONENGINE_ORC_SPECULATION_H<br>
><br>
> Modified: llvm/trunk/lib/ExecutionEngine/Orc/CMakeLists.txt<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/CMakeLists.txt?rev=367756&r1=367755&r2=367756&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/CMakeLists.txt?rev=367756&r1=367755&r2=367756&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/ExecutionEngine/Orc/CMakeLists.txt (original)<br>
> +++ llvm/trunk/lib/ExecutionEngine/Orc/CMakeLists.txt Sat Aug 3 07:42:13 2019<br>
> @@ -21,7 +21,8 @@ add_llvm_library(LLVMOrcJIT<br>
> RPCUtils.cpp<br>
> RTDyldObjectLinkingLayer.cpp<br>
> ThreadSafeModule.cpp<br>
> -<br>
> + Speculation.cpp<br>
> + SpeculateAnalyses.cpp<br>
> ADDITIONAL_HEADER_DIRS<br>
> ${LLVM_MAIN_INCLUDE_DIR}/llvm/ExecutionEngine/Orc<br>
><br>
> @@ -31,6 +32,7 @@ add_llvm_library(LLVMOrcJIT<br>
><br>
> target_link_libraries(LLVMOrcJIT<br>
> PRIVATE<br>
> + LLVMAnalysis<br>
> LLVMBitReader<br>
> LLVMBitWriter<br>
> )<br>
><br>
> Modified: llvm/trunk/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp?rev=367756&r1=367755&r2=367756&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp?rev=367756&r1=367755&r2=367756&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp (original)<br>
> +++ llvm/trunk/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp Sat Aug 3 07:42:13 2019<br>
> @@ -118,6 +118,9 @@ void CompileOnDemandLayer::setPartitionF<br>
> this->Partition = std::move(Partition);<br>
> }<br>
><br>
> +void CompileOnDemandLayer::setImplMap(ImplSymbolMap *Imp) {<br>
> + this->AliaseeImpls = Imp;<br>
> +}<br>
> void CompileOnDemandLayer::emit(MaterializationResponsibility R,<br>
> ThreadSafeModule TSM) {<br>
> assert(TSM && "Null module");<br>
> @@ -161,7 +164,7 @@ void CompileOnDemandLayer::emit(Material<br>
><br>
> R.replace(reexports(PDR.getImplDylib(), std::move(NonCallables), true));<br>
> R.replace(lazyReexports(LCTMgr, PDR.getISManager(), PDR.getImplDylib(),<br>
> - std::move(Callables)));<br>
> + std::move(Callables), AliaseeImpls));<br>
> }<br>
><br>
> CompileOnDemandLayer::PerDylibResources &<br>
><br>
> Modified: llvm/trunk/lib/ExecutionEngine/Orc/LazyReexports.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/LazyReexports.cpp?rev=367756&r1=367755&r2=367756&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/LazyReexports.cpp?rev=367756&r1=367755&r2=367756&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/ExecutionEngine/Orc/LazyReexports.cpp (original)<br>
> +++ llvm/trunk/lib/ExecutionEngine/Orc/LazyReexports.cpp Sat Aug 3 07:42:13 2019<br>
> @@ -50,7 +50,6 @@ LazyCallThroughManager::callThroughToSym<br>
> SourceJD = I->second.first;<br>
> SymbolName = I->second.second;<br>
> }<br>
> -<br>
> auto LookupResult =<br>
> ES.lookup(JITDylibSearchList({{SourceJD, true}}), SymbolName);<br>
><br>
> @@ -121,7 +120,8 @@ createLocalLazyCallThroughManager(const<br>
><br>
> LazyReexportsMaterializationUnit::LazyReexportsMaterializationUnit(<br>
> LazyCallThroughManager &LCTManager, IndirectStubsManager &ISManager,<br>
> - JITDylib &SourceJD, SymbolAliasMap CallableAliases, VModuleKey K)<br>
> + JITDylib &SourceJD, SymbolAliasMap CallableAliases, ImplSymbolMap *SrcJDLoc,<br>
> + VModuleKey K)<br>
> : MaterializationUnit(extractFlags(CallableAliases), std::move(K)),<br>
> LCTManager(LCTManager), ISManager(ISManager), SourceJD(SourceJD),<br>
> CallableAliases(std::move(CallableAliases)),<br>
> @@ -129,7 +129,8 @@ LazyReexportsMaterializationUnit::LazyRe<br>
> [&ISManager](JITDylib &JD, const SymbolStringPtr &SymbolName,<br>
> JITTargetAddress ResolvedAddr) {<br>
> return ISManager.updatePointer(*SymbolName, ResolvedAddr);<br>
> - })) {}<br>
> + })),<br>
> + AliaseeTable(SrcJDLoc) {}<br>
><br>
> StringRef LazyReexportsMaterializationUnit::getName() const {<br>
> return "<Lazy Reexports>";<br>
> @@ -149,7 +150,7 @@ void LazyReexportsMaterializationUnit::m<br>
><br>
> if (!CallableAliases.empty())<br>
> R.replace(lazyReexports(LCTManager, ISManager, SourceJD,<br>
> - std::move(CallableAliases)));<br>
> + std::move(CallableAliases), AliaseeTable));<br>
><br>
> IndirectStubsManager::StubInitsMap StubInits;<br>
> for (auto &Alias : RequestedAliases) {<br>
> @@ -168,6 +169,9 @@ void LazyReexportsMaterializationUnit::m<br>
> std::make_pair(*CallThroughTrampoline, Alias.second.AliasFlags);<br>
> }<br>
><br>
> + if (AliaseeTable != nullptr && !RequestedAliases.empty())<br>
> + AliaseeTable->trackImpls(RequestedAliases, &SourceJD);<br>
> +<br>
> if (auto Err = ISManager.createStubs(StubInits)) {<br>
> SourceJD.getExecutionSession().reportError(std::move(Err));<br>
> R.failMaterialization();<br>
><br>
> Added: llvm/trunk/lib/ExecutionEngine/Orc/SpeculateAnalyses.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/SpeculateAnalyses.cpp?rev=367756&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/SpeculateAnalyses.cpp?rev=367756&view=auto</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/ExecutionEngine/Orc/SpeculateAnalyses.cpp (added)<br>
> +++ llvm/trunk/lib/ExecutionEngine/Orc/SpeculateAnalyses.cpp Sat Aug 3 07:42:13 2019<br>
> @@ -0,0 +1,87 @@<br>
> +//===-- SpeculateAnalyses.cpp --*- C++ -*-===//<br>
> +//<br>
> +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.<br>
> +// See <a href="https://llvm.org/LICENSE.txt" rel="noreferrer" target="_blank">https://llvm.org/LICENSE.txt</a> for license information.<br>
> +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception<br>
> +//<br>
> +//===----------------------------------------------------------------------===//<br>
> +<br>
> +#include "llvm/ExecutionEngine/Orc/SpeculateAnalyses.h"<br>
> +#include "llvm/ADT/DenseMap.h"<br>
> +#include "llvm/ADT/STLExtras.h"<br>
> +#include "llvm/ADT/SmallVector.h"<br>
> +#include "llvm/Analysis/BlockFrequencyInfo.h"<br>
> +<br>
> +// Implementations of Queries shouldn't need to lock the resources<br>
> +// such as LLVMContext, each argument (function) has a non-shared LLVMContext<br>
> +namespace llvm {<br>
> +namespace orc {<br>
> +<br>
> +// Collect direct calls only<br>
> +void BlockFreqQuery::findCalles(const BasicBlock *BB,<br>
> + DenseSet<StringRef> &CallesNames) {<br>
> + assert(BB != nullptr && "Traversing Null BB to find calls?");<br>
> +<br>
> + auto getCalledFunction = [&CallesNames](const CallBase *Call) {<br>
> + auto CalledValue = Call->getCalledOperand()->stripPointerCasts();<br>
> + if (auto DirectCall = dyn_cast<Function>(CalledValue))<br>
> + CallesNames.insert(DirectCall->getName());<br>
> + };<br>
> + for (auto &I : BB->instructionsWithoutDebug())<br>
> + if (auto CI = dyn_cast<CallInst>(&I))<br>
> + getCalledFunction(CI);<br>
> +<br>
> + if (auto II = dyn_cast<InvokeInst>(BB->getTerminator()))<br>
> + getCalledFunction(II);<br>
> +}<br>
> +<br>
> +// blind calculation<br>
> +size_t BlockFreqQuery::numBBToGet(size_t numBB) {<br>
> + // small CFG<br>
> + if (numBB < 4)<br>
> + return numBB;<br>
> + // mid-size CFG<br>
> + else if (numBB < 20)<br>
> + return (numBB / 2);<br>
> + else<br>
> + return (numBB / 2) + (numBB / 4);<br>
> +}<br>
> +<br>
> +BlockFreqQuery::ResultTy BlockFreqQuery::<br>
> +operator()(Function &F, FunctionAnalysisManager &FAM) {<br>
> + DenseMap<StringRef, DenseSet<StringRef>> CallerAndCalles;<br>
> + DenseSet<StringRef> Calles;<br>
> + SmallVector<std::pair<const BasicBlock *, uint64_t>, 8> BBFreqs;<br>
> +<br>
> + auto IBBs = findBBwithCalls(F);<br>
> +<br>
> + if (IBBs.empty())<br>
> + return None;<br>
> +<br>
> + auto &BFI = FAM.getResult<BlockFrequencyAnalysis>(F);<br>
> +<br>
> + for (const auto I : IBBs)<br>
> + BBFreqs.push_back({I, BFI.getBlockFreq(I).getFrequency()});<br>
> +<br>
> + assert(IBBs.size() == BBFreqs.size() && "BB Count Mismatch");<br>
> +<br>
> + llvm::sort(BBFreqs.begin(), BBFreqs.end(),<br>
> + [](decltype(BBFreqs)::const_reference BBF,<br>
> + decltype(BBFreqs)::const_reference BBS) {<br>
> + return BBF.second > BBS.second ? true : false;<br>
> + });<br>
> +<br>
> + // ignoring number of direct calls in a BB<br>
> + auto Topk = numBBToGet(BBFreqs.size());<br>
> +<br>
> + for (size_t i = 0; i < Topk; i++)<br>
> + findCalles(BBFreqs[i].first, Calles);<br>
> +<br>
> + assert(!Calles.empty() && "Running Analysis on Function with no calls?");<br>
> +<br>
> + CallerAndCalles.insert({F.getName(), std::move(Calles)});<br>
> +<br>
> + return CallerAndCalles;<br>
> +}<br>
> +} // namespace orc<br>
> +} // namespace llvm<br>
><br>
> Added: llvm/trunk/lib/ExecutionEngine/Orc/Speculation.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/Speculation.cpp?rev=367756&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/Speculation.cpp?rev=367756&view=auto</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/ExecutionEngine/Orc/Speculation.cpp (added)<br>
> +++ llvm/trunk/lib/ExecutionEngine/Orc/Speculation.cpp Sat Aug 3 07:42:13 2019<br>
> @@ -0,0 +1,97 @@<br>
> +//===---------- speculation.cpp - Utilities for Speculation ----------===//<br>
> +//<br>
> +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.<br>
> +// See <a href="https://llvm.org/LICENSE.txt" rel="noreferrer" target="_blank">https://llvm.org/LICENSE.txt</a> for license information.<br>
> +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception<br>
> +//<br>
> +//===----------------------------------------------------------------------===//<br>
> +<br>
> +#include "llvm/ExecutionEngine/Orc/Speculation.h"<br>
> +<br>
> +#include "llvm/IR/BasicBlock.h"<br>
> +#include "llvm/IR/Function.h"<br>
> +#include "llvm/IR/IRBuilder.h"<br>
> +#include "llvm/IR/Instruction.h"<br>
> +#include "llvm/IR/Instructions.h"<br>
> +#include "llvm/IR/LLVMContext.h"<br>
> +#include "llvm/IR/Module.h"<br>
> +#include "llvm/IR/Type.h"<br>
> +#include "llvm/IR/Verifier.h"<br>
> +<br>
> +#include <vector><br>
> +<br>
> +namespace llvm {<br>
> +<br>
> +namespace orc {<br>
> +<br>
> +// ImplSymbolMap methods<br>
> +void ImplSymbolMap::trackImpls(SymbolAliasMap ImplMaps, JITDylib *SrcJD) {<br>
> + assert(SrcJD && "Tracking on Null Source .impl dylib");<br>
> + std::lock_guard<std::mutex> Lockit(ConcurrentAccess);<br>
> + for (auto &I : ImplMaps) {<br>
> + auto It = Maps.insert({I.first, {I.second.Aliasee, SrcJD}});<br>
> + // check rationale when independent dylibs have same symbol name?<br>
> + assert(It.second && "ImplSymbols are already tracked for this Symbol?");<br>
> + (void)(It);<br>
> + }<br>
> +}<br>
> +<br>
> +// If two modules, share the same LLVMContext, different threads must<br>
> +// not access those modules concurrently, doing so leave the<br>
> +// LLVMContext in in-consistent state.<br>
> +// But here since each TSM has a unique Context associated with it,<br>
> +// on locking is necessary!<br>
> +void IRSpeculationLayer::emit(MaterializationResponsibility R,<br>
> + ThreadSafeModule TSM) {<br>
> +<br>
> + assert(TSM && "Speculation Layer received Null Module ?");<br>
> + assert(TSM.getContext().getContext() != nullptr &&<br>
> + "Module with null LLVMContext?");<br>
> +<br>
> + // Instrumentation of runtime calls<br>
> + auto &InContext = *TSM.getContext().getContext();<br>
> + auto SpeculatorVTy = StructType::create(InContext, "Class.Speculator");<br>
> + auto RuntimeCallTy = FunctionType::get(<br>
> + Type::getVoidTy(InContext),<br>
> + {SpeculatorVTy->getPointerTo(), Type::getInt64Ty(InContext)}, false);<br>
> + auto RuntimeCall =<br>
> + Function::Create(RuntimeCallTy, Function::LinkageTypes::ExternalLinkage,<br>
> + "__orc_speculate_for", TSM.getModuleUnlocked());<br>
> + auto SpeclAddr = new GlobalVariable(<br>
> + *TSM.getModuleUnlocked(), SpeculatorVTy, false,<br>
> + GlobalValue::LinkageTypes::ExternalLinkage, nullptr, "__orc_speculator");<br>
> +<br>
> + IRBuilder<> Mutator(InContext);<br>
> +<br>
> + // QueryAnalysis allowed to transform the IR source, one such example is<br>
> + // Simplify CFG helps the static branch prediction heuristics!<br>
> + for (auto &Fn : TSM.getModuleUnlocked()->getFunctionList()) {<br>
> + if (!Fn.isDeclaration()) {<br>
> + auto IRNames = QueryAnalysis(Fn, FAM);<br>
> + // Instrument and register if Query has result<br>
> + if (IRNames.hasValue()) {<br>
> + Mutator.SetInsertPoint(&(Fn.getEntryBlock().front()));<br>
> + auto ImplAddrToUint =<br>
> + Mutator.CreatePtrToInt(&Fn, Type::getInt64Ty(InContext));<br>
> + Mutator.CreateCall(RuntimeCallTy, RuntimeCall,<br>
> + {SpeclAddr, ImplAddrToUint});<br>
> + S.registerSymbols(internToJITSymbols(IRNames.getValue()),<br>
> + &R.getTargetJITDylib());<br>
> + }<br>
> + }<br>
> + }<br>
> + // No locking needed read only operation.<br>
> + assert(!(verifyModule(*TSM.getModuleUnlocked())) &&<br>
> + "Speculation Instrumentation breaks IR?");<br>
> +<br>
> + NextLayer.emit(std::move(R), std::move(TSM));<br>
> +}<br>
> +<br>
> +// Runtime Function Implementation<br>
> +extern "C" void __orc_speculate_for(Speculator *Ptr, uint64_t StubId) {<br>
> + assert(Ptr && " Null Address Received in orc_speculate_for ");<br>
> + Ptr->speculateFor(StubId);<br>
> +}<br>
> +<br>
> +} // namespace orc<br>
> +} // namespace llvm<br>
><br>
><br>
> _______________________________________________<br>
> llvm-commits mailing list<br>
> <a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
> <a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div>