1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-20 03:23:01 +02:00

It turns out that the two dimensional vectors were causing big slowdowns

in this for programs with lots of types (like the testcase in PR224).
The problem was that the type ID that the outer vector was using was not
very dense (as many types are getting resolved), so the vector is large
and gets reallocated a lot.

Since there are a lot of values in the program (the .ll file is 10M),
each reallocation has to copy the subvectors, which is also quite slow
(this wouldn't be a problem if C++ supported move semantics, but it
doesn't, at least not yet :(

Changing the outer data structure to a map speeds a release build of
llvm-as up from 11.21s to 5.13s on the testcase in PR224.

llvm-svn: 11244
This commit is contained in:
Chris Lattner 2004-02-09 21:03:38 +00:00
parent ef4a05f780
commit 034a264a99

View File

@ -57,14 +57,14 @@ static bool ObsoleteVarArgs;
// destroyed when the function is completed. // destroyed when the function is completed.
// //
typedef std::vector<Value *> ValueList; // Numbered defs typedef std::vector<Value *> ValueList; // Numbered defs
static void ResolveDefinitions(std::vector<ValueList> &LateResolvers, static void ResolveDefinitions(std::map<unsigned,ValueList> &LateResolvers,
std::vector<ValueList> *FutureLateResolvers = 0); std::map<unsigned,ValueList> *FutureLateResolvers = 0);
static struct PerModuleInfo { static struct PerModuleInfo {
Module *CurrentModule; Module *CurrentModule;
std::vector<ValueList> Values; // Module level numbered definitions std::map<unsigned,ValueList> Values; // Module level numbered definitions
std::vector<ValueList> LateResolveValues; std::map<unsigned,ValueList> LateResolveValues;
std::vector<PATypeHolder> Types; std::vector<PATypeHolder> Types;
std::map<ValID, PATypeHolder> LateResolveTypes; std::map<ValID, PATypeHolder> LateResolveTypes;
// GlobalRefs - This maintains a mapping between <Type, ValID>'s and forward // GlobalRefs - This maintains a mapping between <Type, ValID>'s and forward
@ -142,8 +142,8 @@ static struct PerModuleInfo {
static struct PerFunctionInfo { static struct PerFunctionInfo {
Function *CurrentFunction; // Pointer to current function being created Function *CurrentFunction; // Pointer to current function being created
std::vector<ValueList> Values; // Keep track of numbered definitions std::map<unsigned,ValueList> Values; // Keep track of numbered definitions
std::vector<ValueList> LateResolveValues; std::map<unsigned,ValueList> LateResolveValues;
std::vector<PATypeHolder> Types; std::vector<PATypeHolder> Types;
std::map<ValID, PATypeHolder> LateResolveTypes; std::map<ValID, PATypeHolder> LateResolveTypes;
SymbolTable LocalSymtab; SymbolTable LocalSymtab;
@ -170,11 +170,11 @@ static struct PerFunctionInfo {
FID = ValID::create((char*)CurrentFunction->getName().c_str()); FID = ValID::create((char*)CurrentFunction->getName().c_str());
} else { } else {
unsigned Slot = CurrentFunction->getType()->getUniqueID(); unsigned Slot = CurrentFunction->getType()->getUniqueID();
assert(CurModule.Values.size() > Slot && "Function not inserted?");
// Figure out which slot number if is... // Figure out which slot number if is...
ValueList &List = CurModule.Values[Slot];
for (unsigned i = 0; ; ++i) { for (unsigned i = 0; ; ++i) {
assert(i < CurModule.Values[Slot].size() && "Function not found!"); assert(i < List.size() && "Function not found!");
if (CurModule.Values[Slot][i] == CurrentFunction) { if (List[i] == CurrentFunction) {
FID = ValID::create((int)i); FID = ValID::create((int)i);
break; break;
} }
@ -198,16 +198,15 @@ static bool inFunctionScope() { return CurFun.CurrentFunction != 0; }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
static int InsertValue(Value *D, static int InsertValue(Value *D,
std::vector<ValueList> &ValueTab = CurFun.Values) { std::map<unsigned,ValueList> &ValueTab = CurFun.Values) {
if (D->hasName()) return -1; // Is this a numbered definition? if (D->hasName()) return -1; // Is this a numbered definition?
// Yes, insert the value into the value table... // Yes, insert the value into the value table...
unsigned type = D->getType()->getUniqueID(); unsigned type = D->getType()->getUniqueID();
if (ValueTab.size() <= type)
ValueTab.resize(type+1, ValueList());
//printf("Values[%d][%d] = %d\n", type, ValueTab[type].size(), D); //printf("Values[%d][%d] = %d\n", type, ValueTab[type].size(), D);
ValueTab[type].push_back(D); ValueList &List = ValueTab[type];
return ValueTab[type].size()-1; List.push_back(D);
return List.size()-1;
} }
// TODO: FIXME when Type are not const // TODO: FIXME when Type are not const
@ -297,20 +296,21 @@ static Value *getValNonImprovising(const Type *Ty, const ValID &D) {
unsigned Num = (unsigned)D.Num; unsigned Num = (unsigned)D.Num;
// Module constants occupy the lowest numbered slots... // Module constants occupy the lowest numbered slots...
if (type < CurModule.Values.size()) { std::map<unsigned,ValueList>::iterator VI = CurModule.Values.find(type);
if (Num < CurModule.Values[type].size()) if (VI != CurModule.Values.end()) {
return CurModule.Values[type][Num]; if (Num < VI->second.size())
return VI->second[Num];
Num -= CurModule.Values[type].size(); Num -= VI->second.size();
} }
// Make sure that our type is within bounds // Make sure that our type is within bounds
if (CurFun.Values.size() <= type) return 0; VI = CurFun.Values.find(type);
if (VI == CurFun.Values.end()) return 0;
// Check that the number is within bounds... // Check that the number is within bounds...
if (CurFun.Values[type].size() <= Num) return 0; if (VI->second.size() <= Num) return 0;
return CurFun.Values[type][Num]; return VI->second[Num];
} }
case ValID::NameVal: { // Is it a named definition? case ValID::NameVal: { // Is it a named definition?
@ -415,18 +415,20 @@ static Value *getVal(const Type *Ty, const ValID &D) {
// time (forward branches, phi functions for loops, etc...) resolve the // time (forward branches, phi functions for loops, etc...) resolve the
// defs now... // defs now...
// //
static void ResolveDefinitions(std::vector<ValueList> &LateResolvers, static void ResolveDefinitions(std::map<unsigned,ValueList> &LateResolvers,
std::vector<ValueList> *FutureLateResolvers) { std::map<unsigned,ValueList> *FutureLateResolvers) {
// Loop over LateResolveDefs fixing up stuff that couldn't be resolved // Loop over LateResolveDefs fixing up stuff that couldn't be resolved
for (unsigned ty = 0; ty < LateResolvers.size(); ty++) { for (std::map<unsigned,ValueList>::iterator LRI = LateResolvers.begin(),
while (!LateResolvers[ty].empty()) { E = LateResolvers.end(); LRI != E; ++LRI) {
Value *V = LateResolvers[ty].back(); ValueList &List = LRI->second;
while (!List.empty()) {
Value *V = List.back();
List.pop_back();
assert(!isa<Type>(V) && "Types should be in LateResolveTypes!"); assert(!isa<Type>(V) && "Types should be in LateResolveTypes!");
LateResolvers[ty].pop_back();
ValID &DID = getValIDFromPlaceHolder(V); ValID &DID = getValIDFromPlaceHolder(V);
Value *TheRealValue = getValNonImprovising(Type::getUniqueIDType(ty),DID); Value *TheRealValue =
getValNonImprovising(Type::getUniqueIDType(LRI->first), DID);
if (TheRealValue) { if (TheRealValue) {
V->replaceAllUsesWith(TheRealValue); V->replaceAllUsesWith(TheRealValue);
delete V; delete V;
@ -662,7 +664,7 @@ static PATypeHolder HandleUpRefs(const Type *ty) {
if (TypeToResolve) { if (TypeToResolve) {
UR_OUT(" * Resolving upreference for " UR_OUT(" * Resolving upreference for "
<< UpRefs[i].second->getDescription() << "\n"; << UpRefs[i].second->getDescription() << "\n";
std::string OldName = UpRefs[i].UpRefTy->getDescription()); std::string OldName = TypeToResolve->getDescription());
TypeToResolve->refineAbstractTypeTo(Ty); TypeToResolve->refineAbstractTypeTo(Ty);
} }