It became much less used in later years, partly because low-level fine tuning for memory and speed became less critical, and partly because eliminating the preprocessing made coding simpler and thus enabled more important optimizations.
To enable such optimizations in a predictable manner, the ISO standard for the C programming language (including its newer C99 edition, see section 6.5, paragraph 7) specifies that it is illegal (with some exceptions) for pointers of different types to reference the same memory location.
Users must use compiler options explicitly to tell the compiler to enable interprocedural analysis and other expensive optimizations.
This architecture enables well-known optimizations from other programming languages to be used for JavaScript, including type specialization, function inlining, linear-scan register allocation, dead code elimination, and loop-invariant code motion.
The flag to enable interprocedural optimizations for a single file is -ip, the flag to enable interprocedural optimization across all files in the program is -ipo.
This source code/machine code independence is intended to enable generic optimizations to be shared between versions of the compiler supporting different languages and target processors.
Since the machine code emitted by a dynamic compiler is constructed and optimized at program runtime, the use of dynamic compilation enables optimizations for efficiency not available to compiled programs except through code duplication or metaprogramming.
Some compilers, such as gcc, add extra keywords for a programmer to explicitly mark external functions as pure, to enable such optimizations.
It enables optimizations for the locality of data and computation in the program via abstractions for data distribution and data-driven placement of subcomputations.
This is a subtle optimization which can help eliminate dependencies and thus enable other optimizations.