llvm-project/llvm/examples/ThinLtoJIT/ThinLtoDiscoveryThread.cpp

66 lines
2.0 KiB
C++

#include "ThinLtoDiscoveryThread.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Error.h"
#include "ThinLtoInstrumentationLayer.h"
#include "ThinLtoModuleIndex.h"
#include <thread>
#define DEBUG_TYPE "thinltojit"
namespace llvm {
namespace orc {
void ThinLtoDiscoveryThread::operator()() {
while (KeepRunning.load()) {
std::vector<unsigned> Indexes = Layer.takeFlagsThatFired();
if (!Indexes.empty()) {
LLVM_DEBUG(dbgs() << Indexes.size() << " new flags raised\n");
auto ReachedFunctions = Layer.takeFlagOwners(std::move(Indexes));
for (GlobalValue::GUID F : ReachedFunctions) {
if (GlobalValueSummary *S = GlobalIndex.getSummary(F)) {
assert(isa<FunctionSummary>(S) && "Reached symbols are functions");
GlobalIndex.discoverCalleeModulePaths(cast<FunctionSummary>(S),
LookaheadLevels);
} else {
LLVM_DEBUG(dbgs() << "No summary for GUID: " << F << "\n");
}
}
if (GlobalIndex.getNumDiscoveredModules() > 0)
spawnLookupForHighRankModules();
}
}
}
void ThinLtoDiscoveryThread::spawnLookupForHighRankModules() {
std::vector<std::string> Paths = GlobalIndex.selectNextPaths();
GlobalIndex.scheduleModuleParsing(Paths);
// In order to add modules we need exclusive access to the execution session.
std::thread([this, Paths = std::move(Paths)]() {
ES.runSessionLocked([this, Paths = std::move(Paths)]() mutable {
for (const std::string &Path : Paths) {
ThreadSafeModule TSM = GlobalIndex.takeModule(Path);
if (!TSM)
// In the meantime the module was added synchronously.
continue;
if (Error LoadErr = AddModule(std::move(TSM)))
// Failed to add the module to the session.
ES.reportError(std::move(LoadErr));
++NumModulesSubmitted;
}
});
}).detach();
}
} // namespace orc
} // namespace llvm