mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-29 10:25:12 +00:00
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
This commit is contained in:
@@ -86,27 +86,57 @@ static unsigned ProfileFunction(const Function *F) {
|
|||||||
|
|
||||||
class ComparableFunction {
|
class ComparableFunction {
|
||||||
public:
|
public:
|
||||||
|
static const ComparableFunction EmptyKey;
|
||||||
|
static const ComparableFunction TombstoneKey;
|
||||||
|
|
||||||
ComparableFunction(Function *Func, TargetData *TD)
|
ComparableFunction(Function *Func, TargetData *TD)
|
||||||
: Func(Func), Hash(ProfileFunction(Func)), TD(TD) {}
|
: Func(Func), Hash(ProfileFunction(Func)), TD(TD) {}
|
||||||
|
|
||||||
AssertingVH<Function> const Func;
|
Function *getFunc() const { return Func; }
|
||||||
const unsigned Hash;
|
unsigned getHash() const { return Hash; }
|
||||||
TargetData * const TD;
|
TargetData *getTD() const { return TD; }
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
explicit ComparableFunction(unsigned Hash)
|
||||||
|
: Func(NULL), Hash(Hash), TD(NULL) {}
|
||||||
|
|
||||||
|
AssertingVH<Function> Func;
|
||||||
|
unsigned Hash;
|
||||||
|
TargetData *TD;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MergeFunctionsEqualityInfo {
|
const ComparableFunction ComparableFunction::EmptyKey = ComparableFunction(0);
|
||||||
static ComparableFunction *getEmptyKey() {
|
const ComparableFunction ComparableFunction::TombstoneKey =
|
||||||
return reinterpret_cast<ComparableFunction*>(0);
|
ComparableFunction(1);
|
||||||
}
|
|
||||||
static ComparableFunction *getTombstoneKey() {
|
} // anonymous namespace
|
||||||
return reinterpret_cast<ComparableFunction*>(-1);
|
|
||||||
}
|
namespace llvm {
|
||||||
static unsigned getHashValue(const ComparableFunction *CF) {
|
template <>
|
||||||
return CF->Hash;
|
struct DenseMapInfo<ComparableFunction> {
|
||||||
}
|
static ComparableFunction getEmptyKey() {
|
||||||
static bool isEqual(const ComparableFunction *LHS,
|
return ComparableFunction::EmptyKey;
|
||||||
const ComparableFunction *RHS);
|
}
|
||||||
};
|
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,
|
/// MergeFunctions finds functions which will generate identical machine code,
|
||||||
/// by considering all pointer types to be equivalent. Once identified,
|
/// by considering all pointer types to be equivalent. Once identified,
|
||||||
@@ -121,12 +151,12 @@ public:
|
|||||||
bool runOnModule(Module &M);
|
bool runOnModule(Module &M);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef DenseSet<ComparableFunction *, MergeFunctionsEqualityInfo> FnSetType;
|
typedef DenseSet<ComparableFunction> FnSetType;
|
||||||
|
|
||||||
|
|
||||||
/// Insert a ComparableFunction into the FnSet, or merge it away if it's
|
/// Insert a ComparableFunction into the FnSet, or merge it away if it's
|
||||||
/// equal to one that's already present.
|
/// 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
|
/// MergeTwoFunctions - Merge two equivalent functions. Upon completion, G
|
||||||
/// may be deleted, or may be converted into a thunk. In either case, it
|
/// 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
|
// Insert - Insert a ComparableFunction into the FnSet, or merge it away if
|
||||||
// equal to one that's already inserted.
|
// 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);
|
std::pair<FnSetType::iterator, bool> Result = FnSet.insert(NewF);
|
||||||
if (Result.second)
|
if (Result.second)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
ComparableFunction *OldF = *Result.first;
|
const ComparableFunction &OldF = *Result.first;
|
||||||
assert(OldF && "Expected a hash collision");
|
|
||||||
|
|
||||||
// Never thunk a strong function to a weak function.
|
// 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() << " == "
|
DEBUG(dbgs() << " " << OldF.getFunc()->getName() << " == "
|
||||||
<< NewF->Func->getName() << '\n');
|
<< NewF.getFunc()->getName() << '\n');
|
||||||
|
|
||||||
Function *DeleteF = NewF->Func;
|
Function *DeleteF = NewF.getFunc();
|
||||||
delete NewF;
|
NewF.release();
|
||||||
MergeTwoFunctions(OldF->Func, DeleteF);
|
MergeTwoFunctions(OldF.getFunc(), DeleteF);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -701,7 +731,7 @@ bool MergeFunctions::runOnModule(Module &M) {
|
|||||||
Function *F = I++;
|
Function *F = I++;
|
||||||
if (!F->isDeclaration() && !F->hasAvailableExternallyLinkage() &&
|
if (!F->isDeclaration() && !F->hasAvailableExternallyLinkage() &&
|
||||||
!F->isWeakForLinker() && !IsThunk(F)) {
|
!F->isWeakForLinker() && !IsThunk(F)) {
|
||||||
ComparableFunction *CF = new ComparableFunction(F, TD);
|
ComparableFunction CF = ComparableFunction(F, TD);
|
||||||
LocalChanged |= Insert(FnSet, CF);
|
LocalChanged |= Insert(FnSet, CF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -714,24 +744,25 @@ bool MergeFunctions::runOnModule(Module &M) {
|
|||||||
Function *F = I++;
|
Function *F = I++;
|
||||||
if (!F->isDeclaration() && !F->hasAvailableExternallyLinkage() &&
|
if (!F->isDeclaration() && !F->hasAvailableExternallyLinkage() &&
|
||||||
F->isWeakForLinker() && !IsThunk(F)) {
|
F->isWeakForLinker() && !IsThunk(F)) {
|
||||||
ComparableFunction *CF = new ComparableFunction(F, TD);
|
ComparableFunction CF = ComparableFunction(F, TD);
|
||||||
LocalChanged |= Insert(FnSet, CF);
|
LocalChanged |= Insert(FnSet, CF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DeleteContainerPointers(FnSet);
|
|
||||||
Changed |= LocalChanged;
|
Changed |= LocalChanged;
|
||||||
} while (LocalChanged);
|
} while (LocalChanged);
|
||||||
|
|
||||||
return Changed;
|
return Changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MergeFunctionsEqualityInfo::isEqual(const ComparableFunction *LHS,
|
bool DenseMapInfo<ComparableFunction>::isEqual(const ComparableFunction &LHS,
|
||||||
const ComparableFunction *RHS) {
|
const ComparableFunction &RHS) {
|
||||||
if (LHS == RHS)
|
if (LHS.getFunc() == RHS.getFunc() &&
|
||||||
|
LHS.getHash() == RHS.getHash())
|
||||||
return true;
|
return true;
|
||||||
if (LHS == getEmptyKey() || LHS == getTombstoneKey() ||
|
if (!LHS.getFunc() || !RHS.getFunc())
|
||||||
RHS == getEmptyKey() || RHS == getTombstoneKey())
|
|
||||||
return false;
|
return false;
|
||||||
assert(LHS->TD == RHS->TD && "Comparing functions for different targets");
|
assert(LHS.getTD() == RHS.getTD() &&
|
||||||
return FunctionComparator(LHS->TD, LHS->Func, RHS->Func).Compare();
|
"Comparing functions for different targets");
|
||||||
|
return FunctionComparator(LHS.getTD(),
|
||||||
|
LHS.getFunc(), RHS.getFunc()).Compare();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user