mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-23 04:28:30 +00:00
Make this more efficient in the following ways:
1. Do not statically construct a map when the program starts up, this is expensive and cannot be optimized. Instead, create a list. 2. Do not insert entries for all function in the module into a hashmap that lives the full life of the compiler. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25512 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
e01a9852a0
commit
e05cf71616
@ -42,12 +42,12 @@ Statistic<> SimplifiedLibCalls("simplify-libcalls",
|
|||||||
class LibCallOptimization;
|
class LibCallOptimization;
|
||||||
class SimplifyLibCalls;
|
class SimplifyLibCalls;
|
||||||
|
|
||||||
/// This hash map is populated by the constructor for LibCallOptimization class.
|
/// This list is populated by the constructor for LibCallOptimization class.
|
||||||
/// Therefore all subclasses are registered here at static initialization time
|
/// Therefore all subclasses are registered here at static initialization time
|
||||||
/// and this list is what the SimplifyLibCalls pass uses to apply the individual
|
/// and this list is what the SimplifyLibCalls pass uses to apply the individual
|
||||||
/// optimizations to the call sites.
|
/// optimizations to the call sites.
|
||||||
/// @brief The list of optimizations deriving from LibCallOptimization
|
/// @brief The list of optimizations deriving from LibCallOptimization
|
||||||
static hash_map<std::string,LibCallOptimization*> optlist;
|
static LibCallOptimization *OptList = 0;
|
||||||
|
|
||||||
/// This class is the abstract base class for the set of optimizations that
|
/// This class is the abstract base class for the set of optimizations that
|
||||||
/// corresponds to one library call. The SimplifyLibCalls pass will call the
|
/// corresponds to one library call. The SimplifyLibCalls pass will call the
|
||||||
@ -65,22 +65,37 @@ static hash_map<std::string,LibCallOptimization*> optlist;
|
|||||||
/// way (e.g. strlen(X) can be reduced to a constant if X is a constant global).
|
/// way (e.g. strlen(X) can be reduced to a constant if X is a constant global).
|
||||||
/// @brief Base class for library call optimizations
|
/// @brief Base class for library call optimizations
|
||||||
class LibCallOptimization {
|
class LibCallOptimization {
|
||||||
|
LibCallOptimization **Prev, *Next;
|
||||||
|
const char *FunctionName; ///< Name of the library call we optimize
|
||||||
|
#ifndef NDEBUG
|
||||||
|
Statistic<> occurrences; ///< debug statistic (-debug-only=simplify-libcalls)
|
||||||
|
#endif
|
||||||
public:
|
public:
|
||||||
/// The \p fname argument must be the name of the library function being
|
/// The \p fname argument must be the name of the library function being
|
||||||
/// optimized by the subclass.
|
/// optimized by the subclass.
|
||||||
/// @brief Constructor that registers the optimization.
|
/// @brief Constructor that registers the optimization.
|
||||||
LibCallOptimization(const char* fname, const char* description )
|
LibCallOptimization(const char *FName, const char *Description)
|
||||||
: func_name(fname)
|
: FunctionName(FName)
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
, occurrences("simplify-libcalls",description)
|
, occurrences("simplify-libcalls", Description)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
// Register this call optimizer in the optlist (a hash_map)
|
// Register this optimizer in the list of optimizations.
|
||||||
optlist[fname] = this;
|
Next = OptList;
|
||||||
|
OptList = this;
|
||||||
|
Prev = &OptList;
|
||||||
|
if (Next) Next->Prev = &Next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// getNext - All libcall optimizations are chained together into a list,
|
||||||
|
/// return the next one in the list.
|
||||||
|
LibCallOptimization *getNext() { return Next; }
|
||||||
|
|
||||||
/// @brief Deregister from the optlist
|
/// @brief Deregister from the optlist
|
||||||
virtual ~LibCallOptimization() { optlist.erase(func_name); }
|
virtual ~LibCallOptimization() {
|
||||||
|
*Prev = Next;
|
||||||
|
if (Next) Next->Prev = Prev;
|
||||||
|
}
|
||||||
|
|
||||||
/// The implementation of this function in subclasses should determine if
|
/// The implementation of this function in subclasses should determine if
|
||||||
/// \p F is suitable for the optimization. This method is called by
|
/// \p F is suitable for the optimization. This method is called by
|
||||||
@ -110,18 +125,14 @@ public:
|
|||||||
) = 0;
|
) = 0;
|
||||||
|
|
||||||
/// @brief Get the name of the library call being optimized
|
/// @brief Get the name of the library call being optimized
|
||||||
const char * getFunctionName() const { return func_name; }
|
const char *getFunctionName() const { return FunctionName; }
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
/// @brief Called by SimplifyLibCalls to update the occurrences statistic.
|
/// @brief Called by SimplifyLibCalls to update the occurrences statistic.
|
||||||
void succeeded() { DEBUG(++occurrences); }
|
void succeeded() {
|
||||||
#endif
|
|
||||||
|
|
||||||
private:
|
|
||||||
const char* func_name; ///< Name of the library call we optimize
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
Statistic<> occurrences; ///< debug statistic (-debug-only=simplify-libcalls)
|
DEBUG(++occurrences);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// This class is an LLVM Pass that applies each of the LibCallOptimization
|
/// This class is an LLVM Pass that applies each of the LibCallOptimization
|
||||||
@ -151,6 +162,9 @@ public:
|
|||||||
reset(M);
|
reset(M);
|
||||||
|
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
hash_map<std::string, LibCallOptimization*> OptznMap;
|
||||||
|
for (LibCallOptimization *Optzn = OptList; Optzn; Optzn = Optzn->getNext())
|
||||||
|
OptznMap[Optzn->getFunctionName()] = Optzn;
|
||||||
|
|
||||||
// The call optimizations can be recursive. That is, the optimization might
|
// The call optimizations can be recursive. That is, the optimization might
|
||||||
// generate a call to another function which can also be optimized. This way
|
// generate a call to another function which can also be optimized. This way
|
||||||
@ -169,12 +183,14 @@ public:
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Get the optimization class that pertains to this function
|
// Get the optimization class that pertains to this function
|
||||||
LibCallOptimization* CO = optlist[FI->getName().c_str()];
|
hash_map<std::string, LibCallOptimization*>::iterator OMI =
|
||||||
if (!CO)
|
OptznMap.find(FI->getName());
|
||||||
continue;
|
if (OMI == OptznMap.end()) continue;
|
||||||
|
|
||||||
|
LibCallOptimization *CO = OMI->second;
|
||||||
|
|
||||||
// Make sure the called function is suitable for the optimization
|
// Make sure the called function is suitable for the optimization
|
||||||
if (!CO->ValidateCalledFunction(FI,*this))
|
if (!CO->ValidateCalledFunction(FI, *this))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Loop over each of the uses of the function
|
// Loop over each of the uses of the function
|
||||||
@ -186,14 +202,13 @@ public:
|
|||||||
if (CO->OptimizeCall(CI, *this)) {
|
if (CO->OptimizeCall(CI, *this)) {
|
||||||
++SimplifiedLibCalls;
|
++SimplifiedLibCalls;
|
||||||
found_optimization = result = true;
|
found_optimization = result = true;
|
||||||
#ifndef NDEBUG
|
|
||||||
CO->succeeded();
|
CO->succeeded();
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (found_optimization);
|
} while (found_optimization);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user