Skip to content

Commit ec8df3d

Browse files
Print out module in more places when we abort (#50723)
1 parent 382ba35 commit ec8df3d

File tree

3 files changed

+64
-16
lines changed

3 files changed

+64
-16
lines changed

src/jitlayers.cpp

Lines changed: 59 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -698,18 +698,26 @@ static Expected<orc::ThreadSafeModule> validateExternRelocations(orc::ThreadSafe
698698
auto Err = TSM.withModuleDo([isIntrinsicFunction](Module &M) JL_NOTSAFEPOINT {
699699
Error Err = Error::success();
700700
for (auto &GO : make_early_inc_range(M.global_objects())) {
701-
if (GO.isDeclaration()) {
702-
if (GO.use_empty())
703-
GO.eraseFromParent();
704-
else if (!isIntrinsicFunction(GO) &&
705-
!jl_ExecutionEngine->findUnmangledSymbol(GO.getName()) &&
706-
!SectionMemoryManager::getSymbolAddressInProcess(
701+
if (!GO.isDeclarationForLinker())
702+
continue;
703+
if (GO.use_empty()) {
704+
GO.eraseFromParent();
705+
continue;
706+
}
707+
if (isIntrinsicFunction(GO))
708+
continue;
709+
auto sym = jl_ExecutionEngine->findUnmangledSymbol(GO.getName());
710+
if (sym)
711+
continue;
712+
// TODO have we ever run into this check? It's been guaranteed to not
713+
// fire in an assert build, since previously LLVM would abort due to
714+
// not handling the error if we didn't find the unmangled symbol
715+
if (SectionMemoryManager::getSymbolAddressInProcess(
707716
jl_ExecutionEngine->getMangledName(GO.getName()))) {
708-
Err = joinErrors(std::move(Err), make_error<StringError>(
709-
"Symbol \"" + GO.getName().str() + "\" not found",
710-
inconvertibleErrorCode()));
711-
}
717+
consumeError(sym.takeError());
718+
continue;
712719
}
720+
Err = joinErrors(std::move(Err), sym.takeError());
713721
}
714722
return Err;
715723
});
@@ -750,6 +758,18 @@ static Expected<orc::ThreadSafeModule> selectOptLevel(orc::ThreadSafeModule TSM,
750758
return std::move(TSM);
751759
}
752760

761+
static void recordDebugTSM(orc::MaterializationResponsibility &, orc::ThreadSafeModule TSM) JL_NOTSAFEPOINT {
762+
auto ptr = TSM.withModuleDo([](Module &M) JL_NOTSAFEPOINT {
763+
auto md = M.getModuleFlag("julia.__jit_debug_tsm_addr");
764+
if (!md)
765+
return static_cast<orc::ThreadSafeModule *>(nullptr);
766+
return reinterpret_cast<orc::ThreadSafeModule *>(cast<ConstantInt>(cast<ConstantAsMetadata>(md)->getValue())->getZExtValue());
767+
});
768+
if (ptr) {
769+
*ptr = std::move(TSM);
770+
}
771+
}
772+
753773
void jl_register_jit_object(const object::ObjectFile &debugObj,
754774
std::function<uint64_t(const StringRef &)> getLoadAddress,
755775
std::function<void *(void *)> lookupWriteAddress);
@@ -1287,7 +1307,6 @@ namespace {
12871307
{
12881308
JL_TIMING(LLVM_JIT, JIT_Opt);
12891309
//Run the optimization
1290-
assert(!verifyLLVMIR(M));
12911310
(****PMs[PoolIdx]).run(M);
12921311
assert(!verifyLLVMIR(M));
12931312
}
@@ -1506,6 +1525,7 @@ JuliaOJIT::JuliaOJIT()
15061525
registerRTDyldJITObject(Object, LO, MemMgr);
15071526
});
15081527
#endif
1528+
CompileLayer.setNotifyCompiled(recordDebugTSM);
15091529

15101530
std::string ErrorStr;
15111531

@@ -1616,22 +1636,46 @@ void JuliaOJIT::addModule(orc::ThreadSafeModule TSM)
16161636
JL_TIMING(LLVM_JIT, JIT_Total);
16171637
++ModulesAdded;
16181638
orc::SymbolLookupSet NewExports;
1639+
orc::ThreadSafeModule CurrentlyCompiling;
16191640
TSM.withModuleDo([&](Module &M) JL_NOTSAFEPOINT {
16201641
for (auto &F : M.global_values()) {
16211642
if (!F.isDeclaration() && F.getLinkage() == GlobalValue::ExternalLinkage) {
16221643
auto Name = ES.intern(getMangledName(F.getName()));
16231644
NewExports.add(std::move(Name));
16241645
}
16251646
}
1647+
assert(!verifyLLVMIR(M));
1648+
auto jit_debug_tsm_addr = ConstantInt::get(Type::getIntNTy(M.getContext(), sizeof(void*) * CHAR_BIT), (uintptr_t) &CurrentlyCompiling);
1649+
M.addModuleFlag(Module::Error, "julia.__jit_debug_tsm_addr", jit_debug_tsm_addr);
16261650
});
16271651

16281652
// TODO: what is the performance characteristics of this?
1629-
cantFail(OptSelLayer.add(JD, std::move(TSM)));
1653+
auto Err = DepsVerifyLayer.add(JD, std::move(TSM));
1654+
if (Err) {
1655+
ES.reportError(std::move(Err));
1656+
errs() << "Failed to add module to JIT!\n";
1657+
if (CurrentlyCompiling) {
1658+
CurrentlyCompiling.withModuleDo([](Module &M) JL_NOTSAFEPOINT { errs() << "Dumping failing module\n" << M << "\n"; });
1659+
} else {
1660+
errs() << "Module unavailable to be printed\n";
1661+
}
1662+
abort();
1663+
}
16301664
// force eager compilation (for now), due to memory management specifics
16311665
// (can't handle compilation recursion)
1632-
for (auto &sym : cantFail(ES.lookup({{&JD, orc::JITDylibLookupFlags::MatchExportedSymbolsOnly}}, NewExports))) {
1633-
assert(sym.second);
1634-
(void) sym;
1666+
auto Lookups = ES.lookup({{&JD, orc::JITDylibLookupFlags::MatchExportedSymbolsOnly}}, NewExports);
1667+
if (!Lookups) {
1668+
ES.reportError(Lookups.takeError());
1669+
errs() << "Failed to lookup symbols in module!";
1670+
if (CurrentlyCompiling) {
1671+
CurrentlyCompiling.withModuleDo([](Module &M) JL_NOTSAFEPOINT { errs() << "Dumping failing module\n" << M << "\n"; });
1672+
} else {
1673+
errs() << "Module unavailable to be printed\n";
1674+
}
1675+
}
1676+
for (auto &Sym : *Lookups) {
1677+
assert(Sym.second);
1678+
(void) Sym;
16351679
}
16361680
}
16371681

src/pipeline.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -818,6 +818,7 @@ static llvm::Optional<std::pair<OptimizationLevel, OptimizationOptions>> parseJu
818818
}
819819

820820
bool verifyLLVMIR(const Module &M) JL_NOTSAFEPOINT {
821+
JL_TIMING(VERIFY_IR, VERIFY_Module);
821822
if (verifyModule(M, &errs())) {
822823
errs() << "Failed to verify module '" << M.getModuleIdentifier() << "', dumping entire module!\n\n";
823824
errs() << M << "\n";
@@ -827,6 +828,7 @@ bool verifyLLVMIR(const Module &M) JL_NOTSAFEPOINT {
827828
}
828829

829830
bool verifyLLVMIR(const Function &F) JL_NOTSAFEPOINT {
831+
JL_TIMING(VERIFY_IR, VERIFY_Function);
830832
if (verifyFunction(F, &errs())) {
831833
errs() << "Failed to verify function '" << F.getName() << "', dumping entire module!\n\n";
832834
errs() << *F.getParent() << "\n";
@@ -836,8 +838,9 @@ bool verifyLLVMIR(const Function &F) JL_NOTSAFEPOINT {
836838
}
837839

838840
bool verifyLLVMIR(const Loop &L) JL_NOTSAFEPOINT {
841+
JL_TIMING(VERIFY_IR, VERIFY_Loop);
839842
if (verifyFunction(*L.getHeader()->getParent(), &errs())) {
840-
errs() << "Failed to verify loop '" << L.getName() << "', dumping entire module!\n\n";
843+
errs() << "Failed to verify loop '" << L << "', dumping entire module!\n\n";
841844
errs() << *L.getHeader()->getModule() << "\n";
842845
return true;
843846
}

src/timing.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ JL_DLLEXPORT void jl_timing_puts(jl_timing_block_t *cur_block, const char *str);
174174
X(LOAD_MODULE) \
175175
X(LOAD_IMAGE) \
176176
X(VERIFY_IMAGE) \
177+
X(VERIFY_IR) \
177178
X(SAVE_MODULE) \
178179
X(INIT_MODULE) \
179180
X(LOCK_SPIN) \

0 commit comments

Comments
 (0)