<commit_before>//===-- JITEmitter.cpp - Write machine code to executable memory ----------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines a MachineCodeEmitter object that is used by the JIT to
// write machine code to memory and remember where relocatable values are.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "jit"
#include "JIT.h"
#include "JITDwarfEmitter.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/Constants.h"
#include "llvm/Module.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Analysis/DebugInfo.h"
#include "llvm/CodeGen/JITCodeEmitter.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineCodeInfo.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRelocation.h"
#include "llvm/ExecutionEngine/GenericValue.h"
#include "llvm/ExecutionEngine/JITEventListener.h"
#include "llvm/ExecutionEngine/JITMemoryManager.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetJITInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MutexGuard.h"
#include "llvm/Support/ValueHandle.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Disassembler.h"
#include "llvm/Support/Memory.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/ValueMap.h"
#include <algorithm>
#ifndef NDEBUG
#include <iomanip>
#endif
using namespace llvm;

STATISTIC(NumBytes, "Number of bytes of machine code compiled");
STATISTIC(NumRelos, "Number of relocations applied");
STATISTIC(NumRetries, "Number of retries with more memory");


// A declaration may stop being a declaration once it's fully read from bitcode.
// This function returns true if F is fully read and is still a declaration.
static bool isNonGhostDeclaration(const Function *F) {
  return F->isDeclaration() && !F->isMaterializable();
}

//===----------------------------------------------------------------------===//
// JIT lazy compilation code.
//
namespace {
  class JITEmitter;
  class JITResolverState;

  template<typename ValueTy>
  struct NoRAUWValueMapConfig : public ValueMapConfig<ValueTy> {
    typedef JITResolverState *ExtraData;
    static void onRAUW(JITResolverState *, Value *Old, Value *New) {
      llvm_unreachable("The JIT doesn't know how to handle a"
                       " RAUW on a value it has emitted.");
    }
  };

  struct CallSiteValueMapConfig : public NoRAUWValueMapConfig<Function*> {
    typedef JITResolverState *ExtraData;
    static void onDelete(JITResolverState *JRS, Function *F);
  };

  class JITResolverState {
  public:
    typedef ValueMap<Function*, void*, NoRAUWValueMapConfig<Function*> >
      FunctionToLazyStubMapTy;
    typedef std::map<void*, AssertingVH<Function> > CallSiteToFunctionMapTy;
    typedef ValueMap<Function *, SmallPtrSet<void*, 1>,
                     CallSiteValueMapConfig> FunctionToCallSitesMapTy;
    typedef std::map<AssertingVH<GlobalValue>, void*> GlobalToIndirectSymMapTy;
  private:
    /// FunctionToLazyStubMap - Keep track of the lazy stub created for a
    /// particular function so that we can reuse them if necessary.
    FunctionToLazyStubMapTy FunctionToLazyStubMap;

    /// CallSiteToFunctionMap - Keep track of the function that each lazy call
    /// site corresponds to, and vice versa.
    CallSiteToFunctionMapTy CallSiteToFunctionMap;
    FunctionToCallSitesMapTy FunctionToCallSitesMap;

    /// GlobalToIndirectSymMap - Keep track of the indirect symbol created for a
    /// particular GlobalVariable so that we can reuse them if necessary.
    GlobalToIndirectSymMapTy GlobalToIndirectSymMap;

    /// Instance of the JIT this ResolverState serves.
    JIT *TheJIT;

  public:
    JITResolverState(JIT *jit) : FunctionToLazyStubMap(this),
                                 FunctionToCallSitesMap(this),
                                 TheJIT(jit) {}

    FunctionToLazyStubMapTy& getFunctionToLazyStubMap(
      const MutexGuard& locked) {
      assert(locked.holds(TheJIT->lock));
      return FunctionToLazyStubMap;
    }

    GlobalToIndirectSymMapTy& getGlobalToIndirectSymMap(const MutexGuard& lck) {
      assert(lck.holds(TheJIT->lock));
      return GlobalToIndirectSymMap;
    }

    std::pair<void *, Function *> LookupFunctionFromCallSite(
        const MutexGuard &locked, void *CallSite) const {
      assert(locked.holds(TheJIT->lock));

      // The address given to us for the stub may not be exactly right, it
      // might be a little bit after the stub.  As such, use upper_bound to
      // find it.
      CallSiteToFunctionMapTy::const_iterator I =
        CallSiteToFunctionMap.upper_bound(CallSite);
      assert(I != CallSiteToFunctionMap.begin() &&
             "This is not a known call site!");
      --I;
      return *I;
    }

    void AddCallSite(const MutexGuard &locked, void *CallSite, Function *F) {
      assert(locked.holds(TheJIT->lock));

      bool Inserted = CallSiteToFunctionMap.insert(
          std::make_pair(CallSite, F)).second;
      (void)Inserted;
      assert(Inserted && "Pair was already in CallSiteToFunctionMap");
      FunctionToCallSitesMap[F].insert(CallSite);
    }

    void EraseAllCallSitesForPrelocked(Function *F);

    // Erases _all_ call sites regardless of their function.  This is used to
    // unregister the stub addresses from the StubToResolverMap in
    // ~JITResolver().
    void EraseAllCallSitesPrelocked();
  };

  /// JITResolver - Keep track of, and resolve, call sites for functions that
  /// have not yet been compiled.
  class JITResolver {
    typedef JITResolverState::FunctionToLazyStubMapTy FunctionToLazyStubMapTy;
    typedef JITResolverState::CallSiteToFunctionMapTy CallSiteToFunctionMapTy;
    typedef JITResolverState::GlobalToIndirectSymMapTy GlobalToIndirectSymMapTy;

    /// LazyResolverFn - The target lazy resolver function that we actually
    /// rewrite instructions to use.
    TargetJITInfo::LazyResolverFn LazyResolverFn;

    JITResolverState state;

    /// ExternalFnToStubMap - This is the equivalent of FunctionToLazyStubMap
    /// for external functions.  TODO: Of course, external functions don't need
    /// a lazy stub.  It's actually here to make it more likely that far calls
    /// succeed, but no single stub can guarantee that.  I'll remove this in a
    /// subsequent checkin when I actually fix far calls.
    std::map<void*, void*> ExternalFnToStubMap;

    /// revGOTMap - map addresses to indexes in the GOT
    std::map<void*, unsigned> revGOTMap;
    unsigned nextGOTIndex;

    JITEmitter &JE;

#ifndef NDEBUG
    /// Instance of JIT corresponding to this Resolver.
    JIT *TheJIT;
#endif

  public:
    explicit JITResolver(JIT &jit, JITEmitter &je)
      : state(&jit), nextGOTIndex(0), JE(je) {
#ifndef NDEBUG
      TheJIT = &jit;
#endif
      LazyResolverFn = jit.getJITInfo().getLazyResolverFunction(JITCompilerFn);
    }

    ~JITResolver();

    /// getLazyFunctionStubIfAvailable - This returns a pointer to a function's
    /// lazy-compilation stub if it has already been created.
    void *getLazyFunctionStubIfAvailable(Function *F);

    /// getLazyFunctionStub - This returns a pointer to a function's<commit_msg>Disable the right instance of TheJIT, this one is only used in asserts.<commit_after>//===-- JITEmitter.cpp - Write machine code to executable memory ----------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines a MachineCodeEmitter object that is used by the JIT to
// write machine code to memory and remember where relocatable values are.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "jit"
#include "JIT.h"
#include "JITDwarfEmitter.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/Constants.h"
#include "llvm/Module.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Analysis/DebugInfo.h"
#include "llvm/CodeGen/JITCodeEmitter.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineCodeInfo.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRelocation.h"
#include "llvm/ExecutionEngine/GenericValue.h"
#include "llvm/ExecutionEngine/JITEventListener.h"
#include "llvm/ExecutionEngine/JITMemoryManager.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetJITInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MutexGuard.h"
#include "llvm/Support/ValueHandle.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Disassembler.h"
#include "llvm/Support/Memory.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/ValueMap.h"
#include <algorithm>
#ifndef NDEBUG
#include <iomanip>
#endif
using namespace llvm;

STATISTIC(NumBytes, "Number of bytes of machine code compiled");
STATISTIC(NumRelos, "Number of relocations applied");
STATISTIC(NumRetries, "Number of retries with more memory");


// A declaration may stop being a declaration once it's fully read from bitcode.
// This function returns true if F is fully read and is still a declaration.
static bool isNonGhostDeclaration(const Function *F) {
  return F->isDeclaration() && !F->isMaterializable();
}

//===----------------------------------------------------------------------===//
// JIT lazy compilation code.
//
namespace {
  class JITEmitter;
  class JITResolverState;

  template<typename ValueTy>
  struct NoRAUWValueMapConfig : public ValueMapConfig<ValueTy> {
    typedef JITResolverState *ExtraData;
    static void onRAUW(JITResolverState *, Value *Old, Value *New) {
      llvm_unreachable("The JIT doesn't know how to handle a"
                       " RAUW on a value it has emitted.");
    }
  };

  struct CallSiteValueMapConfig : public NoRAUWValueMapConfig<Function*> {
    typedef JITResolverState *ExtraData;
    static void onDelete(JITResolverState *JRS, Function *F);
  };

  class JITResolverState {
  public:
    typedef ValueMap<Function*, void*, NoRAUWValueMapConfig<Function*> >
      FunctionToLazyStubMapTy;
    typedef std::map<void*, AssertingVH<Function> > CallSiteToFunctionMapTy;
    typedef ValueMap<Function *, SmallPtrSet<void*, 1>,
                     CallSiteValueMapConfig> FunctionToCallSitesMapTy;
    typedef std::map<AssertingVH<GlobalValue>, void*> GlobalToIndirectSymMapTy;
  private:
    /// FunctionToLazyStubMap - Keep track of the lazy stub created for a
    /// particular function so that we can reuse them if necessary.
    FunctionToLazyStubMapTy FunctionToLazyStubMap;

    /// CallSiteToFunctionMap - Keep track of the function that each lazy call
    /// site corresponds to, and vice versa.
    CallSiteToFunctionMapTy CallSiteToFunctionMap;
    FunctionToCallSitesMapTy FunctionToCallSitesMap;

    /// GlobalToIndirectSymMap - Keep track of the indirect symbol created for a
    /// particular GlobalVariable so that we can reuse them if necessary.
    GlobalToIndirectSymMapTy GlobalToIndirectSymMap;

#ifndef NDEBUG
    /// Instance of the JIT this ResolverState serves.
    JIT *TheJIT;
#endif

  public:
    JITResolverState(JIT *jit) : FunctionToLazyStubMap(this),
                                 FunctionToCallSitesMap(this) {
#ifndef NDEBUG
      TheJIT = jit;
#endif
    }

    FunctionToLazyStubMapTy& getFunctionToLazyStubMap(
      const MutexGuard& locked) {
      assert(locked.holds(TheJIT->lock));
      return FunctionToLazyStubMap;
    }

    GlobalToIndirectSymMapTy& getGlobalToIndirectSymMap(const MutexGuard& lck) {
      assert(lck.holds(TheJIT->lock));
      return GlobalToIndirectSymMap;
    }

    std::pair<void *, Function *> LookupFunctionFromCallSite(
        const MutexGuard &locked, void *CallSite) const {
      assert(locked.holds(TheJIT->lock));

      // The address given to us for the stub may not be exactly right, it
      // might be a little bit after the stub.  As such, use upper_bound to
      // find it.
      CallSiteToFunctionMapTy::const_iterator I =
        CallSiteToFunctionMap.upper_bound(CallSite);
      assert(I != CallSiteToFunctionMap.begin() &&
             "This is not a known call site!");
      --I;
      return *I;
    }

    void AddCallSite(const MutexGuard &locked, void *CallSite, Function *F) {
      assert(locked.holds(TheJIT->lock));

      bool Inserted = CallSiteToFunctionMap.insert(
          std::make_pair(CallSite, F)).second;
      (void)Inserted;
      assert(Inserted && "Pair was already in CallSiteToFunctionMap");
      FunctionToCallSitesMap[F].insert(CallSite);
    }

    void EraseAllCallSitesForPrelocked(Function *F);

    // Erases _all_ call sites regardless of their function.  This is used to
    // unregister the stub addresses from the StubToResolverMap in
    // ~JITResolver().
    void EraseAllCallSitesPrelocked();
  };

  /// JITResolver - Keep track of, and resolve, call sites for functions that
  /// have not yet been compiled.
  class JITResolver {
    typedef JITResolverState::FunctionToLazyStubMapTy FunctionToLazyStubMapTy;
    typedef JITResolverState::CallSiteToFunctionMapTy CallSiteToFunctionMapTy;
    typedef JITResolverState::GlobalToIndirectSymMapTy GlobalToIndirectSymMapTy;

    /// LazyResolverFn - The target lazy resolver function that we actually
    /// rewrite instructions to use.
    TargetJITInfo::LazyResolverFn LazyResolverFn;

    JITResolverState state;

    /// ExternalFnToStubMap - This is the equivalent of FunctionToLazyStubMap
    /// for external functions.  TODO: Of course, external functions don't need
    /// a lazy stub.  It's actually here to make it more likely that far calls
    /// succeed, but no single stub can guarantee that.  I'll remove this in a
    /// subsequent checkin when I actually fix far calls.
    std::map<void*, void*> ExternalFnToStubMap;

    /// revGOTMap - map addresses to indexes in the GOT
    std::map<void*, unsigned> revGOTMap;
    unsigned nextGOTIndex;

    JITEmitter &JE;

    /// Instance of JIT corresponding to this Resolver.
    JIT *TheJIT;

  public:
    explicit JITResolver(JIT &jit, JITEmitter &je)
      : state(&jit), nextGOTIndex(0), JE(je), TheJIT(&jit) {
      LazyResolverFn = jit.getJITInfo().getLazyResolverFunction(JITCompilerFn);
    }

    ~JITResolver();

    /// getLazyFunctionStubIfAvailable - This returns a pointer to a function's
    /// lazy-compilation stub if it has already been created.
    void *getLazyFunctionStubIfAvailable(Function *F);

    /// getLazyFunctionStub - This returns a pointer to a function's
{'fraction_non_alphanumeric': 0.12607193139639064, 'fraction_numerical': 0.0002559836170485089, 'mean_word_length': 3.255718954248366, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 47, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 3, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4724476', 'n_tokens_mistral': 4648, 'n_tokens_neox': 4582, 'n_words': 1275}