5.18 Comparison of pure and impure functions

The two sample routines in the following table illustrate the use of the __pure keyword.

Both routines call a function fact() to calculate the sum of n! and n!. fact() depends only on its input argument n to compute n!. Therefore, fact() is a pure function.

The first routine shows a naive implementation of the function fact(), where fact() is not declared __pure. In the second implementation, fact() is qualified as __pure to indicate to the compiler that it is a pure function.

Table 5-7 C code for pure and impure functions

A pure function not declared __pure A pure function declared __pure
int fact(int n)
{
    int f = 1;
    while (n > 0)
        f *= n--;
    return f;
} 
int foo(int n)
{
    return fact(n)+fact(n);
}
int fact(int n) __pure
{
    int f = 1;
    while (n > 0)
        f *= n--;
    return f;
}
int foo(int n)
{
    return fact(n)+fact(n);
}

The following table shows the corresponding disassembly of the machine code produced by the compiler for each of the sample implementations above, where the C code for each implementation has been compiled using the option -O2, and inlining has been suppressed.

Table 5-8 Disassembly for pure and impure functions

A pure function not declared __pure A pure function declared __pure
fact PROC
    ...
foo PROC
    MOV      r3, r0
    PUSH     {lr}
    BL       fact
    MOV      r2, r0
    MOV      r0, r3
    BL       fact
    ADD      r0, r0, r2
    POP      {pc}
    ENDP
fact PROC
    ...
foo PROC
    PUSH     {lr}
    BL       fact
    LSL      r0,r0,#1
    POP      {pc}
    ENDP

In the disassembly where fact() is not qualified as __pure, fact() is called twice because the compiler does not know that the function is a candidate for Common Subexpression Elimination (CSE). In contrast, in the disassembly where fact() is qualified as __pure, fact() is called only once, instead of twice, because the compiler has been able to perform CSE when adding fact(n) + fact(n).

Non-ConfidentialPDF file icon PDF versionARM DUI0472M
Copyright © 2010-2016 ARM Limited or its affiliates. All rights reserved.