Hello,
I'm writing optimization of string.c. The point is that functions
there run strlen() and then in general discard the returned
information by running strcpy(). Consider this:
http://www.opensource.apple.com/source/Libc/Libc-997.1.1/string/strcpy.c
Of course there are different implementations that will not run
strlen() second time:
http://www.opensource.apple.com/source/Libc/Libc-262/i386/gen/strcpy.c
but still - utilizing the information allows for optimizations.
I think I've encountered a bug in Apple's llvm. Changing 11 line in
the patch, from "if( l < 8 ) {" to "if( l < 0 ) {" causes the script
to run for 2.5 seconds. Changing it to "if( l < 1 ) {" restores
running time of 2 seconds. Looking at generated assembly shows that
"if( l < 0 ) {" is treated as "if( 0 )" and only the memcpy() part is
emitted. That's fine, but why does that optimized version run slower
having in mind that "if( l < 1 ) {" is impossible condition (every
string has at least 1 byte). The problem doesn't reproduce on FreeBSD
10.1 and Ubuntu 12.10, running times are equal there. I thought I will
show the asm source, maybe someone will find something interesting in
it. In general this seems a bug that should be maybe considered as Zsh
uses memcpy() in various places (also: google
"-Wno-builtin-memcpy-chk-size"). As for string.c, I will provide
memcpy's implementation taken from glibc or other library.
The compiler is:
# gcc --version
Configured with:
--prefix=/Applications/Xcode.app/Contents/Developer/usr
--with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin13.1.0
Thread model: posix
Best regards,
Sebastian Gniazdowski
Attachment:
copymemory.patch
Description: Binary data
Attachment:
out_if_smaller_t0.asm
Description: Binary data
Attachment:
out_if_smaller_t1.asm
Description: Binary data
Attachment:
opttest3.zsh
Description: Binary data