<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>