This sort of optimization depends on the compiler knowing that a function named printf can only be the printf function as defined by the C standard. If program defines printf to mean something else then the program is invoking undefined behaviour. This lets the compiler substitute a call to puts in cases where it would work "as if" the standard printf function was being called. It doesn't have worry about it working "as if" a user defined printf function was called. So these kind of function substitution optimizations are pretty much limited to functions defined in the C or C++ standards. (Maybe other standards as well if the compiler somehow knows that a given standard is in force.)
Short of modifying the source code of the compiler yourself there's no way tell the compiler that these kind of function substitutions are possible with your own functions. However, with limitations, you can do something similar with inline functions. For example you could implement something similar to the printf/puts optimization with something like this:
inline int myprintf(char const *fmt, char const *arg) {
if (strcmp(fmt, "%s\n") == 0) {
return myputs(args);
}
return _myprintf_impl(fmt, arg)
}
With optimization turned on the compiler can choose at compile time which function to call based on the fmt parameter, but only if it it can determine it's a constant string. If it can't, or optimization isn't enabled, then the compiler has to emit code that checks it on each call and that could easily turn this into a pessimization. Note that this optimization is dependent on the compiler knowing how strcmp works and removing the call entirely, and so is an example of another library function call substitution the compiler can make.
You can improve on this with GCC's __builtin_constant_p function:
inline int myprintf(char const *fmt, char const *arg) {
if (__builtin_constant_p(fmt[0])
&& strcmp(fmt, "%s\n") == 0) {
return myputs(arg);
}
return _myprintf_impl(fmt, arg);
}
Under GCC this results in code that never checks the format string a run time. If can determine at compile time that fmt is "%s\n" then it generates code that calls myputs unconditionally, otherwise it generates code that calls _myprintf_impl unconditionally. So with optimization enabled this function is never a pessimization. Unfortunately while clang supports the __builtin_constant_p function my version of clang always generates code that calls _myprintf_impl unconditionally.