strlen(x) != 0 -> *x != 0
strlen(x) == 0 -> *x == 0
* Change nested statistics to use style of other LLVM statistics so that
only the name of the optimization (simplify-libcalls) is used as the
statistic name, and the description indicates which specific all is
optimized. Cuts down on some redundancy and saves a few bytes of space.
* Make note of stpcpy optimization that could be done.
llvm-svn: 21766
library function:
isdigit(chr) -> 0 or 1 if chr is constant
isdigit(chr) -> chr - '0' <= 9 otherwise
Although there are many calls to isdigit in llvm-test, most of them are
compiled away by macros leaving only this:
2 MultiSource/Applications/hexxagon
llvm-svn: 21688
actual spec (int -> uint)
* Add the ability to get/cache the strlen function prototype.
* Make sure generated values are appropriately named for debugging purposes
* Add the SPrintFOptimiation for 4 casts of sprintf optimization:
sprintf(str,cstr) -> llvm.memcpy(str,cstr) (if cstr has no %)
sprintf(str,"") -> store sbyte 0, str
sprintf(str,"%s",src) -> llvm.memcpy(str,src) (if src is constant)
sprintf(str,"%c",chr) -> store chr, str ; store sbyte 0, str+1
The sprintf optimization didn't fire as much as I had hoped:
2 MultiSource/Applications/SPASS
5 MultiSource/Benchmarks/McCat/18-imp
22 MultiSource/Benchmarks/Prolangs-C/TimberWolfMC
1 MultiSource/Benchmarks/Prolangs-C/assembler
6 MultiSource/Benchmarks/Prolangs-C/unix-smail
2 MultiSource/Benchmarks/mediabench/mpeg2/mpeg2dec
llvm-svn: 21679
Neither of these activated as many times as was hoped:
strchr:
9 MultiSource/Applications/siod
1 MultiSource/Applications/d
2 MultiSource/Prolangs-C/archie-client
1 External/SPEC/CINT2000/176.gcc/176.gcc
llvm.memset:
no hits
llvm-svn: 21669
strings passed to Statistic's constructor are not destructable. The stats
are printed during static destruction and the SimplifyLibCalls module was
getting destructed before the statistics.
llvm-svn: 21661
type be obtained from a CallInst we're optimizing.
* Make it possible for getConstantStringLength to return the ConstantArray
that it extracts in case the content is needed by an Optimization.
* Implement the strcmp optimization
* Implement the toascii optimization
This pass is now firing several to many times in the following MultiSource
tests:
Applications/Burg - 7 (strcat,strcpy)
Applications/siod - 13 (strcat,strcpy,strlen)
Applications/spiff - 120 (exit,fputs,strcat,strcpy,strlen)
Applications/treecc - 66 (exit,fputs,strcat,strcpy)
Applications/kimwitu++ - 34 (strcmp,strcpy,strlen)
Applications/SPASS - 588 (exit,fputs,strcat,strcpy,strlen)
llvm-svn: 21626
* Correct stale documentation in a few places
* Re-order the file to better associate things and reduce line count
* Make the pass thread safe by caching the Function* objects needed by the
optimizers in the pass object instead of globally.
* Provide the SimplifyLibCalls pass object to the optimizer classes so they
can access cached Function* objects and TargetData info
* Make sure the pass resets its cache if the Module passed to runOnModule
changes
* Rename CallOptimizer LibCallOptimization. All the classes are named
*Optimization while the objects are *Optimizer.
* Don't cache Function* in the optimizer objects because they could be used
by multiple PassManager's running in multiple threads
* Add an optimization for strcpy which is similar to strcat
* Add a "TODO" list at the end of the file for ideas on additional libcall
optimizations that could be added (get ideas from other compilers).
Sorry for the huge diff. Its mostly reorganization of code. That won't
happen again as I believe the design and infrastructure for this pass is
now done or close to it.
llvm-svn: 21589
call to them into an 'unreachable' instruction.
This triggers a bunch of times, particularly on gcc:
gzip: 36
gcc: 601
eon: 12
bzip: 38
llvm-svn: 21587
* MemCpyOptimization can only be optimized if the 3rd and 4th arguments are
constants and we weren't checking for that.
* The result of llvm.memcpy (and llvm.memmove) is void* not sbyte*, put in
a cast.
llvm-svn: 21570
* Have the SimplifyLibCalls pass acquire the TargetData and pass it down to
the optimization classes so they can use it to make better choices for
the signatures of functions, etc.
* Rearrange the code a little so the utility functions are closer to their
usage and keep the core of the pass near the top of the files.
* Adjust the StrLen pass to get/use the correct prototype depending on the
TargetData::getIntPtrType() result. The result of strlen is size_t which
could be either uint or ulong depending on the platform.
* Clean up some coding nits (cast vs. dyn_cast, remove redundant items from
a switch, etc.)
* Implement the MemMoveOptimization as a twin of MemCpyOptimization (they
only differ in name).
llvm-svn: 21569
named getConstantStringLength. This is the common part of StrCpy and
StrLen optimizations and probably several others, yet to be written. It
performs all the validity checks for looking at constant arrays that are
supposed to be null-terminated strings and then computes the actual
length of the string.
* Implement the MemCpyOptimization class. This just turns memcpy of 1, 2, 4
and 8 byte data blocks that are properly aligned on those boundaries into
a load and a store. Much more could be done here but alignment
restrictions and lack of knowledge of the target instruction set prevent
use from doing significantly more. That will have to be delegated to the
code generators as they lower llvm.memcpy calls.
llvm-svn: 21562
* Change signatures of OptimizeCall and ValidateCalledFunction so they are
non-const, allowing the optimization object to be modified. This is in
support of caching things used across multiple calls.
* Provide two functions for constructing and caching function types
* Modify the StrCatOptimization to cache Function objects for strlen and
llvm.memcpy so it doesn't regenerate them on each call site. Make sure
these are invalidated each time we start the pass.
* Handle both a GEP Instruction and a GEP ConstantExpr
* Add additional checks to make sure we really are dealing with an arary of
sbyte and that all the element initializers are ConstantInt or
ConstantExpr that reduce to ConstantInt.
* Make sure the GlobalVariable is constant!
* Don't use ConstantArray::getString as it can fail and it doesn't give us
the right thing. We must check for null bytes in the middle of the array.
* Use llvm.memcpy instead of memcpy so we can factor alignment into it.
* Don't use void* types in signatures, replace with sbyte* instead.
llvm-svn: 21555
* Don't use std::string for the function names, const char* will suffice
* Allow each CallOptimizer to validate the function signature before
doing anything
* Repeatedly loop over the functions until an iteration produces
no more optimizations. This allows one optimization to insert a
call that is optimized by another optimization.
* Implement the ConstantArray portion of the StrCatOptimization
* Provide a template for the MemCpyOptimization
* Make ExitInMainOptimization split the block, not delete everything
after the return instruction.
(This covers revision 1.3 and 1.4, as the 1.3 comments were botched)
llvm-svn: 21548
* Fix comments at top of file
* Change algorithm for running the call optimizations from n*n to something
closer to n.
* Use a hash_map to store and lookup the optimizations since there will
eventually (or potentially) be a large number of them. This gets lookup
based on the name of the function to O(1). Each CallOptimizer now has a
std::string member named func_name that tracks the name of the function
that it applies to. It is this string that is entered into the hash_map
for fast comparison against the function names encountered in the module.
* Cleanup some style issues pertaining to iterator invalidation
* Don't pass the Function pointer to the OptimizeCall function because if
the optimization needs it, it can get it from the CallInst passed in.
* Add the skeleton for a new CallOptimizer, StrCatOptimizer which will
eventually replace strcat's of constant strings with direct copies.
llvm-svn: 21526
calls. The pass visits all external functions in the module and determines
if such function calls can be optimized. The optimizations are specific to
the library calls involved. This initial version only optimizes calls to
exit(3) when they occur in main(): it changes them to ret instructions.
llvm-svn: 21522