From ec8df3da3597d0acd503ff85ac84a5f8f73f625b Mon Sep 17 00:00:00 2001 From: pchintalapudi <34727397+pchintalapudi@users.noreply.github.com> Date: Mon, 31 Jul 2023 19:24:34 +0000 Subject: [PATCH] Print out module in more places when we abort (#50723) --- src/jitlayers.cpp | 74 +++++++++++++++++++++++++++++++++++++---------- src/pipeline.cpp | 5 +++- src/timing.h | 1 + 3 files changed, 64 insertions(+), 16 deletions(-) diff --git a/src/jitlayers.cpp b/src/jitlayers.cpp index b3c9f2190df48..2ba1ad35ec9ec 100644 --- a/src/jitlayers.cpp +++ b/src/jitlayers.cpp @@ -698,18 +698,26 @@ static Expected validateExternRelocations(orc::ThreadSafe auto Err = TSM.withModuleDo([isIntrinsicFunction](Module &M) JL_NOTSAFEPOINT { Error Err = Error::success(); for (auto &GO : make_early_inc_range(M.global_objects())) { - if (GO.isDeclaration()) { - if (GO.use_empty()) - GO.eraseFromParent(); - else if (!isIntrinsicFunction(GO) && - !jl_ExecutionEngine->findUnmangledSymbol(GO.getName()) && - !SectionMemoryManager::getSymbolAddressInProcess( + if (!GO.isDeclarationForLinker()) + continue; + if (GO.use_empty()) { + GO.eraseFromParent(); + continue; + } + if (isIntrinsicFunction(GO)) + continue; + auto sym = jl_ExecutionEngine->findUnmangledSymbol(GO.getName()); + if (sym) + continue; + // TODO have we ever run into this check? It's been guaranteed to not + // fire in an assert build, since previously LLVM would abort due to + // not handling the error if we didn't find the unmangled symbol + if (SectionMemoryManager::getSymbolAddressInProcess( jl_ExecutionEngine->getMangledName(GO.getName()))) { - Err = joinErrors(std::move(Err), make_error( - "Symbol \"" + GO.getName().str() + "\" not found", - inconvertibleErrorCode())); - } + consumeError(sym.takeError()); + continue; } + Err = joinErrors(std::move(Err), sym.takeError()); } return Err; }); @@ -750,6 +758,18 @@ static Expected selectOptLevel(orc::ThreadSafeModule TSM, return std::move(TSM); } +static void recordDebugTSM(orc::MaterializationResponsibility &, orc::ThreadSafeModule TSM) JL_NOTSAFEPOINT { + auto ptr = TSM.withModuleDo([](Module &M) JL_NOTSAFEPOINT { + auto md = M.getModuleFlag("julia.__jit_debug_tsm_addr"); + if (!md) + return static_cast(nullptr); + return reinterpret_cast(cast(cast(md)->getValue())->getZExtValue()); + }); + if (ptr) { + *ptr = std::move(TSM); + } +} + void jl_register_jit_object(const object::ObjectFile &debugObj, std::function getLoadAddress, std::function lookupWriteAddress); @@ -1287,7 +1307,6 @@ namespace { { JL_TIMING(LLVM_JIT, JIT_Opt); //Run the optimization - assert(!verifyLLVMIR(M)); (****PMs[PoolIdx]).run(M); assert(!verifyLLVMIR(M)); } @@ -1506,6 +1525,7 @@ JuliaOJIT::JuliaOJIT() registerRTDyldJITObject(Object, LO, MemMgr); }); #endif + CompileLayer.setNotifyCompiled(recordDebugTSM); std::string ErrorStr; @@ -1616,6 +1636,7 @@ void JuliaOJIT::addModule(orc::ThreadSafeModule TSM) JL_TIMING(LLVM_JIT, JIT_Total); ++ModulesAdded; orc::SymbolLookupSet NewExports; + orc::ThreadSafeModule CurrentlyCompiling; TSM.withModuleDo([&](Module &M) JL_NOTSAFEPOINT { for (auto &F : M.global_values()) { if (!F.isDeclaration() && F.getLinkage() == GlobalValue::ExternalLinkage) { @@ -1623,15 +1644,38 @@ void JuliaOJIT::addModule(orc::ThreadSafeModule TSM) NewExports.add(std::move(Name)); } } + assert(!verifyLLVMIR(M)); + auto jit_debug_tsm_addr = ConstantInt::get(Type::getIntNTy(M.getContext(), sizeof(void*) * CHAR_BIT), (uintptr_t) &CurrentlyCompiling); + M.addModuleFlag(Module::Error, "julia.__jit_debug_tsm_addr", jit_debug_tsm_addr); }); // TODO: what is the performance characteristics of this? - cantFail(OptSelLayer.add(JD, std::move(TSM))); + auto Err = DepsVerifyLayer.add(JD, std::move(TSM)); + if (Err) { + ES.reportError(std::move(Err)); + errs() << "Failed to add module to JIT!\n"; + if (CurrentlyCompiling) { + CurrentlyCompiling.withModuleDo([](Module &M) JL_NOTSAFEPOINT { errs() << "Dumping failing module\n" << M << "\n"; }); + } else { + errs() << "Module unavailable to be printed\n"; + } + abort(); + } // force eager compilation (for now), due to memory management specifics // (can't handle compilation recursion) - for (auto &sym : cantFail(ES.lookup({{&JD, orc::JITDylibLookupFlags::MatchExportedSymbolsOnly}}, NewExports))) { - assert(sym.second); - (void) sym; + auto Lookups = ES.lookup({{&JD, orc::JITDylibLookupFlags::MatchExportedSymbolsOnly}}, NewExports); + if (!Lookups) { + ES.reportError(Lookups.takeError()); + errs() << "Failed to lookup symbols in module!"; + if (CurrentlyCompiling) { + CurrentlyCompiling.withModuleDo([](Module &M) JL_NOTSAFEPOINT { errs() << "Dumping failing module\n" << M << "\n"; }); + } else { + errs() << "Module unavailable to be printed\n"; + } + } + for (auto &Sym : *Lookups) { + assert(Sym.second); + (void) Sym; } } diff --git a/src/pipeline.cpp b/src/pipeline.cpp index 365ff97bb2f3a..49930c0ee0e78 100644 --- a/src/pipeline.cpp +++ b/src/pipeline.cpp @@ -818,6 +818,7 @@ static llvm::Optional> parseJu } bool verifyLLVMIR(const Module &M) JL_NOTSAFEPOINT { + JL_TIMING(VERIFY_IR, VERIFY_Module); if (verifyModule(M, &errs())) { errs() << "Failed to verify module '" << M.getModuleIdentifier() << "', dumping entire module!\n\n"; errs() << M << "\n"; @@ -827,6 +828,7 @@ bool verifyLLVMIR(const Module &M) JL_NOTSAFEPOINT { } bool verifyLLVMIR(const Function &F) JL_NOTSAFEPOINT { + JL_TIMING(VERIFY_IR, VERIFY_Function); if (verifyFunction(F, &errs())) { errs() << "Failed to verify function '" << F.getName() << "', dumping entire module!\n\n"; errs() << *F.getParent() << "\n"; @@ -836,8 +838,9 @@ bool verifyLLVMIR(const Function &F) JL_NOTSAFEPOINT { } bool verifyLLVMIR(const Loop &L) JL_NOTSAFEPOINT { + JL_TIMING(VERIFY_IR, VERIFY_Loop); if (verifyFunction(*L.getHeader()->getParent(), &errs())) { - errs() << "Failed to verify loop '" << L.getName() << "', dumping entire module!\n\n"; + errs() << "Failed to verify loop '" << L << "', dumping entire module!\n\n"; errs() << *L.getHeader()->getModule() << "\n"; return true; } diff --git a/src/timing.h b/src/timing.h index 5181d43d34b5e..1cc82b67e2b6a 100644 --- a/src/timing.h +++ b/src/timing.h @@ -174,6 +174,7 @@ JL_DLLEXPORT void jl_timing_puts(jl_timing_block_t *cur_block, const char *str); X(LOAD_MODULE) \ X(LOAD_IMAGE) \ X(VERIFY_IMAGE) \ + X(VERIFY_IR) \ X(SAVE_MODULE) \ X(INIT_MODULE) \ X(LOCK_SPIN) \