29.10.2014 Views

ARM Compiler toolchain v4.1 for µVision Using the Compiler

ARM Compiler toolchain v4.1 for µVision Using the Compiler

ARM Compiler toolchain v4.1 for µVision Using the Compiler

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

<strong>Compiler</strong> Coding Practices<br />

5.17 Comparison of pure and impure functions<br />

The use of <strong>the</strong> __pure keyword is illustrated in <strong>the</strong> two sample routines of Table 5-7. Both<br />

routines call a function fact() to calculate <strong>the</strong> sum of n! and n!. fact() depends only on its input<br />

argument n to compute n!. There<strong>for</strong>e, fact() is a pure function.<br />

The first routine shows a naive implementation of <strong>the</strong> function fact(), where fact() is not<br />

declared __pure. In <strong>the</strong> second implementation, fact() is qualified as __pure to indicate to <strong>the</strong><br />

compiler that it is a pure function.<br />

Table 5-7 C code <strong>for</strong> pure and impure functions<br />

A pure function not declared __pure<br />

int fact(int n)<br />

{<br />

int f = 1;<br />

while (n > 0)<br />

f *= n--;<br />

return f;<br />

}<br />

int foo(int n)<br />

{<br />

return fact(n)+fact(n);<br />

}<br />

A pure function declared __pure<br />

int fact(int n) __pure<br />

{<br />

int f = 1;<br />

while (n > 0)<br />

f *= n--;<br />

return f;<br />

}<br />

int foo(int n)<br />

{<br />

return fact(n)+fact(n);<br />

}<br />

Table 5-8 shows <strong>the</strong> corresponding disassembly of <strong>the</strong> machine code produced by <strong>the</strong> compiler<br />

<strong>for</strong> each of <strong>the</strong> sample implementations of Table 5-7, where <strong>the</strong> C code <strong>for</strong> each implementation<br />

has been compiled using <strong>the</strong> option -O2, and inlining has been suppressed.<br />

Table 5-8 Disassembly <strong>for</strong> pure and impure functions<br />

A pure function not declared __pure<br />

A pure function declared __pure<br />

fact PROC<br />

...<br />

foo PROC<br />

MOV<br />

PUSH<br />

BL<br />

MOV<br />

MOV<br />

BL<br />

ADD<br />

POP<br />

ENDP<br />

r3, r0<br />

{lr}<br />

fact<br />

r2, r0<br />

r0, r3<br />

fact<br />

r0, r0, r2<br />

{pc}<br />

fact PROC<br />

...<br />

foo PROC<br />

PUSH<br />

BL<br />

LSL<br />

POP<br />

ENDP<br />

{lr}<br />

fact<br />

r0,r0,#1<br />

{pc}<br />

In <strong>the</strong> disassembly of function foo() in Table 5-8 where fact() is not qualified as __pure, fact()<br />

is called twice because <strong>the</strong> compiler does not know that <strong>the</strong> function is a candidate <strong>for</strong> Common<br />

Subexpression Elimination (CSE). In contrast, in <strong>the</strong> disassembly of foo() in Table 5-8 where<br />

fact() is qualified as __pure, fact() is called only once, instead of twice, because <strong>the</strong> compiler<br />

has been able to per<strong>for</strong>m CSE when adding fact(n) + fact(n).<br />

5.17.1 See also<br />

Concepts<br />

• Functions that return <strong>the</strong> same result when called with <strong>the</strong> same arguments on page 5-24.<br />

<strong>ARM</strong> DUI 0375C Copyright © 2007-2008, 2011 <strong>ARM</strong>. All rights reserved. 5-25<br />

ID061811<br />

Non-Confidential

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!