Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Barthelmann V.VBCC compiler system.2004.pdf
Скачиваний:
12
Добавлен:
23.08.2013
Размер:
390.02 Кб
Скачать

Chapter 3: The Compiler

23

Analysis], page 27, Section 3.4.15 [Inter-Procedural Analysis], page 29 and Section 3.4.16

[Cross-Module Optimizations], page 29.

3.4.10 Loop Unrolling

vbcc reduces the loop overhead by replicating the loop body and reducing the number of iterations. Also, additional optimizations between di erent iterations of the loop will often be enabled by creating larger basic blocks. However, code-size as well as compilation-times can increase significantly.

This optimization can be controlled by ‘-unroll-size’ and ‘-unroll-all’. ‘-unroll-size’ specifies the maximum number of intermediate instructions for the unrolled loop body. vbcc will try to unroll the loop as many times to suit this value.

If the number of iterations is constant and the size of the loop body multiplied by this number is less or equal to the value specified by ‘-unroll-size’, the loop will be unrolled completely. If the loop is known to be executed exactly once, it will always be unrolled completely.

For example, the following code

void f()

{

int i;

for (i = 0; i < 4; i++) q(i);

}

will be optimized like:

void f()

{

q(0);

q(1);

q(2);

q(3);

}

If the number of iteration is constant the loop will be unrolled as many times as permitted by the size of the loop and ‘-unroll-size’. If the number of iterations is not a multiple of the number of replications, the remaining iterations will be unrolled separately.

For example, the following code

void f()

{

int i;

for (i = 0; i < 102; i++) q(i);

}

will be optimized like:

24

vbcc manual

void f()

{

int i; q(0); q(1);

for(i = 2; i < 102;){ q(i++);

q(i++);

q(i++);

q(i++);

}

}

By default, only loops with a constant number of iterations will be unrolled. However, if ‘-unroll-all’ is specified, vbcc will also unroll loops if the number of iterations can be calculated at entry to the loop.

For example, the following code

void f(int n)

{

int i;

for (i = 0; i < n; i++) q(i);

}

will be optimized like:

void f(int n)

{

int i, tmp;

i = 0;

tmp = n & 3; switch(tmp){ case 3:

q(i++); case 2:

q(i++); case 1:

q(i++);

}

while(i < n){ q(i++); q(i++); q(i++); q(i++);

}

}

Chapter 3: The Compiler

25

As

this optimization

requires detecting whether operands

of

an expression

may

have

changed, it will

be a ected by other optimizations.

See

Section 3.4.14

[Alias

Analysis], page 27, Section 3.4.15 [Inter-Procedural Analysis], page 29 and Section 3.4.16 [Cross-Module Optimizations], page 29.

3.4.11 Function Inlining

To reduce the overhead, a function call can be expanded inline. Passing parameters can be optimized as the arguments can be directly accessed by the inlined function. Also, further optimizations are enabled, e.g. constant arguments can be evaluated or common subexpressions between the caller and the callee can be eliminated. An inlined function call is as fast as a macro. However (just as with using large macros), code size and compilation time can increase significantly.

Therefore, this optimization can be controlled with ‘-inline-size’ and ‘-inline-depth’. vbcc will only inline functions which contain less intermediate instructions than specified with this option.

For example, the following code

int f(int n)

{

return q(&n,1);

}

void q(int *x, int y)

{

if(y > 0)

*x = *x + y; else

abort();

}

will be optimized like:

int f(int n)

{

return n + 1;

}

void q(int *x, int y)

{

if(y > 0)

*x = *x + y; else

abort();

}

If a function to be inlined calls another function, that function can also be inlined. This also includes a recursive call of the function.

For example, the following code

26

vbcc manual

int f(int n)

{

if(n < 2) return 1;

else

return f(n - 1) + f(n - 2);

}

will be optimized like:

int f(int n)

{

if(n < 2) return 1;

else{

int tmp1 = n - 1, tmp2, tmp3 = n - 2, tmp4; if(tmp1 < 2)

tmp2 = 1; else

tmp2 = f(tmp1 - 1) + f(tmp2 - 2); if(tmp3 < 2)

tmp4 = 1; else

tmp4 = f(tmp3 - 1) + f(tmp3 - 2); return tmp2 + tmp4;

}

}

By default, only one level of inlining is done. The maximum nesting of inlining can be set with ‘-inline-depth’. However, this option should be used with care. The code-size can increase very fast and in many cases the code will be slower. Only use it for fine-tuning after measuring if it is really beneficial.

At lower optimization levels a function must be defined in the same translation-unit as the caller to be inlined. With cross-module optimizations, vbcc will also inline functions which are defined in other files. See Section 3.4.16 [Cross-Module Optimizations], page 29.

See also Section 3.5.3 [Inline-Assembly Functions], page 33.

3.4.12 Intrinsic Functions

This optimization will replace calls to some known functions (usually library functions) with calls to di erent functions or special inline-code. This optimization usually depends on the arguments to a function. Typical candidates are the printf family of functions and string-functions applied to string-literals.

For example, the following code

int f()

{

return strlen("vbcc");

}