mirror of
https://github.com/RPCSX/llvm.git
synced 2025-02-26 07:56:43 +00:00
Remove static global GCNames from Function.cpp and move it to the Context
This remove the need for locking when deleting a function. Differential Revision: http://reviews.llvm.org/D15988 From: Mehdi Amini <mehdi.amini@apple.com> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@257139 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
e51b530b12
commit
3569d3c5eb
@ -66,7 +66,8 @@ private:
|
||||
* bit 2 : HasPrologueData
|
||||
* bit 3 : HasPersonalityFn
|
||||
* bits 4-13 : CallingConvention
|
||||
* bits 14-15 : [reserved]
|
||||
* bits 14 : HasGC
|
||||
* bits 15 : [reserved]
|
||||
*/
|
||||
|
||||
/// Bits from GlobalObject::GlobalObjectSubclassData.
|
||||
@ -220,9 +221,11 @@ public:
|
||||
|
||||
/// hasGC/getGC/setGC/clearGC - The name of the garbage collection algorithm
|
||||
/// to use during code generation.
|
||||
bool hasGC() const;
|
||||
const char *getGC() const;
|
||||
void setGC(const char *Str);
|
||||
bool hasGC() const {
|
||||
return getSubclassDataFromValue() & (1<<14);
|
||||
}
|
||||
const std::string &getGC() const;
|
||||
void setGC(const std::string Str);
|
||||
void clearGC();
|
||||
|
||||
/// @brief adds the attribute to the list of attributes.
|
||||
|
@ -93,6 +93,17 @@ public:
|
||||
/// tag registered with an LLVMContext has an unique ID.
|
||||
uint32_t getOperandBundleTagID(StringRef Tag) const;
|
||||
|
||||
|
||||
/// Define the GC for a function
|
||||
void setGC(const Function &Fn, std::string GCName);
|
||||
|
||||
/// Return the GC for a function
|
||||
const std::string &getGC(const Function &Fn);
|
||||
|
||||
/// Remove the GC for a function
|
||||
void deleteGC(const Function &Fn);
|
||||
|
||||
|
||||
typedef void (*InlineAsmDiagHandlerTy)(const SMDiagnostic&, void *Context,
|
||||
unsigned LocCookie);
|
||||
|
||||
|
@ -1722,7 +1722,7 @@ void LLVMSetFunctionCallConv(LLVMValueRef Fn, unsigned CC) {
|
||||
|
||||
const char *LLVMGetGC(LLVMValueRef Fn) {
|
||||
Function *F = unwrap<Function>(Fn);
|
||||
return F->hasGC()? F->getGC() : nullptr;
|
||||
return F->hasGC()? F->getGC().c_str() : nullptr;
|
||||
}
|
||||
|
||||
void LLVMSetGC(LLVMValueRef Fn, const char *GC) {
|
||||
|
@ -366,47 +366,21 @@ void Function::addDereferenceableOrNullAttr(unsigned i, uint64_t Bytes) {
|
||||
setAttributes(PAL);
|
||||
}
|
||||
|
||||
// Maintain the GC name for each function in an on-the-side table. This saves
|
||||
// allocating an additional word in Function for programs which do not use GC
|
||||
// (i.e., most programs) at the cost of increased overhead for clients which do
|
||||
// use GC.
|
||||
static DenseMap<const Function*,PooledStringPtr> *GCNames;
|
||||
static StringPool *GCNamePool;
|
||||
static ManagedStatic<sys::SmartRWMutex<true> > GCLock;
|
||||
|
||||
bool Function::hasGC() const {
|
||||
sys::SmartScopedReader<true> Reader(*GCLock);
|
||||
return GCNames && GCNames->count(this);
|
||||
}
|
||||
|
||||
const char *Function::getGC() const {
|
||||
const std::string &Function::getGC() const {
|
||||
assert(hasGC() && "Function has no collector");
|
||||
sys::SmartScopedReader<true> Reader(*GCLock);
|
||||
return *(*GCNames)[this];
|
||||
return getContext().getGC(*this);
|
||||
}
|
||||
|
||||
void Function::setGC(const char *Str) {
|
||||
sys::SmartScopedWriter<true> Writer(*GCLock);
|
||||
if (!GCNamePool)
|
||||
GCNamePool = new StringPool();
|
||||
if (!GCNames)
|
||||
GCNames = new DenseMap<const Function*,PooledStringPtr>();
|
||||
(*GCNames)[this] = GCNamePool->intern(Str);
|
||||
void Function::setGC(const std::string Str) {
|
||||
setValueSubclassDataBit(14, !Str.empty());
|
||||
getContext().setGC(*this, std::move(Str));
|
||||
}
|
||||
|
||||
void Function::clearGC() {
|
||||
sys::SmartScopedWriter<true> Writer(*GCLock);
|
||||
if (GCNames) {
|
||||
GCNames->erase(this);
|
||||
if (GCNames->empty()) {
|
||||
delete GCNames;
|
||||
GCNames = nullptr;
|
||||
if (GCNamePool->empty()) {
|
||||
delete GCNamePool;
|
||||
GCNamePool = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!hasGC())
|
||||
return;
|
||||
getContext().deleteGC(*this);
|
||||
setValueSubclassDataBit(14, false);
|
||||
}
|
||||
|
||||
/// Copy all additional attributes (those not needed to create a Function) from
|
||||
|
@ -304,3 +304,19 @@ void LLVMContext::getOperandBundleTags(SmallVectorImpl<StringRef> &Tags) const {
|
||||
uint32_t LLVMContext::getOperandBundleTagID(StringRef Tag) const {
|
||||
return pImpl->getOperandBundleTagID(Tag);
|
||||
}
|
||||
|
||||
void LLVMContext::setGC(const Function &Fn, std::string GCName) {
|
||||
auto It = pImpl->GCNames.find(&Fn);
|
||||
|
||||
if (It == pImpl->GCNames.end()) {
|
||||
pImpl->GCNames.insert(std::make_pair(&Fn, std::move(GCName)));
|
||||
return;
|
||||
}
|
||||
It->second = std::move(GCName);
|
||||
}
|
||||
const std::string &LLVMContext::getGC(const Function &Fn) {
|
||||
return pImpl->GCNames[&Fn];
|
||||
}
|
||||
void LLVMContext::deleteGC(const Function &Fn) {
|
||||
pImpl->GCNames.erase(&Fn);
|
||||
}
|
||||
|
@ -1027,6 +1027,13 @@ public:
|
||||
void getOperandBundleTags(SmallVectorImpl<StringRef> &Tags) const;
|
||||
uint32_t getOperandBundleTagID(StringRef Tag) const;
|
||||
|
||||
/// Maintain the GC name for each function.
|
||||
///
|
||||
/// This saves allocating an additional word in Function for programs which
|
||||
/// do not use GC (i.e., most programs) at the cost of increased overhead for
|
||||
/// clients which do use GC.
|
||||
DenseMap<const Function*, std::string> GCNames;
|
||||
|
||||
LLVMContextImpl(LLVMContext &C);
|
||||
~LLVMContextImpl();
|
||||
|
||||
|
@ -499,7 +499,7 @@ static bool isGCSafepointPoll(Function &F) {
|
||||
static bool shouldRewriteFunction(Function &F) {
|
||||
// TODO: This should check the GCStrategy
|
||||
if (F.hasGC()) {
|
||||
const char *FunctionGCName = F.getGC();
|
||||
const auto &FunctionGCName = F.getGC();
|
||||
const StringRef StatepointExampleName("statepoint-example");
|
||||
const StringRef CoreCLRName("coreclr");
|
||||
return (StatepointExampleName == FunctionGCName) ||
|
||||
|
@ -2558,7 +2558,7 @@ void RewriteStatepointsForGC::stripNonValidAttributesFromBody(Function &F) {
|
||||
static bool shouldRewriteStatepointsIn(Function &F) {
|
||||
// TODO: This should check the GCStrategy
|
||||
if (F.hasGC()) {
|
||||
const char *FunctionGCName = F.getGC();
|
||||
const auto &FunctionGCName = F.getGC();
|
||||
const StringRef StatepointExampleName("statepoint-example");
|
||||
const StringRef CoreCLRName("coreclr");
|
||||
return (StatepointExampleName == FunctionGCName) ||
|
||||
|
Loading…
x
Reference in New Issue
Block a user