- BasicBlocks.clear(); // Delete all basic blocks...
-}
-
-// Maintain the collector 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> *CollectorNames;
-static StringPool *CollectorNamePool;
-
-bool Function::hasCollector() const {
- return CollectorNames && CollectorNames->count(this);
-}
-
-const char *Function::getCollector() const {
- assert(hasCollector() && "Function has no collector");
- return *(*CollectorNames)[this];
-}
-
-void Function::setCollector(const char *Str) {
- if (!CollectorNamePool)
- CollectorNamePool = new StringPool();
- if (!CollectorNames)
- CollectorNames = new DenseMap<const Function*,PooledStringPtr>();
- (*CollectorNames)[this] = CollectorNamePool->intern(Str);
-}
-
-void Function::clearCollector() {
- if (CollectorNames) {
- CollectorNames->erase(this);
- if (CollectorNames->empty()) {
- delete CollectorNames;
- CollectorNames = 0;
- if (CollectorNamePool->empty()) {
- delete CollectorNamePool;
- CollectorNamePool = 0;
+
+ // Delete all basic blocks. They are now unused, except possibly by
+ // blockaddresses, but BasicBlock's destructor takes care of those.
+ while (!BasicBlocks.empty())
+ BasicBlocks.begin()->eraseFromParent();
+}
+
+void Function::addAttribute(unsigned i, Attributes attr) {
+ AttrListPtr PAL = getAttributes();
+ PAL = PAL.addAttr(i, attr);
+ setAttributes(PAL);
+}
+
+void Function::removeAttribute(unsigned i, Attributes attr) {
+ AttrListPtr PAL = getAttributes();
+ PAL = PAL.removeAttr(i, attr);
+ 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 {
+ assert(hasGC() && "Function has no collector");
+ sys::SmartScopedReader<true> Reader(*GCLock);
+ return *(*GCNames)[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::clearGC() {
+ sys::SmartScopedWriter<true> Writer(*GCLock);
+ if (GCNames) {
+ GCNames->erase(this);
+ if (GCNames->empty()) {
+ delete GCNames;
+ GCNames = 0;
+ if (GCNamePool->empty()) {
+ delete GCNamePool;
+ GCNamePool = 0;