In-line Expansion

In-line expansion or inlining for short is a compiler optimization which "expands" a function call site into the actual implementation of the function which is called, rather than each call transferring control to a common piece of code. This reduces overhead associated with the function call, which is especially important for small and frequently called functions, and it helps call-site-specific compiler optimizations, especially constant propagation. The main drawback is that the expansion usually results in a larger binary code, which can actually hurt performance if it damages locality of reference or exceeds resource constraints. In the context of functional programming languages, in-line expansion is often referred to as beta reduction, a term used in the lambda calculus, the formal language underlying these languages.

Implementing in-line expansion

Once the compiler has decided to in-line a particular function, it is usually a simple matter to do so. Depending on whether one wants cross-language inline functions, the inlining can be done with either a high-level intermediate representation, like abstract syntax trees, or a low-level intermediate representation. In either case, one simply computes the arguments, stores them in variables corresponding to the function's arguments, and then inserts the body of the function at the call site. Function inlining can also be performed at link-time, which enables inlining of functions whose source is not available such as library functions (see link-time optimization) and at run time, which enables using dynamic profiling information to make better decisions about which functions to inline, as in the Java Hotspot compiler. Here's a simple example of in-line expansion performed "by hand" at the source level in the C programming language:
   int pred(int x) {       if (x == 0) return 0; else return x - 1;   }    
Before inlining:
   int f(int y) {       return pred(y) + pred(0) + pred(y+1);   } 
After inlining:
   int f(int y) {       int temp = 0;       if (y   == 0) temp += 0; else temp += y       - 1;       if (0   == 0) temp += 0; else temp += 0       - 1;       if (y+1 == 0) temp += 0; else temp += (y + 1) - 1;       return temp;   } 
Note that this is only an example; in an actual C application, it would be preferable to use an inlining language feature such as parameterized macros or inline functions to tell the compiler to perform this transformation.

Benefits of in-lining

Inline expansion itself is an optimization, since it eliminates call overhead, but it is much more important as an enabling transformation. That is, once the body of the function is expanded in the context of its call site, often with arguments that may be fixed constants, the code is opened to a variety of new optimizations that were not possible before. For example, a branch using an argument may turn out to be always true or always false in this one case, allowing dead code elimination, loop-invariant statements may be moved outside a loop, or a variable may become a candidate for induction variable elimination. In our C example, we see that optimization opportunities abound. We can reduce it in the following steps:
  • The temp += 0 statements do nothing. We can remove them.
  • The condition 0 == 0 is always true, so we can use just the true branch (which does nothing).
  • The condition y+1

    0 is equivalent to y

    -1.
  • The expression (y + 1) - 1 reduces to simply y.
  • The expressions y and y+1 cannot both equal zero. This leaves three cases we can explicitly consider.
Our new function looks like:
   int f(int y) {       if (y == 0)           return y;            /* or return 0 */       else if (y == -1)           return y - 1;        /* or return -2 */       else           return y + y - 1;   } 

Problems with in-lining

Replacing a call site with an expanded function body can present several problems that may make this "optimization" actually hurt performance:
  • In applications where code size is more important than speed, such as many embedded systems, in-lining is usually disadvantageous except for very small functions.
  • The increase in code size may cause a small, critical section of code to no longer fit in the cache, causing cache misses and slowdown.
  • The added variables from the in-lined procedure may consume additional registers, and in an area where register pressure is already high this may force spilling, which causes additional RAM accesses.
  • A language specification may allow a program to make additional assumptions about arguments to procedures which it can no longer make after the procedure is in-lined.
  • If code size is increased too much, resource constraints such as RAM size may be exceeded, leading to programs that either cannot be run or that cause thrashing.
Typically, a compiler is aware of these issues and strives to choose which functions to inline in such a way that performance is only enhanced in most cases.

Selection methods and language support

Many compilers aggressively inline functions wherever it is beneficial to do so. Although this can lead to larger executables, this has nevertheless become more and more desirable as growth of memory capacities have outpaced growth of CPU speed. This automatic type of inlining is a critical optimization in functional languages and object-oriented programming languages, which rely on it to give enough context to their typically small functions to make classical optimization effective. In imperative programming languages, the approach to inline functions is quite different, since functions are typically much larger. Usually only obvious or key functions are inlined, using language features like inline functions, or in their absence, simple source-level constructs such as parameterized macros. In either case, the programmer chooses which functions to inline manually, although the compiler may in some cases not be able or willing to inline a function marked for inlining.

See also

External links

*Article "Whole Program Optimization with Visual C++ .NET" by Brandon Bray

 

<< PreviousWord BrowserNext >>
tara calishain
yp
yellow pages (computing)
nis
stockholm school
french consulate
network information service
history of northern ireland
gothenburg school of economics and commercial law
the relapse
lund school of economics and management
economic history of britain
french colonial empire
ample
schwalm eder
the market for lemons
ali ahmad jalali
thomas arnold
borken
yusuf nooristani
mentor graphics
eda
anwar ul haq ahadi
a1 road
northrop corporation
electronic design automation
lule university of technology
northrop grumman
edirne
lund institute of technology
linkping institute of technology
ume institute of technology
jrgen trittin
grub (search engine)
uppsala school of engineering
green jay
looksmart
swedish university of agricultural sciences
karolinska institute
moshe sharett
history of the halfpenny
sekaninaite
go ask alice
cyanocorax