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:
Chris Lattner 2006-01-22 23:10:26 +00:00
parent e01a9852a0
commit e05cf71616

View File

@ -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;
} }