A.2. Ackermann's Function

Using an informal functional notation, Ackermann's function is defined as follows:


A(0, n) = n+1
A(m, 0) = A(m-1, 1)
A(m, n) = A(m-1, A(m, n-1))

From the point of view of benchmarking, Ackermann's function is interesting because it consists almost entirely of subprogram calls, and nests the calls deeply if required. The number of calls and the degree of nesting is controlled using the two arguments.

We use A(3,6) as the benchmark. This gives us 172233 calls, with a nesting depth of 511.

Example A-3. Source Code for Ackermann's Function


function Ackermann (M, N : in Integer) return Integer is
begin
   if M = 0 then
      return N + 1;
   elsif N = 0 then
      return Ackermann (M - 1, 1);
   else
      return Ackermann (M - 1, Ackermann (M, N - 1));
   end if;
end Ackermann;

Ackermann's function provides two opportunities for tail recursion optimization, both of which are taken here. The two parameters are passed in register, and the called procedure saves and restores registers using the register cache mechanism.

The generated code for the default optimization level is given in Example A-4.

Example A-4. Generated Code for Ackermann's Function


   1                            .file  "ackermann.adb"
   2                    gcc2_compiled.:
   3                    __gnu_compiled_ada:
   4                            .text
   5                            .align  4
   6                            .global _ada_ackermann
   7                            .proc   04
   8                    _ada_ackermann:
   9 0000 9DE3BF98              save    %sp,-104,%sp
  10 0004 A0100018              mov     %i0,%l0
  11 0008 80A38007              cmp     %sp,%g7
  12 000c 89D02009              tleu    9
  13                    .L5:
  14 0010 80A42000              cmp     %l0,0
  15 0014 12800004              bne     .L2
  16 0018 80A66000              cmp     %i1,0
  17 001c 1080000C              b       .L6
  18 0020 B0066001              add     %i1,1,%i0
  19                    .L2:
  20 0024 12800005              bne     .L4
  21 0028 90100010              mov     %l0,%o0
  22 002c A0043FFF              add     %l0,-1,%l0
  23 0030 10BFFFF8              b       .L5
  24 0034 B2102001              mov     1,%i1
  25                    .L4:
  26 0038 A0023FFF              add     %o0,-1,%l0
  27 003c 7FFFFFF1              call    _ada_ackermann,0
  28 0040 92067FFF              add     %i1,-1,%o1
  29 0044 10BFFFF3              b       .L5
  30 0048 B2100008              mov     %o0,%i1
  31                    .L6:
  32 004c 81C7E008              ret
  33 0050 81E80000              restore