blob: e4239e319877f70bbcc90b8f98c2da79f39ed924 [file] [log] [blame]
Reid Spencer9bbaa2a2005-04-25 03:59:26 +00001//===- SimplifyLibCalls.cpp - Optimize specific well-known library calls --===//
Reid Spencer39a762d2005-04-25 02:53:12 +00002//
3// The LLVM Compiler Infrastructure
4//
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00005// This file was developed by Reid Spencer and is distributed under the
Reid Spencer9bbaa2a2005-04-25 03:59:26 +00006// University of Illinois Open Source License. See LICENSE.TXT for details.
Reid Spencer39a762d2005-04-25 02:53:12 +00007//
8//===----------------------------------------------------------------------===//
9//
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +000010// This file implements a module pass that applies a variety of small
11// optimizations for calls to specific well-known function calls (e.g. runtime
12// library functions). For example, a call to the function "exit(3)" that
Reid Spencer0b13cda2005-05-21 00:57:44 +000013// occurs within the main() function can be transformed into a simple "return 3"
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +000014// instruction. Any optimization that takes this form (replace call to library
15// function with simpler code that provides the same result) belongs in this
16// file.
Reid Spencer39a762d2005-04-25 02:53:12 +000017//
18//===----------------------------------------------------------------------===//
19
Reid Spencer18b99812005-04-26 23:05:17 +000020#define DEBUG_TYPE "simplify-libcalls"
Reid Spencer2bc7a4f2005-04-26 23:02:16 +000021#include "llvm/Constants.h"
22#include "llvm/DerivedTypes.h"
23#include "llvm/Instructions.h"
Reid Spencer39a762d2005-04-25 02:53:12 +000024#include "llvm/Module.h"
25#include "llvm/Pass.h"
Reid Spencer9bbaa2a2005-04-25 03:59:26 +000026#include "llvm/ADT/hash_map"
Reid Spencer2bc7a4f2005-04-26 23:02:16 +000027#include "llvm/ADT/Statistic.h"
Reid Spencerade18212006-01-19 08:36:56 +000028#include "llvm/Config/config.h"
Reid Spencer2bc7a4f2005-04-26 23:02:16 +000029#include "llvm/Support/Debug.h"
Reid Spencerbb92b4f2005-04-26 19:13:17 +000030#include "llvm/Target/TargetData.h"
Reid Spencer2bc7a4f2005-04-26 23:02:16 +000031#include "llvm/Transforms/IPO.h"
Reid Spencerf2534c72005-04-25 21:11:48 +000032#include <iostream>
Reid Spencer39a762d2005-04-25 02:53:12 +000033using namespace llvm;
34
35namespace {
Reid Spencer39a762d2005-04-25 02:53:12 +000036
Reid Spencere249a822005-04-27 07:54:40 +000037/// This statistic keeps track of the total number of library calls that have
38/// been simplified regardless of which call it is.
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +000039Statistic<> SimplifiedLibCalls("simplify-libcalls",
Chris Lattner579b20b2005-08-07 20:02:04 +000040 "Number of library calls simplified");
Reid Spencer39a762d2005-04-25 02:53:12 +000041
Reid Spencer7ddcfb32005-04-27 21:29:20 +000042// Forward declarations
Reid Spencere249a822005-04-27 07:54:40 +000043class LibCallOptimization;
44class SimplifyLibCalls;
Reid Spencer7ddcfb32005-04-27 21:29:20 +000045
Reid Spencer9fbad132005-05-21 01:27:04 +000046/// This hash map is populated by the constructor for LibCallOptimization class.
47/// Therefore all subclasses are registered here at static initialization time
48/// and this list is what the SimplifyLibCalls pass uses to apply the individual
49/// optimizations to the call sites.
Reid Spencer7ddcfb32005-04-27 21:29:20 +000050/// @brief The list of optimizations deriving from LibCallOptimization
Reid Spencer9fbad132005-05-21 01:27:04 +000051static hash_map<std::string,LibCallOptimization*> optlist;
Reid Spencer39a762d2005-04-25 02:53:12 +000052
Reid Spencere249a822005-04-27 07:54:40 +000053/// This class is the abstract base class for the set of optimizations that
Reid Spencer7ddcfb32005-04-27 21:29:20 +000054/// corresponds to one library call. The SimplifyLibCalls pass will call the
Reid Spencere249a822005-04-27 07:54:40 +000055/// ValidateCalledFunction method to ask the optimization if a given Function
Reid Spencer7ddcfb32005-04-27 21:29:20 +000056/// is the kind that the optimization can handle. If the subclass returns true,
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +000057/// then SImplifyLibCalls will also call the OptimizeCall method to perform,
Reid Spencer7ddcfb32005-04-27 21:29:20 +000058/// or attempt to perform, the optimization(s) for the library call. Otherwise,
59/// OptimizeCall won't be called. Subclasses are responsible for providing the
60/// name of the library call (strlen, strcpy, etc.) to the LibCallOptimization
61/// constructor. This is used to efficiently select which call instructions to
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +000062/// optimize. The criteria for a "lib call" is "anything with well known
Reid Spencer7ddcfb32005-04-27 21:29:20 +000063/// semantics", typically a library function that is defined by an international
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +000064/// standard. Because the semantics are well known, the optimizations can
Reid Spencer7ddcfb32005-04-27 21:29:20 +000065/// generally short-circuit actually calling the function if there's a simpler
66/// way (e.g. strlen(X) can be reduced to a constant if X is a constant global).
Reid Spencere249a822005-04-27 07:54:40 +000067/// @brief Base class for library call optimizations
Jeff Cohen4bc952f2005-04-29 03:05:44 +000068class LibCallOptimization
Reid Spencere249a822005-04-27 07:54:40 +000069{
Jeff Cohen4bc952f2005-04-29 03:05:44 +000070public:
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +000071 /// The \p fname argument must be the name of the library function being
Reid Spencer7ddcfb32005-04-27 21:29:20 +000072 /// optimized by the subclass.
73 /// @brief Constructor that registers the optimization.
Reid Spencer170ae7f2005-05-07 20:15:59 +000074 LibCallOptimization(const char* fname, const char* description )
Reid Spencer9bbaa2a2005-04-25 03:59:26 +000075 : func_name(fname)
Reid Spencere95a6472005-04-27 00:05:45 +000076#ifndef NDEBUG
Reid Spencer170ae7f2005-05-07 20:15:59 +000077 , occurrences("simplify-libcalls",description)
Reid Spencere95a6472005-04-27 00:05:45 +000078#endif
Reid Spencer39a762d2005-04-25 02:53:12 +000079 {
Reid Spencer7ddcfb32005-04-27 21:29:20 +000080 // Register this call optimizer in the optlist (a hash_map)
Reid Spencer95d8efd2005-05-03 02:54:54 +000081 optlist[fname] = this;
Reid Spencer39a762d2005-04-25 02:53:12 +000082 }
83
Reid Spencer7ddcfb32005-04-27 21:29:20 +000084 /// @brief Deregister from the optlist
85 virtual ~LibCallOptimization() { optlist.erase(func_name); }
Reid Spencer8ee5aac2005-04-26 03:26:15 +000086
Reid Spencere249a822005-04-27 07:54:40 +000087 /// The implementation of this function in subclasses should determine if
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +000088 /// \p F is suitable for the optimization. This method is called by
89 /// SimplifyLibCalls::runOnModule to short circuit visiting all the call
90 /// sites of such a function if that function is not suitable in the first
Reid Spencer7ddcfb32005-04-27 21:29:20 +000091 /// place. If the called function is suitabe, this method should return true;
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +000092 /// false, otherwise. This function should also perform any lazy
93 /// initialization that the LibCallOptimization needs to do, if its to return
Reid Spencere249a822005-04-27 07:54:40 +000094 /// true. This avoids doing initialization until the optimizer is actually
95 /// going to be called upon to do some optimization.
Reid Spencer7ddcfb32005-04-27 21:29:20 +000096 /// @brief Determine if the function is suitable for optimization
Reid Spencere249a822005-04-27 07:54:40 +000097 virtual bool ValidateCalledFunction(
98 const Function* F, ///< The function that is the target of call sites
99 SimplifyLibCalls& SLC ///< The pass object invoking us
100 ) = 0;
Reid Spencerbb92b4f2005-04-26 19:13:17 +0000101
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000102 /// The implementations of this function in subclasses is the heart of the
103 /// SimplifyLibCalls algorithm. Sublcasses of this class implement
Reid Spencere249a822005-04-27 07:54:40 +0000104 /// OptimizeCall to determine if (a) the conditions are right for optimizing
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000105 /// the call and (b) to perform the optimization. If an action is taken
Reid Spencere249a822005-04-27 07:54:40 +0000106 /// against ci, the subclass is responsible for returning true and ensuring
107 /// that ci is erased from its parent.
Reid Spencere249a822005-04-27 07:54:40 +0000108 /// @brief Optimize a call, if possible.
109 virtual bool OptimizeCall(
110 CallInst* ci, ///< The call instruction that should be optimized.
111 SimplifyLibCalls& SLC ///< The pass object invoking us
112 ) = 0;
Reid Spencerbb92b4f2005-04-26 19:13:17 +0000113
Reid Spencere249a822005-04-27 07:54:40 +0000114 /// @brief Get the name of the library call being optimized
115 const char * getFunctionName() const { return func_name; }
Reid Spencerbb92b4f2005-04-26 19:13:17 +0000116
Reid Spencere95a6472005-04-27 00:05:45 +0000117#ifndef NDEBUG
Reid Spencer7ddcfb32005-04-27 21:29:20 +0000118 /// @brief Called by SimplifyLibCalls to update the occurrences statistic.
Reid Spencer4f01a822005-05-07 04:59:45 +0000119 void succeeded() { DEBUG(++occurrences); }
Reid Spencere95a6472005-04-27 00:05:45 +0000120#endif
Reid Spencere249a822005-04-27 07:54:40 +0000121
122private:
123 const char* func_name; ///< Name of the library call we optimize
124#ifndef NDEBUG
Reid Spencere249a822005-04-27 07:54:40 +0000125 Statistic<> occurrences; ///< debug statistic (-debug-only=simplify-libcalls)
126#endif
127};
128
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000129/// This class is an LLVM Pass that applies each of the LibCallOptimization
Reid Spencere249a822005-04-27 07:54:40 +0000130/// instances to all the call sites in a module, relatively efficiently. The
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000131/// purpose of this pass is to provide optimizations for calls to well-known
Reid Spencere249a822005-04-27 07:54:40 +0000132/// functions with well-known semantics, such as those in the c library. The
Chris Lattner4201cd12005-08-24 17:22:17 +0000133/// class provides the basic infrastructure for handling runOnModule. Whenever
134/// this pass finds a function call, it asks the appropriate optimizer to
Reid Spencer7ddcfb32005-04-27 21:29:20 +0000135/// validate the call (ValidateLibraryCall). If it is validated, then
136/// the OptimizeCall method is also called.
Reid Spencere249a822005-04-27 07:54:40 +0000137/// @brief A ModulePass for optimizing well-known function calls.
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000138class SimplifyLibCalls : public ModulePass
Reid Spencere249a822005-04-27 07:54:40 +0000139{
Jeff Cohen4bc952f2005-04-29 03:05:44 +0000140public:
Reid Spencere249a822005-04-27 07:54:40 +0000141 /// We need some target data for accurate signature details that are
142 /// target dependent. So we require target data in our AnalysisUsage.
Reid Spencer7ddcfb32005-04-27 21:29:20 +0000143 /// @brief Require TargetData from AnalysisUsage.
Reid Spencere249a822005-04-27 07:54:40 +0000144 virtual void getAnalysisUsage(AnalysisUsage& Info) const
145 {
146 // Ask that the TargetData analysis be performed before us so we can use
147 // the target data.
148 Info.addRequired<TargetData>();
149 }
150
151 /// For this pass, process all of the function calls in the module, calling
152 /// ValidateLibraryCall and OptimizeCall as appropriate.
Reid Spencer7ddcfb32005-04-27 21:29:20 +0000153 /// @brief Run all the lib call optimizations on a Module.
Reid Spencere249a822005-04-27 07:54:40 +0000154 virtual bool runOnModule(Module &M)
155 {
156 reset(M);
157
158 bool result = false;
159
160 // The call optimizations can be recursive. That is, the optimization might
161 // generate a call to another function which can also be optimized. This way
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000162 // we make the LibCallOptimization instances very specific to the case they
163 // handle. It also means we need to keep running over the function calls in
Reid Spencere249a822005-04-27 07:54:40 +0000164 // the module until we don't get any more optimizations possible.
165 bool found_optimization = false;
166 do
167 {
168 found_optimization = false;
169 for (Module::iterator FI = M.begin(), FE = M.end(); FI != FE; ++FI)
170 {
171 // All the "well-known" functions are external and have external linkage
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000172 // because they live in a runtime library somewhere and were (probably)
173 // not compiled by LLVM. So, we only act on external functions that
Reid Spencer38cabd72005-05-03 07:23:44 +0000174 // have external linkage and non-empty uses.
Reid Spencere249a822005-04-27 07:54:40 +0000175 if (!FI->isExternal() || !FI->hasExternalLinkage() || FI->use_empty())
176 continue;
177
178 // Get the optimization class that pertains to this function
179 LibCallOptimization* CO = optlist[FI->getName().c_str()];
180 if (!CO)
181 continue;
182
183 // Make sure the called function is suitable for the optimization
184 if (!CO->ValidateCalledFunction(FI,*this))
185 continue;
186
187 // Loop over each of the uses of the function
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000188 for (Value::use_iterator UI = FI->use_begin(), UE = FI->use_end();
Reid Spencere249a822005-04-27 07:54:40 +0000189 UI != UE ; )
190 {
191 // If the use of the function is a call instruction
192 if (CallInst* CI = dyn_cast<CallInst>(*UI++))
193 {
194 // Do the optimization on the LibCallOptimization.
195 if (CO->OptimizeCall(CI,*this))
196 {
197 ++SimplifiedLibCalls;
198 found_optimization = result = true;
199#ifndef NDEBUG
Reid Spencer7ddcfb32005-04-27 21:29:20 +0000200 CO->succeeded();
Reid Spencere249a822005-04-27 07:54:40 +0000201#endif
202 }
Reid Spencerbb92b4f2005-04-26 19:13:17 +0000203 }
204 }
205 }
Reid Spencere249a822005-04-27 07:54:40 +0000206 } while (found_optimization);
207 return result;
208 }
Reid Spencerbb92b4f2005-04-26 19:13:17 +0000209
Reid Spencere249a822005-04-27 07:54:40 +0000210 /// @brief Return the *current* module we're working on.
Reid Spencer93616972005-04-29 09:39:47 +0000211 Module* getModule() const { return M; }
Reid Spencerbb92b4f2005-04-26 19:13:17 +0000212
Reid Spencere249a822005-04-27 07:54:40 +0000213 /// @brief Return the *current* target data for the module we're working on.
Reid Spencer93616972005-04-29 09:39:47 +0000214 TargetData* getTargetData() const { return TD; }
215
216 /// @brief Return the size_t type -- syntactic shortcut
217 const Type* getIntPtrType() const { return TD->getIntPtrType(); }
218
219 /// @brief Return a Function* for the fputc libcall
Reid Spencer4c444fe2005-04-30 03:17:54 +0000220 Function* get_fputc(const Type* FILEptr_type)
Reid Spencer93616972005-04-29 09:39:47 +0000221 {
222 if (!fputc_func)
223 {
224 std::vector<const Type*> args;
225 args.push_back(Type::IntTy);
Reid Spencer4c444fe2005-04-30 03:17:54 +0000226 args.push_back(FILEptr_type);
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000227 FunctionType* fputc_type =
Reid Spencer93616972005-04-29 09:39:47 +0000228 FunctionType::get(Type::IntTy, args, false);
229 fputc_func = M->getOrInsertFunction("fputc",fputc_type);
230 }
231 return fputc_func;
232 }
233
234 /// @brief Return a Function* for the fwrite libcall
Reid Spencer4c444fe2005-04-30 03:17:54 +0000235 Function* get_fwrite(const Type* FILEptr_type)
Reid Spencer93616972005-04-29 09:39:47 +0000236 {
237 if (!fwrite_func)
238 {
239 std::vector<const Type*> args;
240 args.push_back(PointerType::get(Type::SByteTy));
241 args.push_back(TD->getIntPtrType());
242 args.push_back(TD->getIntPtrType());
Reid Spencer4c444fe2005-04-30 03:17:54 +0000243 args.push_back(FILEptr_type);
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000244 FunctionType* fwrite_type =
Reid Spencer93616972005-04-29 09:39:47 +0000245 FunctionType::get(TD->getIntPtrType(), args, false);
246 fwrite_func = M->getOrInsertFunction("fwrite",fwrite_type);
247 }
248 return fwrite_func;
249 }
250
251 /// @brief Return a Function* for the sqrt libcall
252 Function* get_sqrt()
253 {
254 if (!sqrt_func)
255 {
256 std::vector<const Type*> args;
257 args.push_back(Type::DoubleTy);
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000258 FunctionType* sqrt_type =
Reid Spencer93616972005-04-29 09:39:47 +0000259 FunctionType::get(Type::DoubleTy, args, false);
260 sqrt_func = M->getOrInsertFunction("sqrt",sqrt_type);
261 }
262 return sqrt_func;
263 }
Reid Spencere249a822005-04-27 07:54:40 +0000264
265 /// @brief Return a Function* for the strlen libcall
Reid Spencer1e520fd2005-05-04 03:20:21 +0000266 Function* get_strcpy()
267 {
268 if (!strcpy_func)
269 {
270 std::vector<const Type*> args;
271 args.push_back(PointerType::get(Type::SByteTy));
272 args.push_back(PointerType::get(Type::SByteTy));
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000273 FunctionType* strcpy_type =
Reid Spencer1e520fd2005-05-04 03:20:21 +0000274 FunctionType::get(PointerType::get(Type::SByteTy), args, false);
275 strcpy_func = M->getOrInsertFunction("strcpy",strcpy_type);
276 }
277 return strcpy_func;
278 }
279
280 /// @brief Return a Function* for the strlen libcall
Reid Spencere249a822005-04-27 07:54:40 +0000281 Function* get_strlen()
Reid Spencer8ee5aac2005-04-26 03:26:15 +0000282 {
Reid Spencere249a822005-04-27 07:54:40 +0000283 if (!strlen_func)
Reid Spencer8ee5aac2005-04-26 03:26:15 +0000284 {
285 std::vector<const Type*> args;
286 args.push_back(PointerType::get(Type::SByteTy));
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000287 FunctionType* strlen_type =
Reid Spencere249a822005-04-27 07:54:40 +0000288 FunctionType::get(TD->getIntPtrType(), args, false);
289 strlen_func = M->getOrInsertFunction("strlen",strlen_type);
Reid Spencer8ee5aac2005-04-26 03:26:15 +0000290 }
Reid Spencere249a822005-04-27 07:54:40 +0000291 return strlen_func;
Reid Spencer8ee5aac2005-04-26 03:26:15 +0000292 }
293
Reid Spencer38cabd72005-05-03 07:23:44 +0000294 /// @brief Return a Function* for the memchr libcall
295 Function* get_memchr()
296 {
297 if (!memchr_func)
298 {
299 std::vector<const Type*> args;
300 args.push_back(PointerType::get(Type::SByteTy));
301 args.push_back(Type::IntTy);
302 args.push_back(TD->getIntPtrType());
303 FunctionType* memchr_type = FunctionType::get(
304 PointerType::get(Type::SByteTy), args, false);
305 memchr_func = M->getOrInsertFunction("memchr",memchr_type);
306 }
307 return memchr_func;
308 }
309
Reid Spencere249a822005-04-27 07:54:40 +0000310 /// @brief Return a Function* for the memcpy libcall
Chris Lattner4201cd12005-08-24 17:22:17 +0000311 Function* get_memcpy() {
312 if (!memcpy_func) {
313 const Type *SBP = PointerType::get(Type::SByteTy);
314 memcpy_func = M->getOrInsertFunction("llvm.memcpy", Type::VoidTy,SBP, SBP,
Jeff Cohen11e26b52005-10-23 04:37:20 +0000315 Type::UIntTy, Type::UIntTy,
316 (Type *)0);
Reid Spencer8ee5aac2005-04-26 03:26:15 +0000317 }
Reid Spencere249a822005-04-27 07:54:40 +0000318 return memcpy_func;
Reid Spencer8ee5aac2005-04-26 03:26:15 +0000319 }
Reid Spencer76dab9a2005-04-26 05:24:00 +0000320
Reid Spencerade18212006-01-19 08:36:56 +0000321#ifdef HAVE_FLOORF
Chris Lattner4201cd12005-08-24 17:22:17 +0000322 Function* get_floorf() {
323 if (!floorf_func)
324 floorf_func = M->getOrInsertFunction("floorf", Type::FloatTy,
Jeff Cohen11e26b52005-10-23 04:37:20 +0000325 Type::FloatTy, (Type *)0);
Chris Lattner4201cd12005-08-24 17:22:17 +0000326 return floorf_func;
327 }
Reid Spencerade18212006-01-19 08:36:56 +0000328#endif
Chris Lattner4201cd12005-08-24 17:22:17 +0000329
Reid Spencere249a822005-04-27 07:54:40 +0000330private:
Reid Spencer7ddcfb32005-04-27 21:29:20 +0000331 /// @brief Reset our cached data for a new Module
Reid Spencere249a822005-04-27 07:54:40 +0000332 void reset(Module& mod)
Reid Spencer76dab9a2005-04-26 05:24:00 +0000333 {
Reid Spencere249a822005-04-27 07:54:40 +0000334 M = &mod;
335 TD = &getAnalysis<TargetData>();
Reid Spencer93616972005-04-29 09:39:47 +0000336 fputc_func = 0;
337 fwrite_func = 0;
Reid Spencere249a822005-04-27 07:54:40 +0000338 memcpy_func = 0;
Reid Spencer38cabd72005-05-03 07:23:44 +0000339 memchr_func = 0;
Reid Spencer93616972005-04-29 09:39:47 +0000340 sqrt_func = 0;
Reid Spencer1e520fd2005-05-04 03:20:21 +0000341 strcpy_func = 0;
Reid Spencere249a822005-04-27 07:54:40 +0000342 strlen_func = 0;
Reid Spencerade18212006-01-19 08:36:56 +0000343#ifdef HAVE_FLOORF
Chris Lattner4201cd12005-08-24 17:22:17 +0000344 floorf_func = 0;
Reid Spencerade18212006-01-19 08:36:56 +0000345#endif
Reid Spencer76dab9a2005-04-26 05:24:00 +0000346 }
Reid Spencer39a762d2005-04-25 02:53:12 +0000347
Reid Spencere249a822005-04-27 07:54:40 +0000348private:
Reid Spencer93616972005-04-29 09:39:47 +0000349 Function* fputc_func; ///< Cached fputc function
350 Function* fwrite_func; ///< Cached fwrite function
Reid Spencer7ddcfb32005-04-27 21:29:20 +0000351 Function* memcpy_func; ///< Cached llvm.memcpy function
Reid Spencer38cabd72005-05-03 07:23:44 +0000352 Function* memchr_func; ///< Cached memchr function
Reid Spencer93616972005-04-29 09:39:47 +0000353 Function* sqrt_func; ///< Cached sqrt function
Reid Spencer1e520fd2005-05-04 03:20:21 +0000354 Function* strcpy_func; ///< Cached strcpy function
Reid Spencer7ddcfb32005-04-27 21:29:20 +0000355 Function* strlen_func; ///< Cached strlen function
Reid Spencerade18212006-01-19 08:36:56 +0000356#ifdef HAVE_FLOORF
Chris Lattner4201cd12005-08-24 17:22:17 +0000357 Function* floorf_func; ///< Cached floorf function
Reid Spencerade18212006-01-19 08:36:56 +0000358#endif
Reid Spencer7ddcfb32005-04-27 21:29:20 +0000359 Module* M; ///< Cached Module
360 TargetData* TD; ///< Cached TargetData
Reid Spencere249a822005-04-27 07:54:40 +0000361};
362
363// Register the pass
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000364RegisterOpt<SimplifyLibCalls>
Reid Spencere249a822005-04-27 07:54:40 +0000365X("simplify-libcalls","Simplify well-known library calls");
366
367} // anonymous namespace
368
369// The only public symbol in this file which just instantiates the pass object
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000370ModulePass *llvm::createSimplifyLibCallsPass()
371{
372 return new SimplifyLibCalls();
Reid Spencere249a822005-04-27 07:54:40 +0000373}
374
375// Classes below here, in the anonymous namespace, are all subclasses of the
376// LibCallOptimization class, each implementing all optimizations possible for a
377// single well-known library call. Each has a static singleton instance that
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000378// auto registers it into the "optlist" global above.
Reid Spencere249a822005-04-27 07:54:40 +0000379namespace {
380
Reid Spencera7828ba2005-06-18 17:46:28 +0000381// Forward declare utility functions.
Reid Spencer4c444fe2005-04-30 03:17:54 +0000382bool getConstantStringLength(Value* V, uint64_t& len, ConstantArray** A = 0 );
Reid Spencera7828ba2005-06-18 17:46:28 +0000383Value *CastToCStr(Value *V, Instruction &IP);
Reid Spencere249a822005-04-27 07:54:40 +0000384
385/// This LibCallOptimization will find instances of a call to "exit" that occurs
Reid Spencer39a762d2005-04-25 02:53:12 +0000386/// within the "main" function and change it to a simple "ret" instruction with
Reid Spencer7ddcfb32005-04-27 21:29:20 +0000387/// the same value passed to the exit function. When this is done, it splits the
388/// basic block at the exit(3) call and deletes the call instruction.
Reid Spencer39a762d2005-04-25 02:53:12 +0000389/// @brief Replace calls to exit in main with a simple return
Reid Spencere249a822005-04-27 07:54:40 +0000390struct ExitInMainOptimization : public LibCallOptimization
Reid Spencer39a762d2005-04-25 02:53:12 +0000391{
Reid Spencer95d8efd2005-05-03 02:54:54 +0000392 ExitInMainOptimization() : LibCallOptimization("exit",
Reid Spencer170ae7f2005-05-07 20:15:59 +0000393 "Number of 'exit' calls simplified") {}
Reid Spencerf2534c72005-04-25 21:11:48 +0000394
395 // Make sure the called function looks like exit (int argument, int return
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000396 // type, external linkage, not varargs).
Reid Spencere249a822005-04-27 07:54:40 +0000397 virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC)
Reid Spencerf2534c72005-04-25 21:11:48 +0000398 {
Reid Spencerb4f7b832005-04-26 07:45:18 +0000399 if (f->arg_size() >= 1)
400 if (f->arg_begin()->getType()->isInteger())
401 return true;
Reid Spencerf2534c72005-04-25 21:11:48 +0000402 return false;
403 }
404
Reid Spencere249a822005-04-27 07:54:40 +0000405 virtual bool OptimizeCall(CallInst* ci, SimplifyLibCalls& SLC)
Reid Spencer9bbaa2a2005-04-25 03:59:26 +0000406 {
Reid Spencerf2534c72005-04-25 21:11:48 +0000407 // To be careful, we check that the call to exit is coming from "main", that
408 // main has external linkage, and the return type of main and the argument
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000409 // to exit have the same type.
Reid Spencerf2534c72005-04-25 21:11:48 +0000410 Function *from = ci->getParent()->getParent();
411 if (from->hasExternalLinkage())
412 if (from->getReturnType() == ci->getOperand(1)->getType())
413 if (from->getName() == "main")
414 {
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000415 // Okay, time to actually do the optimization. First, get the basic
Reid Spencerf2534c72005-04-25 21:11:48 +0000416 // block of the call instruction
417 BasicBlock* bb = ci->getParent();
Reid Spencer39a762d2005-04-25 02:53:12 +0000418
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000419 // Create a return instruction that we'll replace the call with.
420 // Note that the argument of the return is the argument of the call
Reid Spencerf2534c72005-04-25 21:11:48 +0000421 // instruction.
422 ReturnInst* ri = new ReturnInst(ci->getOperand(1), ci);
Reid Spencer39a762d2005-04-25 02:53:12 +0000423
Reid Spencerf2534c72005-04-25 21:11:48 +0000424 // Split the block at the call instruction which places it in a new
425 // basic block.
Reid Spencer8ee5aac2005-04-26 03:26:15 +0000426 bb->splitBasicBlock(ci);
Reid Spencer39a762d2005-04-25 02:53:12 +0000427
Reid Spencerf2534c72005-04-25 21:11:48 +0000428 // The block split caused a branch instruction to be inserted into
429 // the end of the original block, right after the return instruction
430 // that we put there. That's not a valid block, so delete the branch
431 // instruction.
Reid Spencer8ee5aac2005-04-26 03:26:15 +0000432 bb->getInstList().pop_back();
Reid Spencer39a762d2005-04-25 02:53:12 +0000433
Reid Spencerf2534c72005-04-25 21:11:48 +0000434 // Now we can finally get rid of the call instruction which now lives
435 // in the new basic block.
436 ci->eraseFromParent();
437
438 // Optimization succeeded, return true.
439 return true;
440 }
441 // We didn't pass the criteria for this optimization so return false
442 return false;
Reid Spencer9bbaa2a2005-04-25 03:59:26 +0000443 }
Reid Spencer39a762d2005-04-25 02:53:12 +0000444} ExitInMainOptimizer;
445
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000446/// This LibCallOptimization will simplify a call to the strcat library
447/// function. The simplification is possible only if the string being
448/// concatenated is a constant array or a constant expression that results in
449/// a constant string. In this case we can replace it with strlen + llvm.memcpy
Reid Spencer7ddcfb32005-04-27 21:29:20 +0000450/// of the constant string. Both of these calls are further reduced, if possible
451/// on subsequent passes.
Reid Spencerf2534c72005-04-25 21:11:48 +0000452/// @brief Simplify the strcat library function.
Reid Spencere249a822005-04-27 07:54:40 +0000453struct StrCatOptimization : public LibCallOptimization
Reid Spencer9bbaa2a2005-04-25 03:59:26 +0000454{
Reid Spencer8ee5aac2005-04-26 03:26:15 +0000455public:
Reid Spencer7ddcfb32005-04-27 21:29:20 +0000456 /// @brief Default constructor
Reid Spencer95d8efd2005-05-03 02:54:54 +0000457 StrCatOptimization() : LibCallOptimization("strcat",
Reid Spencer170ae7f2005-05-07 20:15:59 +0000458 "Number of 'strcat' calls simplified") {}
Reid Spencere249a822005-04-27 07:54:40 +0000459
460public:
Reid Spencerf2534c72005-04-25 21:11:48 +0000461
462 /// @brief Make sure that the "strcat" function has the right prototype
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000463 virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC)
Reid Spencerf2534c72005-04-25 21:11:48 +0000464 {
465 if (f->getReturnType() == PointerType::get(Type::SByteTy))
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000466 if (f->arg_size() == 2)
Reid Spencerf2534c72005-04-25 21:11:48 +0000467 {
468 Function::const_arg_iterator AI = f->arg_begin();
469 if (AI++->getType() == PointerType::get(Type::SByteTy))
470 if (AI->getType() == PointerType::get(Type::SByteTy))
Reid Spencer8ee5aac2005-04-26 03:26:15 +0000471 {
Reid Spencer8ee5aac2005-04-26 03:26:15 +0000472 // Indicate this is a suitable call type.
Reid Spencerf2534c72005-04-25 21:11:48 +0000473 return true;
Reid Spencer8ee5aac2005-04-26 03:26:15 +0000474 }
Reid Spencerf2534c72005-04-25 21:11:48 +0000475 }
476 return false;
477 }
478
Reid Spencere249a822005-04-27 07:54:40 +0000479 /// @brief Optimize the strcat library function
480 virtual bool OptimizeCall(CallInst* ci, SimplifyLibCalls& SLC)
Reid Spencer9bbaa2a2005-04-25 03:59:26 +0000481 {
Reid Spencer08b49402005-04-27 17:46:54 +0000482 // Extract some information from the instruction
483 Module* M = ci->getParent()->getParent()->getParent();
484 Value* dest = ci->getOperand(1);
485 Value* src = ci->getOperand(2);
486
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000487 // Extract the initializer (while making numerous checks) from the
Reid Spencer76dab9a2005-04-26 05:24:00 +0000488 // source operand of the call to strcat. If we get null back, one of
489 // a variety of checks in get_GVInitializer failed
Reid Spencerb4f7b832005-04-26 07:45:18 +0000490 uint64_t len = 0;
Reid Spencer08b49402005-04-27 17:46:54 +0000491 if (!getConstantStringLength(src,len))
Reid Spencer8ee5aac2005-04-26 03:26:15 +0000492 return false;
493
Reid Spencerb4f7b832005-04-26 07:45:18 +0000494 // Handle the simple, do-nothing case
495 if (len == 0)
Reid Spencer8ee5aac2005-04-26 03:26:15 +0000496 {
Reid Spencer08b49402005-04-27 17:46:54 +0000497 ci->replaceAllUsesWith(dest);
Reid Spencer8ee5aac2005-04-26 03:26:15 +0000498 ci->eraseFromParent();
499 return true;
500 }
501
Reid Spencerb4f7b832005-04-26 07:45:18 +0000502 // Increment the length because we actually want to memcpy the null
503 // terminator as well.
504 len++;
Reid Spencerf2534c72005-04-25 21:11:48 +0000505
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000506 // We need to find the end of the destination string. That's where the
507 // memory is to be moved to. We just generate a call to strlen (further
508 // optimized in another pass). Note that the SLC.get_strlen() call
Reid Spencerb4f7b832005-04-26 07:45:18 +0000509 // caches the Function* for us.
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000510 CallInst* strlen_inst =
Reid Spencer08b49402005-04-27 17:46:54 +0000511 new CallInst(SLC.get_strlen(), dest, dest->getName()+".len",ci);
Reid Spencerb4f7b832005-04-26 07:45:18 +0000512
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000513 // Now that we have the destination's length, we must index into the
Reid Spencerb4f7b832005-04-26 07:45:18 +0000514 // destination's pointer to get the actual memcpy destination (end of
515 // the string .. we're concatenating).
516 std::vector<Value*> idx;
517 idx.push_back(strlen_inst);
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000518 GetElementPtrInst* gep =
Reid Spencer08b49402005-04-27 17:46:54 +0000519 new GetElementPtrInst(dest,idx,dest->getName()+".indexed",ci);
Reid Spencerb4f7b832005-04-26 07:45:18 +0000520
521 // We have enough information to now generate the memcpy call to
522 // do the concatenation for us.
523 std::vector<Value*> vals;
524 vals.push_back(gep); // destination
525 vals.push_back(ci->getOperand(2)); // source
Reid Spencer1e520fd2005-05-04 03:20:21 +0000526 vals.push_back(ConstantUInt::get(Type::UIntTy,len)); // length
527 vals.push_back(ConstantUInt::get(Type::UIntTy,1)); // alignment
Reid Spencer08b49402005-04-27 17:46:54 +0000528 new CallInst(SLC.get_memcpy(), vals, "", ci);
Reid Spencerb4f7b832005-04-26 07:45:18 +0000529
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000530 // Finally, substitute the first operand of the strcat call for the
531 // strcat call itself since strcat returns its first operand; and,
Reid Spencerb4f7b832005-04-26 07:45:18 +0000532 // kill the strcat CallInst.
Reid Spencer08b49402005-04-27 17:46:54 +0000533 ci->replaceAllUsesWith(dest);
Reid Spencerb4f7b832005-04-26 07:45:18 +0000534 ci->eraseFromParent();
535 return true;
Reid Spencer9bbaa2a2005-04-25 03:59:26 +0000536 }
537} StrCatOptimizer;
538
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000539/// This LibCallOptimization will simplify a call to the strchr library
Reid Spencer38cabd72005-05-03 07:23:44 +0000540/// function. It optimizes out cases where the arguments are both constant
541/// and the result can be determined statically.
542/// @brief Simplify the strcmp library function.
543struct StrChrOptimization : public LibCallOptimization
544{
545public:
546 StrChrOptimization() : LibCallOptimization("strchr",
Reid Spencer170ae7f2005-05-07 20:15:59 +0000547 "Number of 'strchr' calls simplified") {}
Reid Spencer38cabd72005-05-03 07:23:44 +0000548
549 /// @brief Make sure that the "strchr" function has the right prototype
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000550 virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC)
Reid Spencer38cabd72005-05-03 07:23:44 +0000551 {
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000552 if (f->getReturnType() == PointerType::get(Type::SByteTy) &&
Reid Spencer38cabd72005-05-03 07:23:44 +0000553 f->arg_size() == 2)
554 return true;
555 return false;
556 }
557
Chris Lattnerf8053ce2005-05-20 22:22:25 +0000558 /// @brief Perform the strchr optimizations
Reid Spencer38cabd72005-05-03 07:23:44 +0000559 virtual bool OptimizeCall(CallInst* ci, SimplifyLibCalls& SLC)
560 {
561 // If there aren't three operands, bail
562 if (ci->getNumOperands() != 3)
563 return false;
564
565 // Check that the first argument to strchr is a constant array of sbyte.
566 // If it is, get the length and data, otherwise return false.
567 uint64_t len = 0;
568 ConstantArray* CA;
569 if (!getConstantStringLength(ci->getOperand(1),len,&CA))
570 return false;
571
572 // Check that the second argument to strchr is a constant int, return false
573 // if it isn't
574 ConstantSInt* CSI = dyn_cast<ConstantSInt>(ci->getOperand(2));
575 if (!CSI)
576 {
577 // Just lower this to memchr since we know the length of the string as
578 // it is constant.
579 Function* f = SLC.get_memchr();
580 std::vector<Value*> args;
581 args.push_back(ci->getOperand(1));
582 args.push_back(ci->getOperand(2));
583 args.push_back(ConstantUInt::get(SLC.getIntPtrType(),len));
584 ci->replaceAllUsesWith( new CallInst(f,args,ci->getName(),ci));
585 ci->eraseFromParent();
586 return true;
587 }
588
589 // Get the character we're looking for
590 int64_t chr = CSI->getValue();
591
592 // Compute the offset
593 uint64_t offset = 0;
594 bool char_found = false;
595 for (uint64_t i = 0; i < len; ++i)
596 {
597 if (ConstantSInt* CI = dyn_cast<ConstantSInt>(CA->getOperand(i)))
598 {
599 // Check for the null terminator
600 if (CI->isNullValue())
601 break; // we found end of string
602 else if (CI->getValue() == chr)
603 {
604 char_found = true;
605 offset = i;
606 break;
607 }
608 }
609 }
610
611 // strchr(s,c) -> offset_of_in(c,s)
612 // (if c is a constant integer and s is a constant string)
613 if (char_found)
614 {
615 std::vector<Value*> indices;
616 indices.push_back(ConstantUInt::get(Type::ULongTy,offset));
617 GetElementPtrInst* GEP = new GetElementPtrInst(ci->getOperand(1),indices,
618 ci->getOperand(1)->getName()+".strchr",ci);
619 ci->replaceAllUsesWith(GEP);
620 }
621 else
622 ci->replaceAllUsesWith(
623 ConstantPointerNull::get(PointerType::get(Type::SByteTy)));
624
625 ci->eraseFromParent();
626 return true;
627 }
628} StrChrOptimizer;
629
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000630/// This LibCallOptimization will simplify a call to the strcmp library
Reid Spencer4c444fe2005-04-30 03:17:54 +0000631/// function. It optimizes out cases where one or both arguments are constant
632/// and the result can be determined statically.
633/// @brief Simplify the strcmp library function.
634struct StrCmpOptimization : public LibCallOptimization
635{
636public:
Reid Spencer95d8efd2005-05-03 02:54:54 +0000637 StrCmpOptimization() : LibCallOptimization("strcmp",
Reid Spencer170ae7f2005-05-07 20:15:59 +0000638 "Number of 'strcmp' calls simplified") {}
Reid Spencer4c444fe2005-04-30 03:17:54 +0000639
Chris Lattnerf8053ce2005-05-20 22:22:25 +0000640 /// @brief Make sure that the "strcmp" function has the right prototype
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000641 virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC)
Reid Spencer4c444fe2005-04-30 03:17:54 +0000642 {
643 if (f->getReturnType() == Type::IntTy && f->arg_size() == 2)
644 return true;
645 return false;
646 }
647
Chris Lattnerf8053ce2005-05-20 22:22:25 +0000648 /// @brief Perform the strcmp optimization
Reid Spencer4c444fe2005-04-30 03:17:54 +0000649 virtual bool OptimizeCall(CallInst* ci, SimplifyLibCalls& SLC)
650 {
651 // First, check to see if src and destination are the same. If they are,
Reid Spencer16449a92005-04-30 06:45:47 +0000652 // then the optimization is to replace the CallInst with a constant 0
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000653 // because the call is a no-op.
Reid Spencer4c444fe2005-04-30 03:17:54 +0000654 Value* s1 = ci->getOperand(1);
655 Value* s2 = ci->getOperand(2);
656 if (s1 == s2)
657 {
658 // strcmp(x,x) -> 0
659 ci->replaceAllUsesWith(ConstantInt::get(Type::IntTy,0));
660 ci->eraseFromParent();
661 return true;
662 }
663
664 bool isstr_1 = false;
665 uint64_t len_1 = 0;
666 ConstantArray* A1;
667 if (getConstantStringLength(s1,len_1,&A1))
668 {
669 isstr_1 = true;
670 if (len_1 == 0)
671 {
672 // strcmp("",x) -> *x
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000673 LoadInst* load =
Reid Spencera7828ba2005-06-18 17:46:28 +0000674 new LoadInst(CastToCStr(s2,*ci), ci->getName()+".load",ci);
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000675 CastInst* cast =
Reid Spencer4c444fe2005-04-30 03:17:54 +0000676 new CastInst(load,Type::IntTy,ci->getName()+".int",ci);
677 ci->replaceAllUsesWith(cast);
678 ci->eraseFromParent();
679 return true;
680 }
681 }
682
683 bool isstr_2 = false;
684 uint64_t len_2 = 0;
685 ConstantArray* A2;
686 if (getConstantStringLength(s2,len_2,&A2))
687 {
688 isstr_2 = true;
689 if (len_2 == 0)
690 {
691 // strcmp(x,"") -> *x
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000692 LoadInst* load =
Reid Spencera7828ba2005-06-18 17:46:28 +0000693 new LoadInst(CastToCStr(s1,*ci),ci->getName()+".val",ci);
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000694 CastInst* cast =
Reid Spencer4c444fe2005-04-30 03:17:54 +0000695 new CastInst(load,Type::IntTy,ci->getName()+".int",ci);
696 ci->replaceAllUsesWith(cast);
697 ci->eraseFromParent();
698 return true;
699 }
700 }
701
702 if (isstr_1 && isstr_2)
703 {
704 // strcmp(x,y) -> cnst (if both x and y are constant strings)
705 std::string str1 = A1->getAsString();
706 std::string str2 = A2->getAsString();
707 int result = strcmp(str1.c_str(), str2.c_str());
708 ci->replaceAllUsesWith(ConstantSInt::get(Type::IntTy,result));
709 ci->eraseFromParent();
710 return true;
711 }
712 return false;
713 }
714} StrCmpOptimizer;
715
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000716/// This LibCallOptimization will simplify a call to the strncmp library
Reid Spencer49fa07042005-05-03 01:43:45 +0000717/// function. It optimizes out cases where one or both arguments are constant
718/// and the result can be determined statically.
719/// @brief Simplify the strncmp library function.
720struct StrNCmpOptimization : public LibCallOptimization
721{
722public:
Reid Spencer95d8efd2005-05-03 02:54:54 +0000723 StrNCmpOptimization() : LibCallOptimization("strncmp",
Reid Spencer170ae7f2005-05-07 20:15:59 +0000724 "Number of 'strncmp' calls simplified") {}
Reid Spencer49fa07042005-05-03 01:43:45 +0000725
Chris Lattnerf8053ce2005-05-20 22:22:25 +0000726 /// @brief Make sure that the "strncmp" function has the right prototype
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000727 virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC)
Reid Spencer49fa07042005-05-03 01:43:45 +0000728 {
729 if (f->getReturnType() == Type::IntTy && f->arg_size() == 3)
730 return true;
731 return false;
732 }
733
734 /// @brief Perform the strncpy optimization
735 virtual bool OptimizeCall(CallInst* ci, SimplifyLibCalls& SLC)
736 {
737 // First, check to see if src and destination are the same. If they are,
738 // then the optimization is to replace the CallInst with a constant 0
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000739 // because the call is a no-op.
Reid Spencer49fa07042005-05-03 01:43:45 +0000740 Value* s1 = ci->getOperand(1);
741 Value* s2 = ci->getOperand(2);
742 if (s1 == s2)
743 {
744 // strncmp(x,x,l) -> 0
745 ci->replaceAllUsesWith(ConstantInt::get(Type::IntTy,0));
746 ci->eraseFromParent();
747 return true;
748 }
749
750 // Check the length argument, if it is Constant zero then the strings are
751 // considered equal.
752 uint64_t len_arg = 0;
753 bool len_arg_is_const = false;
754 if (ConstantInt* len_CI = dyn_cast<ConstantInt>(ci->getOperand(3)))
755 {
756 len_arg_is_const = true;
757 len_arg = len_CI->getRawValue();
758 if (len_arg == 0)
759 {
760 // strncmp(x,y,0) -> 0
761 ci->replaceAllUsesWith(ConstantInt::get(Type::IntTy,0));
762 ci->eraseFromParent();
763 return true;
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000764 }
Reid Spencer49fa07042005-05-03 01:43:45 +0000765 }
766
767 bool isstr_1 = false;
768 uint64_t len_1 = 0;
769 ConstantArray* A1;
770 if (getConstantStringLength(s1,len_1,&A1))
771 {
772 isstr_1 = true;
773 if (len_1 == 0)
774 {
775 // strncmp("",x) -> *x
776 LoadInst* load = new LoadInst(s1,ci->getName()+".load",ci);
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000777 CastInst* cast =
Reid Spencer49fa07042005-05-03 01:43:45 +0000778 new CastInst(load,Type::IntTy,ci->getName()+".int",ci);
779 ci->replaceAllUsesWith(cast);
780 ci->eraseFromParent();
781 return true;
782 }
783 }
784
785 bool isstr_2 = false;
786 uint64_t len_2 = 0;
787 ConstantArray* A2;
788 if (getConstantStringLength(s2,len_2,&A2))
789 {
790 isstr_2 = true;
791 if (len_2 == 0)
792 {
793 // strncmp(x,"") -> *x
794 LoadInst* load = new LoadInst(s2,ci->getName()+".val",ci);
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000795 CastInst* cast =
Reid Spencer49fa07042005-05-03 01:43:45 +0000796 new CastInst(load,Type::IntTy,ci->getName()+".int",ci);
797 ci->replaceAllUsesWith(cast);
798 ci->eraseFromParent();
799 return true;
800 }
801 }
802
803 if (isstr_1 && isstr_2 && len_arg_is_const)
804 {
805 // strncmp(x,y,const) -> constant
806 std::string str1 = A1->getAsString();
807 std::string str2 = A2->getAsString();
808 int result = strncmp(str1.c_str(), str2.c_str(), len_arg);
809 ci->replaceAllUsesWith(ConstantSInt::get(Type::IntTy,result));
810 ci->eraseFromParent();
811 return true;
812 }
813 return false;
814 }
815} StrNCmpOptimizer;
816
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000817/// This LibCallOptimization will simplify a call to the strcpy library
818/// function. Two optimizations are possible:
Reid Spencere249a822005-04-27 07:54:40 +0000819/// (1) If src and dest are the same and not volatile, just return dest
820/// (2) If the src is a constant then we can convert to llvm.memmove
821/// @brief Simplify the strcpy library function.
822struct StrCpyOptimization : public LibCallOptimization
823{
824public:
Reid Spencer95d8efd2005-05-03 02:54:54 +0000825 StrCpyOptimization() : LibCallOptimization("strcpy",
Reid Spencer170ae7f2005-05-07 20:15:59 +0000826 "Number of 'strcpy' calls simplified") {}
Reid Spencere249a822005-04-27 07:54:40 +0000827
828 /// @brief Make sure that the "strcpy" function has the right prototype
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000829 virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC)
Reid Spencere249a822005-04-27 07:54:40 +0000830 {
831 if (f->getReturnType() == PointerType::get(Type::SByteTy))
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000832 if (f->arg_size() == 2)
Reid Spencere249a822005-04-27 07:54:40 +0000833 {
834 Function::const_arg_iterator AI = f->arg_begin();
835 if (AI++->getType() == PointerType::get(Type::SByteTy))
836 if (AI->getType() == PointerType::get(Type::SByteTy))
837 {
838 // Indicate this is a suitable call type.
839 return true;
840 }
841 }
842 return false;
843 }
844
845 /// @brief Perform the strcpy optimization
846 virtual bool OptimizeCall(CallInst* ci, SimplifyLibCalls& SLC)
847 {
848 // First, check to see if src and destination are the same. If they are,
849 // then the optimization is to replace the CallInst with the destination
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000850 // because the call is a no-op. Note that this corresponds to the
Reid Spencere249a822005-04-27 07:54:40 +0000851 // degenerate strcpy(X,X) case which should have "undefined" results
852 // according to the C specification. However, it occurs sometimes and
853 // we optimize it as a no-op.
854 Value* dest = ci->getOperand(1);
855 Value* src = ci->getOperand(2);
856 if (dest == src)
857 {
858 ci->replaceAllUsesWith(dest);
859 ci->eraseFromParent();
860 return true;
861 }
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000862
Reid Spencere249a822005-04-27 07:54:40 +0000863 // Get the length of the constant string referenced by the second operand,
864 // the "src" parameter. Fail the optimization if we can't get the length
865 // (note that getConstantStringLength does lots of checks to make sure this
866 // is valid).
867 uint64_t len = 0;
868 if (!getConstantStringLength(ci->getOperand(2),len))
869 return false;
870
871 // If the constant string's length is zero we can optimize this by just
872 // doing a store of 0 at the first byte of the destination
873 if (len == 0)
874 {
875 new StoreInst(ConstantInt::get(Type::SByteTy,0),ci->getOperand(1),ci);
876 ci->replaceAllUsesWith(dest);
877 ci->eraseFromParent();
878 return true;
879 }
880
881 // Increment the length because we actually want to memcpy the null
882 // terminator as well.
883 len++;
884
885 // Extract some information from the instruction
886 Module* M = ci->getParent()->getParent()->getParent();
887
888 // We have enough information to now generate the memcpy call to
889 // do the concatenation for us.
890 std::vector<Value*> vals;
891 vals.push_back(dest); // destination
892 vals.push_back(src); // source
Reid Spencer1e520fd2005-05-04 03:20:21 +0000893 vals.push_back(ConstantUInt::get(Type::UIntTy,len)); // length
894 vals.push_back(ConstantUInt::get(Type::UIntTy,1)); // alignment
Reid Spencer08b49402005-04-27 17:46:54 +0000895 new CallInst(SLC.get_memcpy(), vals, "", ci);
Reid Spencere249a822005-04-27 07:54:40 +0000896
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000897 // Finally, substitute the first operand of the strcat call for the
898 // strcat call itself since strcat returns its first operand; and,
Reid Spencere249a822005-04-27 07:54:40 +0000899 // kill the strcat CallInst.
900 ci->replaceAllUsesWith(dest);
901 ci->eraseFromParent();
902 return true;
903 }
904} StrCpyOptimizer;
905
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000906/// This LibCallOptimization will simplify a call to the strlen library
907/// function by replacing it with a constant value if the string provided to
Reid Spencer7ddcfb32005-04-27 21:29:20 +0000908/// it is a constant array.
Reid Spencer76dab9a2005-04-26 05:24:00 +0000909/// @brief Simplify the strlen library function.
Reid Spencere249a822005-04-27 07:54:40 +0000910struct StrLenOptimization : public LibCallOptimization
Reid Spencer76dab9a2005-04-26 05:24:00 +0000911{
Reid Spencer95d8efd2005-05-03 02:54:54 +0000912 StrLenOptimization() : LibCallOptimization("strlen",
Reid Spencer170ae7f2005-05-07 20:15:59 +0000913 "Number of 'strlen' calls simplified") {}
Reid Spencer76dab9a2005-04-26 05:24:00 +0000914
915 /// @brief Make sure that the "strlen" function has the right prototype
Reid Spencere249a822005-04-27 07:54:40 +0000916 virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC)
Reid Spencer76dab9a2005-04-26 05:24:00 +0000917 {
Reid Spencere249a822005-04-27 07:54:40 +0000918 if (f->getReturnType() == SLC.getTargetData()->getIntPtrType())
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000919 if (f->arg_size() == 1)
Reid Spencer76dab9a2005-04-26 05:24:00 +0000920 if (Function::const_arg_iterator AI = f->arg_begin())
921 if (AI->getType() == PointerType::get(Type::SByteTy))
922 return true;
923 return false;
924 }
925
926 /// @brief Perform the strlen optimization
Reid Spencere249a822005-04-27 07:54:40 +0000927 virtual bool OptimizeCall(CallInst* ci, SimplifyLibCalls& SLC)
Reid Spencer76dab9a2005-04-26 05:24:00 +0000928 {
Reid Spencer170ae7f2005-05-07 20:15:59 +0000929 // Make sure we're dealing with an sbyte* here.
930 Value* str = ci->getOperand(1);
931 if (str->getType() != PointerType::get(Type::SByteTy))
932 return false;
933
934 // Does the call to strlen have exactly one use?
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +0000935 if (ci->hasOneUse())
Reid Spencer170ae7f2005-05-07 20:15:59 +0000936 // Is that single use a binary operator?
937 if (BinaryOperator* bop = dyn_cast<BinaryOperator>(ci->use_back()))
938 // Is it compared against a constant integer?
939 if (ConstantInt* CI = dyn_cast<ConstantInt>(bop->getOperand(1)))
940 {
941 // Get the value the strlen result is compared to
942 uint64_t val = CI->getRawValue();
943
944 // If its compared against length 0 with == or !=
945 if (val == 0 &&
946 (bop->getOpcode() == Instruction::SetEQ ||
947 bop->getOpcode() == Instruction::SetNE))
948 {
949 // strlen(x) != 0 -> *x != 0
950 // strlen(x) == 0 -> *x == 0
951 LoadInst* load = new LoadInst(str,str->getName()+".first",ci);
952 BinaryOperator* rbop = BinaryOperator::create(bop->getOpcode(),
953 load, ConstantSInt::get(Type::SByteTy,0),
954 bop->getName()+".strlen", ci);
955 bop->replaceAllUsesWith(rbop);
956 bop->eraseFromParent();
957 ci->eraseFromParent();
958 return true;
959 }
960 }
961
962 // Get the length of the constant string operand
Reid Spencerb4f7b832005-04-26 07:45:18 +0000963 uint64_t len = 0;
964 if (!getConstantStringLength(ci->getOperand(1),len))
Reid Spencer76dab9a2005-04-26 05:24:00 +0000965 return false;
966
Reid Spencer170ae7f2005-05-07 20:15:59 +0000967 // strlen("xyz") -> 3 (for example)
Chris Lattnere17c5d02005-08-01 16:52:50 +0000968 const Type *Ty = SLC.getTargetData()->getIntPtrType();
969 if (Ty->isSigned())
970 ci->replaceAllUsesWith(ConstantSInt::get(Ty, len));
971 else
972 ci->replaceAllUsesWith(ConstantUInt::get(Ty, len));
973
Reid Spencerb4f7b832005-04-26 07:45:18 +0000974 ci->eraseFromParent();
975 return true;
Reid Spencer76dab9a2005-04-26 05:24:00 +0000976 }
977} StrLenOptimizer;
978
Chris Lattnerc244e7c2005-09-29 04:54:20 +0000979/// IsOnlyUsedInEqualsComparison - Return true if it only matters that the value
980/// is equal or not-equal to zero.
981static bool IsOnlyUsedInEqualsZeroComparison(Instruction *I) {
982 for (Value::use_iterator UI = I->use_begin(), E = I->use_end();
983 UI != E; ++UI) {
984 Instruction *User = cast<Instruction>(*UI);
985 if (User->getOpcode() == Instruction::SetNE ||
986 User->getOpcode() == Instruction::SetEQ) {
987 if (isa<Constant>(User->getOperand(1)) &&
988 cast<Constant>(User->getOperand(1))->isNullValue())
989 continue;
990 } else if (CastInst *CI = dyn_cast<CastInst>(User))
991 if (CI->getType() == Type::BoolTy)
992 continue;
993 // Unknown instruction.
994 return false;
995 }
996 return true;
997}
998
999/// This memcmpOptimization will simplify a call to the memcmp library
1000/// function.
1001struct memcmpOptimization : public LibCallOptimization {
1002 /// @brief Default Constructor
1003 memcmpOptimization()
1004 : LibCallOptimization("memcmp", "Number of 'memcmp' calls simplified") {}
1005
1006 /// @brief Make sure that the "memcmp" function has the right prototype
1007 virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &TD) {
1008 Function::const_arg_iterator AI = F->arg_begin();
1009 if (F->arg_size() != 3 || !isa<PointerType>(AI->getType())) return false;
1010 if (!isa<PointerType>((++AI)->getType())) return false;
1011 if (!(++AI)->getType()->isInteger()) return false;
1012 if (!F->getReturnType()->isInteger()) return false;
1013 return true;
1014 }
1015
1016 /// Because of alignment and instruction information that we don't have, we
1017 /// leave the bulk of this to the code generators.
1018 ///
1019 /// Note that we could do much more if we could force alignment on otherwise
1020 /// small aligned allocas, or if we could indicate that loads have a small
1021 /// alignment.
1022 virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &TD) {
1023 Value *LHS = CI->getOperand(1), *RHS = CI->getOperand(2);
1024
1025 // If the two operands are the same, return zero.
1026 if (LHS == RHS) {
1027 // memcmp(s,s,x) -> 0
1028 CI->replaceAllUsesWith(Constant::getNullValue(CI->getType()));
1029 CI->eraseFromParent();
1030 return true;
1031 }
1032
1033 // Make sure we have a constant length.
1034 ConstantInt *LenC = dyn_cast<ConstantInt>(CI->getOperand(3));
1035 if (!LenC) return false;
1036 uint64_t Len = LenC->getRawValue();
1037
1038 // If the length is zero, this returns 0.
1039 switch (Len) {
1040 case 0:
1041 // memcmp(s1,s2,0) -> 0
1042 CI->replaceAllUsesWith(Constant::getNullValue(CI->getType()));
1043 CI->eraseFromParent();
1044 return true;
1045 case 1: {
1046 // memcmp(S1,S2,1) -> *(ubyte*)S1 - *(ubyte*)S2
1047 const Type *UCharPtr = PointerType::get(Type::UByteTy);
1048 CastInst *Op1Cast = new CastInst(LHS, UCharPtr, LHS->getName(), CI);
1049 CastInst *Op2Cast = new CastInst(RHS, UCharPtr, RHS->getName(), CI);
1050 Value *S1V = new LoadInst(Op1Cast, LHS->getName()+".val", CI);
1051 Value *S2V = new LoadInst(Op2Cast, RHS->getName()+".val", CI);
1052 Value *RV = BinaryOperator::createSub(S1V, S2V, CI->getName()+".diff",CI);
1053 if (RV->getType() != CI->getType())
1054 RV = new CastInst(RV, CI->getType(), RV->getName(), CI);
1055 CI->replaceAllUsesWith(RV);
1056 CI->eraseFromParent();
1057 return true;
1058 }
1059 case 2:
1060 if (IsOnlyUsedInEqualsZeroComparison(CI)) {
1061 // TODO: IF both are aligned, use a short load/compare.
1062
1063 // memcmp(S1,S2,2) -> S1[0]-S2[0] | S1[1]-S2[1] iff only ==/!= 0 matters
1064 const Type *UCharPtr = PointerType::get(Type::UByteTy);
1065 CastInst *Op1Cast = new CastInst(LHS, UCharPtr, LHS->getName(), CI);
1066 CastInst *Op2Cast = new CastInst(RHS, UCharPtr, RHS->getName(), CI);
1067 Value *S1V1 = new LoadInst(Op1Cast, LHS->getName()+".val1", CI);
1068 Value *S2V1 = new LoadInst(Op2Cast, RHS->getName()+".val1", CI);
1069 Value *D1 = BinaryOperator::createSub(S1V1, S2V1,
1070 CI->getName()+".d1", CI);
1071 Constant *One = ConstantInt::get(Type::IntTy, 1);
1072 Value *G1 = new GetElementPtrInst(Op1Cast, One, "next1v", CI);
1073 Value *G2 = new GetElementPtrInst(Op2Cast, One, "next2v", CI);
1074 Value *S1V2 = new LoadInst(G1, LHS->getName()+".val2", CI);
1075 Value *S2V2 = new LoadInst(G1, RHS->getName()+".val2", CI);
1076 Value *D2 = BinaryOperator::createSub(S1V2, S2V2,
1077 CI->getName()+".d1", CI);
1078 Value *Or = BinaryOperator::createOr(D1, D2, CI->getName()+".res", CI);
1079 if (Or->getType() != CI->getType())
1080 Or = new CastInst(Or, CI->getType(), Or->getName(), CI);
1081 CI->replaceAllUsesWith(Or);
1082 CI->eraseFromParent();
1083 return true;
1084 }
1085 break;
1086 default:
1087 break;
1088 }
1089
1090
1091
1092 return false;
1093 }
1094} memcmpOptimizer;
1095
1096
1097
1098
1099
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00001100/// This LibCallOptimization will simplify a call to the memcpy library
1101/// function by expanding it out to a single store of size 0, 1, 2, 4, or 8
Reid Spencer7ddcfb32005-04-27 21:29:20 +00001102/// bytes depending on the length of the string and the alignment. Additional
1103/// optimizations are possible in code generation (sequence of immediate store)
Reid Spencerf2534c72005-04-25 21:11:48 +00001104/// @brief Simplify the memcpy library function.
Reid Spencer38cabd72005-05-03 07:23:44 +00001105struct LLVMMemCpyOptimization : public LibCallOptimization
Reid Spencerf2534c72005-04-25 21:11:48 +00001106{
Reid Spencer7ddcfb32005-04-27 21:29:20 +00001107 /// @brief Default Constructor
Reid Spencer38cabd72005-05-03 07:23:44 +00001108 LLVMMemCpyOptimization() : LibCallOptimization("llvm.memcpy",
Reid Spencer95d8efd2005-05-03 02:54:54 +00001109 "Number of 'llvm.memcpy' calls simplified") {}
1110
Reid Spencerbb92b4f2005-04-26 19:13:17 +00001111protected:
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00001112 /// @brief Subclass Constructor
Reid Spencer170ae7f2005-05-07 20:15:59 +00001113 LLVMMemCpyOptimization(const char* fname, const char* desc)
1114 : LibCallOptimization(fname, desc) {}
Reid Spencerbb92b4f2005-04-26 19:13:17 +00001115public:
Reid Spencerf2534c72005-04-25 21:11:48 +00001116
1117 /// @brief Make sure that the "memcpy" function has the right prototype
Reid Spencere249a822005-04-27 07:54:40 +00001118 virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& TD)
Reid Spencerf2534c72005-04-25 21:11:48 +00001119 {
Reid Spencerbb92b4f2005-04-26 19:13:17 +00001120 // Just make sure this has 4 arguments per LLVM spec.
Reid Spencer2bc7a4f2005-04-26 23:02:16 +00001121 return (f->arg_size() == 4);
Reid Spencerf2534c72005-04-25 21:11:48 +00001122 }
1123
Reid Spencerb4f7b832005-04-26 07:45:18 +00001124 /// Because of alignment and instruction information that we don't have, we
1125 /// leave the bulk of this to the code generators. The optimization here just
1126 /// deals with a few degenerate cases where the length of the string and the
1127 /// alignment match the sizes of our intrinsic types so we can do a load and
1128 /// store instead of the memcpy call.
1129 /// @brief Perform the memcpy optimization.
Reid Spencere249a822005-04-27 07:54:40 +00001130 virtual bool OptimizeCall(CallInst* ci, SimplifyLibCalls& TD)
Reid Spencerf2534c72005-04-25 21:11:48 +00001131 {
Reid Spencer4855ebf2005-04-26 19:55:57 +00001132 // Make sure we have constant int values to work with
1133 ConstantInt* LEN = dyn_cast<ConstantInt>(ci->getOperand(3));
1134 if (!LEN)
1135 return false;
1136 ConstantInt* ALIGN = dyn_cast<ConstantInt>(ci->getOperand(4));
1137 if (!ALIGN)
1138 return false;
1139
1140 // If the length is larger than the alignment, we can't optimize
1141 uint64_t len = LEN->getRawValue();
1142 uint64_t alignment = ALIGN->getRawValue();
Reid Spencer38cabd72005-05-03 07:23:44 +00001143 if (alignment == 0)
1144 alignment = 1; // Alignment 0 is identity for alignment 1
Reid Spencerbb92b4f2005-04-26 19:13:17 +00001145 if (len > alignment)
Reid Spencerb4f7b832005-04-26 07:45:18 +00001146 return false;
1147
Reid Spencer08b49402005-04-27 17:46:54 +00001148 // Get the type we will cast to, based on size of the string
Reid Spencerb4f7b832005-04-26 07:45:18 +00001149 Value* dest = ci->getOperand(1);
1150 Value* src = ci->getOperand(2);
Reid Spencer08b49402005-04-27 17:46:54 +00001151 Type* castType = 0;
Reid Spencerb4f7b832005-04-26 07:45:18 +00001152 switch (len)
1153 {
Reid Spencerbb92b4f2005-04-26 19:13:17 +00001154 case 0:
Reid Spencer93616972005-04-29 09:39:47 +00001155 // memcpy(d,s,0,a) -> noop
Reid Spencerbb92b4f2005-04-26 19:13:17 +00001156 ci->eraseFromParent();
1157 return true;
Reid Spencer08b49402005-04-27 17:46:54 +00001158 case 1: castType = Type::SByteTy; break;
1159 case 2: castType = Type::ShortTy; break;
1160 case 4: castType = Type::IntTy; break;
1161 case 8: castType = Type::LongTy; break;
Reid Spencerb4f7b832005-04-26 07:45:18 +00001162 default:
1163 return false;
1164 }
Reid Spencer08b49402005-04-27 17:46:54 +00001165
1166 // Cast source and dest to the right sized primitive and then load/store
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00001167 CastInst* SrcCast =
Reid Spencer08b49402005-04-27 17:46:54 +00001168 new CastInst(src,PointerType::get(castType),src->getName()+".cast",ci);
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00001169 CastInst* DestCast =
Reid Spencer08b49402005-04-27 17:46:54 +00001170 new CastInst(dest,PointerType::get(castType),dest->getName()+".cast",ci);
1171 LoadInst* LI = new LoadInst(SrcCast,SrcCast->getName()+".val",ci);
Reid Spencerb4f7b832005-04-26 07:45:18 +00001172 StoreInst* SI = new StoreInst(LI, DestCast, ci);
Reid Spencerb4f7b832005-04-26 07:45:18 +00001173 ci->eraseFromParent();
1174 return true;
Reid Spencerf2534c72005-04-25 21:11:48 +00001175 }
Reid Spencer38cabd72005-05-03 07:23:44 +00001176} LLVMMemCpyOptimizer;
Reid Spencerbb92b4f2005-04-26 19:13:17 +00001177
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00001178/// This LibCallOptimization will simplify a call to the memmove library
1179/// function. It is identical to MemCopyOptimization except for the name of
Reid Spencer7ddcfb32005-04-27 21:29:20 +00001180/// the intrinsic.
Reid Spencerbb92b4f2005-04-26 19:13:17 +00001181/// @brief Simplify the memmove library function.
Reid Spencer38cabd72005-05-03 07:23:44 +00001182struct LLVMMemMoveOptimization : public LLVMMemCpyOptimization
Reid Spencerbb92b4f2005-04-26 19:13:17 +00001183{
Reid Spencer7ddcfb32005-04-27 21:29:20 +00001184 /// @brief Default Constructor
Reid Spencer38cabd72005-05-03 07:23:44 +00001185 LLVMMemMoveOptimization() : LLVMMemCpyOptimization("llvm.memmove",
Reid Spencer95d8efd2005-05-03 02:54:54 +00001186 "Number of 'llvm.memmove' calls simplified") {}
Reid Spencerbb92b4f2005-04-26 19:13:17 +00001187
Reid Spencer38cabd72005-05-03 07:23:44 +00001188} LLVMMemMoveOptimizer;
1189
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00001190/// This LibCallOptimization will simplify a call to the memset library
1191/// function by expanding it out to a single store of size 0, 1, 2, 4, or 8
1192/// bytes depending on the length argument.
Reid Spencer38cabd72005-05-03 07:23:44 +00001193struct LLVMMemSetOptimization : public LibCallOptimization
1194{
1195 /// @brief Default Constructor
1196 LLVMMemSetOptimization() : LibCallOptimization("llvm.memset",
Reid Spencer38cabd72005-05-03 07:23:44 +00001197 "Number of 'llvm.memset' calls simplified") {}
1198
1199public:
Reid Spencer38cabd72005-05-03 07:23:44 +00001200
1201 /// @brief Make sure that the "memset" function has the right prototype
1202 virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& TD)
1203 {
1204 // Just make sure this has 3 arguments per LLVM spec.
1205 return (f->arg_size() == 4);
1206 }
1207
1208 /// Because of alignment and instruction information that we don't have, we
1209 /// leave the bulk of this to the code generators. The optimization here just
1210 /// deals with a few degenerate cases where the length parameter is constant
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00001211 /// and the alignment matches the sizes of our intrinsic types so we can do
Reid Spencer38cabd72005-05-03 07:23:44 +00001212 /// store instead of the memcpy call. Other calls are transformed into the
1213 /// llvm.memset intrinsic.
1214 /// @brief Perform the memset optimization.
1215 virtual bool OptimizeCall(CallInst* ci, SimplifyLibCalls& TD)
1216 {
1217 // Make sure we have constant int values to work with
1218 ConstantInt* LEN = dyn_cast<ConstantInt>(ci->getOperand(3));
1219 if (!LEN)
1220 return false;
1221 ConstantInt* ALIGN = dyn_cast<ConstantInt>(ci->getOperand(4));
1222 if (!ALIGN)
1223 return false;
1224
1225 // Extract the length and alignment
1226 uint64_t len = LEN->getRawValue();
1227 uint64_t alignment = ALIGN->getRawValue();
1228
1229 // Alignment 0 is identity for alignment 1
1230 if (alignment == 0)
1231 alignment = 1;
1232
1233 // If the length is zero, this is a no-op
1234 if (len == 0)
1235 {
1236 // memset(d,c,0,a) -> noop
1237 ci->eraseFromParent();
1238 return true;
1239 }
1240
1241 // If the length is larger than the alignment, we can't optimize
1242 if (len > alignment)
1243 return false;
1244
1245 // Make sure we have a constant ubyte to work with so we can extract
1246 // the value to be filled.
1247 ConstantUInt* FILL = dyn_cast<ConstantUInt>(ci->getOperand(2));
1248 if (!FILL)
1249 return false;
1250 if (FILL->getType() != Type::UByteTy)
1251 return false;
1252
1253 // memset(s,c,n) -> store s, c (for n=1,2,4,8)
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00001254
Reid Spencer38cabd72005-05-03 07:23:44 +00001255 // Extract the fill character
1256 uint64_t fill_char = FILL->getValue();
1257 uint64_t fill_value = fill_char;
1258
1259 // Get the type we will cast to, based on size of memory area to fill, and
1260 // and the value we will store there.
1261 Value* dest = ci->getOperand(1);
1262 Type* castType = 0;
1263 switch (len)
1264 {
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00001265 case 1:
1266 castType = Type::UByteTy;
Reid Spencer38cabd72005-05-03 07:23:44 +00001267 break;
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00001268 case 2:
1269 castType = Type::UShortTy;
Reid Spencer38cabd72005-05-03 07:23:44 +00001270 fill_value |= fill_char << 8;
1271 break;
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00001272 case 4:
Reid Spencer38cabd72005-05-03 07:23:44 +00001273 castType = Type::UIntTy;
1274 fill_value |= fill_char << 8 | fill_char << 16 | fill_char << 24;
1275 break;
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00001276 case 8:
Reid Spencer38cabd72005-05-03 07:23:44 +00001277 castType = Type::ULongTy;
1278 fill_value |= fill_char << 8 | fill_char << 16 | fill_char << 24;
1279 fill_value |= fill_char << 32 | fill_char << 40 | fill_char << 48;
1280 fill_value |= fill_char << 56;
1281 break;
1282 default:
1283 return false;
1284 }
1285
1286 // Cast dest to the right sized primitive and then load/store
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00001287 CastInst* DestCast =
Reid Spencer38cabd72005-05-03 07:23:44 +00001288 new CastInst(dest,PointerType::get(castType),dest->getName()+".cast",ci);
1289 new StoreInst(ConstantUInt::get(castType,fill_value),DestCast, ci);
1290 ci->eraseFromParent();
1291 return true;
1292 }
1293} LLVMMemSetOptimizer;
Reid Spencerbb92b4f2005-04-26 19:13:17 +00001294
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00001295/// This LibCallOptimization will simplify calls to the "pow" library
1296/// function. It looks for cases where the result of pow is well known and
Reid Spencer93616972005-04-29 09:39:47 +00001297/// substitutes the appropriate value.
1298/// @brief Simplify the pow library function.
1299struct PowOptimization : public LibCallOptimization
1300{
1301public:
1302 /// @brief Default Constructor
Reid Spencer95d8efd2005-05-03 02:54:54 +00001303 PowOptimization() : LibCallOptimization("pow",
Reid Spencer170ae7f2005-05-07 20:15:59 +00001304 "Number of 'pow' calls simplified") {}
Reid Spencer95d8efd2005-05-03 02:54:54 +00001305
Reid Spencer93616972005-04-29 09:39:47 +00001306 /// @brief Make sure that the "pow" function has the right prototype
1307 virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC)
1308 {
1309 // Just make sure this has 2 arguments
1310 return (f->arg_size() == 2);
1311 }
1312
1313 /// @brief Perform the pow optimization.
1314 virtual bool OptimizeCall(CallInst* ci, SimplifyLibCalls& SLC)
1315 {
1316 const Type *Ty = cast<Function>(ci->getOperand(0))->getReturnType();
1317 Value* base = ci->getOperand(1);
1318 Value* expn = ci->getOperand(2);
1319 if (ConstantFP *Op1 = dyn_cast<ConstantFP>(base)) {
1320 double Op1V = Op1->getValue();
1321 if (Op1V == 1.0)
1322 {
1323 // pow(1.0,x) -> 1.0
1324 ci->replaceAllUsesWith(ConstantFP::get(Ty,1.0));
1325 ci->eraseFromParent();
1326 return true;
1327 }
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00001328 }
1329 else if (ConstantFP* Op2 = dyn_cast<ConstantFP>(expn))
Reid Spencer93616972005-04-29 09:39:47 +00001330 {
1331 double Op2V = Op2->getValue();
1332 if (Op2V == 0.0)
1333 {
1334 // pow(x,0.0) -> 1.0
1335 ci->replaceAllUsesWith(ConstantFP::get(Ty,1.0));
1336 ci->eraseFromParent();
1337 return true;
1338 }
1339 else if (Op2V == 0.5)
1340 {
1341 // pow(x,0.5) -> sqrt(x)
1342 CallInst* sqrt_inst = new CallInst(SLC.get_sqrt(), base,
1343 ci->getName()+".pow",ci);
1344 ci->replaceAllUsesWith(sqrt_inst);
1345 ci->eraseFromParent();
1346 return true;
1347 }
1348 else if (Op2V == 1.0)
1349 {
1350 // pow(x,1.0) -> x
1351 ci->replaceAllUsesWith(base);
1352 ci->eraseFromParent();
1353 return true;
1354 }
1355 else if (Op2V == -1.0)
1356 {
1357 // pow(x,-1.0) -> 1.0/x
Chris Lattner4201cd12005-08-24 17:22:17 +00001358 BinaryOperator* div_inst= BinaryOperator::createDiv(
Reid Spencer93616972005-04-29 09:39:47 +00001359 ConstantFP::get(Ty,1.0), base, ci->getName()+".pow", ci);
1360 ci->replaceAllUsesWith(div_inst);
1361 ci->eraseFromParent();
1362 return true;
1363 }
1364 }
1365 return false; // opt failed
1366 }
1367} PowOptimizer;
1368
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00001369/// This LibCallOptimization will simplify calls to the "fprintf" library
Reid Spencer2d5c7be2005-05-02 23:59:26 +00001370/// function. It looks for cases where the result of fprintf is not used and the
1371/// operation can be reduced to something simpler.
1372/// @brief Simplify the pow library function.
1373struct FPrintFOptimization : public LibCallOptimization
1374{
1375public:
1376 /// @brief Default Constructor
Reid Spencer95d8efd2005-05-03 02:54:54 +00001377 FPrintFOptimization() : LibCallOptimization("fprintf",
Reid Spencer170ae7f2005-05-07 20:15:59 +00001378 "Number of 'fprintf' calls simplified") {}
Reid Spencer2d5c7be2005-05-02 23:59:26 +00001379
Reid Spencer2d5c7be2005-05-02 23:59:26 +00001380 /// @brief Make sure that the "fprintf" function has the right prototype
1381 virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC)
1382 {
1383 // Just make sure this has at least 2 arguments
1384 return (f->arg_size() >= 2);
1385 }
1386
1387 /// @brief Perform the fprintf optimization.
1388 virtual bool OptimizeCall(CallInst* ci, SimplifyLibCalls& SLC)
1389 {
1390 // If the call has more than 3 operands, we can't optimize it
1391 if (ci->getNumOperands() > 4 || ci->getNumOperands() <= 2)
1392 return false;
1393
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00001394 // If the result of the fprintf call is used, none of these optimizations
Reid Spencer2d5c7be2005-05-02 23:59:26 +00001395 // can be made.
Chris Lattner175463a2005-09-24 22:17:06 +00001396 if (!ci->use_empty())
Reid Spencer2d5c7be2005-05-02 23:59:26 +00001397 return false;
1398
1399 // All the optimizations depend on the length of the second argument and the
1400 // fact that it is a constant string array. Check that now
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00001401 uint64_t len = 0;
Reid Spencer2d5c7be2005-05-02 23:59:26 +00001402 ConstantArray* CA = 0;
1403 if (!getConstantStringLength(ci->getOperand(2), len, &CA))
1404 return false;
1405
1406 if (ci->getNumOperands() == 3)
1407 {
1408 // Make sure there's no % in the constant array
1409 for (unsigned i = 0; i < len; ++i)
1410 {
1411 if (ConstantInt* CI = dyn_cast<ConstantInt>(CA->getOperand(i)))
1412 {
1413 // Check for the null terminator
1414 if (CI->getRawValue() == '%')
1415 return false; // we found end of string
1416 }
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00001417 else
Reid Spencer2d5c7be2005-05-02 23:59:26 +00001418 return false;
1419 }
1420
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00001421 // fprintf(file,fmt) -> fwrite(fmt,strlen(fmt),file)
Reid Spencer2d5c7be2005-05-02 23:59:26 +00001422 const Type* FILEptr_type = ci->getOperand(1)->getType();
1423 Function* fwrite_func = SLC.get_fwrite(FILEptr_type);
1424 if (!fwrite_func)
1425 return false;
John Criswell4642afd2005-06-29 15:03:18 +00001426
1427 // Make sure that the fprintf() and fwrite() functions both take the
1428 // same type of char pointer.
1429 if (ci->getOperand(2)->getType() !=
1430 fwrite_func->getFunctionType()->getParamType(0))
John Criswell4642afd2005-06-29 15:03:18 +00001431 return false;
John Criswell4642afd2005-06-29 15:03:18 +00001432
Reid Spencer2d5c7be2005-05-02 23:59:26 +00001433 std::vector<Value*> args;
1434 args.push_back(ci->getOperand(2));
1435 args.push_back(ConstantUInt::get(SLC.getIntPtrType(),len));
1436 args.push_back(ConstantUInt::get(SLC.getIntPtrType(),1));
1437 args.push_back(ci->getOperand(1));
Reid Spencer1e520fd2005-05-04 03:20:21 +00001438 new CallInst(fwrite_func,args,ci->getName(),ci);
1439 ci->replaceAllUsesWith(ConstantSInt::get(Type::IntTy,len));
Reid Spencer2d5c7be2005-05-02 23:59:26 +00001440 ci->eraseFromParent();
1441 return true;
1442 }
1443
1444 // The remaining optimizations require the format string to be length 2
1445 // "%s" or "%c".
1446 if (len != 2)
1447 return false;
1448
1449 // The first character has to be a %
1450 if (ConstantInt* CI = dyn_cast<ConstantInt>(CA->getOperand(0)))
1451 if (CI->getRawValue() != '%')
1452 return false;
1453
1454 // Get the second character and switch on its value
1455 ConstantInt* CI = dyn_cast<ConstantInt>(CA->getOperand(1));
1456 switch (CI->getRawValue())
1457 {
1458 case 's':
1459 {
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00001460 uint64_t len = 0;
Reid Spencer2d5c7be2005-05-02 23:59:26 +00001461 ConstantArray* CA = 0;
1462 if (!getConstantStringLength(ci->getOperand(3), len, &CA))
1463 return false;
1464
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00001465 // fprintf(file,"%s",str) -> fwrite(fmt,strlen(fmt),1,file)
Reid Spencer2d5c7be2005-05-02 23:59:26 +00001466 const Type* FILEptr_type = ci->getOperand(1)->getType();
1467 Function* fwrite_func = SLC.get_fwrite(FILEptr_type);
1468 if (!fwrite_func)
1469 return false;
1470 std::vector<Value*> args;
Reid Spencer45bb4af2005-05-21 00:39:30 +00001471 args.push_back(CastToCStr(ci->getOperand(3), *ci));
Reid Spencer2d5c7be2005-05-02 23:59:26 +00001472 args.push_back(ConstantUInt::get(SLC.getIntPtrType(),len));
1473 args.push_back(ConstantUInt::get(SLC.getIntPtrType(),1));
1474 args.push_back(ci->getOperand(1));
Reid Spencer1e520fd2005-05-04 03:20:21 +00001475 new CallInst(fwrite_func,args,ci->getName(),ci);
1476 ci->replaceAllUsesWith(ConstantSInt::get(Type::IntTy,len));
Reid Spencer2d5c7be2005-05-02 23:59:26 +00001477 break;
1478 }
1479 case 'c':
1480 {
1481 ConstantInt* CI = dyn_cast<ConstantInt>(ci->getOperand(3));
1482 if (!CI)
1483 return false;
1484
1485 const Type* FILEptr_type = ci->getOperand(1)->getType();
1486 Function* fputc_func = SLC.get_fputc(FILEptr_type);
1487 if (!fputc_func)
1488 return false;
1489 CastInst* cast = new CastInst(CI,Type::IntTy,CI->getName()+".int",ci);
1490 new CallInst(fputc_func,cast,ci->getOperand(1),"",ci);
Reid Spencer1e520fd2005-05-04 03:20:21 +00001491 ci->replaceAllUsesWith(ConstantSInt::get(Type::IntTy,1));
Reid Spencer2d5c7be2005-05-02 23:59:26 +00001492 break;
1493 }
1494 default:
1495 return false;
1496 }
1497 ci->eraseFromParent();
1498 return true;
1499 }
1500} FPrintFOptimizer;
1501
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00001502/// This LibCallOptimization will simplify calls to the "sprintf" library
Reid Spencer1e520fd2005-05-04 03:20:21 +00001503/// function. It looks for cases where the result of sprintf is not used and the
1504/// operation can be reduced to something simpler.
1505/// @brief Simplify the pow library function.
1506struct SPrintFOptimization : public LibCallOptimization
1507{
1508public:
1509 /// @brief Default Constructor
1510 SPrintFOptimization() : LibCallOptimization("sprintf",
Reid Spencer170ae7f2005-05-07 20:15:59 +00001511 "Number of 'sprintf' calls simplified") {}
Reid Spencer1e520fd2005-05-04 03:20:21 +00001512
Reid Spencer1e520fd2005-05-04 03:20:21 +00001513 /// @brief Make sure that the "fprintf" function has the right prototype
1514 virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC)
1515 {
1516 // Just make sure this has at least 2 arguments
1517 return (f->getReturnType() == Type::IntTy && f->arg_size() >= 2);
1518 }
1519
1520 /// @brief Perform the sprintf optimization.
1521 virtual bool OptimizeCall(CallInst* ci, SimplifyLibCalls& SLC)
1522 {
1523 // If the call has more than 3 operands, we can't optimize it
1524 if (ci->getNumOperands() > 4 || ci->getNumOperands() < 3)
1525 return false;
1526
1527 // All the optimizations depend on the length of the second argument and the
1528 // fact that it is a constant string array. Check that now
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00001529 uint64_t len = 0;
Reid Spencer1e520fd2005-05-04 03:20:21 +00001530 ConstantArray* CA = 0;
1531 if (!getConstantStringLength(ci->getOperand(2), len, &CA))
1532 return false;
1533
1534 if (ci->getNumOperands() == 3)
1535 {
1536 if (len == 0)
1537 {
1538 // If the length is 0, we just need to store a null byte
1539 new StoreInst(ConstantInt::get(Type::SByteTy,0),ci->getOperand(1),ci);
1540 ci->replaceAllUsesWith(ConstantSInt::get(Type::IntTy,0));
1541 ci->eraseFromParent();
1542 return true;
1543 }
1544
1545 // Make sure there's no % in the constant array
1546 for (unsigned i = 0; i < len; ++i)
1547 {
1548 if (ConstantInt* CI = dyn_cast<ConstantInt>(CA->getOperand(i)))
1549 {
1550 // Check for the null terminator
1551 if (CI->getRawValue() == '%')
1552 return false; // we found a %, can't optimize
1553 }
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00001554 else
Reid Spencer1e520fd2005-05-04 03:20:21 +00001555 return false; // initializer is not constant int, can't optimize
1556 }
1557
1558 // Increment length because we want to copy the null byte too
1559 len++;
1560
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00001561 // sprintf(str,fmt) -> llvm.memcpy(str,fmt,strlen(fmt),1)
Reid Spencer1e520fd2005-05-04 03:20:21 +00001562 Function* memcpy_func = SLC.get_memcpy();
1563 if (!memcpy_func)
1564 return false;
1565 std::vector<Value*> args;
1566 args.push_back(ci->getOperand(1));
1567 args.push_back(ci->getOperand(2));
1568 args.push_back(ConstantUInt::get(Type::UIntTy,len));
1569 args.push_back(ConstantUInt::get(Type::UIntTy,1));
1570 new CallInst(memcpy_func,args,"",ci);
1571 ci->replaceAllUsesWith(ConstantSInt::get(Type::IntTy,len));
1572 ci->eraseFromParent();
1573 return true;
1574 }
1575
1576 // The remaining optimizations require the format string to be length 2
1577 // "%s" or "%c".
1578 if (len != 2)
1579 return false;
1580
1581 // The first character has to be a %
1582 if (ConstantInt* CI = dyn_cast<ConstantInt>(CA->getOperand(0)))
1583 if (CI->getRawValue() != '%')
1584 return false;
1585
1586 // Get the second character and switch on its value
1587 ConstantInt* CI = dyn_cast<ConstantInt>(CA->getOperand(1));
Chris Lattner175463a2005-09-24 22:17:06 +00001588 switch (CI->getRawValue()) {
1589 case 's': {
1590 // sprintf(dest,"%s",str) -> llvm.memcpy(dest, str, strlen(str)+1, 1)
1591 Function* strlen_func = SLC.get_strlen();
1592 Function* memcpy_func = SLC.get_memcpy();
1593 if (!strlen_func || !memcpy_func)
Reid Spencer1e520fd2005-05-04 03:20:21 +00001594 return false;
Chris Lattner175463a2005-09-24 22:17:06 +00001595
1596 Value *Len = new CallInst(strlen_func, CastToCStr(ci->getOperand(3), *ci),
1597 ci->getOperand(3)->getName()+".len", ci);
1598 Value *Len1 = BinaryOperator::createAdd(Len,
1599 ConstantInt::get(Len->getType(), 1),
1600 Len->getName()+"1", ci);
1601 if (Len1->getType() != Type::UIntTy)
1602 Len1 = new CastInst(Len1, Type::UIntTy, Len1->getName(), ci);
1603 std::vector<Value*> args;
1604 args.push_back(CastToCStr(ci->getOperand(1), *ci));
1605 args.push_back(CastToCStr(ci->getOperand(3), *ci));
1606 args.push_back(Len1);
1607 args.push_back(ConstantUInt::get(Type::UIntTy,1));
1608 new CallInst(memcpy_func, args, "", ci);
1609
1610 // The strlen result is the unincremented number of bytes in the string.
Chris Lattnerf4877682005-09-25 07:06:48 +00001611 if (!ci->use_empty()) {
1612 if (Len->getType() != ci->getType())
1613 Len = new CastInst(Len, ci->getType(), Len->getName(), ci);
1614 ci->replaceAllUsesWith(Len);
1615 }
Chris Lattner175463a2005-09-24 22:17:06 +00001616 ci->eraseFromParent();
1617 return true;
Reid Spencer1e520fd2005-05-04 03:20:21 +00001618 }
Chris Lattner175463a2005-09-24 22:17:06 +00001619 case 'c': {
1620 // sprintf(dest,"%c",chr) -> store chr, dest
1621 CastInst* cast = new CastInst(ci->getOperand(3),Type::SByteTy,"char",ci);
1622 new StoreInst(cast, ci->getOperand(1), ci);
1623 GetElementPtrInst* gep = new GetElementPtrInst(ci->getOperand(1),
1624 ConstantUInt::get(Type::UIntTy,1),ci->getOperand(1)->getName()+".end",
1625 ci);
1626 new StoreInst(ConstantInt::get(Type::SByteTy,0),gep,ci);
1627 ci->replaceAllUsesWith(ConstantSInt::get(Type::IntTy,1));
1628 ci->eraseFromParent();
1629 return true;
1630 }
1631 }
1632 return false;
Reid Spencer1e520fd2005-05-04 03:20:21 +00001633 }
1634} SPrintFOptimizer;
1635
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00001636/// This LibCallOptimization will simplify calls to the "fputs" library
Reid Spencer93616972005-04-29 09:39:47 +00001637/// function. It looks for cases where the result of fputs is not used and the
1638/// operation can be reduced to something simpler.
1639/// @brief Simplify the pow library function.
1640struct PutsOptimization : public LibCallOptimization
1641{
1642public:
1643 /// @brief Default Constructor
Reid Spencer95d8efd2005-05-03 02:54:54 +00001644 PutsOptimization() : LibCallOptimization("fputs",
Reid Spencer170ae7f2005-05-07 20:15:59 +00001645 "Number of 'fputs' calls simplified") {}
Reid Spencer93616972005-04-29 09:39:47 +00001646
Reid Spencer93616972005-04-29 09:39:47 +00001647 /// @brief Make sure that the "fputs" function has the right prototype
1648 virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC)
1649 {
1650 // Just make sure this has 2 arguments
1651 return (f->arg_size() == 2);
1652 }
1653
1654 /// @brief Perform the fputs optimization.
1655 virtual bool OptimizeCall(CallInst* ci, SimplifyLibCalls& SLC)
1656 {
1657 // If the result is used, none of these optimizations work
Chris Lattner175463a2005-09-24 22:17:06 +00001658 if (!ci->use_empty())
Reid Spencer93616972005-04-29 09:39:47 +00001659 return false;
1660
1661 // All the optimizations depend on the length of the first argument and the
1662 // fact that it is a constant string array. Check that now
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00001663 uint64_t len = 0;
Reid Spencer93616972005-04-29 09:39:47 +00001664 if (!getConstantStringLength(ci->getOperand(1), len))
1665 return false;
1666
1667 switch (len)
1668 {
1669 case 0:
1670 // fputs("",F) -> noop
1671 break;
1672 case 1:
1673 {
1674 // fputs(s,F) -> fputc(s[0],F) (if s is constant and strlen(s) == 1)
Reid Spencer4c444fe2005-04-30 03:17:54 +00001675 const Type* FILEptr_type = ci->getOperand(2)->getType();
1676 Function* fputc_func = SLC.get_fputc(FILEptr_type);
Reid Spencer93616972005-04-29 09:39:47 +00001677 if (!fputc_func)
1678 return false;
1679 LoadInst* loadi = new LoadInst(ci->getOperand(1),
1680 ci->getOperand(1)->getName()+".byte",ci);
1681 CastInst* casti = new CastInst(loadi,Type::IntTy,
1682 loadi->getName()+".int",ci);
1683 new CallInst(fputc_func,casti,ci->getOperand(2),"",ci);
1684 break;
1685 }
1686 default:
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00001687 {
Reid Spencer93616972005-04-29 09:39:47 +00001688 // fputs(s,F) -> fwrite(s,1,len,F) (if s is constant and strlen(s) > 1)
Reid Spencer4c444fe2005-04-30 03:17:54 +00001689 const Type* FILEptr_type = ci->getOperand(2)->getType();
1690 Function* fwrite_func = SLC.get_fwrite(FILEptr_type);
Reid Spencer93616972005-04-29 09:39:47 +00001691 if (!fwrite_func)
1692 return false;
1693 std::vector<Value*> parms;
1694 parms.push_back(ci->getOperand(1));
1695 parms.push_back(ConstantUInt::get(SLC.getIntPtrType(),len));
1696 parms.push_back(ConstantUInt::get(SLC.getIntPtrType(),1));
1697 parms.push_back(ci->getOperand(2));
1698 new CallInst(fwrite_func,parms,"",ci);
1699 break;
1700 }
1701 }
1702 ci->eraseFromParent();
1703 return true; // success
1704 }
1705} PutsOptimizer;
1706
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00001707/// This LibCallOptimization will simplify calls to the "isdigit" library
Reid Spencer282d0572005-05-04 18:58:28 +00001708/// function. It simply does range checks the parameter explicitly.
1709/// @brief Simplify the isdigit library function.
Chris Lattner5f6035f2005-09-29 06:16:11 +00001710struct isdigitOptimization : public LibCallOptimization {
Reid Spencer282d0572005-05-04 18:58:28 +00001711public:
Chris Lattner5f6035f2005-09-29 06:16:11 +00001712 isdigitOptimization() : LibCallOptimization("isdigit",
Reid Spencer170ae7f2005-05-07 20:15:59 +00001713 "Number of 'isdigit' calls simplified") {}
Reid Spencer282d0572005-05-04 18:58:28 +00001714
Chris Lattner5f6035f2005-09-29 06:16:11 +00001715 /// @brief Make sure that the "isdigit" function has the right prototype
Reid Spencer282d0572005-05-04 18:58:28 +00001716 virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC)
1717 {
1718 // Just make sure this has 1 argument
1719 return (f->arg_size() == 1);
1720 }
1721
1722 /// @brief Perform the toascii optimization.
1723 virtual bool OptimizeCall(CallInst* ci, SimplifyLibCalls& SLC)
1724 {
1725 if (ConstantInt* CI = dyn_cast<ConstantInt>(ci->getOperand(1)))
1726 {
1727 // isdigit(c) -> 0 or 1, if 'c' is constant
1728 uint64_t val = CI->getRawValue();
1729 if (val >= '0' && val <='9')
1730 ci->replaceAllUsesWith(ConstantSInt::get(Type::IntTy,1));
1731 else
1732 ci->replaceAllUsesWith(ConstantSInt::get(Type::IntTy,0));
1733 ci->eraseFromParent();
1734 return true;
1735 }
1736
1737 // isdigit(c) -> (unsigned)c - '0' <= 9
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00001738 CastInst* cast =
Reid Spencer282d0572005-05-04 18:58:28 +00001739 new CastInst(ci->getOperand(1),Type::UIntTy,
1740 ci->getOperand(1)->getName()+".uint",ci);
Chris Lattner4201cd12005-08-24 17:22:17 +00001741 BinaryOperator* sub_inst = BinaryOperator::createSub(cast,
Reid Spencer282d0572005-05-04 18:58:28 +00001742 ConstantUInt::get(Type::UIntTy,0x30),
1743 ci->getOperand(1)->getName()+".sub",ci);
1744 SetCondInst* setcond_inst = new SetCondInst(Instruction::SetLE,sub_inst,
1745 ConstantUInt::get(Type::UIntTy,9),
1746 ci->getOperand(1)->getName()+".cmp",ci);
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00001747 CastInst* c2 =
Reid Spencer282d0572005-05-04 18:58:28 +00001748 new CastInst(setcond_inst,Type::IntTy,
1749 ci->getOperand(1)->getName()+".isdigit",ci);
1750 ci->replaceAllUsesWith(c2);
1751 ci->eraseFromParent();
1752 return true;
1753 }
Chris Lattner5f6035f2005-09-29 06:16:11 +00001754} isdigitOptimizer;
1755
Chris Lattner87ef9432005-09-29 06:17:27 +00001756struct isasciiOptimization : public LibCallOptimization {
1757public:
1758 isasciiOptimization()
1759 : LibCallOptimization("isascii", "Number of 'isascii' calls simplified") {}
1760
1761 virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &SLC){
1762 return F->arg_size() == 1 && F->arg_begin()->getType()->isInteger() &&
1763 F->getReturnType()->isInteger();
1764 }
1765
1766 /// @brief Perform the isascii optimization.
1767 virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &SLC) {
1768 // isascii(c) -> (unsigned)c < 128
1769 Value *V = CI->getOperand(1);
1770 if (V->getType()->isSigned())
1771 V = new CastInst(V, V->getType()->getUnsignedVersion(), V->getName(), CI);
1772 Value *Cmp = BinaryOperator::createSetLT(V, ConstantUInt::get(V->getType(),
1773 128),
1774 V->getName()+".isascii", CI);
1775 if (Cmp->getType() != CI->getType())
1776 Cmp = new CastInst(Cmp, CI->getType(), Cmp->getName(), CI);
1777 CI->replaceAllUsesWith(Cmp);
1778 CI->eraseFromParent();
1779 return true;
1780 }
1781} isasciiOptimizer;
Chris Lattner5f6035f2005-09-29 06:16:11 +00001782
Reid Spencer282d0572005-05-04 18:58:28 +00001783
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00001784/// This LibCallOptimization will simplify calls to the "toascii" library
Reid Spencer4c444fe2005-04-30 03:17:54 +00001785/// function. It simply does the corresponding and operation to restrict the
1786/// range of values to the ASCII character set (0-127).
1787/// @brief Simplify the toascii library function.
1788struct ToAsciiOptimization : public LibCallOptimization
1789{
1790public:
1791 /// @brief Default Constructor
Reid Spencer95d8efd2005-05-03 02:54:54 +00001792 ToAsciiOptimization() : LibCallOptimization("toascii",
Reid Spencer170ae7f2005-05-07 20:15:59 +00001793 "Number of 'toascii' calls simplified") {}
Reid Spencer4c444fe2005-04-30 03:17:54 +00001794
Reid Spencer4c444fe2005-04-30 03:17:54 +00001795 /// @brief Make sure that the "fputs" function has the right prototype
1796 virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC)
1797 {
1798 // Just make sure this has 2 arguments
1799 return (f->arg_size() == 1);
1800 }
1801
1802 /// @brief Perform the toascii optimization.
1803 virtual bool OptimizeCall(CallInst* ci, SimplifyLibCalls& SLC)
1804 {
1805 // toascii(c) -> (c & 0x7f)
1806 Value* chr = ci->getOperand(1);
Chris Lattner4201cd12005-08-24 17:22:17 +00001807 BinaryOperator* and_inst = BinaryOperator::createAnd(chr,
Reid Spencer4c444fe2005-04-30 03:17:54 +00001808 ConstantInt::get(chr->getType(),0x7F),ci->getName()+".toascii",ci);
1809 ci->replaceAllUsesWith(and_inst);
1810 ci->eraseFromParent();
1811 return true;
1812 }
1813} ToAsciiOptimizer;
1814
Reid Spencerb195fcd2005-05-14 16:42:52 +00001815/// This LibCallOptimization will simplify calls to the "ffs" library
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00001816/// calls which find the first set bit in an int, long, or long long. The
Reid Spencerb195fcd2005-05-14 16:42:52 +00001817/// optimization is to compute the result at compile time if the argument is
1818/// a constant.
1819/// @brief Simplify the ffs library function.
Chris Lattner801f4752006-01-17 18:27:17 +00001820struct FFSOptimization : public LibCallOptimization {
Reid Spencerb195fcd2005-05-14 16:42:52 +00001821protected:
1822 /// @brief Subclass Constructor
1823 FFSOptimization(const char* funcName, const char* description)
Chris Lattner801f4752006-01-17 18:27:17 +00001824 : LibCallOptimization(funcName, description) {}
Reid Spencerb195fcd2005-05-14 16:42:52 +00001825
1826public:
1827 /// @brief Default Constructor
1828 FFSOptimization() : LibCallOptimization("ffs",
1829 "Number of 'ffs' calls simplified") {}
1830
Chris Lattner801f4752006-01-17 18:27:17 +00001831 /// @brief Make sure that the "ffs" function has the right prototype
1832 virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &SLC){
Reid Spencerb195fcd2005-05-14 16:42:52 +00001833 // Just make sure this has 2 arguments
Chris Lattner801f4752006-01-17 18:27:17 +00001834 return F->arg_size() == 1 && F->getReturnType() == Type::IntTy;
Reid Spencerb195fcd2005-05-14 16:42:52 +00001835 }
1836
1837 /// @brief Perform the ffs optimization.
Chris Lattner801f4752006-01-17 18:27:17 +00001838 virtual bool OptimizeCall(CallInst *TheCall, SimplifyLibCalls &SLC) {
1839 if (ConstantInt *CI = dyn_cast<ConstantInt>(TheCall->getOperand(1))) {
Reid Spencerb195fcd2005-05-14 16:42:52 +00001840 // ffs(cnst) -> bit#
1841 // ffsl(cnst) -> bit#
Reid Spencer17f77842005-05-15 21:19:45 +00001842 // ffsll(cnst) -> bit#
Reid Spencerb195fcd2005-05-14 16:42:52 +00001843 uint64_t val = CI->getRawValue();
Reid Spencer17f77842005-05-15 21:19:45 +00001844 int result = 0;
Chris Lattner801f4752006-01-17 18:27:17 +00001845 if (val) {
1846 ++result;
1847 while ((val & 1) == 0) {
1848 ++result;
1849 val >>= 1;
1850 }
Reid Spencer17f77842005-05-15 21:19:45 +00001851 }
Chris Lattner801f4752006-01-17 18:27:17 +00001852 TheCall->replaceAllUsesWith(ConstantSInt::get(Type::IntTy, result));
1853 TheCall->eraseFromParent();
Reid Spencerb195fcd2005-05-14 16:42:52 +00001854 return true;
1855 }
Reid Spencer17f77842005-05-15 21:19:45 +00001856
Chris Lattner801f4752006-01-17 18:27:17 +00001857 // ffs(x) -> x == 0 ? 0 : llvm.cttz(x)+1
1858 // ffsl(x) -> x == 0 ? 0 : llvm.cttz(x)+1
1859 // ffsll(x) -> x == 0 ? 0 : llvm.cttz(x)+1
1860 const Type *ArgType = TheCall->getOperand(1)->getType();
1861 ArgType = ArgType->getUnsignedVersion();
1862 const char *CTTZName;
1863 switch (ArgType->getTypeID()) {
1864 default: assert(0 && "Unknown unsigned type!");
1865 case Type::UByteTyID : CTTZName = "llvm.cttz.i8" ; break;
1866 case Type::UShortTyID: CTTZName = "llvm.cttz.i16"; break;
1867 case Type::UIntTyID : CTTZName = "llvm.cttz.i32"; break;
1868 case Type::ULongTyID : CTTZName = "llvm.cttz.i64"; break;
1869 }
1870
1871 Function *F = SLC.getModule()->getOrInsertFunction(CTTZName, ArgType,
1872 ArgType, NULL);
1873 Value *V = new CastInst(TheCall->getOperand(1), ArgType, "tmp", TheCall);
1874 Value *V2 = new CallInst(F, V, "tmp", TheCall);
1875 V2 = new CastInst(V2, Type::IntTy, "tmp", TheCall);
1876 V2 = BinaryOperator::createAdd(V2, ConstantSInt::get(Type::IntTy, 1),
1877 "tmp", TheCall);
1878 Value *Cond =
1879 BinaryOperator::createSetEQ(V, Constant::getNullValue(V->getType()),
1880 "tmp", TheCall);
1881 V2 = new SelectInst(Cond, ConstantInt::get(Type::IntTy, 0), V2,
1882 TheCall->getName(), TheCall);
1883 TheCall->replaceAllUsesWith(V2);
1884 TheCall->eraseFromParent();
Reid Spencer17f77842005-05-15 21:19:45 +00001885 return true;
Reid Spencerb195fcd2005-05-14 16:42:52 +00001886 }
1887} FFSOptimizer;
1888
1889/// This LibCallOptimization will simplify calls to the "ffsl" library
1890/// calls. It simply uses FFSOptimization for which the transformation is
1891/// identical.
1892/// @brief Simplify the ffsl library function.
1893struct FFSLOptimization : public FFSOptimization
1894{
1895public:
1896 /// @brief Default Constructor
1897 FFSLOptimization() : FFSOptimization("ffsl",
1898 "Number of 'ffsl' calls simplified") {}
1899
1900} FFSLOptimizer;
1901
1902/// This LibCallOptimization will simplify calls to the "ffsll" library
1903/// calls. It simply uses FFSOptimization for which the transformation is
1904/// identical.
1905/// @brief Simplify the ffsl library function.
1906struct FFSLLOptimization : public FFSOptimization
1907{
1908public:
1909 /// @brief Default Constructor
1910 FFSLLOptimization() : FFSOptimization("ffsll",
1911 "Number of 'ffsll' calls simplified") {}
1912
1913} FFSLLOptimizer;
1914
Chris Lattner4201cd12005-08-24 17:22:17 +00001915
Reid Spencerade18212006-01-19 08:36:56 +00001916#ifdef HAVE_FLOORF
Chris Lattner4201cd12005-08-24 17:22:17 +00001917/// This LibCallOptimization will simplify calls to the "floor" library
1918/// function.
1919/// @brief Simplify the floor library function.
1920struct FloorOptimization : public LibCallOptimization {
1921 FloorOptimization()
1922 : LibCallOptimization("floor", "Number of 'floor' calls simplified") {}
1923
1924 /// @brief Make sure that the "floor" function has the right prototype
1925 virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &SLC){
1926 return F->arg_size() == 1 && F->arg_begin()->getType() == Type::DoubleTy &&
1927 F->getReturnType() == Type::DoubleTy;
1928 }
1929
1930 virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &SLC) {
1931 // If this is a float argument passed in, convert to floorf.
1932 // e.g. floor((double)FLT) -> (double)floorf(FLT). There can be no loss of
1933 // precision due to this.
1934 if (CastInst *Cast = dyn_cast<CastInst>(CI->getOperand(1)))
1935 if (Cast->getOperand(0)->getType() == Type::FloatTy) {
1936 Value *New = new CallInst(SLC.get_floorf(), Cast->getOperand(0),
1937 CI->getName(), CI);
1938 New = new CastInst(New, Type::DoubleTy, CI->getName(), CI);
1939 CI->replaceAllUsesWith(New);
1940 CI->eraseFromParent();
1941 if (Cast->use_empty())
1942 Cast->eraseFromParent();
1943 return true;
1944 }
1945 return false; // opt failed
1946 }
1947} FloorOptimizer;
Reid Spencerade18212006-01-19 08:36:56 +00001948#endif
Chris Lattner4201cd12005-08-24 17:22:17 +00001949
1950
1951
Reid Spencer7ddcfb32005-04-27 21:29:20 +00001952/// A function to compute the length of a null-terminated constant array of
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00001953/// integers. This function can't rely on the size of the constant array
1954/// because there could be a null terminator in the middle of the array.
1955/// We also have to bail out if we find a non-integer constant initializer
1956/// of one of the elements or if there is no null-terminator. The logic
Reid Spencer7ddcfb32005-04-27 21:29:20 +00001957/// below checks each of these conditions and will return true only if all
1958/// conditions are met. In that case, the \p len parameter is set to the length
1959/// of the null-terminated string. If false is returned, the conditions were
1960/// not met and len is set to 0.
1961/// @brief Get the length of a constant string (null-terminated array).
Reid Spencer4c444fe2005-04-30 03:17:54 +00001962bool getConstantStringLength(Value* V, uint64_t& len, ConstantArray** CA )
Reid Spencere249a822005-04-27 07:54:40 +00001963{
1964 assert(V != 0 && "Invalid args to getConstantStringLength");
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00001965 len = 0; // make sure we initialize this
Reid Spencere249a822005-04-27 07:54:40 +00001966 User* GEP = 0;
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00001967 // If the value is not a GEP instruction nor a constant expression with a
1968 // GEP instruction, then return false because ConstantArray can't occur
Reid Spencere249a822005-04-27 07:54:40 +00001969 // any other way
1970 if (GetElementPtrInst* GEPI = dyn_cast<GetElementPtrInst>(V))
1971 GEP = GEPI;
1972 else if (ConstantExpr* CE = dyn_cast<ConstantExpr>(V))
1973 if (CE->getOpcode() == Instruction::GetElementPtr)
1974 GEP = CE;
1975 else
1976 return false;
1977 else
1978 return false;
1979
1980 // Make sure the GEP has exactly three arguments.
1981 if (GEP->getNumOperands() != 3)
1982 return false;
1983
1984 // Check to make sure that the first operand of the GEP is an integer and
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00001985 // has value 0 so that we are sure we're indexing into the initializer.
Reid Spencere249a822005-04-27 07:54:40 +00001986 if (ConstantInt* op1 = dyn_cast<ConstantInt>(GEP->getOperand(1)))
1987 {
1988 if (!op1->isNullValue())
1989 return false;
1990 }
1991 else
1992 return false;
1993
1994 // Ensure that the second operand is a ConstantInt. If it isn't then this
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00001995 // GEP is wonky and we're not really sure what were referencing into and
Reid Spencere249a822005-04-27 07:54:40 +00001996 // better of not optimizing it. While we're at it, get the second index
1997 // value. We'll need this later for indexing the ConstantArray.
1998 uint64_t start_idx = 0;
1999 if (ConstantInt* CI = dyn_cast<ConstantInt>(GEP->getOperand(2)))
2000 start_idx = CI->getRawValue();
2001 else
2002 return false;
2003
2004 // The GEP instruction, constant or instruction, must reference a global
2005 // variable that is a constant and is initialized. The referenced constant
2006 // initializer is the array that we'll use for optimization.
2007 GlobalVariable* GV = dyn_cast<GlobalVariable>(GEP->getOperand(0));
2008 if (!GV || !GV->isConstant() || !GV->hasInitializer())
2009 return false;
2010
2011 // Get the initializer.
2012 Constant* INTLZR = GV->getInitializer();
2013
2014 // Handle the ConstantAggregateZero case
2015 if (ConstantAggregateZero* CAZ = dyn_cast<ConstantAggregateZero>(INTLZR))
2016 {
2017 // This is a degenerate case. The initializer is constant zero so the
2018 // length of the string must be zero.
2019 len = 0;
2020 return true;
2021 }
2022
2023 // Must be a Constant Array
2024 ConstantArray* A = dyn_cast<ConstantArray>(INTLZR);
2025 if (!A)
2026 return false;
2027
2028 // Get the number of elements in the array
2029 uint64_t max_elems = A->getType()->getNumElements();
2030
2031 // Traverse the constant array from start_idx (derived above) which is
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00002032 // the place the GEP refers to in the array.
Reid Spencere249a822005-04-27 07:54:40 +00002033 for ( len = start_idx; len < max_elems; len++)
2034 {
2035 if (ConstantInt* CI = dyn_cast<ConstantInt>(A->getOperand(len)))
2036 {
2037 // Check for the null terminator
2038 if (CI->isNullValue())
2039 break; // we found end of string
2040 }
2041 else
2042 return false; // This array isn't suitable, non-int initializer
2043 }
2044 if (len >= max_elems)
2045 return false; // This array isn't null terminated
2046
2047 // Subtract out the initial value from the length
2048 len -= start_idx;
Reid Spencer4c444fe2005-04-30 03:17:54 +00002049 if (CA)
2050 *CA = A;
Reid Spencere249a822005-04-27 07:54:40 +00002051 return true; // success!
2052}
2053
Reid Spencera7828ba2005-06-18 17:46:28 +00002054/// CastToCStr - Return V if it is an sbyte*, otherwise cast it to sbyte*,
2055/// inserting the cast before IP, and return the cast.
2056/// @brief Cast a value to a "C" string.
2057Value *CastToCStr(Value *V, Instruction &IP) {
2058 const Type *SBPTy = PointerType::get(Type::SByteTy);
2059 if (V->getType() != SBPTy)
2060 return new CastInst(V, SBPTy, V->getName(), &IP);
2061 return V;
2062}
2063
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00002064// TODO:
Reid Spencer649ac282005-04-28 04:40:06 +00002065// Additional cases that we need to add to this file:
2066//
Reid Spencer649ac282005-04-28 04:40:06 +00002067// cbrt:
Reid Spencer649ac282005-04-28 04:40:06 +00002068// * cbrt(expN(X)) -> expN(x/3)
2069// * cbrt(sqrt(x)) -> pow(x,1/6)
2070// * cbrt(sqrt(x)) -> pow(x,1/9)
2071//
Reid Spencer649ac282005-04-28 04:40:06 +00002072// cos, cosf, cosl:
Reid Spencer16983ca2005-04-28 18:05:16 +00002073// * cos(-x) -> cos(x)
Reid Spencer649ac282005-04-28 04:40:06 +00002074//
2075// exp, expf, expl:
Reid Spencer649ac282005-04-28 04:40:06 +00002076// * exp(log(x)) -> x
2077//
Reid Spencer649ac282005-04-28 04:40:06 +00002078// log, logf, logl:
Reid Spencer649ac282005-04-28 04:40:06 +00002079// * log(exp(x)) -> x
2080// * log(x**y) -> y*log(x)
2081// * log(exp(y)) -> y*log(e)
2082// * log(exp2(y)) -> y*log(2)
2083// * log(exp10(y)) -> y*log(10)
2084// * log(sqrt(x)) -> 0.5*log(x)
2085// * log(pow(x,y)) -> y*log(x)
2086//
2087// lround, lroundf, lroundl:
2088// * lround(cnst) -> cnst'
2089//
2090// memcmp:
Reid Spencer649ac282005-04-28 04:40:06 +00002091// * memcmp(x,y,l) -> cnst
2092// (if all arguments are constant and strlen(x) <= l and strlen(y) <= l)
Reid Spencer649ac282005-04-28 04:40:06 +00002093//
Reid Spencer649ac282005-04-28 04:40:06 +00002094// memmove:
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00002095// * memmove(d,s,l,a) -> memcpy(d,s,l,a)
Reid Spencer649ac282005-04-28 04:40:06 +00002096// (if s is a global constant array)
2097//
Reid Spencer649ac282005-04-28 04:40:06 +00002098// pow, powf, powl:
Reid Spencer649ac282005-04-28 04:40:06 +00002099// * pow(exp(x),y) -> exp(x*y)
2100// * pow(sqrt(x),y) -> pow(x,y*0.5)
2101// * pow(pow(x,y),z)-> pow(x,y*z)
2102//
2103// puts:
2104// * puts("") -> fputc("\n",stdout) (how do we get "stdout"?)
2105//
2106// round, roundf, roundl:
2107// * round(cnst) -> cnst'
2108//
2109// signbit:
2110// * signbit(cnst) -> cnst'
2111// * signbit(nncst) -> 0 (if pstv is a non-negative constant)
2112//
Reid Spencer649ac282005-04-28 04:40:06 +00002113// sqrt, sqrtf, sqrtl:
Reid Spencer649ac282005-04-28 04:40:06 +00002114// * sqrt(expN(x)) -> expN(x*0.5)
2115// * sqrt(Nroot(x)) -> pow(x,1/(2*N))
2116// * sqrt(pow(x,y)) -> pow(|x|,y*0.5)
2117//
Reid Spencer170ae7f2005-05-07 20:15:59 +00002118// stpcpy:
2119// * stpcpy(str, "literal") ->
2120// llvm.memcpy(str,"literal",strlen("literal")+1,1)
Reid Spencer38cabd72005-05-03 07:23:44 +00002121// strrchr:
Reid Spencer649ac282005-04-28 04:40:06 +00002122// * strrchr(s,c) -> reverse_offset_of_in(c,s)
2123// (if c is a constant integer and s is a constant string)
2124// * strrchr(s1,0) -> strchr(s1,0)
2125//
Reid Spencer649ac282005-04-28 04:40:06 +00002126// strncat:
2127// * strncat(x,y,0) -> x
2128// * strncat(x,y,0) -> x (if strlen(y) = 0)
2129// * strncat(x,y,l) -> strcat(x,y) (if y and l are constants an l > strlen(y))
2130//
Reid Spencer649ac282005-04-28 04:40:06 +00002131// strncpy:
2132// * strncpy(d,s,0) -> d
2133// * strncpy(d,s,l) -> memcpy(d,s,l,1)
2134// (if s and l are constants)
2135//
2136// strpbrk:
2137// * strpbrk(s,a) -> offset_in_for(s,a)
2138// (if s and a are both constant strings)
2139// * strpbrk(s,"") -> 0
2140// * strpbrk(s,a) -> strchr(s,a[0]) (if a is constant string of length 1)
2141//
2142// strspn, strcspn:
2143// * strspn(s,a) -> const_int (if both args are constant)
2144// * strspn("",a) -> 0
2145// * strspn(s,"") -> 0
2146// * strcspn(s,a) -> const_int (if both args are constant)
2147// * strcspn("",a) -> 0
2148// * strcspn(s,"") -> strlen(a)
2149//
2150// strstr:
2151// * strstr(x,x) -> x
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00002152// * strstr(s1,s2) -> offset_of_s2_in(s1)
Reid Spencer649ac282005-04-28 04:40:06 +00002153// (if s1 and s2 are constant strings)
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00002154//
Reid Spencer649ac282005-04-28 04:40:06 +00002155// tan, tanf, tanl:
Reid Spencer649ac282005-04-28 04:40:06 +00002156// * tan(atan(x)) -> x
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00002157//
Reid Spencer649ac282005-04-28 04:40:06 +00002158// trunc, truncf, truncl:
2159// * trunc(cnst) -> cnst'
2160//
Jeff Cohen5f4ef3c2005-07-27 06:12:32 +00002161//
Reid Spencer39a762d2005-04-25 02:53:12 +00002162}