forked from OSchip/llvm-project
78 lines
2.3 KiB
C++
78 lines
2.3 KiB
C++
#ifndef LLVM_EXAMPLES_THINLTOJIT_DISCOVERYLAYER_H
|
|
#define LLVM_EXAMPLES_THINLTOJIT_DISCOVERYLAYER_H
|
|
|
|
#include "llvm/ExecutionEngine/JITSymbol.h"
|
|
#include "llvm/ExecutionEngine/Orc/Core.h"
|
|
#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
|
|
#include "llvm/ExecutionEngine/Orc/Layer.h"
|
|
#include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h"
|
|
#include "llvm/IR/GlobalValue.h"
|
|
#include "llvm/IR/IRBuilder.h"
|
|
#include "llvm/Support/raw_ostream.h"
|
|
|
|
#include "ThinLtoJIT.h"
|
|
|
|
#include <atomic>
|
|
#include <cstdint>
|
|
#include <map>
|
|
#include <mutex>
|
|
#include <vector>
|
|
|
|
namespace llvm {
|
|
namespace orc {
|
|
|
|
class ThinLtoInstrumentationLayer : public IRLayer {
|
|
public:
|
|
ThinLtoInstrumentationLayer(ExecutionSession &ES, IRCompileLayer &BaseLayer,
|
|
ThinLtoJIT::ExplicitMemoryBarrier MemFence,
|
|
unsigned FlagsPerBucket)
|
|
: IRLayer(ES, BaseLayer.getManglingOptions()), BaseLayer(BaseLayer),
|
|
MemFence(MemFence) {
|
|
// TODO: So far we only allocate one bucket.
|
|
allocateDiscoveryFlags(FlagsPerBucket);
|
|
}
|
|
|
|
~ThinLtoInstrumentationLayer() override;
|
|
|
|
void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override;
|
|
|
|
unsigned reserveDiscoveryFlags(unsigned Count);
|
|
void registerDiscoveryFlagOwners(std::vector<GlobalValue::GUID> Guids,
|
|
unsigned FirstIdx);
|
|
|
|
void nudgeIntoDiscovery(std::vector<GlobalValue::GUID> Functions);
|
|
|
|
std::vector<unsigned> takeFlagsThatFired();
|
|
std::vector<GlobalValue::GUID> takeFlagOwners(std::vector<unsigned> Indexes);
|
|
|
|
void dump(raw_ostream &OS);
|
|
|
|
private:
|
|
IRCompileLayer &BaseLayer;
|
|
ThinLtoJIT::ExplicitMemoryBarrier MemFence;
|
|
|
|
enum Flag : uint8_t { Clear = 0, Fired = 1 };
|
|
|
|
// Lock-free read access.
|
|
uint8_t *FlagsStorage;
|
|
Flag *FlagsIncoming; // lock-free write by design
|
|
Flag *FlagsHandled;
|
|
unsigned NumFlagsAllocated;
|
|
std::atomic<unsigned> NumFlagsUsed; // spin-lock
|
|
|
|
// Acquire/release sync between writers and reader
|
|
std::atomic<uint64_t> FlagsSync;
|
|
|
|
// STL container requires locking for both, read and write access.
|
|
mutable std::mutex DiscoveryFlagsInfoLock;
|
|
std::map<unsigned, GlobalValue::GUID> FlagOwnersMap;
|
|
|
|
void allocateDiscoveryFlags(unsigned MinFlags);
|
|
void compileFunctionReachedFlagSetter(IRBuilder<> &B, Flag *F);
|
|
};
|
|
|
|
} // namespace orc
|
|
} // namespace llvm
|
|
|
|
#endif
|