[llvm-commits] CVS: llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp

Reid Spencer reid at x10sys.com
Wed Apr 27 14:29:32 PDT 2005



Changes in directory llvm/lib/Transforms/IPO:

SimplifyLibCalls.cpp updated: 1.18 -> 1.19
---
Log message:

Doxygenate.


---
Diffs of the changes:  (+71 -54)

 SimplifyLibCalls.cpp |  125 ++++++++++++++++++++++++++++-----------------------
 1 files changed, 71 insertions(+), 54 deletions(-)


Index: llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp
diff -u llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp:1.18 llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp:1.19
--- llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp:1.18	Wed Apr 27 12:46:54 2005
+++ llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp	Wed Apr 27 16:29:20 2005
@@ -37,23 +37,33 @@
 Statistic<> SimplifiedLibCalls("simplify-libcalls", 
   "Number of well-known library calls simplified");
 
-/// @brief The list of optimizations deriving from LibCallOptimization
+// Forward declarations
 class LibCallOptimization;
 class SimplifyLibCalls;
+
+/// @brief The list of optimizations deriving from LibCallOptimization
 hash_map<std::string,LibCallOptimization*> optlist;
 
 /// This class is the abstract base class for the set of optimizations that
-/// corresponds to one library call. The SimplifyLibCall pass will call the
+/// corresponds to one library call. The SimplifyLibCalls pass will call the
 /// ValidateCalledFunction method to ask the optimization if a given Function
-/// is the kind that the optimization can handle. It will also call the
-/// OptimizeCall method to perform, or attempt to perform, the optimization(s)
-/// for the library call. Subclasses of this class are located toward the
-/// end of this file.
+/// is the kind that the optimization can handle. If the subclass returns true,
+/// then SImplifyLibCalls will also call the OptimizeCall method to perform, 
+/// or attempt to perform, the optimization(s) for the library call. Otherwise,
+/// OptimizeCall won't be called. Subclasses are responsible for providing the
+/// name of the library call (strlen, strcpy, etc.) to the LibCallOptimization
+/// constructor. This is used to efficiently select which call instructions to
+/// optimize. The criteria for a "lib call" is "anything with well known 
+/// semantics", typically a library function that is defined by an international
+/// standard. Because the semantics are well known, the optimizations can 
+/// generally short-circuit actually calling the function if there's a simpler
+/// way (e.g. strlen(X) can be reduced to a constant if X is a constant global).
 /// @brief Base class for library call optimizations
 struct LibCallOptimization
 {
-  /// @brief Constructor that registers the optimization. The \p fname argument
-  /// must be the name of the library function being optimized by the subclass.
+  /// The \p fname argument must be the name of the library function being 
+  /// optimized by the subclass.
+  /// @brief Constructor that registers the optimization.
   LibCallOptimization(const char * fname )
     : func_name(fname)
 #ifndef NDEBUG
@@ -61,22 +71,23 @@
     , occurrences(stat_name.c_str(),"Number of calls simplified") 
 #endif
   {
-    // Register this call optimizer
+    // Register this call optimizer in the optlist (a hash_map)
     optlist[func_name] = this;
   }
 
-  /// @brief Destructor
-  virtual ~LibCallOptimization() {}
+  /// @brief Deregister from the optlist
+  virtual ~LibCallOptimization() { optlist.erase(func_name); }
 
   /// The implementation of this function in subclasses should determine if
   /// \p F is suitable for the optimization. This method is called by 
-  /// runOnModule to short circuit visiting all the call sites of such a
-  /// function if that function is not suitable in the first place.
-  /// If the called function is suitabe, this method should return true;
+  /// SimplifyLibCalls::runOnModule to short circuit visiting all the call 
+  /// sites of such a function if that function is not suitable in the first 
+  /// place.  If the called function is suitabe, this method should return true;
   /// false, otherwise. This function should also perform any lazy 
   /// initialization that the LibCallOptimization needs to do, if its to return 
   /// true. This avoids doing initialization until the optimizer is actually
   /// going to be called upon to do some optimization.
+  /// @brief Determine if the function is suitable for optimization
   virtual bool ValidateCalledFunction(
     const Function* F,    ///< The function that is the target of call sites
     SimplifyLibCalls& SLC ///< The pass object invoking us
@@ -88,8 +99,6 @@
   /// the call and (b) to perform the optimization. If an action is taken 
   /// against ci, the subclass is responsible for returning true and ensuring
   /// that ci is erased from its parent.
-  /// @param ci the call instruction under consideration
-  /// @param f the function that ci calls.
   /// @brief Optimize a call, if possible.
   virtual bool OptimizeCall(
     CallInst* ci,          ///< The call instruction that should be optimized.
@@ -100,7 +109,8 @@
   const char * getFunctionName() const { return func_name; }
 
 #ifndef NDEBUG
-  void occurred() { ++occurrences; }
+  /// @brief Called by SimplifyLibCalls to update the occurrences statistic.
+  void succeeded() { ++occurrences; }
 #endif
 
 private:
@@ -111,23 +121,19 @@
 #endif
 };
 
-/// This class is the base class for a set of small but important 
-/// optimizations of calls to well-known functions, such as those in the c
-/// library. 
-
 /// This class is an LLVM Pass that applies each of the LibCallOptimization 
 /// instances to all the call sites in a module, relatively efficiently. The
 /// purpose of this pass is to provide optimizations for calls to well-known 
 /// functions with well-known semantics, such as those in the c library. The
-/// class provides the basic infrastructure for handling runOnModule.  
-/// Whenever this pass finds a function call, it asks the subclasses to 
-/// validate the call by calling ValidateLibraryCall. If it is validated, then
-/// the OptimizeCall method is called. 
+/// class provides the basic infrastructure for handling runOnModule.  Whenever /// this pass finds a function call, it asks the appropriate optimizer to 
+/// validate the call (ValidateLibraryCall). If it is validated, then
+/// the OptimizeCall method is also called.
 /// @brief A ModulePass for optimizing well-known function calls.
 struct SimplifyLibCalls : public ModulePass 
 {
   /// We need some target data for accurate signature details that are
   /// target dependent. So we require target data in our AnalysisUsage.
+  /// @brief Require TargetData from AnalysisUsage.
   virtual void getAnalysisUsage(AnalysisUsage& Info) const
   {
     // Ask that the TargetData analysis be performed before us so we can use
@@ -137,6 +143,7 @@
 
   /// For this pass, process all of the function calls in the module, calling
   /// ValidateLibraryCall and OptimizeCall as appropriate.
+  /// @brief Run all the lib call optimizations on a Module.
   virtual bool runOnModule(Module &M)
   {
     reset(M);
@@ -183,7 +190,7 @@
               ++SimplifiedLibCalls;
               found_optimization = result = true;
 #ifndef NDEBUG
-              CO->occurred();
+              CO->succeeded();
 #endif
             }
           }
@@ -230,10 +237,8 @@
     return memcpy_func;
   }
 
-  /// @brief Compute length of constant string
-  bool getConstantStringLength(Value* V, uint64_t& len );
-
 private:
+  /// @brief Reset our cached data for a new Module
   void reset(Module& mod)
   {
     M = &mod;
@@ -243,10 +248,10 @@
   }
 
 private:
-  Function* memcpy_func;
-  Function* strlen_func;
-  Module* M;
-  TargetData* TD;
+  Function* memcpy_func; ///< Cached llvm.memcpy function
+  Function* strlen_func; ///< Cached strlen function
+  Module* M;             ///< Cached Module
+  TargetData* TD;        ///< Cached TargetData
 };
 
 // Register the pass
@@ -272,9 +277,8 @@
 
 /// This LibCallOptimization will find instances of a call to "exit" that occurs
 /// within the "main" function and change it to a simple "ret" instruction with
-/// the same value as passed to the exit function. It assumes that the 
-/// instructions after the call to exit(3) can be deleted since they are 
-/// unreachable anyway.
+/// the same value passed to the exit function. When this is done, it splits the
+/// basic block at the exit(3) call and deletes the call instruction.
 /// @brief Replace calls to exit in main with a simple return
 struct ExitInMainOptimization : public LibCallOptimization
 {
@@ -335,16 +339,18 @@
 /// This LibCallOptimization will simplify a call to the strcat library 
 /// function. The simplification is possible only if the string being 
 /// concatenated is a constant array or a constant expression that results in 
-/// a constant array. In this case, if the array is small, we can generate a 
-/// series of inline store instructions to effect the concatenation without 
-/// calling strcat.
+/// a constant string. In this case we can replace it with strlen + llvm.memcpy 
+/// of the constant string. Both of these calls are further reduced, if possible
+/// on subsequent passes.
 /// @brief Simplify the strcat library function.
 struct StrCatOptimization : public LibCallOptimization
 {
 public:
+  /// @brief Default constructor
   StrCatOptimization() : LibCallOptimization("strcat") {}
 
 public:
+  /// @breif  Destructor
   virtual ~StrCatOptimization() {}
 
   /// @brief Make sure that the "strcat" function has the right prototype
@@ -425,8 +431,8 @@
   }
 } StrCatOptimizer;
 
-/// This LibCallOptimization will simplify a call to the strcpy library function. 
-/// Several optimizations are possible: 
+/// This LibCallOptimization will simplify a call to the strcpy library 
+/// function.  Two optimizations are possible: 
 /// (1) If src and dest are the same and not volatile, just return dest
 /// (2) If the src is a constant then we can convert to llvm.memmove
 /// @brief Simplify the strcpy library function.
@@ -514,9 +520,9 @@
   }
 } StrCpyOptimizer;
 
-/// This LibCallOptimization will simplify a call to the strlen library function by
-/// replacing it with a constant value if the string provided to it is a 
-/// constant array.
+/// This LibCallOptimization will simplify a call to the strlen library 
+/// function by replacing it with a constant value if the string provided to 
+/// it is a constant array.
 /// @brief Simplify the strlen library function.
 struct StrLenOptimization : public LibCallOptimization
 {
@@ -549,16 +555,20 @@
   }
 } StrLenOptimizer;
 
-/// This LibCallOptimization will simplify a call to the memcpy library function by
-/// expanding it out to a single store of size 0, 1, 2, 4, or 8 bytes depending
-/// on the length of the string and the alignment.
+/// This LibCallOptimization will simplify a call to the memcpy library 
+/// function by expanding it out to a single store of size 0, 1, 2, 4, or 8 
+/// bytes depending on the length of the string and the alignment. Additional
+/// optimizations are possible in code generation (sequence of immediate store)
 /// @brief Simplify the memcpy library function.
 struct MemCpyOptimization : public LibCallOptimization
 {
+  /// @brief Default Constructor
   MemCpyOptimization() : LibCallOptimization("llvm.memcpy") {}
 protected:
+  /// @brief Subclass Constructor 
   MemCpyOptimization(const char* fname) : LibCallOptimization(fname) {}
 public:
+  /// @brief Destructor
   virtual ~MemCpyOptimization() {}
 
   /// @brief Make sure that the "memcpy" function has the right prototype
@@ -620,19 +630,27 @@
   }
 } MemCpyOptimizer;
 
-/// This LibCallOptimization will simplify a call to the memmove library function. /// It is identical to MemCopyOptimization except for the name of the intrinsic.
+/// This LibCallOptimization will simplify a call to the memmove library 
+/// function. It is identical to MemCopyOptimization except for the name of 
+/// the intrinsic.
 /// @brief Simplify the memmove library function.
 struct MemMoveOptimization : public MemCpyOptimization
 {
+  /// @brief Default Constructor
   MemMoveOptimization() : MemCpyOptimization("llvm.memmove") {}
 
 } MemMoveOptimizer;
 
-/// A function to compute the length of a null-terminated string of integers.
-/// This function can't rely on the size of the constant array because there 
-/// could be a null terminator in the middle of the array. We also have to 
-/// bail out if we find a non-integer constant initializer of one of the 
-/// elements or if there is no null-terminator. The logic below checks
+/// A function to compute the length of a null-terminated constant array of
+/// integers.  This function can't rely on the size of the constant array 
+/// because there could be a null terminator in the middle of the array. 
+/// We also have to bail out if we find a non-integer constant initializer 
+/// of one of the elements or if there is no null-terminator. The logic 
+/// below checks each of these conditions and will return true only if all
+/// conditions are met. In that case, the \p len parameter is set to the length
+/// of the null-terminated string. If false is returned, the conditions were
+/// not met and len is set to 0.
+/// @brief Get the length of a constant string (null-terminated array).
 bool getConstantStringLength(Value* V, uint64_t& len )
 {
   assert(V != 0 && "Invalid args to getConstantStringLength");
@@ -723,7 +741,6 @@
   return true; // success!
 }
 
-
 // TODO: Additional cases that we need to add to this file:
 // 1. memmove -> memcpy if src is a global constant array
 }






More information about the llvm-commits mailing list