From: Chris Lattner Date: Thu, 19 Sep 2002 19:22:11 +0000 (+0000) Subject: Add an optimization to support the most common access pattern for the X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=3f6962e0886140c2f5889f752d21ae49b76b0e78;p=oota-llvm.git Add an optimization to support the most common access pattern for the library. This speeds debug builds up significantly. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@3826 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Support/LeakDetector.cpp b/lib/Support/LeakDetector.cpp index 3dbd2e6e8d2..ecc4868d2e6 100644 --- a/lib/Support/LeakDetector.cpp +++ b/lib/Support/LeakDetector.cpp @@ -12,6 +12,13 @@ static std::set *Objects = 0; static std::set *LLVMObjects = 0; +// Because the most common usage pattern, by far, is to add a garbage object, +// then remove it immediately, we optimize this case. When an object is added, +// it is not added to the set immediately, it is added to the CachedValue Value. +// If it is immediately removed, no set search need be performed. +// +static const Value *CachedValue; + void LeakDetector::addGarbageObjectImpl(void *Object) { if (Objects == 0) Objects = new std::set(); @@ -25,18 +32,28 @@ void LeakDetector::removeGarbageObjectImpl(void *Object) { } void LeakDetector::addGarbageObjectImpl(const Value *Object) { - if (LLVMObjects == 0) - LLVMObjects = new std::set(); - assert(LLVMObjects->count(Object) == 0 && "Object already in set!"); - LLVMObjects->insert(Object); + if (CachedValue) { + if (LLVMObjects == 0) + LLVMObjects = new std::set(); + assert(LLVMObjects->count(CachedValue) == 0 && "Object already in set!"); + LLVMObjects->insert(CachedValue); + } + CachedValue = Object; } void LeakDetector::removeGarbageObjectImpl(const Value *Object) { - if (LLVMObjects) + if (Object == CachedValue) + CachedValue = 0; // Cache hit! + else if (LLVMObjects) LLVMObjects->erase(Object); } void LeakDetector::checkForGarbageImpl(const std::string &Message) { + if (CachedValue) // Flush the cache to the set... + addGarbageObjectImpl((Value*)0); + + assert(CachedValue == 0 && "No value should be cached anymore!"); + if ((Objects && !Objects->empty()) || (LLVMObjects && !LLVMObjects->empty())){ std::cerr << "Leaked objects found: " << Message << "\n"; diff --git a/lib/VMCore/LeakDetector.cpp b/lib/VMCore/LeakDetector.cpp index 3dbd2e6e8d2..ecc4868d2e6 100644 --- a/lib/VMCore/LeakDetector.cpp +++ b/lib/VMCore/LeakDetector.cpp @@ -12,6 +12,13 @@ static std::set *Objects = 0; static std::set *LLVMObjects = 0; +// Because the most common usage pattern, by far, is to add a garbage object, +// then remove it immediately, we optimize this case. When an object is added, +// it is not added to the set immediately, it is added to the CachedValue Value. +// If it is immediately removed, no set search need be performed. +// +static const Value *CachedValue; + void LeakDetector::addGarbageObjectImpl(void *Object) { if (Objects == 0) Objects = new std::set(); @@ -25,18 +32,28 @@ void LeakDetector::removeGarbageObjectImpl(void *Object) { } void LeakDetector::addGarbageObjectImpl(const Value *Object) { - if (LLVMObjects == 0) - LLVMObjects = new std::set(); - assert(LLVMObjects->count(Object) == 0 && "Object already in set!"); - LLVMObjects->insert(Object); + if (CachedValue) { + if (LLVMObjects == 0) + LLVMObjects = new std::set(); + assert(LLVMObjects->count(CachedValue) == 0 && "Object already in set!"); + LLVMObjects->insert(CachedValue); + } + CachedValue = Object; } void LeakDetector::removeGarbageObjectImpl(const Value *Object) { - if (LLVMObjects) + if (Object == CachedValue) + CachedValue = 0; // Cache hit! + else if (LLVMObjects) LLVMObjects->erase(Object); } void LeakDetector::checkForGarbageImpl(const std::string &Message) { + if (CachedValue) // Flush the cache to the set... + addGarbageObjectImpl((Value*)0); + + assert(CachedValue == 0 && "No value should be cached anymore!"); + if ((Objects && !Objects->empty()) || (LLVMObjects && !LLVMObjects->empty())){ std::cerr << "Leaked objects found: " << Message << "\n"; diff --git a/support/lib/Support/LeakDetector.cpp b/support/lib/Support/LeakDetector.cpp index 3dbd2e6e8d2..ecc4868d2e6 100644 --- a/support/lib/Support/LeakDetector.cpp +++ b/support/lib/Support/LeakDetector.cpp @@ -12,6 +12,13 @@ static std::set *Objects = 0; static std::set *LLVMObjects = 0; +// Because the most common usage pattern, by far, is to add a garbage object, +// then remove it immediately, we optimize this case. When an object is added, +// it is not added to the set immediately, it is added to the CachedValue Value. +// If it is immediately removed, no set search need be performed. +// +static const Value *CachedValue; + void LeakDetector::addGarbageObjectImpl(void *Object) { if (Objects == 0) Objects = new std::set(); @@ -25,18 +32,28 @@ void LeakDetector::removeGarbageObjectImpl(void *Object) { } void LeakDetector::addGarbageObjectImpl(const Value *Object) { - if (LLVMObjects == 0) - LLVMObjects = new std::set(); - assert(LLVMObjects->count(Object) == 0 && "Object already in set!"); - LLVMObjects->insert(Object); + if (CachedValue) { + if (LLVMObjects == 0) + LLVMObjects = new std::set(); + assert(LLVMObjects->count(CachedValue) == 0 && "Object already in set!"); + LLVMObjects->insert(CachedValue); + } + CachedValue = Object; } void LeakDetector::removeGarbageObjectImpl(const Value *Object) { - if (LLVMObjects) + if (Object == CachedValue) + CachedValue = 0; // Cache hit! + else if (LLVMObjects) LLVMObjects->erase(Object); } void LeakDetector::checkForGarbageImpl(const std::string &Message) { + if (CachedValue) // Flush the cache to the set... + addGarbageObjectImpl((Value*)0); + + assert(CachedValue == 0 && "No value should be cached anymore!"); + if ((Objects && !Objects->empty()) || (LLVMObjects && !LLVMObjects->empty())){ std::cerr << "Leaked objects found: " << Message << "\n";