Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / native_client / tests / toolchain / vla.c
1 /*
2  * Copyright (c) 2013 The Native Client Authors. All rights reserved.
3  * Use of this source code is governed by a BSD-style license that can be
4  * found in the LICENSE file.
5  */
6
7 /*
8  * Simple test to verify that C99 VLAs (variable length arrays) work.
9  */
10 #include <stdio.h>
11
12 void test_basic_vla(int size) {
13   /* "volatile", to try to prevent optimizing known summation patterns. */
14   volatile int vla[size];
15   for (int i = 0; i < size; ++i) {
16     vla[i] = i + 10;
17   }
18   printf("test_basic_vla w/ size %d\n", size);
19   printf("  %d + 10 == %d\n", 0, vla[0]);
20   printf("  %d + 10 == %d\n", size / 2, vla[size / 2]);
21   printf("  %d + 10 == %d\n", size - 1, vla[size - 1]);
22 }
23
24 void test_basic_in_loop(int size) {
25   int saved_0 = 0;
26   int saved_mid = 0;
27   int saved_last = 0;
28   for (int i = 0; i < size; ++i) {
29     volatile int vla[size];
30     vla[i] = i + 10;
31     if (i == 0)
32       saved_0 = vla[i];
33     if (i == size / 2)
34       saved_mid = vla[i];
35     if (i == size - 1)
36       saved_last = vla[i];
37   }
38   printf("test_basic_in_loop w/ size %d\n", size);
39   printf("  %d + 10 == %d\n", 0, saved_0);
40   printf("  %d + 10 == %d\n", size / 2, saved_mid);
41   printf("  %d + 10 == %d\n", size - 1, saved_last);
42 }
43
44 void test_two_in_loops(int size) {
45   volatile int vla1[size];
46   for (int i = 0; i < size; i++) {
47     volatile int vla2[size];
48     for (int j = 0; j < size; j++) {
49       vla2[j] = j;
50     }
51     /*
52      * At this point, vla2[size - 1] == size - 1.
53      * We keep adding that vla2[size - 1] to the previous value in vla1:
54      * (size - 1) + (size - 1) + ... + (size - 1), a total of "size" times.
55      */
56     if (i > 0)
57       vla1[i] = vla1[i - 1] + vla2[size - 1];
58     else
59       vla1[i] = vla2[size - 1];
60   }
61   printf("test_two_in_loops w/ size %d, should be\n  (%d - 1) * %d == %d\n",
62          size, size, size, vla1[size - 1]);
63 }
64
65 /*
66  * Just like test_two_in_loops, but with recursion.
67  * Make test_two_recursion_help() "noinline" to ensure that there really
68  * is a function call within the loop (to adjust the stack), and the
69  * recursive call doesn't get optimized into a loop.
70  */
71 void test_two_recursion_help(int size,
72                              int counter,
73                              volatile int *arr) __attribute__((noinline));
74 void test_two_recursion(int size) {
75   volatile int vla1[size];
76   for (int i = 0; i < size; i++) {
77     volatile int vla2[size];
78     /* Adjust stack again with function call */
79     test_two_recursion_help(size, 0, vla2);
80     if (i > 0)
81       vla1[i] = vla1[i - 1] + vla2[size - 1];
82     else
83       vla1[i] = vla2[size - 1];
84   }
85   printf("test_two_recursion w/ size %d, should be\n  (%d - 1) * %d == %d\n",
86          size, size, size, vla1[size - 1]);
87 }
88
89 void test_two_recursion_help(int size, int counter, volatile int *arr) {
90   if (counter < size) {
91     arr[counter] = counter;
92     test_two_recursion_help(size, ++counter, arr);
93   }
94 }
95
96 int main(int argc, char *argv[]) {
97   volatile int one_iter = 1;
98   volatile int ten_iters = 10;
99   test_basic_vla(one_iter);
100   test_basic_vla(ten_iters);
101   test_basic_in_loop(one_iter);
102   test_basic_in_loop(ten_iters);
103   test_two_in_loops(one_iter);
104   test_two_in_loops(ten_iters);
105   test_two_recursion(one_iter);
106   test_two_recursion(ten_iters);
107   return 0;
108 }