Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion interpreter/cling/LastKnownGoodLLVMSVNRevision.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
302975
release_50
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace clingoptions {
OPT_INVALID = 0, // This is not an option ID.
#define PREFIX(NAME, VALUE)
#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
HELPTEXT, METAVAR) OPT_##ID,
HELPTEXT, METAVAR, VALUES) OPT_##ID,
#include "cling/Interpreter/ClingOptions.inc"
LastOption
#undef OPTION
Expand Down
24 changes: 12 additions & 12 deletions interpreter/cling/include/cling/Interpreter/ClingOptions.inc
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,26 @@ PREFIX(prefix_2, {"--" COMMA 0})
#error "Define OPTION prior to including this file!"
#endif

OPTION(prefix_0, "<input>", INPUT, Input, INVALID, INVALID, 0, 0, 0, 0, 0)
OPTION(prefix_0, "<unknown>", UNKNOWN, Unknown, INVALID, INVALID, 0, 0, 0, 0, 0)
OPTION(prefix_0, "<input>", INPUT, Input, INVALID, INVALID, 0, 0, 0, 0, 0, 0)
OPTION(prefix_0, "<unknown>", UNKNOWN, Unknown, INVALID, INVALID, 0, 0, 0, 0, 0, 0)
OPTION(prefix_2, "errorout", _errorout, Flag, INVALID, INVALID, 0, 0, 0,
"Do not recover from input errors", 0)
"Do not recover from input errors", 0, 0)
OPTION(prefix_3, "help", help, Flag, INVALID, INVALID, 0, 0, 0,
"Print this help text", 0)
"Print this help text", 0, 0)
OPTION(prefix_1, "L", L, JoinedOrSeparate, INVALID, INVALID, 0, 0, 0,
"Add directory to library search path", "<directory>")
"Add directory to library search path", "<directory>", 0)
// Re-implement to forward to our help
OPTION(prefix_1, "l", l, JoinedOrSeparate, INVALID, INVALID, 0, 0, 0,
"Load a library before prompt", "<library>")
"Load a library before prompt", "<library>", 0)
OPTION(prefix_2, "metastr=", _metastr_EQ, Joined, INVALID, INVALID, 0, 0, 0,
"Set the meta command tag, default '.'", 0)
"Set the meta command tag, default '.'", 0, 0)
OPTION(prefix_2, "metastr", _metastr, Separate, INVALID, INVALID, 0, 0, 0,
"Set the meta command tag, default '.'", 0)
"Set the meta command tag, default '.'", 0, 0)
OPTION(prefix_2, "nologo", _nologo, Flag, INVALID, INVALID, 0, 0, 0,
"Do not show startup-banner", 0)
"Do not show startup-banner", 0, 0)
OPTION(prefix_3, "noruntime", noruntime, Flag, INVALID, INVALID, 0, 0, 0,
"Disable runtime support (no null checking, no value printing)", 0)
"Disable runtime support (no null checking, no value printing)", 0, 0)
OPTION(prefix_3, "version", version, Flag, INVALID, INVALID, 0, 0, 0,
"Print the compiler version", 0)
"Print the compiler version", 0, 0)
OPTION(prefix_1, "v", v, Flag, INVALID, INVALID, 0, 0, 0,
"Enable verbose output", 0)
"Enable verbose output", 0, 0)
1 change: 0 additions & 1 deletion interpreter/cling/lib/Interpreter/BackendPasses.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,6 @@ void BackendPasses::CreatePasses(llvm::Module& M, int OptLevel)
llvm::PassManagerBuilder PMBuilder;
PMBuilder.OptLevel = OptLevel;
PMBuilder.SizeLevel = m_CGOpts.OptimizeSize;
PMBuilder.BBVectorize = 0; // m_CGOpts.VectorizeBB;
PMBuilder.SLPVectorize = OptLevel > 1 ? 1 : 0; // m_CGOpts.VectorizeSLP
PMBuilder.LoopVectorize = OptLevel > 1 ? 1 : 0; // m_CGOpts.VectorizeLoop

Expand Down
4 changes: 2 additions & 2 deletions interpreter/cling/lib/Interpreter/DynamicLibraryManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
#include "cling/Utils/Platform.h"
#include "cling/Utils/Output.h"

#include "llvm/BinaryFormat/Magic.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"

#include <system_error>
Expand Down Expand Up @@ -64,7 +64,7 @@ namespace cling {
DynamicLibraryManager::~DynamicLibraryManager() {}

static bool isSharedLib(llvm::StringRef LibName, bool* exists = 0) {
using namespace llvm::sys::fs;
using namespace llvm;
file_magic Magic;
const std::error_code Error = identify_magic(LibName, Magic);
if (exists)
Expand Down
5 changes: 3 additions & 2 deletions interpreter/cling/lib/Interpreter/IncrementalExecutor.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,9 @@ namespace cling {

///\brief Unload a set of JIT symbols.
bool unloadModule(const std::shared_ptr<llvm::Module>& M) {
m_JIT->removeModule(M);
// FIXME: Propagate if we removed a module or not.
// FIXME: Propagate the error in a more verbose way.
if (auto Err = m_JIT->removeModule(M))
return false;
return true;
}

Expand Down
80 changes: 57 additions & 23 deletions interpreter/cling/lib/Interpreter/IncrementalJIT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "cling/Utils/Platform.h"

#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include "llvm/Support/DynamicLibrary.h"

#ifdef __APPLE__
Expand Down Expand Up @@ -41,7 +42,7 @@ class ClingMemoryManager: public SectionMemoryManager {
class NotifyFinalizedT {
public:
NotifyFinalizedT(cling::IncrementalJIT &jit) : m_JIT(jit) {}
void operator()(llvm::orc::RTDyldObjectLinkingLayerBase::ObjSetHandleT H) {
void operator()(llvm::orc::RTDyldObjectLinkingLayerBase::ObjHandleT H) {
m_JIT.RemoveUnfinalizedSection(H);
}

Expand Down Expand Up @@ -220,9 +221,16 @@ class Azog: public RTDyldMemoryManager {
}

uint64_t getSymbolAddress(const std::string &Name) override {
return m_jit.getSymbolAddressWithoutMangling(Name,
true /*also use dlsym*/)
.getAddress();
// FIXME: We should decide if we want to handle the error here or make the
// return type of the function llvm::Expected<uint64_t> relying on the
// users to decide how to handle the error.
if (auto Addr = m_jit.getSymbolAddressWithoutMangling(Name,
true /*also use dlsym*/)
.getAddress())
return *Addr;

llvm_unreachable("Handle the error case");
return ~0U;
}

void *getPointerToNamedFunction(const std::string &Name,
Expand Down Expand Up @@ -267,12 +275,29 @@ IncrementalJIT::IncrementalJIT(IncrementalExecutor& exe,
m_Parent(exe),
m_TM(std::move(TM)),
m_TMDataLayout(m_TM->createDataLayout()),
m_ExeMM(llvm::make_unique<ClingMemoryManager>(m_Parent)),
m_ExeMM(std::make_shared<ClingMemoryManager>(m_Parent)),
m_NotifyObjectLoaded(*this),
m_ObjectLayer(m_SymbolMap, m_NotifyObjectLoaded, NotifyFinalizedT(*this)),
m_ObjectLayer(m_SymbolMap, [this] () { return llvm::make_unique<Azog>(*this); },
m_NotifyObjectLoaded, NotifyFinalizedT(*this)),
m_CompileLayer(m_ObjectLayer, llvm::orc::SimpleCompiler(*m_TM)),
m_LazyEmitLayer(m_CompileLayer) {

// Force the JIT to query for symbols local to itself, i.e. if it resides in a
// shared library it will resolve symbols from there first. This is done to
// implement our proto symbol versioning protection. Namely, if some other
// library provides llvm symbols, we want out JIT to avoid looking at them.
//
// FIXME: In general, this approach causes numerous issues when cling is
// embedded and the framework needs to provide its own set of symbols which
// exist in llvm. Most notably if the framework links against different
// versions of linked against llvm libraries. For instance, if we want to provide
// a custom zlib in the framework the JIT will still resolve to llvm's version
// of libz causing hard-to-debug bugs. In order to work around such cases we
// need to swap the llvm system libraries, which can be tricky for two
// reasons: (a) llvm's cmake doesn't really support it; (b) only works if we
// build llvm from sources.
llvm::sys::DynamicLibrary::SearchOrder
= llvm::sys::DynamicLibrary::SO_LoadedFirst;
// Enable JIT symbol resolution from the binary.
llvm::sys::DynamicLibrary::LoadLibraryPermanently(0, 0);

Expand Down Expand Up @@ -343,9 +368,12 @@ IncrementalJIT::getSymbolAddressWithoutMangling(const std::string& Name,
return Sym;

if (AlsoInProcess) {
if (llvm::JITSymbol SymInfo = m_ExeMM->findSymbol(Name))
return llvm::JITSymbol(SymInfo.getAddress(),
llvm::JITSymbolFlags::Exported);
if (llvm::JITSymbol SymInfo = m_ExeMM->findSymbol(Name)) {
if (auto AddrOrErr = SymInfo.getAddress())
return llvm::JITSymbol(*AddrOrErr, llvm::JITSymbolFlags::Exported);
else
llvm_unreachable("Handle the error case");
}
#ifdef LLVM_ON_WIN32
// FIXME: DLSym symbol lookup can overlap m_ExeMM->findSymbol wasting time
// looking for a symbol in libs where it is already known not to exist.
Expand Down Expand Up @@ -374,13 +402,21 @@ void IncrementalJIT::addModule(const std::shared_ptr<llvm::Module>& module) {
// LLVM MERGE FIXME: update this to use new interfaces.
auto Resolver = llvm::orc::createLambdaResolver(
[&](const std::string &S) {
if (auto Sym = getInjectedSymbols(S))
return JITSymbol((uint64_t)Sym.getAddress(), Sym.getFlags());
if (auto Sym = getInjectedSymbols(S)) {
if (auto AddrOrErr = Sym.getAddress())
return JITSymbol((uint64_t)*AddrOrErr, Sym.getFlags());
else
llvm_unreachable("Handle the error case");
}
return m_ExeMM->findSymbol(S);
},
[&](const std::string &Name) {
if (auto Sym = getSymbolAddressWithoutMangling(Name, true))
return JITSymbol(Sym.getAddress(), Sym.getFlags());
if (auto Sym = getSymbolAddressWithoutMangling(Name, true)) {
if (auto AddrOrErr = Sym.getAddress())
return JITSymbol(*AddrOrErr, Sym.getFlags());
else
llvm_unreachable("Handle the error case");
}

const std::string* NameNP = &Name;
#ifdef MANGLE_PREFIX
Expand All @@ -401,25 +437,23 @@ void IncrementalJIT::addModule(const std::shared_ptr<llvm::Module>& module) {
return JITSymbol(addr, llvm::JITSymbolFlags::Weak);
});

std::vector<llvm::Module*> moduleSet;
moduleSet.push_back(module.get());
ModuleSetHandleT MSHandle =
m_LazyEmitLayer.addModuleSet(std::move(moduleSet),
llvm::make_unique<Azog>(*this),
std::move(Resolver));
m_UnloadPoints[module.get()] = MSHandle;
if (auto H = m_LazyEmitLayer.addModule(module, std::move(Resolver)))
m_UnloadPoints[module.get()] = *H;
else
llvm_unreachable("Handle the error case");
}

void IncrementalJIT::removeModule(const std::shared_ptr<llvm::Module>& module) {
llvm::Error
IncrementalJIT::removeModule(const std::shared_ptr<llvm::Module>& module) {
// FIXME: Track down what calls this routine on a not-yet-added module. Once
// this is resolved we can remove this check enabling the assert.
auto IUnload = m_UnloadPoints.find(module.get());
if (IUnload == m_UnloadPoints.end())
return;
return llvm::Error::success();
auto Handle = IUnload->second;
assert(*Handle && "Trying to remove a non existent module!");
m_UnloadPoints.erase(IUnload);
m_LazyEmitLayer.removeModuleSet(Handle);
return m_LazyEmitLayer.removeModule(Handle);
}

}// end namespace cling
Loading