mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-31 10:34:17 +00:00
Add a lock() function in PassRegistry to speed up multi-thread synchronization.
When calling lock() after all passes are registered, the PassRegistry doesn't need a mutex anymore to look up passes. This speeds up multithreaded llvm execution by ~5% (tested with 4 threads). In an asserts build of llvm this has an even bigger impact. Note that it's not required to use the lock function. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@231276 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
be61f2b51c
commit
953be88190
@ -41,6 +41,9 @@ struct PassRegistrationListener;
|
|||||||
class PassRegistry {
|
class PassRegistry {
|
||||||
mutable sys::SmartRWMutex<true> Lock;
|
mutable sys::SmartRWMutex<true> Lock;
|
||||||
|
|
||||||
|
/// Only if false, synchronization must use the Lock mutex.
|
||||||
|
std::atomic<bool> locked;
|
||||||
|
|
||||||
/// PassInfoMap - Keep track of the PassInfo object for each registered pass.
|
/// PassInfoMap - Keep track of the PassInfo object for each registered pass.
|
||||||
typedef DenseMap<const void *, const PassInfo *> MapType;
|
typedef DenseMap<const void *, const PassInfo *> MapType;
|
||||||
MapType PassInfoMap;
|
MapType PassInfoMap;
|
||||||
@ -52,7 +55,7 @@ class PassRegistry {
|
|||||||
std::vector<PassRegistrationListener *> Listeners;
|
std::vector<PassRegistrationListener *> Listeners;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PassRegistry() {}
|
PassRegistry() : locked(false) {}
|
||||||
~PassRegistry();
|
~PassRegistry();
|
||||||
|
|
||||||
/// getPassRegistry - Access the global registry object, which is
|
/// getPassRegistry - Access the global registry object, which is
|
||||||
@ -60,6 +63,10 @@ public:
|
|||||||
/// llvm_shutdown.
|
/// llvm_shutdown.
|
||||||
static PassRegistry *getPassRegistry();
|
static PassRegistry *getPassRegistry();
|
||||||
|
|
||||||
|
/// Enables fast thread synchronization in getPassInfo().
|
||||||
|
/// After calling lock() no more passes may be registered.
|
||||||
|
void lock() { locked = true; }
|
||||||
|
|
||||||
/// getPassInfo - Look up a pass' corresponding PassInfo, indexed by the pass'
|
/// getPassInfo - Look up a pass' corresponding PassInfo, indexed by the pass'
|
||||||
/// type identifier (&MyPass::ID).
|
/// type identifier (&MyPass::ID).
|
||||||
const PassInfo *getPassInfo(const void *TI) const;
|
const PassInfo *getPassInfo(const void *TI) const;
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "llvm/PassRegistry.h"
|
#include "llvm/PassRegistry.h"
|
||||||
|
#include "llvm/ADT/Optional.h"
|
||||||
#include "llvm/IR/Function.h"
|
#include "llvm/IR/Function.h"
|
||||||
#include "llvm/PassSupport.h"
|
#include "llvm/PassSupport.h"
|
||||||
#include "llvm/Support/Compiler.h"
|
#include "llvm/Support/Compiler.h"
|
||||||
@ -39,13 +40,23 @@ PassRegistry *PassRegistry::getPassRegistry() {
|
|||||||
PassRegistry::~PassRegistry() {}
|
PassRegistry::~PassRegistry() {}
|
||||||
|
|
||||||
const PassInfo *PassRegistry::getPassInfo(const void *TI) const {
|
const PassInfo *PassRegistry::getPassInfo(const void *TI) const {
|
||||||
sys::SmartScopedReader<true> Guard(Lock);
|
// We don't need thread synchronization after the PassRegistry is locked
|
||||||
|
// (that means: is read-only).
|
||||||
|
Optional<sys::SmartScopedReader<true>> Guard;
|
||||||
|
if (!locked)
|
||||||
|
Guard.emplace(Lock);
|
||||||
|
|
||||||
MapType::const_iterator I = PassInfoMap.find(TI);
|
MapType::const_iterator I = PassInfoMap.find(TI);
|
||||||
return I != PassInfoMap.end() ? I->second : nullptr;
|
return I != PassInfoMap.end() ? I->second : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const PassInfo *PassRegistry::getPassInfo(StringRef Arg) const {
|
const PassInfo *PassRegistry::getPassInfo(StringRef Arg) const {
|
||||||
sys::SmartScopedReader<true> Guard(Lock);
|
// We don't need thread synchronization after the PassRegistry is locked
|
||||||
|
// (that means: is read-only).
|
||||||
|
Optional<sys::SmartScopedReader<true>> Guard;
|
||||||
|
if (!locked)
|
||||||
|
Guard.emplace(Lock);
|
||||||
|
|
||||||
StringMapType::const_iterator I = PassInfoStringMap.find(Arg);
|
StringMapType::const_iterator I = PassInfoStringMap.find(Arg);
|
||||||
return I != PassInfoStringMap.end() ? I->second : nullptr;
|
return I != PassInfoStringMap.end() ? I->second : nullptr;
|
||||||
}
|
}
|
||||||
@ -55,6 +66,9 @@ const PassInfo *PassRegistry::getPassInfo(StringRef Arg) const {
|
|||||||
//
|
//
|
||||||
|
|
||||||
void PassRegistry::registerPass(const PassInfo &PI, bool ShouldFree) {
|
void PassRegistry::registerPass(const PassInfo &PI, bool ShouldFree) {
|
||||||
|
|
||||||
|
assert(!locked && "Trying to register a pass in a locked PassRegistry");
|
||||||
|
|
||||||
sys::SmartScopedWriter<true> Guard(Lock);
|
sys::SmartScopedWriter<true> Guard(Lock);
|
||||||
bool Inserted =
|
bool Inserted =
|
||||||
PassInfoMap.insert(std::make_pair(PI.getTypeInfo(), &PI)).second;
|
PassInfoMap.insert(std::make_pair(PI.getTypeInfo(), &PI)).second;
|
||||||
@ -68,6 +82,8 @@ void PassRegistry::registerPass(const PassInfo &PI, bool ShouldFree) {
|
|||||||
|
|
||||||
if (ShouldFree)
|
if (ShouldFree)
|
||||||
ToFree.push_back(std::unique_ptr<const PassInfo>(&PI));
|
ToFree.push_back(std::unique_ptr<const PassInfo>(&PI));
|
||||||
|
|
||||||
|
assert(!locked && "PassRegistry locked during registering a pass");
|
||||||
}
|
}
|
||||||
|
|
||||||
void PassRegistry::enumerateWith(PassRegistrationListener *L) {
|
void PassRegistry::enumerateWith(PassRegistrationListener *L) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user