This paper shows that code expanding optimizations
have strong and non-intuitive implications on instruction
cache design. Three types of code expanding optimizations
are studied in this paper: instruction placement, function
inline expansion, and superscalar optimizations. Overall,
instruction placement reduces the miss ratio of small caches.
Function inline expansion improves the performance for small
cache sizes, but degrades the performance of medium caches.
Superscalar optimizations increases the cache size required
for a given miss ration. On the other hand, they also
increase the sequentiality of instruction access so that a
simple load-forward scheme effectively cancels the negative
effects. Overall, we show that with load forwarding, the
three types of code expanding optimizations jointly improve
the performance of small caches and have little effect on
large caches.