llvm.org GIT mirror llvm / 3569d3c
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 Mehdi Amini 4 years ago
8 changed file(s) with 55 addition(s) and 44 deletion(s). Raw diff Collapse all Expand all
6565 * bit 2 : HasPrologueData
6666 * bit 3 : HasPersonalityFn
6767 * bits 4-13 : CallingConvention
68 * bits 14-15 : [reserved]
68 * bits 14 : HasGC
69 * bits 15 : [reserved]
6970 */
7071
7172 /// Bits from GlobalObject::GlobalObjectSubclassData.
219220
220221 /// hasGC/getGC/setGC/clearGC - The name of the garbage collection algorithm
221222 /// to use during code generation.
222 bool hasGC() const;
223 const char *getGC() const;
224 void setGC(const char *Str);
223 bool hasGC() const {
224 return getSubclassDataFromValue() & (1<<14);
225 }
226 const std::string &getGC() const;
227 void setGC(const std::string Str);
225228 void clearGC();
226229
227230 /// @brief adds the attribute to the list of attributes.
9292 /// tag registered with an LLVMContext has an unique ID.
9393 uint32_t getOperandBundleTagID(StringRef Tag) const;
9494
95
96 /// Define the GC for a function
97 void setGC(const Function &Fn, std::string GCName);
98
99 /// Return the GC for a function
100 const std::string &getGC(const Function &Fn);
101
102 /// Remove the GC for a function
103 void deleteGC(const Function &Fn);
104
105
95106 typedef void (*InlineAsmDiagHandlerTy)(const SMDiagnostic&, void *Context,
96107 unsigned LocCookie);
97108
17211721
17221722 const char *LLVMGetGC(LLVMValueRef Fn) {
17231723 Function *F = unwrap(Fn);
1724 return F->hasGC()? F->getGC() : nullptr;
1724 return F->hasGC()? F->getGC().c_str() : nullptr;
17251725 }
17261726
17271727 void LLVMSetGC(LLVMValueRef Fn, const char *GC) {
365365 setAttributes(PAL);
366366 }
367367
368 // Maintain the GC name for each function in an on-the-side table. This saves
369 // allocating an additional word in Function for programs which do not use GC
370 // (i.e., most programs) at the cost of increased overhead for clients which do
371 // use GC.
372 static DenseMap *GCNames;
373 static StringPool *GCNamePool;
374 static ManagedStatic > GCLock;
375
376 bool Function::hasGC() const {
377 sys::SmartScopedReader Reader(*GCLock);
378 return GCNames && GCNames->count(this);
379 }
380
381 const char *Function::getGC() const {
368 const std::string &Function::getGC() const {
382369 assert(hasGC() && "Function has no collector");
383 sys::SmartScopedReader Reader(*GCLock);
384 return *(*GCNames)[this];
385 }
386
387 void Function::setGC(const char *Str) {
388 sys::SmartScopedWriter Writer(*GCLock);
389 if (!GCNamePool)
390 GCNamePool = new StringPool();
391 if (!GCNames)
392 GCNames = new DenseMap();
393 (*GCNames)[this] = GCNamePool->intern(Str);
370 return getContext().getGC(*this);
371 }
372
373 void Function::setGC(const std::string Str) {
374 setValueSubclassDataBit(14, !Str.empty());
375 getContext().setGC(*this, std::move(Str));
394376 }
395377
396378 void Function::clearGC() {
397 sys::SmartScopedWriter Writer(*GCLock);
398 if (GCNames) {
399 GCNames->erase(this);
400 if (GCNames->empty()) {
401 delete GCNames;
402 GCNames = nullptr;
403 if (GCNamePool->empty()) {
404 delete GCNamePool;
405 GCNamePool = nullptr;
406 }
407 }
408 }
379 if (!hasGC())
380 return;
381 getContext().deleteGC(*this);
382 setValueSubclassDataBit(14, false);
409383 }
410384
411385 /// Copy all additional attributes (those not needed to create a Function) from
303303 uint32_t LLVMContext::getOperandBundleTagID(StringRef Tag) const {
304304 return pImpl->getOperandBundleTagID(Tag);
305305 }
306
307 void LLVMContext::setGC(const Function &Fn, std::string GCName) {
308 auto It = pImpl->GCNames.find(&Fn);
309
310 if (It == pImpl->GCNames.end()) {
311 pImpl->GCNames.insert(std::make_pair(&Fn, std::move(GCName)));
312 return;
313 }
314 It->second = std::move(GCName);
315 }
316 const std::string &LLVMContext::getGC(const Function &Fn) {
317 return pImpl->GCNames[&Fn];
318 }
319 void LLVMContext::deleteGC(const Function &Fn) {
320 pImpl->GCNames.erase(&Fn);
321 }
10261026 void getOperandBundleTags(SmallVectorImpl &Tags) const;
10271027 uint32_t getOperandBundleTagID(StringRef Tag) const;
10281028
1029 /// Maintain the GC name for each function.
1030 ///
1031 /// This saves allocating an additional word in Function for programs which
1032 /// do not use GC (i.e., most programs) at the cost of increased overhead for
1033 /// clients which do use GC.
1034 DenseMap GCNames;
1035
10291036 LLVMContextImpl(LLVMContext &C);
10301037 ~LLVMContextImpl();
10311038
498498 static bool shouldRewriteFunction(Function &F) {
499499 // TODO: This should check the GCStrategy
500500 if (F.hasGC()) {
501 const char *FunctionGCName = F.getGC();
501 const auto &FunctionGCName = F.getGC();
502502 const StringRef StatepointExampleName("statepoint-example");
503503 const StringRef CoreCLRName("coreclr");
504504 return (StatepointExampleName == FunctionGCName) ||
25572557 static bool shouldRewriteStatepointsIn(Function &F) {
25582558 // TODO: This should check the GCStrategy
25592559 if (F.hasGC()) {
2560 const char *FunctionGCName = F.getGC();
2560 const auto &FunctionGCName = F.getGC();
25612561 const StringRef StatepointExampleName("statepoint-example");
25622562 const StringRef CoreCLRName("coreclr");
25632563 return (StatepointExampleName == FunctionGCName) ||