summaryrefslogtreecommitdiff
path: root/lib/Transforms/IPO/MergeFunctions.cpp
diff options
context:
space:
mode:
authorNick Lewycky <nicholas@mxc.ca>2010-09-05 09:00:32 +0000
committerNick Lewycky <nicholas@mxc.ca>2010-09-05 09:00:32 +0000
commitb0e17779ba401feae32cdd1dd4096d49c1746153 (patch)
treedce245e6bc96244683a7ad1bc335125df8bf9e32 /lib/Transforms/IPO/MergeFunctions.cpp
parentb0104e1bb56cde925d91a5b2432a18f87214484a (diff)
downloadllvm-b0e17779ba401feae32cdd1dd4096d49c1746153.tar.gz
llvm-b0e17779ba401feae32cdd1dd4096d49c1746153.tar.bz2
llvm-b0e17779ba401feae32cdd1dd4096d49c1746153.tar.xz
Switch FnSet to containing the ComparableFunction instead of a pointer to one.
This reduces malloc traffic (yay!) and removes MergeFunctionsEqualityInfo. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@113105 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/IPO/MergeFunctions.cpp')
-rw-r--r--lib/Transforms/IPO/MergeFunctions.cpp103
1 files changed, 67 insertions, 36 deletions
diff --git a/lib/Transforms/IPO/MergeFunctions.cpp b/lib/Transforms/IPO/MergeFunctions.cpp
index 726466ec81..f58f08ae81 100644
--- a/lib/Transforms/IPO/MergeFunctions.cpp
+++ b/lib/Transforms/IPO/MergeFunctions.cpp
@@ -86,28 +86,58 @@ static unsigned ProfileFunction(const Function *F) {
class ComparableFunction {
public:
+ static const ComparableFunction EmptyKey;
+ static const ComparableFunction TombstoneKey;
+
ComparableFunction(Function *Func, TargetData *TD)
: Func(Func), Hash(ProfileFunction(Func)), TD(TD) {}
- AssertingVH<Function> const Func;
- const unsigned Hash;
- TargetData * const TD;
-};
+ Function *getFunc() const { return Func; }
+ unsigned getHash() const { return Hash; }
+ TargetData *getTD() const { return TD; }
-struct MergeFunctionsEqualityInfo {
- static ComparableFunction *getEmptyKey() {
- return reinterpret_cast<ComparableFunction*>(0);
- }
- static ComparableFunction *getTombstoneKey() {
- return reinterpret_cast<ComparableFunction*>(-1);
+ // Drops AssertingVH reference to the function. Outside of debug mode, this
+ // does nothing.
+ void release() {
+ assert(Func &&
+ "Attempted to release function twice, or release empty/tombstone!");
+ Func = NULL;
}
- static unsigned getHashValue(const ComparableFunction *CF) {
- return CF->Hash;
- }
- static bool isEqual(const ComparableFunction *LHS,
- const ComparableFunction *RHS);
+
+private:
+ explicit ComparableFunction(unsigned Hash)
+ : Func(NULL), Hash(Hash), TD(NULL) {}
+
+ AssertingVH<Function> Func;
+ unsigned Hash;
+ TargetData *TD;
};
+const ComparableFunction ComparableFunction::EmptyKey = ComparableFunction(0);
+const ComparableFunction ComparableFunction::TombstoneKey =
+ ComparableFunction(1);
+
+} // anonymous namespace
+
+namespace llvm {
+ template <>
+ struct DenseMapInfo<ComparableFunction> {
+ static ComparableFunction getEmptyKey() {
+ return ComparableFunction::EmptyKey;
+ }
+ static ComparableFunction getTombstoneKey() {
+ return ComparableFunction::TombstoneKey;
+ }
+ static unsigned getHashValue(const ComparableFunction &CF) {
+ return CF.getHash();
+ }
+ static bool isEqual(const ComparableFunction &LHS,
+ const ComparableFunction &RHS);
+ };
+}
+
+namespace {
+
/// MergeFunctions finds functions which will generate identical machine code,
/// by considering all pointer types to be equivalent. Once identified,
/// MergeFunctions will fold them by replacing a call to one to a call to a
@@ -121,12 +151,12 @@ public:
bool runOnModule(Module &M);
private:
- typedef DenseSet<ComparableFunction *, MergeFunctionsEqualityInfo> FnSetType;
+ typedef DenseSet<ComparableFunction> FnSetType;
/// Insert a ComparableFunction into the FnSet, or merge it away if it's
/// equal to one that's already present.
- bool Insert(FnSetType &FnSet, ComparableFunction *NewF);
+ bool Insert(FnSetType &FnSet, ComparableFunction &NewF);
/// MergeTwoFunctions - Merge two equivalent functions. Upon completion, G
/// may be deleted, or may be converted into a thunk. In either case, it
@@ -602,23 +632,23 @@ void MergeFunctions::MergeTwoFunctions(Function *F, Function *G) const {
// Insert - Insert a ComparableFunction into the FnSet, or merge it away if
// equal to one that's already inserted.
-bool MergeFunctions::Insert(FnSetType &FnSet, ComparableFunction *NewF) {
+bool MergeFunctions::Insert(FnSetType &FnSet, ComparableFunction &NewF) {
std::pair<FnSetType::iterator, bool> Result = FnSet.insert(NewF);
if (Result.second)
return false;
- ComparableFunction *OldF = *Result.first;
- assert(OldF && "Expected a hash collision");
+ const ComparableFunction &OldF = *Result.first;
// Never thunk a strong function to a weak function.
- assert(!OldF->Func->isWeakForLinker() || NewF->Func->isWeakForLinker());
+ assert(!OldF.getFunc()->isWeakForLinker() ||
+ NewF.getFunc()->isWeakForLinker());
- DEBUG(dbgs() << " " << OldF->Func->getName() << " == "
- << NewF->Func->getName() << '\n');
+ DEBUG(dbgs() << " " << OldF.getFunc()->getName() << " == "
+ << NewF.getFunc()->getName() << '\n');
- Function *DeleteF = NewF->Func;
- delete NewF;
- MergeTwoFunctions(OldF->Func, DeleteF);
+ Function *DeleteF = NewF.getFunc();
+ NewF.release();
+ MergeTwoFunctions(OldF.getFunc(), DeleteF);
return true;
}
@@ -701,7 +731,7 @@ bool MergeFunctions::runOnModule(Module &M) {
Function *F = I++;
if (!F->isDeclaration() && !F->hasAvailableExternallyLinkage() &&
!F->isWeakForLinker() && !IsThunk(F)) {
- ComparableFunction *CF = new ComparableFunction(F, TD);
+ ComparableFunction CF = ComparableFunction(F, TD);
LocalChanged |= Insert(FnSet, CF);
}
}
@@ -714,24 +744,25 @@ bool MergeFunctions::runOnModule(Module &M) {
Function *F = I++;
if (!F->isDeclaration() && !F->hasAvailableExternallyLinkage() &&
F->isWeakForLinker() && !IsThunk(F)) {
- ComparableFunction *CF = new ComparableFunction(F, TD);
+ ComparableFunction CF = ComparableFunction(F, TD);
LocalChanged |= Insert(FnSet, CF);
}
}
- DeleteContainerPointers(FnSet);
Changed |= LocalChanged;
} while (LocalChanged);
return Changed;
}
-bool MergeFunctionsEqualityInfo::isEqual(const ComparableFunction *LHS,
- const ComparableFunction *RHS) {
- if (LHS == RHS)
+bool DenseMapInfo<ComparableFunction>::isEqual(const ComparableFunction &LHS,
+ const ComparableFunction &RHS) {
+ if (LHS.getFunc() == RHS.getFunc() &&
+ LHS.getHash() == RHS.getHash())
return true;
- if (LHS == getEmptyKey() || LHS == getTombstoneKey() ||
- RHS == getEmptyKey() || RHS == getTombstoneKey())
+ if (!LHS.getFunc() || !RHS.getFunc())
return false;
- assert(LHS->TD == RHS->TD && "Comparing functions for different targets");
- return FunctionComparator(LHS->TD, LHS->Func, RHS->Func).Compare();
+ assert(LHS.getTD() == RHS.getTD() &&
+ "Comparing functions for different targets");
+ return FunctionComparator(LHS.getTD(),
+ LHS.getFunc(), RHS.getFunc()).Compare();
}