We now run a dead function elim before running any generic specializer. generic specializer generates some
prespecialized functions and explicitly keep them alive (i.e. make them not removeable by dead function elim)
However, the recently added dead function elimination gets rid of the calls which the prespecialization uses
to generate the prespecialization.
Create a caller with special name (avoid conflict) to make sure the specialization does happen.
Hopefully, eventually we will be able to move to a cleaner approach to do prespecialization.
rdar://24543234
This reverts commit 0d001480a9.
The commit that changed the iteration style from c-based loops into for-each
loops caused major regressions in our string benchmarks. Arnold believes that we
are making a different inlining decision in the for-each loops. We should
reapply this patch after we fix the optimizer
The regression was detected in rdar://23776732.
This patch implements the pre-specialization for the most popular generic types from the standard library. If there are invocations of generic functions from the standard library in the user-code and the compiler can find the specialized, optimized versions of these functions, then calls of generic functions are simply replaced by the calls of the specialized functions.
This feature is supposed to be used with -Onone to produce much faster (e.g. 5x-10x faster) executables in debug builds without impacting the compile time. In fact, the compile-time is even improved, because IRGen has less work to do. The feature can be considered a light-weight version of the -Odebug, because pre-specialization is limited in scope, but does not have a potentially negative compile-time impact compared to -Odebug. It is planned to enable it by default in the future.
This feature is disabled by default for the time being. It can be enabled by using a hidden flag: -Xllvm -use-prespecialized.
The implementation consists of two logical steps:
- When the standard library is being built, we force a creation of specializations for the most popular generic types from the stdlib, e.g. Arrays of integer and floating point types, Range<Int>, etc. The list of specializations is not fixed and can be easily altered by editing the Prespecialized.swift file, which is responsible for forcing the specialization of generic types (this is simple solution for now, until we have a proper annotation to indicate which specializations of a given generic type or function we want to generate by means of the pre-specialization). These specializations are then optimized and preserved in the stdlib dylib and in the Swift SIL module. The size increase of the stdlib due to creation of pre-specializations is currently about 3%-7%.
- When a user-code is being compiled with -Onone, the compiler would run a generic specializer over the user-code. If there are calls of generic functions from the standard library, the specializer would check if there is an existing specialization matching these invocations. If such a specialization is found, the original call is replaced by the call of this more efficient specialized version.
Swift SVN r30309