aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/doc/gnat_ugn/gnat_and_program_execution.rst
blob: 68117ae2c49499371bf0fdc9805b59a24fb0d03f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
.. role:: switch(samp)

.. |with| replace:: *with*
.. |withs| replace:: *with*\ s
.. |withed| replace:: *with*\ ed
.. |withing| replace:: *with*\ ing

.. -- Example: A |withing| unit has a |with| clause, it |withs| a |withed| unit


.. _GNAT_and_Program_Execution:

**************************
GNAT and Program Execution
**************************

This chapter covers several topics:

* `Running and Debugging Ada Programs`_
* `Code Coverage and Profiling`_
* `Improving Performance`_
* `Overflow Check Handling in GNAT`_
* `Performing Dimensionality Analysis in GNAT`_
* `Stack Related Facilities`_
* `Memory Management Issues`_

.. _Running_and_Debugging_Ada_Programs:

Running and Debugging Ada Programs
==================================

.. index:: Debugging

This section discusses how to debug Ada programs.

An incorrect Ada program may be handled in three ways by the GNAT compiler:

* The illegality may be a violation of the static semantics of Ada. In
  that case GNAT diagnoses the constructs in the program that are illegal.
  It is then a straightforward matter for the user to modify those parts of
  the program.

* The illegality may be a violation of the dynamic semantics of Ada. In
  that case the program compiles and executes, but may generate incorrect
  results, or may terminate abnormally with some exception.

* When presented with a program that contains convoluted errors, GNAT
  itself may terminate abnormally without providing full diagnostics on
  the incorrect user program.

.. index:: Debugger

.. index:: !  gdb

.. _The_GNAT_Debugger_GDB:

The GNAT Debugger GDB
---------------------

``GDB`` is a general purpose, platform-independent debugger that
can be used to debug mixed-language programs compiled with ``gcc``,
and in particular is capable of debugging Ada programs compiled with
GNAT. The latest versions of ``GDB`` are Ada-aware and can handle
complex Ada data structures.

See :title:`Debugging with GDB`,
for full details on the usage of ``GDB``, including a section on
its usage on programs. This manual should be consulted for full
details. The section that follows is a brief introduction to the
philosophy and use of ``GDB``.

When GNAT programs are compiled, the compiler optionally writes debugging
information into the generated object file, including information on
line numbers, and on declared types and variables. This information is
separate from the generated code. It makes the object files considerably
larger, but it does not add to the size of the actual executable that
will be loaded into memory, and has no impact on run-time performance. The
generation of debug information is triggered by the use of the
:switch:`-g` switch in the ``gcc`` or ``gnatmake`` command
used to carry out the compilations. It is important to emphasize that
the use of these options does not change the generated code.

The debugging information is written in standard system formats that
are used by many tools, including debuggers and profilers. The format
of the information is typically designed to describe C types and
semantics, but GNAT implements a translation scheme which allows full
details about Ada types and variables to be encoded into these
standard C formats. Details of this encoding scheme may be found in
the file exp_dbug.ads in the GNAT source distribution. However, the
details of this encoding are, in general, of no interest to a user,
since ``GDB`` automatically performs the necessary decoding.

When a program is bound and linked, the debugging information is
collected from the object files, and stored in the executable image of
the program. Again, this process significantly increases the size of
the generated executable file, but it does not increase the size of
the executable program itself. Furthermore, if this program is run in
the normal manner, it runs exactly as if the debug information were
not present, and takes no more actual memory.

However, if the program is run under control of ``GDB``, the
debugger is activated.  The image of the program is loaded, at which
point it is ready to run.  If a run command is given, then the program
will run exactly as it would have if ``GDB`` were not present. This
is a crucial part of the ``GDB`` design philosophy.  ``GDB`` is
entirely non-intrusive until a breakpoint is encountered.  If no
breakpoint is ever hit, the program will run exactly as it would if no
debugger were present. When a breakpoint is hit, ``GDB`` accesses
the debugging information and can respond to user commands to inspect
variables, and more generally to report on the state of execution.

.. _Running_GDB:

Running GDB
-----------

This section describes how to initiate the debugger.

The debugger can be launched from a ``GPS`` menu or
directly from the command line. The description below covers the latter use.
All the commands shown can be used in the ``GPS`` debug console window,
but there are usually more GUI-based ways to achieve the same effect.

The command to run ``GDB`` is

  ::

     $ gdb program

where ``program`` is the name of the executable file. This
activates the debugger and results in a prompt for debugger commands.
The simplest command is simply ``run``, which causes the program to run
exactly as if the debugger were not present. The following section
describes some of the additional commands that can be given to ``GDB``.


.. _Introduction_to_GDB_Commands:

Introduction to GDB Commands
----------------------------

``GDB`` contains a large repertoire of commands.
See :title:`Debugging with GDB` for extensive documentation on the use
of these commands, together with examples of their use. Furthermore,
the command *help* invoked from within GDB activates a simple help
facility which summarizes the available commands and their options.
In this section we summarize a few of the most commonly
used commands to give an idea of what ``GDB`` is about. You should create
a simple program with debugging information and experiment with the use of
these ``GDB`` commands on the program as you read through the
following section.

* :samp:`set args {arguments}`
    The *arguments* list above is a list of arguments to be passed to
    the program on a subsequent run command, just as though the arguments
    had been entered on a normal invocation of the program. The ``set args``
    command is not needed if the program does not require arguments.


* :samp:`run`
    The ``run`` command causes execution of the program to start from
    the beginning. If the program is already running, that is to say if
    you are currently positioned at a breakpoint, then a prompt will ask
    for confirmation that you want to abandon the current execution and
    restart.


* :samp:`breakpoint {location}`
    The breakpoint command sets a breakpoint, that is to say a point at which
    execution will halt and ``GDB`` will await further
    commands. *location* is
    either a line number within a file, given in the format ``file:linenumber``,
    or it is the name of a subprogram. If you request that a breakpoint be set on
    a subprogram that is overloaded, a prompt will ask you to specify on which of
    those subprograms you want to breakpoint. You can also
    specify that all of them should be breakpointed. If the program is run
    and execution encounters the breakpoint, then the program
    stops and ``GDB`` signals that the breakpoint was encountered by
    printing the line of code before which the program is halted.


* :samp:`catch exception {name}`
    This command causes the program execution to stop whenever exception
    ``name`` is raised.  If ``name`` is omitted, then the execution is
    suspended when any exception is raised.


* :samp:`print {expression}`
    This will print the value of the given expression. Most simple
    Ada expression formats are properly handled by ``GDB``, so the expression
    can contain function calls, variables, operators, and attribute references.


* :samp:`continue`
    Continues execution following a breakpoint, until the next breakpoint or the
    termination of the program.


* :samp:`step`
    Executes a single line after a breakpoint. If the next statement
    is a subprogram call, execution continues into (the first statement of)
    the called subprogram.


* :samp:`next`
    Executes a single line. If this line is a subprogram call, executes and
    returns from the call.


* :samp:`list`
    Lists a few lines around the current source location. In practice, it
    is usually more convenient to have a separate edit window open with the
    relevant source file displayed. Successive applications of this command
    print subsequent lines. The command can be given an argument which is a
    line number, in which case it displays a few lines around the specified one.


* :samp:`backtrace`
    Displays a backtrace of the call chain. This command is typically
    used after a breakpoint has occurred, to examine the sequence of calls that
    leads to the current breakpoint. The display includes one line for each
    activation record (frame) corresponding to an active subprogram.


* :samp:`up`
    At a breakpoint, ``GDB`` can display the values of variables local
    to the current frame. The command ``up`` can be used to
    examine the contents of other active frames, by moving the focus up
    the stack, that is to say from callee to caller, one frame at a time.


* :samp:`down`
    Moves the focus of ``GDB`` down from the frame currently being
    examined to the frame of its callee (the reverse of the previous command),


* :samp:`frame {n}`
    Inspect the frame with the given number. The value 0 denotes the frame
    of the current breakpoint, that is to say the top of the call stack.


* :samp:`kill`
    Kills the child process in which the program is running under GDB.
    This may be useful for several purposes:

    * It allows you to recompile and relink your program, since on many systems
      you cannot regenerate an executable file while it is running in a process.

    * You can run your program outside the debugger, on systems that do not
      permit executing a program outside GDB while breakpoints are set
      within GDB.

    * It allows you to debug a core dump rather than a running process.

The above list is a very short introduction to the commands that
``GDB`` provides. Important additional capabilities, including conditional
breakpoints, the ability to execute command sequences on a breakpoint,
the ability to debug at the machine instruction level and many other
features are described in detail in :title:`Debugging with GDB`.
Note that most commands can be abbreviated
(for example, c for continue, bt for backtrace).


.. _Using_Ada_Expressions:

Using Ada Expressions
---------------------

.. index:: Ada expressions (in gdb)

``GDB`` supports a fairly large subset of Ada expression syntax, with some
extensions. The philosophy behind the design of this subset is

  * That ``GDB`` should provide basic literals and access to operations for
    arithmetic, dereferencing, field selection, indexing, and subprogram calls,
    leaving more sophisticated computations to subprograms written into the
    program (which therefore may be called from ``GDB``).

  * That type safety and strict adherence to Ada language restrictions
    are not particularly relevant in a debugging context.

  * That brevity is important to the ``GDB`` user.

Thus, for brevity, the debugger acts as if there were
implicit ``with`` and ``use`` clauses in effect for all user-written
packages, thus making it unnecessary to fully qualify most names with
their packages, regardless of context. Where this causes ambiguity,
``GDB`` asks the user's intent.

For details on the supported Ada syntax, see :title:`Debugging with GDB`.


.. _Calling_User-Defined_Subprograms:

Calling User-Defined Subprograms
--------------------------------

An important capability of ``GDB`` is the ability to call user-defined
subprograms while debugging. This is achieved simply by entering
a subprogram call statement in the form:

  ::

     call subprogram-name (parameters)

The keyword ``call`` can be omitted in the normal case where the
``subprogram-name`` does not coincide with any of the predefined
``GDB`` commands.

The effect is to invoke the given subprogram, passing it the
list of parameters that is supplied. The parameters can be expressions and
can include variables from the program being debugged. The
subprogram must be defined
at the library level within your program, and ``GDB`` will call the
subprogram within the environment of your program execution (which
means that the subprogram is free to access or even modify variables
within your program).

The most important use of this facility is in allowing the inclusion of
debugging routines that are tailored to particular data structures
in your program. Such debugging routines can be written to provide a suitably
high-level description of an abstract type, rather than a low-level dump
of its physical layout. After all, the standard
``GDB print`` command only knows the physical layout of your
types, not their abstract meaning. Debugging routines can provide information
at the desired semantic level and are thus enormously useful.

For example, when debugging GNAT itself, it is crucial to have access to
the contents of the tree nodes used to represent the program internally.
But tree nodes are represented simply by an integer value (which in turn
is an index into a table of nodes).
Using the ``print`` command on a tree node would simply print this integer
value, which is not very useful. But the PN routine (defined in file
treepr.adb in the GNAT sources) takes a tree node as input, and displays
a useful high level representation of the tree node, which includes the
syntactic category of the node, its position in the source, the integers
that denote descendant nodes and parent node, as well as varied
semantic information. To study this example in more detail, you might want to
look at the body of the PN procedure in the stated file.

Another useful application of this capability is to deal with situations of
complex data which are not handled suitably by GDB. For example, if you specify
Convention Fortran for a multi-dimensional array, GDB does not know that
the ordering of array elements has been switched and will not properly
address the array elements. In such a case, instead of trying to print the
elements directly from GDB, you can write a callable procedure that prints
the elements in the desired format.


.. _Using_the_Next_Command_in_a_Function:

Using the *next* Command in a Function
--------------------------------------

When you use the ``next`` command in a function, the current source
location will advance to the next statement as usual. A special case
arises in the case of a ``return`` statement.

Part of the code for a return statement is the 'epilogue' of the function.
This is the code that returns to the caller. There is only one copy of
this epilogue code, and it is typically associated with the last return
statement in the function if there is more than one return. In some
implementations, this epilogue is associated with the first statement
of the function.

The result is that if you use the ``next`` command from a return
statement that is not the last return statement of the function you
may see a strange apparent jump to the last return statement or to
the start of the function. You should simply ignore this odd jump.
The value returned is always that from the first return statement
that was stepped through.


.. _Stopping_When_Ada_Exceptions_Are_Raised:

Stopping When Ada Exceptions Are Raised
---------------------------------------

.. index:: Exceptions (in gdb)

You can set catchpoints that stop the program execution when your program
raises selected exceptions.


* :samp:`catch exception`
    Set a catchpoint that stops execution whenever (any task in the) program
    raises any exception.


* :samp:`catch exception {name}`
    Set a catchpoint that stops execution whenever (any task in the) program
    raises the exception *name*.


* :samp:`catch exception unhandled`
    Set a catchpoint that stops executing whenever (any task in the) program
    raises an exception for which there is no handler.


* :samp:`info exceptions`, :samp:`info exceptions {regexp}`
    The ``info exceptions`` command permits the user to examine all defined
    exceptions within Ada programs. With a regular expression, *regexp*, as
    argument, prints out only those exceptions whose name matches *regexp*.


.. index:: Tasks (in gdb)

.. _Ada_Tasks:

Ada Tasks
---------

``GDB`` allows the following task-related commands:


* :samp:`info tasks`
    This command shows a list of current Ada tasks, as in the following example:

    ::

       (gdb) info tasks
         ID       TID P-ID   Thread Pri State                 Name
          1   8088000   0   807e000  15 Child Activation Wait main_task
          2   80a4000   1   80ae000  15 Accept/Select Wait    b
          3   809a800   1   80a4800  15 Child Activation Wait a
       *  4   80ae800   3   80b8000  15 Running               c


    In this listing, the asterisk before the first task indicates it to be the
    currently running task. The first column lists the task ID that is used
    to refer to tasks in the following commands.


.. index:: Breakpoints and tasks

* ``break``*linespec* ``task`` *taskid*, ``break`` *linespec* ``task`` *taskid* ``if`` ...

    These commands are like the ``break ... thread ...``.
    *linespec* specifies source lines.

    Use the qualifier :samp:`task {taskid}` with a breakpoint command
    to specify that you only want ``GDB`` to stop the program when a
    particular Ada task reaches this breakpoint. *taskid* is one of the
    numeric task identifiers assigned by ``GDB``, shown in the first
    column of the ``info tasks`` display.

    If you do not specify :samp:`task {taskid}` when you set a
    breakpoint, the breakpoint applies to *all* tasks of your
    program.

    You can use the ``task`` qualifier on conditional breakpoints as
    well; in this case, place :samp:`task {taskid}` before the
    breakpoint condition (before the ``if``).

.. index:: Task switching (in gdb)

* :samp:`task {taskno}`

    This command allows switching to the task referred by *taskno*. In
    particular, this allows browsing of the backtrace of the specified
    task. It is advisable to switch back to the original task before
    continuing execution otherwise the scheduling of the program may be
    perturbed.

For more detailed information on the tasking support,
see :title:`Debugging with GDB`.


.. index:: Debugging Generic Units
.. index:: Generics

.. _Debugging_Generic_Units:

Debugging Generic Units
-----------------------

GNAT always uses code expansion for generic instantiation. This means that
each time an instantiation occurs, a complete copy of the original code is
made, with appropriate substitutions of formals by actuals.

It is not possible to refer to the original generic entities in
``GDB``, but it is always possible to debug a particular instance of
a generic, by using the appropriate expanded names. For example, if we have

  .. code-block:: ada

     procedure g is

        generic package k is
           procedure kp (v1 : in out integer);
        end k;

        package body k is
           procedure kp (v1 : in out integer) is
           begin
              v1 := v1 + 1;
           end kp;
        end k;

        package k1 is new k;
        package k2 is new k;

        var : integer := 1;

     begin
        k1.kp (var);
        k2.kp (var);
        k1.kp (var);
        k2.kp (var);
     end;

Then to break on a call to procedure kp in the k2 instance, simply
use the command:

  ::

     (gdb) break g.k2.kp

When the breakpoint occurs, you can step through the code of the
instance in the normal manner and examine the values of local variables, as for
other units.


.. index:: Remote Debugging with gdbserver

.. _Remote_Debugging_with_gdbserver:

Remote Debugging with gdbserver
-------------------------------

On platforms where gdbserver is supported, it is possible to use this tool
to debug your application remotely.  This can be useful in situations
where the program needs to be run on a target host that is different
from the host used for development, particularly when the target has
a limited amount of resources (either CPU and/or memory).

To do so, start your program using gdbserver on the target machine.
gdbserver then automatically suspends the execution of your program
at its entry point, waiting for a debugger to connect to it.  The
following commands starts an application and tells gdbserver to
wait for a connection with the debugger on localhost port 4444.


  ::

     $ gdbserver localhost:4444 program
     Process program created; pid = 5685
     Listening on port 4444

Once gdbserver has started listening, we can tell the debugger to establish
a connection with this gdbserver, and then start the same debugging session
as if the program was being debugged on the same host, directly under
the control of GDB.

  ::

     $ gdb program
     (gdb) target remote targethost:4444
     Remote debugging using targethost:4444
     0x00007f29936d0af0 in ?? () from /lib64/ld-linux-x86-64.so.
     (gdb) b foo.adb:3
     Breakpoint 1 at 0x401f0c: file foo.adb, line 3.
     (gdb) continue
     Continuing.

     Breakpoint 1, foo () at foo.adb:4
     4       end foo;

It is also possible to use gdbserver to attach to an already running
program, in which case the execution of that program is simply suspended
until the connection between the debugger and gdbserver is established.

For more information on how to use gdbserver, see the *Using the gdbserver Program*
section in :title:`Debugging with GDB`.
GNAT provides support for gdbserver on x86-linux, x86-windows and x86_64-linux.


.. index:: Abnormal Termination or Failure to Terminate

.. _GNAT_Abnormal_Termination_or_Failure_to_Terminate:

GNAT Abnormal Termination or Failure to Terminate
-------------------------------------------------

When presented with programs that contain serious errors in syntax
or semantics,
GNAT may on rare occasions  experience problems in operation, such
as aborting with a
segmentation fault or illegal memory access, raising an internal
exception, terminating abnormally, or failing to terminate at all.
In such cases, you can activate
various features of GNAT that can help you pinpoint the construct in your
program that is the likely source of the problem.

The following strategies are presented in increasing order of
difficulty, corresponding to your experience in using GNAT and your
familiarity with compiler internals.

* Run ``gcc`` with the :switch:`-gnatf`. This first
  switch causes all errors on a given line to be reported. In its absence,
  only the first error on a line is displayed.

  The :switch:`-gnatdO` switch causes errors to be displayed as soon as they
  are encountered, rather than after compilation is terminated. If GNAT
  terminates prematurely or goes into an infinite loop, the last error
  message displayed may help to pinpoint the culprit.

* Run ``gcc`` with the :switch:`-v` (verbose) switch. In this
  mode, ``gcc`` produces ongoing information about the progress of the
  compilation and provides the name of each procedure as code is
  generated. This switch allows you to find which Ada procedure was being
  compiled when it encountered a code generation problem.

.. index:: -gnatdc switch

* Run ``gcc`` with the :switch:`-gnatdc` switch. This is a GNAT specific
  switch that does for the front-end what :switch:`-v` does
  for the back end. The system prints the name of each unit,
  either a compilation unit or nested unit, as it is being analyzed.

* Finally, you can start
  ``gdb`` directly on the ``gnat1`` executable. ``gnat1`` is the
  front-end of GNAT, and can be run independently (normally it is just
  called from ``gcc``). You can use ``gdb`` on ``gnat1`` as you
  would on a C program (but :ref:`The_GNAT_Debugger_GDB` for caveats). The
  ``where`` command is the first line of attack; the variable
  ``lineno`` (seen by ``print lineno``), used by the second phase of
  ``gnat1`` and by the ``gcc`` backend, indicates the source line at
  which the execution stopped, and ``input_file name`` indicates the name of
  the source file.


.. _Naming_Conventions_for_GNAT_Source_Files:

Naming Conventions for GNAT Source Files
----------------------------------------

In order to examine the workings of the GNAT system, the following
brief description of its organization may be helpful:

* Files with prefix :file:`sc` contain the lexical scanner.

* All files prefixed with :file:`par` are components of the parser. The
  numbers correspond to chapters of the Ada Reference Manual. For example,
  parsing of select statements can be found in :file:`par-ch9.adb`.

* All files prefixed with :file:`sem` perform semantic analysis. The
  numbers correspond to chapters of the Ada standard. For example, all
  issues involving context clauses can be found in :file:`sem_ch10.adb`. In
  addition, some features of the language require sufficient special processing
  to justify their own semantic files: sem_aggr for aggregates, sem_disp for
  dynamic dispatching, etc.

* All files prefixed with :file:`exp` perform normalization and
  expansion of the intermediate representation (abstract syntax tree, or AST).
  these files use the same numbering scheme as the parser and semantics files.
  For example, the construction of record initialization procedures is done in
  :file:`exp_ch3.adb`.

* The files prefixed with :file:`bind` implement the binder, which
  verifies the consistency of the compilation, determines an order of
  elaboration, and generates the bind file.

* The files :file:`atree.ads` and :file:`atree.adb` detail the low-level
  data structures used by the front-end.

* The files :file:`sinfo.ads` and :file:`sinfo.adb` detail the structure of
  the abstract syntax tree as produced by the parser.

* The files :file:`einfo.ads` and :file:`einfo.adb` detail the attributes of
  all entities, computed during semantic analysis.

* Library management issues are dealt with in files with prefix
  :file:`lib`.

  .. index:: Annex A (in Ada Reference Manual)

* Ada files with the prefix :file:`a-` are children of ``Ada``, as
  defined in Annex A.

  .. index:: Annex B (in Ada reference Manual)

* Files with prefix :file:`i-` are children of ``Interfaces``, as
  defined in Annex B.

  .. index::  System (package in Ada Reference Manual)

* Files with prefix :file:`s-` are children of ``System``. This includes
  both language-defined children and GNAT run-time routines.

  .. index:: GNAT (package)

* Files with prefix :file:`g-` are children of ``GNAT``. These are useful
  general-purpose packages, fully documented in their specs. All
  the other :file:`.c` files are modifications of common ``gcc`` files.


.. _Getting_Internal_Debugging_Information:

Getting Internal Debugging Information
--------------------------------------

Most compilers have internal debugging switches and modes. GNAT
does also, except GNAT internal debugging switches and modes are not
secret. A summary and full description of all the compiler and binder
debug flags are in the file :file:`debug.adb`. You must obtain the
sources of the compiler to see the full detailed effects of these flags.

The switches that print the source of the program (reconstructed from
the internal tree) are of general interest for user programs, as are the
options to print
the full internal tree, and the entity table (the symbol table
information). The reconstructed source provides a readable version of the
program after the front-end has completed analysis and  expansion,
and is useful when studying the performance of specific constructs.
For example, constraint checks are indicated, complex aggregates
are replaced with loops and assignments, and tasking primitives
are replaced with run-time calls.


.. index:: traceback
.. index:: stack traceback
.. index:: stack unwinding

.. _Stack_Traceback:

Stack Traceback
---------------

Traceback is a mechanism to display the sequence of subprogram calls that
leads to a specified execution point in a program. Often (but not always)
the execution point is an instruction at which an exception has been raised.
This mechanism is also known as *stack unwinding* because it obtains
its information by scanning the run-time stack and recovering the activation
records of all active subprograms. Stack unwinding is one of the most
important tools for program debugging.

The first entry stored in traceback corresponds to the deepest calling level,
that is to say the subprogram currently executing the instruction
from which we want to obtain the traceback.

Note that there is no runtime performance penalty when stack traceback
is enabled, and no exception is raised during program execution.

.. index:: traceback, non-symbolic

.. _Non-Symbolic_Traceback:

Non-Symbolic Traceback
^^^^^^^^^^^^^^^^^^^^^^

Note: this feature is not supported on all platforms. See
:samp:`GNAT.Traceback` spec in :file:`g-traceb.ads`
for a complete list of supported platforms.

.. rubric:: Tracebacks From an Unhandled Exception

A runtime non-symbolic traceback is a list of addresses of call instructions.
To enable this feature you must use the :switch:`-E`
``gnatbind`` option. With this option a stack traceback is stored as part
of exception information. You can retrieve this information using the
``addr2line`` tool.

Here is a simple example:

  .. code-block:: ada

     procedure STB is

        procedure P1 is
        begin
           raise Constraint_Error;
        end P1;

        procedure P2 is
        begin
           P1;
        end P2;

     begin
        P2;
     end STB;

  ::

     $ gnatmake stb -bargs -E
     $ stb

     Execution terminated by unhandled exception
     Exception name: CONSTRAINT_ERROR
     Message: stb.adb:5
     Call stack traceback locations:
     0x401373 0x40138b 0x40139c 0x401335 0x4011c4 0x4011f1 0x77e892a4

As we see the traceback lists a sequence of addresses for the unhandled
exception ``CONSTRAINT_ERROR`` raised in procedure P1. It is easy to
guess that this exception come from procedure P1. To translate these
addresses into the source lines where the calls appear, the
``addr2line`` tool, described below, is invaluable. The use of this tool
requires the program to be compiled with debug information.

  ::

     $ gnatmake -g stb -bargs -E
     $ stb

     Execution terminated by unhandled exception
     Exception name: CONSTRAINT_ERROR
     Message: stb.adb:5
     Call stack traceback locations:
     0x401373 0x40138b 0x40139c 0x401335 0x4011c4 0x4011f1 0x77e892a4

     $ addr2line --exe=stb 0x401373 0x40138b 0x40139c 0x401335 0x4011c4
        0x4011f1 0x77e892a4

     00401373 at d:/stb/stb.adb:5
     0040138B at d:/stb/stb.adb:10
     0040139C at d:/stb/stb.adb:14
     00401335 at d:/stb/b~stb.adb:104
     004011C4 at /build/.../crt1.c:200
     004011F1 at /build/.../crt1.c:222
     77E892A4 in ?? at ??:0

The ``addr2line`` tool has several other useful options:

  ======================== ========================================================
  :samp:`--functions`      to get the function name corresponding to any location
  :samp:`--demangle=gnat`  to use the gnat decoding mode for the function names.
                           Note that for binutils version 2.9.x the option is
                           simply :samp:`--demangle`.
  ======================== ========================================================

  ::

     $ addr2line --exe=stb --functions --demangle=gnat 0x401373 0x40138b
        0x40139c 0x401335 0x4011c4 0x4011f1

     00401373 in stb.p1 at d:/stb/stb.adb:5
     0040138B in stb.p2 at d:/stb/stb.adb:10
     0040139C in stb at d:/stb/stb.adb:14
     00401335 in main at d:/stb/b~stb.adb:104
     004011C4 in <__mingw_CRTStartup> at /build/.../crt1.c:200
     004011F1 in <mainCRTStartup> at /build/.../crt1.c:222

From this traceback we can see that the exception was raised in
:file:`stb.adb` at line 5, which was reached from a procedure call in
:file:`stb.adb` at line 10, and so on. The :file:`b~std.adb` is the binder file,
which contains the call to the main program.
:ref:`Running_gnatbind`. The remaining entries are assorted runtime routines,
and the output will vary from platform to platform.

It is also possible to use ``GDB`` with these traceback addresses to debug
the program. For example, we can break at a given code location, as reported
in the stack traceback:

  ::

     $ gdb -nw stb

Furthermore, this feature is not implemented inside Windows DLL. Only
the non-symbolic traceback is reported in this case.

  ::

     (gdb) break *0x401373
     Breakpoint 1 at 0x401373: file stb.adb, line 5.

It is important to note that the stack traceback addresses
do not change when debug information is included. This is particularly useful
because it makes it possible to release software without debug information (to
minimize object size), get a field report that includes a stack traceback
whenever an internal bug occurs, and then be able to retrieve the sequence
of calls with the same program compiled with debug information.


.. rubric:: Tracebacks From Exception Occurrences

Non-symbolic tracebacks are obtained by using the :switch:`-E` binder argument.
The stack traceback is attached to the exception information string, and can
be retrieved in an exception handler within the Ada program, by means of the
Ada facilities defined in ``Ada.Exceptions``. Here is a simple example:

  .. code-block:: ada

      with Ada.Text_IO;
      with Ada.Exceptions;

      procedure STB is

         use Ada;
         use Ada.Exceptions;

         procedure P1 is
            K : Positive := 1;
         begin
            K := K - 1;
         exception
            when E : others =>
               Text_IO.Put_Line (Exception_Information (E));
         end P1;

         procedure P2 is
         begin
            P1;
         end P2;

      begin
         P2;
      end STB;

This program will output:

  ::

     $ stb

     Exception name: CONSTRAINT_ERROR
     Message: stb.adb:12
     Call stack traceback locations:
     0x4015e4 0x401633 0x401644 0x401461 0x4011c4 0x4011f1 0x77e892a4


.. rubric:: Tracebacks From Anywhere in a Program

It is also possible to retrieve a stack traceback from anywhere in a
program. For this you need to
use the ``GNAT.Traceback`` API. This package includes a procedure called
``Call_Chain`` that computes a complete stack traceback, as well as useful
display procedures described below. It is not necessary to use the
:switch:`-E` ``gnatbind`` option in this case, because the stack traceback mechanism
is invoked explicitly.

In the following example we compute a traceback at a specific location in
the program, and we display it using ``GNAT.Debug_Utilities.Image`` to
convert addresses to strings:


  .. code-block:: ada

      with Ada.Text_IO;
      with GNAT.Traceback;
      with GNAT.Debug_Utilities;

      procedure STB is

         use Ada;
         use GNAT;
         use GNAT.Traceback;

         procedure P1 is
            TB  : Tracebacks_Array (1 .. 10);
            --  We are asking for a maximum of 10 stack frames.
            Len : Natural;
            --  Len will receive the actual number of stack frames returned.
         begin
            Call_Chain (TB, Len);

            Text_IO.Put ("In STB.P1 : ");

            for K in 1 .. Len loop
               Text_IO.Put (Debug_Utilities.Image (TB (K)));
               Text_IO.Put (' ');
            end loop;

            Text_IO.New_Line;
         end P1;

         procedure P2 is
         begin
            P1;
         end P2;

      begin
         P2;
      end STB;

  ::

     $ gnatmake -g stb
     $ stb

     In STB.P1 : 16#0040_F1E4# 16#0040_14F2# 16#0040_170B# 16#0040_171C#
     16#0040_1461# 16#0040_11C4# 16#0040_11F1# 16#77E8_92A4#


You can then get further information by invoking the ``addr2line``
tool as described earlier (note that the hexadecimal addresses
need to be specified in C format, with a leading '0x').

.. index:: traceback, symbolic

.. _Symbolic_Traceback:

Symbolic Traceback
^^^^^^^^^^^^^^^^^^

A symbolic traceback is a stack traceback in which procedure names are
associated with each code location.

Note that this feature is not supported on all platforms. See
:samp:`GNAT.Traceback.Symbolic` spec in :file:`g-trasym.ads` for a complete
list of currently supported platforms.

Note that the symbolic traceback requires that the program be compiled
with debug information. If it is not compiled with debug information
only the non-symbolic information will be valid.


.. rubric:: Tracebacks From Exception Occurrences

Here is an example:

  .. code-block:: ada

      with Ada.Text_IO;
      with GNAT.Traceback.Symbolic;

      procedure STB is

         procedure P1 is
         begin
            raise Constraint_Error;
         end P1;

         procedure P2 is
         begin
            P1;
         end P2;

         procedure P3 is
         begin
            P2;
         end P3;

      begin
         P3;
      exception
         when E : others =>
            Ada.Text_IO.Put_Line (GNAT.Traceback.Symbolic.Symbolic_Traceback (E));
      end STB;

  ::

      $ gnatmake -g .\stb -bargs -E
      $ stb

      0040149F in stb.p1 at stb.adb:8
      004014B7 in stb.p2 at stb.adb:13
      004014CF in stb.p3 at stb.adb:18
      004015DD in ada.stb at stb.adb:22
      00401461 in main at b~stb.adb:168
      004011C4 in __mingw_CRTStartup at crt1.c:200
      004011F1 in mainCRTStartup at crt1.c:222
      77E892A4 in ?? at ??:0

In the above example the ``.\`` syntax in the ``gnatmake`` command
is currently required by ``addr2line`` for files that are in
the current working directory.
Moreover, the exact sequence of linker options may vary from platform
to platform.
The above :switch:`-largs` section is for Windows platforms. By contrast,
under Unix there is no need for the :switch:`-largs` section.
Differences across platforms are due to details of linker implementation.


.. rubric:: Tracebacks From Anywhere in a Program

It is possible to get a symbolic stack traceback
from anywhere in a program, just as for non-symbolic tracebacks.
The first step is to obtain a non-symbolic
traceback, and then call ``Symbolic_Traceback`` to compute the symbolic
information. Here is an example:

  .. code-block:: ada

      with Ada.Text_IO;
      with GNAT.Traceback;
      with GNAT.Traceback.Symbolic;

      procedure STB is

         use Ada;
         use GNAT.Traceback;
         use GNAT.Traceback.Symbolic;

         procedure P1 is
            TB  : Tracebacks_Array (1 .. 10);
            --  We are asking for a maximum of 10 stack frames.
            Len : Natural;
            --  Len will receive the actual number of stack frames returned.
         begin
            Call_Chain (TB, Len);
            Text_IO.Put_Line (Symbolic_Traceback (TB (1 .. Len)));
         end P1;

         procedure P2 is
         begin
            P1;
         end P2;

      begin
         P2;
      end STB;


.. rubric:: Automatic Symbolic Tracebacks

Symbolic tracebacks may also be enabled by using the -Es switch to gnatbind (as
in ``gprbuild -g ... -bargs -Es``).
This will cause the Exception_Information to contain a symbolic traceback,
which will also be printed if an unhandled exception terminates the
program.


.. _Pretty-Printers_For_The_GNAT_Runtime:

Pretty-Printers for the GNAT runtime
------------------------------------

As discussed in :title:`Calling User-Defined Subprograms`, GDB's
``print`` command only knows about the physical layout of program data
structures and therefore normally displays only low-level dumps, which
are often hard to understand.

An example of this is when trying to display the contents of an Ada
standard container, such as ``Ada.Containers.Ordered_Maps.Map``:

  .. code-block:: ada

      with Ada.Containers.Ordered_Maps;

      procedure PP is
         package Int_To_Nat is
            new Ada.Containers.Ordered_Maps (Integer, Natural);

         Map : Int_To_Nat.Map;
      begin
         Map.Insert (1, 10);
         Map.Insert (2, 20);
         Map.Insert (3, 30);

         Map.Clear; --  BREAK HERE
      end PP;

When this program is built with debugging information and run under
GDB up to the ``Map.Clear`` statement, trying to print ``Map`` will
yield information that is only relevant to the developers of our standard
containers:

  ::

      (gdb) print map
      $1 = (
        tree => (
          first => 0x64e010,
          last => 0x64e070,
          root => 0x64e040,
          length => 3,
          tc => (
            busy => 0,
            lock => 0
          )
        )
      )

Fortunately, GDB has a feature called `pretty-printers
<http://docs.adacore.com/gdb-docs/html/gdb.html#Pretty_002dPrinter-Introduction>`_,
which allows customizing how GDB displays data structures. The GDB
shipped with GNAT embeds such pretty-printers for the most common
containers in the standard library.  To enable them, either run the
following command manually under GDB or add it to your ``.gdbinit`` file:

  ::

      python import gnatdbg; gnatdbg.setup()

Once this is done, GDB's ``print`` command will automatically use
these pretty-printers when appropriate. Using the previous example:

  ::

      (gdb) print map
      $1 = pp.int_to_nat.map of length 3 = {
        [1] = 10,
        [2] = 20,
        [3] = 30
      }

Pretty-printers are invoked each time GDB tries to display a value,
including when displaying the arguments of a called subprogram (in
GDB's ``backtrace`` command) or when printing the value returned by a
function (in GDB's ``finish`` command).

To display a value without involving pretty-printers, ``print`` can be
invoked with its ``/r`` option:

  ::

      (gdb) print/r map
      $1 = (
        tree => (...

Finer control of pretty-printers is also possible: see `GDB's online
documentation
<http://docs.adacore.com/gdb-docs/html/gdb.html#Pretty_002dPrinter-Commands>`_
for more information.


.. index:: Code Coverage
.. index:: Profiling


.. _Code_Coverage_and_Profiling:

Code Coverage and Profiling
===========================

This section describes how to use the ``gcov`` coverage testing tool and
the ``gprof`` profiler tool on Ada programs.

.. index:: !  gcov

.. _Code_Coverage_of_Ada_Programs_with_gcov:

Code Coverage of Ada Programs with gcov
---------------------------------------

``gcov`` is a test coverage program: it analyzes the execution of a given
program on selected tests, to help you determine the portions of the program
that are still untested.

``gcov`` is part of the GCC suite, and is described in detail in the GCC
User's Guide. You can refer to this documentation for a more complete
description.

This chapter provides a quick startup guide, and
details some GNAT-specific features.

.. _Quick_startup_guide:

Quick startup guide
^^^^^^^^^^^^^^^^^^^

In order to perform coverage analysis of a program using ``gcov``, several
steps are needed:

#. Instrument the code during the compilation process,
#. Execute the instrumented program, and
#. Invoke the ``gcov`` tool to generate the coverage results.

.. index:: -fprofile-arcs (gcc)
.. index:: -ftest-coverage (gcc
.. index:: -fprofile-arcs (gnatbind)

The code instrumentation needed by gcov is created at the object level.
The source code is not modified in any way, because the instrumentation code is
inserted by gcc during the compilation process. To compile your code with code
coverage activated, you need to recompile your whole project using the
switches
:switch:`-fprofile-arcs` and :switch:`-ftest-coverage`, and link it using
:switch:`-fprofile-arcs`.

  ::

     $ gnatmake -P my_project.gpr -f -cargs -fprofile-arcs -ftest-coverage \\
        -largs -fprofile-arcs

This compilation process will create :file:`.gcno` files together with
the usual object files.

Once the program is compiled with coverage instrumentation, you can
run it as many times as needed -- on portions of a test suite for
example. The first execution will produce :file:`.gcda` files at the
same location as the :file:`.gcno` files.  Subsequent executions
will update those files, so that a cumulative result of the covered
portions of the program is generated.

Finally, you need to call the ``gcov`` tool. The different options of
``gcov`` are described in the GCC User's Guide, section *Invoking gcov*.

This will create annotated source files with a :file:`.gcov` extension:
:file:`my_main.adb` file will be analyzed in :file:`my_main.adb.gcov`.


.. _GNAT_specifics:

GNAT specifics
^^^^^^^^^^^^^^

Because of Ada semantics, portions of the source code may be shared among
several object files. This is the case for example when generics are
involved, when inlining is active  or when declarations generate  initialisation
calls. In order to take
into account this shared code, you need to call ``gcov`` on all
source files of the tested program at once.

The list of source files might exceed the system's maximum command line
length. In order to bypass this limitation, a new mechanism has been
implemented in ``gcov``: you can now list all your project's files into a
text file, and provide this file to gcov as a parameter,  preceded by a ``@``
(e.g. :samp:`gcov @mysrclist.txt`).

Note that on AIX compiling a static library with :switch:`-fprofile-arcs` is
not supported as there can be unresolved symbols during the final link.


.. index:: !  gprof
.. index:: Profiling

.. _Profiling_an_Ada_Program_with_gprof:

Profiling an Ada Program with gprof
-----------------------------------

This section is not meant to be an exhaustive documentation of ``gprof``.
Full documentation for it can be found in the :title:`GNU Profiler User's Guide`
documentation that is part of this GNAT distribution.

Profiling a program helps determine the parts of a program that are executed
most often, and are therefore the most time-consuming.

``gprof`` is the standard GNU profiling tool; it has been enhanced to
better handle Ada programs and multitasking.
It is currently supported on the following platforms

* linux x86/x86_64
* solaris sparc/sparc64/x86
* windows x86

In order to profile a program using ``gprof``, several steps are needed:

#. Instrument the code, which requires a full recompilation of the project with the
   proper switches.

#. Execute the program under the analysis conditions, i.e. with the desired
   input.

#. Analyze the results using the ``gprof`` tool.

The following sections detail the different steps, and indicate how
to interpret the results.


.. _Compilation_for_profiling:

Compilation for profiling
^^^^^^^^^^^^^^^^^^^^^^^^^

.. index:: -pg (gcc), for profiling
.. index:: -pg (gnatlink), for profiling

In order to profile a program the first step is to tell the compiler
to generate the necessary profiling information. The compiler switch to be used
is ``-pg``, which must be added to other compilation switches. This
switch needs to be specified both during compilation and link stages, and can
be specified once when using gnatmake:

  ::

     $ gnatmake -f -pg -P my_project

Note that only the objects that were compiled with the ``-pg`` switch will
be profiled; if you need to profile your whole project, use the ``-f``
gnatmake switch to force full recompilation.

.. _Program_execution:


Program execution
^^^^^^^^^^^^^^^^^

Once the program has been compiled for profiling, you can run it as usual.

The only constraint imposed by profiling is that the program must terminate
normally. An interrupted program (via a Ctrl-C, kill, etc.) will not be
properly analyzed.

Once the program completes execution, a data file called :file:`gmon.out` is
generated in the directory where the program was launched from. If this file
already exists, it will be overwritten.


.. _Running_gprof:

Running gprof
^^^^^^^^^^^^^

The ``gprof`` tool is called as follow:

  ::

     $ gprof my_prog gmon.out

or simply:

  ::

    $  gprof my_prog

The complete form of the gprof command line is the following:

  ::

     $ gprof [switches] [executable [data-file]]

``gprof`` supports numerous switches. The order of these
switch does not matter. The full list of options can be found in
the GNU Profiler User's Guide documentation that comes with this documentation.

The following is the subset of those switches that is most relevant:

.. index:: --demangle (gprof)

:samp:`--demangle[={style}]`, :samp:`--no-demangle`
  These options control whether symbol names should be demangled when
  printing output.  The default is to demangle C++ symbols.  The
  ``--no-demangle`` option may be used to turn off demangling. Different
  compilers have different mangling styles.  The optional demangling style
  argument can be used to choose an appropriate demangling style for your
  compiler, in particular Ada symbols generated by GNAT can be demangled using
  ``--demangle=gnat``.


.. index:: -e (gprof)

:samp:`-e {function_name}`
  The :samp:`-e {function}` option tells ``gprof`` not to print
  information about the function ``function_name`` (and its
  children...) in the call graph.  The function will still be listed
  as a child of any functions that call it, but its index number will be
  shown as ``[not printed]``.  More than one ``-e`` option may be
  given; only one ``function_name`` may be indicated with each ``-e``
  option.


.. index:: -E (gprof)

:samp:`-E {function_name}`
  The :samp:`-E {function}` option works like the ``-e`` option, but
  execution time spent in the function (and children who were not called from
  anywhere else), will not be used to compute the percentages-of-time for
  the call graph.  More than one :switch:`-E` option may be given; only one
  ``function_name`` may be indicated with each :switch:`-E`` option.


.. index:: -f (gprof)

:samp:`-f {function_name}`
  The :samp:`-f {function}` option causes ``gprof`` to limit the
  call graph to the function ``function_name`` and its children (and
  their children...).  More than one ``-f`` option may be given;
  only one ``function_name`` may be indicated with each ``-f``
  option.


.. index:: -F (gprof)

:samp:`-F {function_name}`
  The :samp:`-F {function}` option works like the ``-f`` option, but
  only time spent in the function and its children (and their
  children...) will be used to determine total-time and
  percentages-of-time for the call graph.  More than one ``-F`` option
  may be given; only one ``function_name`` may be indicated with each
  ``-F`` option.  The ``-F`` option overrides the ``-E`` option.


.. _Interpretation_of_profiling_results:

Interpretation of profiling results
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The results of the profiling analysis are represented by two arrays: the
'flat profile' and the 'call graph'. Full documentation of those outputs
can be found in the GNU Profiler User's Guide.

The flat profile shows the time spent in each function of the program, and how
many time it has been called. This allows you to locate easily the most
time-consuming functions.

The call graph shows, for each subprogram, the subprograms that call it,
and the subprograms that it calls. It also provides an estimate of the time
spent in each of those callers/called subprograms.



.. _Improving_Performance:

Improving Performance
=====================

.. index:: Improving performance

This section presents several topics related to program performance.
It first describes some of the tradeoffs that need to be considered
and some of the techniques for making your program run faster.

.. only:: PRO or GPL

   It then documents the unused subprogram/data elimination feature
   and the ``gnatelim`` tool,
   which can reduce the size of program executables.


.. only:: FSF

   It then documents the unused subprogram/data elimination feature,
   which can reduce the size of program executables.


.. _Performance_Considerations:

Performance Considerations
--------------------------

The GNAT system provides a number of options that allow a trade-off
between

* performance of the generated code

* speed of compilation

* minimization of dependences and recompilation

* the degree of run-time checking.

The defaults (if no options are selected) aim at improving the speed
of compilation and minimizing dependences, at the expense of performance
of the generated code:

* no optimization

* no inlining of subprogram calls

* all run-time checks enabled except overflow and elaboration checks

These options are suitable for most program development purposes. This
section describes how you can modify these choices, and also provides
some guidelines on debugging optimized code.


.. _Controlling_Run-Time_Checks:

Controlling Run-Time Checks
^^^^^^^^^^^^^^^^^^^^^^^^^^^

By default, GNAT generates all run-time checks, except stack overflow
checks, and checks for access before elaboration on subprogram
calls. The latter are not required in default mode, because all
necessary checking is done at compile time.

.. index:: -gnatp (gcc)
.. index:: -gnato (gcc)

The gnat switch, :switch:`-gnatp` allows this default to be modified. See
:ref:`Run-Time_Checks`.

Our experience is that the default is suitable for most development
purposes.

Elaboration checks are off by default, and also not needed by default, since
GNAT uses a static elaboration analysis approach that avoids the need for
run-time checking. This manual contains a full chapter discussing the issue
of elaboration checks, and if the default is not satisfactory for your use,
you should read this chapter.

For validity checks, the minimal checks required by the Ada Reference
Manual (for case statements and assignments to array elements) are on
by default. These can be suppressed by use of the :switch:`-gnatVn` switch.
Note that in Ada 83, there were no validity checks, so if the Ada 83 mode
is acceptable (or when comparing GNAT performance with an Ada 83 compiler),
it may be reasonable to routinely use :switch:`-gnatVn`. Validity checks
are also suppressed entirely if :switch:`-gnatp` is used.

.. index:: Overflow checks
.. index:: Checks, overflow

.. index:: Suppress
.. index:: Unsuppress
.. index:: pragma Suppress
.. index:: pragma Unsuppress

Note that the setting of the switches controls the default setting of
the checks. They may be modified using either ``pragma Suppress`` (to
remove checks) or ``pragma Unsuppress`` (to add back suppressed
checks) in the program source.


.. _Use_of_Restrictions:

Use of Restrictions
^^^^^^^^^^^^^^^^^^^

The use of pragma Restrictions allows you to control which features are
permitted in your program. Apart from the obvious point that if you avoid
relatively expensive features like finalization (enforceable by the use
of pragma Restrictions (No_Finalization), the use of this pragma does not
affect the generated code in most cases.

One notable exception to this rule is that the possibility of task abort
results in some distributed overhead, particularly if finalization or
exception handlers are used. The reason is that certain sections of code
have to be marked as non-abortable.

If you use neither the ``abort`` statement, nor asynchronous transfer
of control (``select ... then abort``), then this distributed overhead
is removed, which may have a general positive effect in improving
overall performance.  Especially code involving frequent use of tasking
constructs and controlled types will show much improved performance.
The relevant restrictions pragmas are

  .. code-block:: ada

      pragma Restrictions (No_Abort_Statements);
      pragma Restrictions (Max_Asynchronous_Select_Nesting => 0);

It is recommended that these restriction pragmas be used if possible. Note
that this also means that you can write code without worrying about the
possibility of an immediate abort at any point.


.. _Optimization_Levels:

Optimization Levels
^^^^^^^^^^^^^^^^^^^

.. index:: -O (gcc)

Without any optimization option,
the compiler's goal is to reduce the cost of
compilation and to make debugging produce the expected results.
Statements are independent: if you stop the program with a breakpoint between
statements, you can then assign a new value to any variable or change
the program counter to any other statement in the subprogram and get exactly
the results you would expect from the source code.

Turning on optimization makes the compiler attempt to improve the
performance and/or code size at the expense of compilation time and
possibly the ability to debug the program.

If you use multiple
-O options, with or without level numbers,
the last such option is the one that is effective.

The default is optimization off. This results in the fastest compile
times, but GNAT makes absolutely no attempt to optimize, and the
generated programs are considerably larger and slower than when
optimization is enabled. You can use the
:switch:`-O` switch (the permitted forms are :switch:`-O0`, :switch:`-O1`
:switch:`-O2`, :switch:`-O3`, and :switch:`-Os`)
to ``gcc`` to control the optimization level:


* :switch:`-O0`
    No optimization (the default);
    generates unoptimized code but has
    the fastest compilation time.

    Note that many other compilers do substantial optimization even
    if 'no optimization' is specified. With gcc, it is very unusual
    to use :switch:`-O0` for production if execution time is of any concern,
    since :switch:`-O0` means (almost) no optimization. This difference
    between gcc and other compilers should be kept in mind when
    doing performance comparisons.

* :switch:`-O1`
    Moderate optimization;
    optimizes reasonably well but does not
    degrade compilation time significantly.

* :switch:`-O2`
    Full optimization;
    generates highly optimized code and has
    the slowest compilation time.

* :switch:`-O3`
    Full optimization as in :switch:`-O2`;
    also uses more aggressive automatic inlining of subprograms within a unit
    (:ref:`Inlining_of_Subprograms`) and attempts to vectorize loops.


* :switch:`-Os`
    Optimize space usage (code and data) of resulting program.

Higher optimization levels perform more global transformations on the
program and apply more expensive analysis algorithms in order to generate
faster and more compact code. The price in compilation time, and the
resulting improvement in execution time,
both depend on the particular application and the hardware environment.
You should experiment to find the best level for your application.

Since the precise set of optimizations done at each level will vary from
release to release (and sometime from target to target), it is best to think
of the optimization settings in general terms.
See the *Options That Control Optimization* section in
:title:`Using the GNU Compiler Collection (GCC)`
for details about
the :switch:`-O` settings and a number of :switch:`-f` options that
individually enable or disable specific optimizations.

Unlike some other compilation systems, ``gcc`` has
been tested extensively at all optimization levels. There are some bugs
which appear only with optimization turned on, but there have also been
bugs which show up only in *unoptimized* code. Selecting a lower
level of optimization does not improve the reliability of the code
generator, which in practice is highly reliable at all optimization
levels.

Note regarding the use of :switch:`-O3`: The use of this optimization level
ought not to be automatically preferred over that of level :switch:`-O2`,
since it often results in larger executables which may run more slowly.
See further discussion of this point in :ref:`Inlining_of_Subprograms`.


.. _Debugging_Optimized_Code:

Debugging Optimized Code
^^^^^^^^^^^^^^^^^^^^^^^^

.. index:: Debugging optimized code
.. index:: Optimization and debugging

Although it is possible to do a reasonable amount of debugging at
nonzero optimization levels,
the higher the level the more likely that
source-level constructs will have been eliminated by optimization.
For example, if a loop is strength-reduced, the loop
control variable may be completely eliminated and thus cannot be
displayed in the debugger.
This can only happen at :switch:`-O2` or :switch:`-O3`.
Explicit temporary variables that you code might be eliminated at
level :switch:`-O1` or higher.

.. index:: -g (gcc)

The use of the :switch:`-g` switch,
which is needed for source-level debugging,
affects the size of the program executable on disk,
and indeed the debugging information can be quite large.
However, it has no effect on the generated code (and thus does not
degrade performance)

Since the compiler generates debugging tables for a compilation unit before
it performs optimizations, the optimizing transformations may invalidate some
of the debugging data.  You therefore need to anticipate certain
anomalous situations that may arise while debugging optimized code.
These are the most common cases:

* *The 'hopping Program Counter':*  Repeated ``step`` or ``next``
  commands show
  the PC bouncing back and forth in the code.  This may result from any of
  the following optimizations:

  - *Common subexpression elimination:* using a single instance of code for a
    quantity that the source computes several times.  As a result you
    may not be able to stop on what looks like a statement.

  - *Invariant code motion:* moving an expression that does not change within a
    loop, to the beginning of the loop.

  - *Instruction scheduling:* moving instructions so as to
    overlap loads and stores (typically) with other code, or in
    general to move computations of values closer to their uses. Often
    this causes you to pass an assignment statement without the assignment
    happening and then later bounce back to the statement when the
    value is actually needed.  Placing a breakpoint on a line of code
    and then stepping over it may, therefore, not always cause all the
    expected side-effects.

* *The 'big leap':* More commonly known as *cross-jumping*, in which
  two identical pieces of code are merged and the program counter suddenly
  jumps to a statement that is not supposed to be executed, simply because
  it (and the code following) translates to the same thing as the code
  that *was* supposed to be executed.  This effect is typically seen in
  sequences that end in a jump, such as a ``goto``, a ``return``, or
  a ``break`` in a C ``switch`` statement.

* *The 'roving variable':* The symptom is an unexpected value in a variable.
  There are various reasons for this effect:

  - In a subprogram prologue, a parameter may not yet have been moved to its
    'home'.

  - A variable may be dead, and its register re-used.  This is
    probably the most common cause.

  - As mentioned above, the assignment of a value to a variable may
    have been moved.

  - A variable may be eliminated entirely by value propagation or
    other means.  In this case, GCC may incorrectly generate debugging
    information for the variable

  In general, when an unexpected value appears for a local variable or parameter
  you should first ascertain if that value was actually computed by
  your program, as opposed to being incorrectly reported by the debugger.
  Record fields or
  array elements in an object designated by an access value
  are generally less of a problem, once you have ascertained that the access
  value is sensible.
  Typically, this means checking variables in the preceding code and in the
  calling subprogram to verify that the value observed is explainable from other
  values (one must apply the procedure recursively to those
  other values); or re-running the code and stopping a little earlier
  (perhaps before the call) and stepping to better see how the variable obtained
  the value in question; or continuing to step *from* the point of the
  strange value to see if code motion had simply moved the variable's
  assignments later.

In light of such anomalies, a recommended technique is to use :switch:`-O0`
early in the software development cycle, when extensive debugging capabilities
are most needed, and then move to :switch:`-O1` and later :switch:`-O2` as
the debugger becomes less critical.
Whether to use the :switch:`-g` switch in the release version is
a release management issue.
Note that if you use :switch:`-g` you can then use the ``strip`` program
on the resulting executable,
which removes both debugging information and global symbols.


.. _Inlining_of_Subprograms:

Inlining of Subprograms
^^^^^^^^^^^^^^^^^^^^^^^

A call to a subprogram in the current unit is inlined if all the
following conditions are met:

* The optimization level is at least :switch:`-O1`.

* The called subprogram is suitable for inlining: It must be small enough
  and not contain something that ``gcc`` cannot support in inlined
  subprograms.

  .. index:: pragma Inline
  .. index:: Inline

* Any one of the following applies: ``pragma Inline`` is applied to the
  subprogram; the subprogram is local to the unit and called once from
  within it; the subprogram is small and optimization level :switch:`-O2` is
  specified; optimization level :switch:`-O3` is specified.

Calls to subprograms in |withed| units are normally not inlined.
To achieve actual inlining (that is, replacement of the call by the code
in the body of the subprogram), the following conditions must all be true:

* The optimization level is at least :switch:`-O1`.

* The called subprogram is suitable for inlining: It must be small enough
  and not contain something that ``gcc`` cannot support in inlined
  subprograms.

* There is a ``pragma Inline`` for the subprogram.

* The :switch:`-gnatn` switch is used on the command line.

Even if all these conditions are met, it may not be possible for
the compiler to inline the call, due to the length of the body,
or features in the body that make it impossible for the compiler
to do the inlining.

Note that specifying the :switch:`-gnatn` switch causes additional
compilation dependencies. Consider the following:

  .. code-block:: ada

      package R is
         procedure Q;
         pragma Inline (Q);
      end R;
      package body R is
         ...
      end R;

      with R;
      procedure Main is
      begin
         ...
         R.Q;
      end Main;

With the default behavior (no :switch:`-gnatn` switch specified), the
compilation of the ``Main`` procedure depends only on its own source,
:file:`main.adb`, and the spec of the package in file :file:`r.ads`. This
means that editing the body of ``R`` does not require recompiling
``Main``.

On the other hand, the call ``R.Q`` is not inlined under these
circumstances. If the :switch:`-gnatn` switch is present when ``Main``
is compiled, the call will be inlined if the body of ``Q`` is small
enough, but now ``Main`` depends on the body of ``R`` in
:file:`r.adb` as well as on the spec. This means that if this body is edited,
the main program must be recompiled. Note that this extra dependency
occurs whether or not the call is in fact inlined by ``gcc``.

The use of front end inlining with :switch:`-gnatN` generates similar
additional dependencies.

.. index:: -fno-inline (gcc)

Note: The :switch:`-fno-inline` switch overrides all other conditions and ensures that
no inlining occurs, unless requested with pragma Inline_Always for ``gcc``
back-ends. The extra dependences resulting from :switch:`-gnatn` will still be active,
even if this switch is used to suppress the resulting inlining actions.

.. index:: -fno-inline-functions (gcc)

Note: The :switch:`-fno-inline-functions` switch can be used to prevent
automatic inlining of subprograms if :switch:`-O3` is used.

.. index:: -fno-inline-small-functions (gcc)

Note: The :switch:`-fno-inline-small-functions` switch can be used to prevent
automatic inlining of small subprograms if :switch:`-O2` is used.

.. index:: -fno-inline-functions-called-once (gcc)

Note: The :switch:`-fno-inline-functions-called-once` switch
can be used to prevent inlining of subprograms local to the unit
and called once from within it if :switch:`-O1` is used.

Note regarding the use of :switch:`-O3`: :switch:`-gnatn` is made up of two
sub-switches :switch:`-gnatn1` and :switch:`-gnatn2` that can be directly
specified in lieu of it, :switch:`-gnatn` being translated into one of them
based on the optimization level. With :switch:`-O2` or below, :switch:`-gnatn`
is equivalent to :switch:`-gnatn1` which activates pragma ``Inline`` with
moderate inlining across modules. With :switch:`-O3`, :switch:`-gnatn` is
equivalent to :switch:`-gnatn2` which activates pragma ``Inline`` with
full inlining across modules. If you have used pragma ``Inline`` in
appropriate cases, then it is usually much better to use :switch:`-O2`
and :switch:`-gnatn` and avoid the use of :switch:`-O3` which has the additional
effect of inlining subprograms you did not think should be inlined. We have
found that the use of :switch:`-O3` may slow down the compilation and increase
the code size by performing excessive inlining, leading to increased
instruction cache pressure from the increased code size and thus minor
performance improvements. So the bottom line here is that you should not
automatically assume that :switch:`-O3` is better than :switch:`-O2`, and
indeed you should use :switch:`-O3` only if tests show that it actually
improves performance for your program.

.. _Floating_Point_Operations:

Floating_Point_Operations
^^^^^^^^^^^^^^^^^^^^^^^^^

.. index:: Floating-Point Operations

On almost all targets, GNAT maps Float and Long_Float to the 32-bit and
64-bit standard IEEE floating-point representations, and operations will
use standard IEEE arithmetic as provided by the processor. On most, but
not all, architectures, the attribute Machine_Overflows is False for these
types, meaning that the semantics of overflow is implementation-defined.
In the case of GNAT, these semantics correspond to the normal IEEE
treatment of infinities and NaN (not a number) values. For example,
1.0 / 0.0 yields plus infinitiy and 0.0 / 0.0 yields a NaN. By
avoiding explicit overflow checks, the performance is greatly improved
on many targets. However, if required, floating-point overflow can be
enabled by the use of the pragma Check_Float_Overflow.

Another consideration that applies specifically to x86 32-bit
architectures is which form of floating-point arithmetic is used.
By default the operations use the old style x86 floating-point,
which implements an 80-bit extended precision form (on these
architectures the type Long_Long_Float corresponds to that form).
In addition, generation of efficient code in this mode means that
the extended precision form will be used for intermediate results.
This may be helpful in improving the final precision of a complex
expression. However it means that the results obtained on the x86
will be different from those on other architectures, and for some
algorithms, the extra intermediate precision can be detrimental.

In addition to this old-style floating-point, all modern x86 chips
implement an alternative floating-point operation model referred
to as SSE2. In this model there is no extended form, and furthermore
execution performance is significantly enhanced. To force GNAT to use
this more modern form, use both of the switches:

   -msse2 -mfpmath=sse

A unit compiled with these switches will automatically use the more
efficient SSE2 instruction set for Float and Long_Float operations.
Note that the ABI has the same form for both floating-point models,
so it is permissible to mix units compiled with and without these
switches.





.. _Vectorization_of_loops:

Vectorization of loops
^^^^^^^^^^^^^^^^^^^^^^

.. index:: Optimization Switches

You can take advantage of the auto-vectorizer present in the ``gcc``
back end to vectorize loops with GNAT.  The corresponding command line switch
is :switch:`-ftree-vectorize` but, as it is enabled by default at :switch:`-O3`
and other aggressive optimizations helpful for vectorization also are enabled
by default at this level, using :switch:`-O3` directly is recommended.

You also need to make sure that the target architecture features a supported
SIMD instruction set.  For example, for the x86 architecture, you should at
least specify :switch:`-msse2` to get significant vectorization (but you don't
need to specify it for x86-64 as it is part of the base 64-bit architecture).
Similarly, for the PowerPC architecture, you should specify :switch:`-maltivec`.

The preferred loop form for vectorization is the ``for`` iteration scheme.
Loops with a ``while`` iteration scheme can also be vectorized if they are
very simple, but the vectorizer will quickly give up otherwise.  With either
iteration scheme, the flow of control must be straight, in particular no
``exit`` statement may appear in the loop body.  The loop may however
contain a single nested loop, if it can be vectorized when considered alone:

  .. code-block:: ada

       A : array (1..4, 1..4) of Long_Float;
       S : array (1..4) of Long_Float;

       procedure Sum is
       begin
          for I in A'Range(1) loop
             for J in A'Range(2) loop
                S (I) := S (I) + A (I, J);
             end loop;
          end loop;
       end Sum;

The vectorizable operations depend on the targeted SIMD instruction set, but
the adding and some of the multiplying operators are generally supported, as
well as the logical operators for modular types. Note that compiling
with :switch:`-gnatp` might well reveal cases where some checks do thwart
vectorization.

Type conversions may also prevent vectorization if they involve semantics that
are not directly supported by the code generator or the SIMD instruction set.
A typical example is direct conversion from floating-point to integer types.
The solution in this case is to use the following idiom:

  .. code-block:: ada

       Integer (S'Truncation (F))

if ``S`` is the subtype of floating-point object ``F``.

In most cases, the vectorizable loops are loops that iterate over arrays.
All kinds of array types are supported, i.e. constrained array types with
static bounds:

  .. code-block:: ada

       type Array_Type is array (1 .. 4) of Long_Float;

constrained array types with dynamic bounds:


  .. code-block:: ada

     type Array_Type is array (1 .. Q.N) of Long_Float;

     type Array_Type is array (Q.K .. 4) of Long_Float;

     type Array_Type is array (Q.K .. Q.N) of Long_Float;

or unconstrained array types:

  .. code-block:: ada

      type Array_Type is array (Positive range <>) of Long_Float;

The quality of the generated code decreases when the dynamic aspect of the
array type increases, the worst code being generated for unconstrained array
types.  This is so because, the less information the compiler has about the
bounds of the array, the more fallback code it needs to generate in order to
fix things up at run time.

It is possible to specify that a given loop should be subject to vectorization
preferably to other optimizations by means of pragma ``Loop_Optimize``:

  .. code-block:: ada

      pragma Loop_Optimize (Vector);

placed immediately within the loop will convey the appropriate hint to the
compiler for this loop.

It is also possible to help the compiler generate better vectorized code
for a given loop by asserting that there are no loop-carried dependencies
in the loop.  Consider for example the procedure:

  .. code-block:: ada

      type Arr is array (1 .. 4) of Long_Float;

      procedure Add (X, Y : not null access Arr; R : not null access Arr) is
      begin
        for I in Arr'Range loop
          R(I) := X(I) + Y(I);
        end loop;
      end;

By default, the compiler cannot unconditionally vectorize the loop because
assigning to a component of the array designated by R in one iteration could
change the value read from the components of the array designated by X or Y
in a later iteration.  As a result, the compiler will generate two versions
of the loop in the object code, one vectorized and the other not vectorized,
as well as a test to select the appropriate version at run time.  This can
be overcome by another hint:

  .. code-block:: ada

     pragma Loop_Optimize (Ivdep);

placed immediately within the loop will tell the compiler that it can safely
omit the non-vectorized version of the loop as well as the run-time test.


.. _Other_Optimization_Switches:

Other Optimization Switches
^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. index:: Optimization Switches

Since GNAT uses the ``gcc`` back end, all the specialized
``gcc`` optimization switches are potentially usable. These switches
have not been extensively tested with GNAT but can generally be expected
to work. Examples of switches in this category are :switch:`-funroll-loops`
and the various target-specific :switch:`-m` options (in particular, it has
been observed that :switch:`-march=xxx` can significantly improve performance
on appropriate machines). For full details of these switches, see
the *Submodel Options* section in the *Hardware Models and Configurations*
chapter of :title:`Using the GNU Compiler Collection (GCC)`.


.. _Optimization_and_Strict_Aliasing:

Optimization and Strict Aliasing
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. index:: Aliasing
.. index:: Strict Aliasing
.. index:: No_Strict_Aliasing

The strong typing capabilities of Ada allow an optimizer to generate
efficient code in situations where other languages would be forced to
make worst case assumptions preventing such optimizations. Consider
the following example:

  .. code-block:: ada

     procedure R is
        type Int1 is new Integer;
        type Int2 is new Integer;
        type Int1A is access Int1;
        type Int2A is access Int2;
        Int1V : Int1A;
        Int2V : Int2A;
        ...

     begin
        ...
        for J in Data'Range loop
           if Data (J) = Int1V.all then
              Int2V.all := Int2V.all + 1;
           end if;
        end loop;
        ...
     end R;

In this example, since the variable ``Int1V`` can only access objects
of type ``Int1``, and ``Int2V`` can only access objects of type
``Int2``, there is no possibility that the assignment to
``Int2V.all`` affects the value of ``Int1V.all``. This means that
the compiler optimizer can "know" that the value ``Int1V.all`` is constant
for all iterations of the loop and avoid the extra memory reference
required to dereference it each time through the loop.

This kind of optimization, called strict aliasing analysis, is
triggered by specifying an optimization level of :switch:`-O2` or
higher or :switch:`-Os` and allows GNAT to generate more efficient code
when access values are involved.

However, although this optimization is always correct in terms of
the formal semantics of the Ada Reference Manual, difficulties can
arise if features like ``Unchecked_Conversion`` are used to break
the typing system. Consider the following complete program example:

  .. code-block:: ada

      package p1 is
         type int1 is new integer;
         type int2 is new integer;
         type a1 is access int1;
         type a2 is access int2;
      end p1;

      with p1; use p1;
      package p2 is
         function to_a2 (Input : a1) return a2;
      end p2;

      with Unchecked_Conversion;
      package body p2 is
         function to_a2 (Input : a1) return a2 is
            function to_a2u is
              new Unchecked_Conversion (a1, a2);
         begin
            return to_a2u (Input);
         end to_a2;
      end p2;

      with p2; use p2;
      with p1; use p1;
      with Text_IO; use Text_IO;
      procedure m is
         v1 : a1 := new int1;
         v2 : a2 := to_a2 (v1);
      begin
         v1.all := 1;
         v2.all := 0;
         put_line (int1'image (v1.all));
      end;

This program prints out 0 in :switch:`-O0` or :switch:`-O1`
mode, but it prints out 1 in :switch:`-O2` mode. That's
because in strict aliasing mode, the compiler can and
does assume that the assignment to ``v2.all`` could not
affect the value of ``v1.all``, since different types
are involved.

This behavior is not a case of non-conformance with the standard, since
the Ada RM specifies that an unchecked conversion where the resulting
bit pattern is not a correct value of the target type can result in an
abnormal value and attempting to reference an abnormal value makes the
execution of a program erroneous.  That's the case here since the result
does not point to an object of type ``int2``.  This means that the
effect is entirely unpredictable.

However, although that explanation may satisfy a language
lawyer, in practice an applications programmer expects an
unchecked conversion involving pointers to create true
aliases and the behavior of printing 1 seems plain wrong.
In this case, the strict aliasing optimization is unwelcome.

Indeed the compiler recognizes this possibility, and the
unchecked conversion generates a warning:

  ::

     p2.adb:5:07: warning: possible aliasing problem with type "a2"
     p2.adb:5:07: warning: use -fno-strict-aliasing switch for references
     p2.adb:5:07: warning:  or use "pragma No_Strict_Aliasing (a2);"

Unfortunately the problem is recognized when compiling the body of
package ``p2``, but the actual "bad" code is generated while
compiling the body of ``m`` and this latter compilation does not see
the suspicious ``Unchecked_Conversion``.

As implied by the warning message, there are approaches you can use to
avoid the unwanted strict aliasing optimization in a case like this.

One possibility is to simply avoid the use of :switch:`-O2`, but
that is a bit drastic, since it throws away a number of useful
optimizations that do not involve strict aliasing assumptions.

A less drastic approach is to compile the program using the
option :switch:`-fno-strict-aliasing`. Actually it is only the
unit containing the dereferencing of the suspicious pointer
that needs to be compiled. So in this case, if we compile
unit ``m`` with this switch, then we get the expected
value of zero printed. Analyzing which units might need
the switch can be painful, so a more reasonable approach
is to compile the entire program with options :switch:`-O2`
and :switch:`-fno-strict-aliasing`. If the performance is
satisfactory with this combination of options, then the
advantage is that the entire issue of possible "wrong"
optimization due to strict aliasing is avoided.

To avoid the use of compiler switches, the configuration
pragma ``No_Strict_Aliasing`` with no parameters may be
used to specify that for all access types, the strict
aliasing optimization should be suppressed.

However, these approaches are still overkill, in that they causes
all manipulations of all access values to be deoptimized. A more
refined approach is to concentrate attention on the specific
access type identified as problematic.

First, if a careful analysis of uses of the pointer shows
that there are no possible problematic references, then
the warning can be suppressed by bracketing the
instantiation of ``Unchecked_Conversion`` to turn
the warning off:

  .. code-block:: ada

     pragma Warnings (Off);
     function to_a2u is
       new Unchecked_Conversion (a1, a2);
     pragma Warnings (On);

Of course that approach is not appropriate for this particular
example, since indeed there is a problematic reference. In this
case we can take one of two other approaches.

The first possibility is to move the instantiation of unchecked
conversion to the unit in which the type is declared. In
this example, we would move the instantiation of
``Unchecked_Conversion`` from the body of package
``p2`` to the spec of package ``p1``. Now the
warning disappears. That's because any use of the
access type knows there is a suspicious unchecked
conversion, and the strict aliasing optimization
is automatically suppressed for the type.

If it is not practical to move the unchecked conversion to the same unit
in which the destination access type is declared (perhaps because the
source type is not visible in that unit), you may use pragma
``No_Strict_Aliasing`` for the type. This pragma must occur in the
same declarative sequence as the declaration of the access type:

  .. code-block:: ada

     type a2 is access int2;
     pragma No_Strict_Aliasing (a2);

Here again, the compiler now knows that the strict aliasing optimization
should be suppressed for any reference to type ``a2`` and the
expected behavior is obtained.

Finally, note that although the compiler can generate warnings for
simple cases of unchecked conversions, there are tricker and more
indirect ways of creating type incorrect aliases which the compiler
cannot detect. Examples are the use of address overlays and unchecked
conversions involving composite types containing access types as
components. In such cases, no warnings are generated, but there can
still be aliasing problems. One safe coding practice is to forbid the
use of address clauses for type overlaying, and to allow unchecked
conversion only for primitive types. This is not really a significant
restriction since any possible desired effect can be achieved by
unchecked conversion of access values.

The aliasing analysis done in strict aliasing mode can certainly
have significant benefits. We have seen cases of large scale
application code where the time is increased by up to 5% by turning
this optimization off. If you have code that includes significant
usage of unchecked conversion, you might want to just stick with
:switch:`-O1` and avoid the entire issue. If you get adequate
performance at this level of optimization level, that's probably
the safest approach. If tests show that you really need higher
levels of optimization, then you can experiment with :switch:`-O2`
and :switch:`-O2 -fno-strict-aliasing` to see how much effect this
has on size and speed of the code. If you really need to use
:switch:`-O2` with strict aliasing in effect, then you should
review any uses of unchecked conversion of access types,
particularly if you are getting the warnings described above.


.. _Aliased_Variables_and_Optimization:

Aliased Variables and Optimization
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. index:: Aliasing

There are scenarios in which programs may
use low level techniques to modify variables
that otherwise might be considered to be unassigned. For example,
a variable can be passed to a procedure by reference, which takes
the address of the parameter and uses the address to modify the
variable's value, even though it is passed as an IN parameter.
Consider the following example:

  .. code-block:: ada

     procedure P is
        Max_Length : constant Natural := 16;
        type Char_Ptr is access all Character;

        procedure Get_String(Buffer: Char_Ptr; Size : Integer);
        pragma Import (C, Get_String, "get_string");

        Name : aliased String (1 .. Max_Length) := (others => ' ');
        Temp : Char_Ptr;

        function Addr (S : String) return Char_Ptr is
           function To_Char_Ptr is
             new Ada.Unchecked_Conversion (System.Address, Char_Ptr);
        begin
           return To_Char_Ptr (S (S'First)'Address);
        end;

     begin
        Temp := Addr (Name);
        Get_String (Temp, Max_Length);
     end;

where Get_String is a C function that uses the address in Temp to
modify the variable ``Name``. This code is dubious, and arguably
erroneous, and the compiler would be entitled to assume that
``Name`` is never modified, and generate code accordingly.

However, in practice, this would cause some existing code that
seems to work with no optimization to start failing at high
levels of optimzization.

What the compiler does for such cases is to assume that marking
a variable as aliased indicates that some "funny business" may
be going on. The optimizer recognizes the aliased keyword and
inhibits optimizations that assume the value cannot be assigned.
This means that the above example will in fact "work" reliably,
that is, it will produce the expected results.


.. _Atomic_Variables_and_Optimization:

Atomic Variables and Optimization
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. index:: Atomic

There are two considerations with regard to performance when
atomic variables are used.

First, the RM only guarantees that access to atomic variables
be atomic, it has nothing to say about how this is achieved,
though there is a strong implication that this should not be
achieved by explicit locking code. Indeed GNAT will never
generate any locking code for atomic variable access (it will
simply reject any attempt to make a variable or type atomic
if the atomic access cannot be achieved without such locking code).

That being said, it is important to understand that you cannot
assume that the entire variable will always be accessed. Consider
this example:

  .. code-block:: ada

     type R is record
        A,B,C,D : Character;
     end record;
     for R'Size use 32;
     for R'Alignment use 4;

     RV : R;
     pragma Atomic (RV);
     X : Character;
     ...
     X := RV.B;

You cannot assume that the reference to ``RV.B``
will read the entire 32-bit
variable with a single load instruction. It is perfectly legitimate if
the hardware allows it to do a byte read of just the B field. This read
is still atomic, which is all the RM requires. GNAT can and does take
advantage of this, depending on the architecture and optimization level.
Any assumption to the contrary is non-portable and risky. Even if you
examine the assembly language and see a full 32-bit load, this might
change in a future version of the compiler.

If your application requires that all accesses to ``RV`` in this
example be full 32-bit loads, you need to make a copy for the access
as in:

  .. code-block:: ada

     declare
        RV_Copy : constant R := RV;
     begin
        X := RV_Copy.B;
     end;

Now the reference to RV must read the whole variable.
Actually one can imagine some compiler which figures
out that the whole copy is not required (because only
the B field is actually accessed), but GNAT
certainly won't do that, and we don't know of any
compiler that would not handle this right, and the
above code will in practice work portably across
all architectures (that permit the Atomic declaration).

The second issue with atomic variables has to do with
the possible requirement of generating synchronization
code. For more details on this, consult the sections on
the pragmas Enable/Disable_Atomic_Synchronization in the
GNAT Reference Manual. If performance is critical, and
such synchronization code is not required, it may be
useful to disable it.


.. _Passive_Task_Optimization:

Passive Task Optimization
^^^^^^^^^^^^^^^^^^^^^^^^^

.. index:: Passive Task

A passive task is one which is sufficiently simple that
in theory a compiler could recognize it an implement it
efficiently without creating a new thread. The original design
of Ada 83 had in mind this kind of passive task optimization, but
only a few Ada 83 compilers attempted it. The problem was that
it was difficult to determine the exact conditions under which
the optimization was possible. The result is a very fragile
optimization where a very minor change in the program can
suddenly silently make a task non-optimizable.

With the revisiting of this issue in Ada 95, there was general
agreement that this approach was fundamentally flawed, and the
notion of protected types was introduced. When using protected
types, the restrictions are well defined, and you KNOW that the
operations will be optimized, and furthermore this optimized
performance is fully portable.

Although it would theoretically be possible for GNAT to attempt to
do this optimization, but it really doesn't make sense in the
context of Ada 95, and none of the Ada 95 compilers implement
this optimization as far as we know. In particular GNAT never
attempts to perform this optimization.

In any new Ada 95 code that is written, you should always
use protected types in place of tasks that might be able to
be optimized in this manner.
Of course this does not help if you have legacy Ada 83 code
that depends on this optimization, but it is unusual to encounter
a case where the performance gains from this optimization
are significant.

Your program should work correctly without this optimization. If
you have performance problems, then the most practical
approach is to figure out exactly where these performance problems
arise, and update those particular tasks to be protected types. Note
that typically clients of the tasks who call entries, will not have
to be modified, only the task definition itself.


.. _Text_IO_Suggestions:

``Text_IO`` Suggestions
-----------------------

.. index:: Text_IO and performance

The ``Ada.Text_IO`` package has fairly high overheads due in part to
the requirement of maintaining page and line counts. If performance
is critical, a recommendation is to use ``Stream_IO`` instead of
``Text_IO`` for volume output, since this package has less overhead.

If ``Text_IO`` must be used, note that by default output to the standard
output and standard error files is unbuffered (this provides better
behavior when output statements are used for debugging, or if the
progress of a program is observed by tracking the output, e.g. by
using the Unix *tail -f* command to watch redirected output.

If you are generating large volumes of output with ``Text_IO`` and
performance is an important factor, use a designated file instead
of the standard output file, or change the standard output file to
be buffered using ``Interfaces.C_Streams.setvbuf``.


.. _Reducing_Size_of_Executables_with_Unused_Subprogram/Data_Elimination:

Reducing Size of Executables with Unused Subprogram/Data Elimination
--------------------------------------------------------------------

.. index:: Uunused subprogram/data elimination

This section describes how you can eliminate unused subprograms and data from
your executable just by setting options at compilation time.

.. _About_unused_subprogram/data_elimination:

About unused subprogram/data elimination
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

By default, an executable contains all code and data of its composing objects
(directly linked or coming from statically linked libraries), even data or code
never used by this executable.

This feature will allow you to eliminate such unused code from your
executable, making it smaller (in disk and in memory).

This functionality is available on all Linux platforms except for the IA-64
architecture and on all cross platforms using the ELF binary file format.
In both cases GNU binutils version 2.16 or later are required to enable it.

.. _Compilation_options:

Compilation options
^^^^^^^^^^^^^^^^^^^

The operation of eliminating the unused code and data from the final executable
is directly performed by the linker.

.. index:: -ffunction-sections (gcc)
.. index:: -fdata-sections (gcc)

In order to do this, it has to work with objects compiled with the
following options:
:switch:`-ffunction-sections` :switch:`-fdata-sections`.

These options are usable with C and Ada files.
They will place respectively each
function or data in a separate section in the resulting object file.

Once the objects and static libraries are created with these options, the
linker can perform the dead code elimination. You can do this by setting
the :switch:`-Wl,--gc-sections` option to gcc command or in the
:switch:`-largs` section of ``gnatmake``. This will perform a
garbage collection of code and data never referenced.

If the linker performs a partial link (:switch:`-r` linker option), then you
will need to provide the entry point using the :switch:`-e` / :switch:`--entry`
linker option.

Note that objects compiled without the :switch:`-ffunction-sections` and
:switch:`-fdata-sections` options can still be linked with the executable.
However, no dead code elimination will be performed on those objects (they will
be linked as is).

The GNAT static library is now compiled with -ffunction-sections and
-fdata-sections on some platforms. This allows you to eliminate the unused code
and data of the GNAT library from your executable.


.. _Example_of_unused_subprogram/data_elimination:

Example of unused subprogram/data elimination
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Here is a simple example:

  .. code-block:: ada

     with Aux;

     procedure Test is
     begin
        Aux.Used (10);
     end Test;

     package Aux is
        Used_Data   : Integer;
        Unused_Data : Integer;

        procedure Used   (Data : Integer);
        procedure Unused (Data : Integer);
     end Aux;

     package body Aux is
        procedure Used (Data : Integer) is
        begin
           Used_Data := Data;
        end Used;

        procedure Unused (Data : Integer) is
        begin
           Unused_Data := Data;
        end Unused;
     end Aux;

``Unused`` and ``Unused_Data`` are never referenced in this code
excerpt, and hence they may be safely removed from the final executable.

  ::

     $ gnatmake test

     $ nm test | grep used
     020015f0 T aux__unused
     02005d88 B aux__unused_data
     020015cc T aux__used
     02005d84 B aux__used_data

     $ gnatmake test -cargs -fdata-sections -ffunction-sections \\
          -largs -Wl,--gc-sections

     $ nm test | grep used
     02005350 T aux__used
     0201ffe0 B aux__used_data

It can be observed that the procedure ``Unused`` and the object
``Unused_Data`` are removed by the linker when using the
appropriate options.

.. only:: PRO or GPL

  .. _Reducing_Size_of_Ada_Executables_with_gnatelim:

  Reducing Size of Ada Executables with ``gnatelim``
  --------------------------------------------------

  .. index:: gnatelim

  This section describes ``gnatelim``, a tool which detects unused
  subprograms and helps the compiler to create a smaller executable for your
  program.

  ``gnatelim`` is a project-aware tool.
  (See :ref:`Using_Project_Files_with_GNAT_Tools` for a description of
  the project-related switches but note that ``gnatelim`` does not support
  the :samp:`-U`, :samp:`-U {main_unit}`, :samp:`--subdirs={dir}`, or
  :samp:`--no_objects_dir` switches.)
  The project file package that can specify
  ``gnatelim`` switches is named ``Eliminate``.

  .. _About_gnatelim:

  About ``gnatelim``
  ^^^^^^^^^^^^^^^^^^

  When a program shares a set of Ada
  packages with other programs, it may happen that this program uses
  only a fraction of the subprograms defined in these packages. The code
  created for these unused subprograms increases the size of the executable.

  ``gnatelim`` tracks unused subprograms in an Ada program and
  outputs a list of GNAT-specific pragmas ``Eliminate`` marking all the
  subprograms that are declared but never called. By placing the list of
  ``Eliminate`` pragmas in the GNAT configuration file :file:`gnat.adc` and
  recompiling your program, you may decrease the size of its executable,
  because the compiler will not generate the code for 'eliminated' subprograms.
  See ``Pragma_Eliminate`` in the :title:`GNAT_Reference_Manual` for more
  information about this pragma.

  ``gnatelim`` needs as its input data the name of the main subprogram.

  If a set of source files is specified as ``gnatelim`` arguments, it
  treats these files as a complete set of sources making up a program to
  analyse, and analyses only these sources.

  After a full successful build of the main subprogram ``gnatelim`` can be
  called without  specifying sources to analyse, in this case it computes
  the source closure of the main unit from the :file:`ALI` files.

  If the set of sources to be processed by ``gnatelim`` contains sources with
  preprocessing directives
  then the needed options should be provided to run preprocessor as a part of
  the ``gnatelim`` call, and the generated set of pragmas ``Eliminate``
  will correspond to preprocessed sources.

  The following command will create the set of :file:`ALI` files needed for
  ``gnatelim``:

    ::

       $ gnatmake -c Main_Prog

  Note that ``gnatelim`` does not need object files.


  .. _Running_gnatelim:

  Running ``gnatelim``
  ^^^^^^^^^^^^^^^^^^^^

  ``gnatelim`` has the following command-line interface:


    ::

        $ gnatelim [switches] -main=`main_unit_name {filename} [-cargs gcc_switches]

  ``main_unit_name`` should be a name of a source file that contains the main
  subprogram of a program (partition).

  Each ``filename`` is the name (including the extension) of a source
  file to process. 'Wildcards' are allowed, and
  the file name may contain path information.

  ``gcc_switches`` is a list of switches for
  ``gcc``. They will be passed on to all compiler invocations made by
  ``gnatelim`` to generate the ASIS trees. Here you can provide
  :switch:`-I` switches to form the source search path,
  use the :switch:`-gnatec` switch to set the configuration file,
  use the :switch:`-gnat05` switch if sources should be compiled in
  Ada 2005 mode etc.

  ``gnatelim`` has the following switches:


  .. index:: --version (gnatelim)

  :samp:`--version`
    Display Copyright and version, then exit disregarding all other options.


  .. index:: --help (gnatelim)

  :samp:`--help`
    Display usage, then exit disregarding all other options.


  .. index:: -P (gnatelim)

  :samp:`-P {file}`
    Indicates the name of the project file that describes the set of sources
    to be processed.


  .. index:: -X (gnatelim)

  :samp:`-X{name}={value}`
    Indicates that external variable ``name`` in the argument project
    has the value ``value``. Has no effect if no project is specified as
    tool argument.


  .. index:: --RTS (gnatelim)

  :samp:`--RTS={rts-path}`
    Specifies the default location of the runtime library. Same meaning as the
    equivalent ``gnatmake`` flag (:ref:`Switches_for_gnatmake`).


  .. index:: -files (gnatelim)

  :samp:`-files={filename}`
    Take the argument source files from the specified file. This file should be an
    ordinary text file containing file names separated by spaces or
    line breaks. You can use this switch more than once in the same call to
    ``gnatelim``. You also can combine this switch with
    an explicit list of files.


  .. index:: -log (gnatelim)

  :samp:`-log`
    Duplicate all the output sent to :file:`stderr` into a log file. The log file
    is named :file:`gnatelim.log` and is located in the current directory.

    .. index:: --no-elim-dispatch (gnatelim)

  :samp:`--no-elim-dispatch`
    Do not generate pragmas for dispatching operations.


  .. index:: --ignore (gnatelim)

  :samp:`--ignore={filename}`
    Do not generate pragmas for subprograms declared in the sources
    listed in a specified file

  .. index:: -o (gnatelim)


  :samp:`-o={report_file}`
    Put ``gnatelim`` output into a specified file. If this file already exists,
    it is overridden. If this switch is not used, ``gnatelim`` outputs its results
    into :file:`stderr`


  .. index:: -j (gnatelim)

  :samp:`-j{n}`
    Use ``n`` processes to carry out the tree creations (internal representations
    of the argument sources). On a multiprocessor machine this speeds up processing
    of big sets of argument sources. If ``n`` is 0, then the maximum number of
    parallel tree creations is the number of core processors on the platform.


  .. index:: -q (gnatelim)

  :samp:`-q`
    Quiet mode: by default ``gnatelim`` outputs to the standard error
    stream the number of program units left to be processed. This option turns
    this trace off.

  .. index:: -t (gnatelim)


  :samp:`-t`
    Print out execution time.


  .. index:: -v (gnatelim)

  :samp:`-v`
    Verbose mode: ``gnatelim`` version information is printed as Ada
    comments to the standard output stream. Also, in addition to the number of
    program units left ``gnatelim`` will output the name of the current unit
    being processed.


  .. index:: -wq (gnatelim)

  :samp:`-wq`
    Quiet warning mode - some warnings are suppressed. In particular warnings that
    indicate that the analysed set of sources is incomplete to make up a
    partition and that some subprogram bodies are missing are not generated.



  .. _Processing_Precompiled_Libraries:

  Processing Precompiled Libraries
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  If some program uses a precompiled Ada library, it can be processed by
  ``gnatelim`` in a usual way. ``gnatelim`` will newer generate an
  Eliminate pragma for a subprogram if the body of this subprogram has not
  been analysed, this is a typical case for subprograms from precompiled
  libraries. Switch :switch:`-wq` may be used to suppress
  warnings about missing source files and non-analyzed subprogram bodies
  that can be generated when processing precompiled Ada libraries.


  .. _Correcting_the_List_of_Eliminate_Pragmas:

  Correcting the List of Eliminate Pragmas
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  In some rare cases ``gnatelim`` may try to eliminate
  subprograms that are actually called in the program. In this case, the
  compiler will generate an error message of the form:

    ::

        main.adb:4:08: cannot reference subprogram "P" eliminated at elim.out:5

  You will need to manually remove the wrong ``Eliminate`` pragmas from
  the configuration file indicated in the error message. You should recompile
  your program from scratch after that, because you need a consistent
  configuration file(s) during the entire compilation.


  .. _Making_Your_Executables_Smaller:

  Making Your Executables Smaller
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  In order to get a smaller executable for your program you now have to
  recompile the program completely with the configuration file containing
  pragmas Eliminate generated by gnatelim. If these pragmas are placed in
  :file:`gnat.adc` file located in your current directory, just do:

    ::

       $ gnatmake -f main_prog

  (Use the :switch:`-f` option for ``gnatmake`` to
  recompile everything
  with the set of pragmas ``Eliminate`` that you have obtained with
  ``gnatelim``).

  Be aware that the set of ``Eliminate`` pragmas is specific to each
  program. It is not recommended to merge sets of ``Eliminate``
  pragmas created for different programs in one configuration file.


  .. _Summary_of_the_gnatelim_Usage_Cycle:

  Summary of the ``gnatelim`` Usage Cycle
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  Here is a quick summary of the steps to be taken in order to reduce
  the size of your executables with ``gnatelim``. You may use
  other GNAT options to control the optimization level,
  to produce the debugging information, to set search path, etc.

  * Create a complete set of :file:`ALI` files (if the program has not been
    built already)

    ::

        $ gnatmake -c main_prog

  * Generate a list of ``Eliminate`` pragmas in default configuration file
    :file:`gnat.adc` in the current directory

    ::

        $ gnatelim main_prog >[>] gnat.adc

  * Recompile the application

    ::

        $ gnatmake -f main_prog



.. index:: Overflow checks
.. index:: Checks (overflow)

.. _Overflow_Check_Handling_in_GNAT:

Overflow Check Handling in GNAT
===============================

This section explains how to control the handling of overflow checks.

.. _Background:

Background
----------

Overflow checks are checks that the compiler may make to ensure
that intermediate results are not out of range. For example:

  .. code-block:: ada

     A : Integer;
     ...
     A := A + 1;

If ``A`` has the value ``Integer'Last``, then the addition may cause
overflow since the result is out of range of the type ``Integer``.
In this case ``Constraint_Error`` will be raised if checks are
enabled.

A trickier situation arises in examples like the following:

  .. code-block:: ada

     A, C : Integer;
     ...
     A := (A + 1) + C;

where ``A`` is ``Integer'Last`` and ``C`` is ``-1``.
Now the final result of the expression on the right hand side is
``Integer'Last`` which is in range, but the question arises whether the
intermediate addition of ``(A + 1)`` raises an overflow error.

The (perhaps surprising) answer is that the Ada language
definition does not answer this question. Instead it leaves
it up to the implementation to do one of two things if overflow
checks are enabled.

* raise an exception (``Constraint_Error``), or

* yield the correct mathematical result which is then used in
  subsequent operations.

If the compiler chooses the first approach, then the assignment of this
example will indeed raise ``Constraint_Error`` if overflow checking is
enabled, or result in erroneous execution if overflow checks are suppressed.

But if the compiler
chooses the second approach, then it can perform both additions yielding
the correct mathematical result, which is in range, so no exception
will be raised, and the right result is obtained, regardless of whether
overflow checks are suppressed.

Note that in the first example an
exception will be raised in either case, since if the compiler
gives the correct mathematical result for the addition, it will
be out of range of the target type of the assignment, and thus
fails the range check.

This lack of specified behavior in the handling of overflow for
intermediate results is a source of non-portability, and can thus
be problematic when programs are ported. Most typically this arises
in a situation where the original compiler did not raise an exception,
and then the application is moved to a compiler where the check is
performed on the intermediate result and an unexpected exception is
raised.

Furthermore, when using Ada 2012's preconditions and other
assertion forms, another issue arises. Consider:

  .. code-block:: ada

       procedure P (A, B : Integer) with
         Pre => A + B <= Integer'Last;

One often wants to regard arithmetic in a context like this from
a mathematical point of view. So for example, if the two actual parameters
for a call to ``P`` are both ``Integer'Last``, then
the precondition should be regarded as False. If we are executing
in a mode with run-time checks enabled for preconditions, then we would
like this precondition to fail, rather than raising an exception
because of the intermediate overflow.

However, the language definition leaves the specification of
whether the above condition fails (raising ``Assert_Error``) or
causes an intermediate overflow (raising ``Constraint_Error``)
up to the implementation.

The situation is worse in a case such as the following:

  .. code-block:: ada

       procedure Q (A, B, C : Integer) with
         Pre => A + B + C <= Integer'Last;

Consider the call

  .. code-block:: ada

       Q (A => Integer'Last, B => 1, C => -1);

From a mathematical point of view the precondition
is True, but at run time we may (but are not guaranteed to) get an
exception raised because of the intermediate overflow (and we really
would prefer this precondition to be considered True at run time).


.. _Management_of_Overflows_in_GNAT:

Management of Overflows in GNAT
-------------------------------

To deal with the portability issue, and with the problem of
mathematical versus run-time interpretation of the expressions in
assertions, GNAT provides comprehensive control over the handling
of intermediate overflow. GNAT can operate in three modes, and
furthemore, permits separate selection of operating modes for
the expressions within assertions (here the term 'assertions'
is used in the technical sense, which includes preconditions and so forth)
and for expressions appearing outside assertions.

The three modes are:

* *Use base type for intermediate operations* (``STRICT``)

  In this mode, all intermediate results for predefined arithmetic
  operators are computed using the base type, and the result must
  be in range of the base type. If this is not the
  case then either an exception is raised (if overflow checks are
  enabled) or the execution is erroneous (if overflow checks are suppressed).
  This is the normal default mode.

* *Most intermediate overflows avoided* (``MINIMIZED``)

  In this mode, the compiler attempts to avoid intermediate overflows by
  using a larger integer type, typically ``Long_Long_Integer``,
  as the type in which arithmetic is
  performed for predefined arithmetic operators. This may be slightly more
  expensive at
  run time (compared to suppressing intermediate overflow checks), though
  the cost is negligible on modern 64-bit machines. For the examples given
  earlier, no intermediate overflows would have resulted in exceptions,
  since the intermediate results are all in the range of
  ``Long_Long_Integer`` (typically 64-bits on nearly all implementations
  of GNAT). In addition, if checks are enabled, this reduces the number of
  checks that must be made, so this choice may actually result in an
  improvement in space and time behavior.

  However, there are cases where ``Long_Long_Integer`` is not large
  enough, consider the following example:

    .. code-block:: ada

           procedure R (A, B, C, D : Integer) with
             Pre => (A**2 * B**2) / (C**2 * D**2) <= 10;

  where ``A`` = ``B`` = ``C`` = ``D`` = ``Integer'Last``.
  Now the intermediate results are
  out of the range of ``Long_Long_Integer`` even though the final result
  is in range and the precondition is True (from a mathematical point
  of view). In such a case, operating in this mode, an overflow occurs
  for the intermediate computation (which is why this mode
  says *most* intermediate overflows are avoided). In this case,
  an exception is raised if overflow checks are enabled, and the
  execution is erroneous if overflow checks are suppressed.

* *All intermediate overflows avoided* (``ELIMINATED``)

  In this mode, the compiler  avoids all intermediate overflows
  by using arbitrary precision arithmetic as required. In this
  mode, the above example with ``A**2 * B**2`` would
  not cause intermediate overflow, because the intermediate result
  would be evaluated using sufficient precision, and the result
  of evaluating the precondition would be True.

  This mode has the advantage of avoiding any intermediate
  overflows, but at the expense of significant run-time overhead,
  including the use of a library (included automatically in this
  mode) for multiple-precision arithmetic.

  This mode provides cleaner semantics for assertions, since now
  the run-time behavior emulates true arithmetic behavior for the
  predefined arithmetic operators, meaning that there is never a
  conflict between the mathematical view of the assertion, and its
  run-time behavior.

  Note that in this mode, the behavior is unaffected by whether or
  not overflow checks are suppressed, since overflow does not occur.
  It is possible for gigantic intermediate expressions to raise
  ``Storage_Error`` as a result of attempting to compute the
  results of such expressions (e.g. ``Integer'Last ** Integer'Last``)
  but overflow is impossible.


Note that these modes apply only to the evaluation of predefined
arithmetic, membership, and comparison operators for signed integer
arithmetic.

For fixed-point arithmetic, checks can be suppressed. But if checks
are enabled
then fixed-point values are always checked for overflow against the
base type for intermediate expressions (that is such checks always
operate in the equivalent of ``STRICT`` mode).

For floating-point, on nearly all architectures, ``Machine_Overflows``
is False, and IEEE infinities are generated, so overflow exceptions
are never raised. If you want to avoid infinities, and check that
final results of expressions are in range, then you can declare a
constrained floating-point type, and range checks will be carried
out in the normal manner (with infinite values always failing all
range checks).


.. _Specifying_the_Desired_Mode:

Specifying the Desired Mode
---------------------------

.. index:: pragma Overflow_Mode

The desired mode of for handling intermediate overflow can be specified using
either the ``Overflow_Mode`` pragma or an equivalent compiler switch.
The pragma has the form

  .. code-block:: ada

      pragma Overflow_Mode ([General =>] MODE [, [Assertions =>] MODE]);

where ``MODE`` is one of

* ``STRICT``:  intermediate overflows checked (using base type)
* ``MINIMIZED``: minimize intermediate overflows
* ``ELIMINATED``: eliminate intermediate overflows

The case is ignored, so ``MINIMIZED``, ``Minimized`` and
``minimized`` all have the same effect.

If only the ``General`` parameter is present, then the given ``MODE`` applies
to expressions both within and outside assertions. If both arguments
are present, then ``General`` applies to expressions outside assertions,
and ``Assertions`` applies to expressions within assertions. For example:

  .. code-block:: ada

     pragma Overflow_Mode
       (General => Minimized, Assertions => Eliminated);

specifies that general expressions outside assertions be evaluated
in 'minimize intermediate overflows' mode, and expressions within
assertions be evaluated in 'eliminate intermediate overflows' mode.
This is often a reasonable choice, avoiding excessive overhead
outside assertions, but assuring a high degree of portability
when importing code from another compiler, while incurring
the extra overhead for assertion expressions to ensure that
the behavior at run time matches the expected mathematical
behavior.

The ``Overflow_Mode`` pragma has the same scoping and placement
rules as pragma ``Suppress``, so it can occur either as a
configuration pragma, specifying a default for the whole
program, or in a declarative scope, where it applies to the
remaining declarations and statements in that scope.

Note that pragma ``Overflow_Mode`` does not affect whether
overflow checks are enabled or suppressed. It only controls the
method used to compute intermediate values. To control whether
overflow checking is enabled or suppressed, use pragma ``Suppress``
or ``Unsuppress`` in the usual manner.


.. index:: -gnato? (gcc)
.. index:: -gnato?? (gcc)

Additionally, a compiler switch :switch:`-gnato?` or :switch:`-gnato??`
can be used to control the checking mode default (which can be subsequently
overridden using pragmas).

Here ``?`` is one of the digits ``1`` through ``3``:

  ====== ======================================================
  ``1``  use base type for intermediate operations (``STRICT``)
  ``2``  minimize intermediate overflows (``MINIMIZED``)
  ``3``  eliminate intermediate overflows (``ELIMINATED``)
  ====== ======================================================

As with the pragma, if only one digit appears then it applies to all
cases; if two digits are given, then the first applies outside
assertions, and the second within assertions. Thus the equivalent
of the example pragma above would be
:switch:`-gnato23`.

If no digits follow the :switch:`-gnato`, then it is equivalent to
:switch:`-gnato11`,
causing all intermediate operations to be computed using the base
type (``STRICT`` mode).


.. _Default_Settings:

Default Settings
----------------

The default mode for overflow checks is

  ::

      General => Strict

which causes all computations both inside and outside assertions to use
the base type.

This retains compatibility with previous versions of
GNAT which suppressed overflow checks by default and always
used the base type for computation of intermediate results.

.. Sphinx allows no emphasis within :index: role. As a workaround we
   point the index to "switch" and use emphasis for "-gnato".

The :index:`switch <-gnato (gcc)>` :switch:`-gnato` (with no digits following)
is equivalent to

  ::

      General => Strict

which causes overflow checking of all intermediate overflows
both inside and outside assertions against the base type.

The pragma ``Suppress (Overflow_Check)`` disables overflow
checking, but it has no effect on the method used for computing
intermediate results.

The pragma ``Unsuppress (Overflow_Check)`` enables overflow
checking, but it has no effect on the method used for computing
intermediate results.


.. _Implementation_Notes:

Implementation Notes
--------------------

In practice on typical 64-bit machines, the ``MINIMIZED`` mode is
reasonably efficient, and can be generally used. It also helps
to ensure compatibility with code imported from some other
compiler to GNAT.

Setting all intermediate overflows checking (``CHECKED`` mode)
makes sense if you want to
make sure that your code is compatible with any other possible
Ada implementation. This may be useful in ensuring portability
for code that is to be exported to some other compiler than GNAT.

The Ada standard allows the reassociation of expressions at
the same precedence level if no parentheses are present. For
example, ``A+B+C`` parses as though it were ``(A+B)+C``, but
the compiler can reintepret this as ``A+(B+C)``, possibly
introducing or eliminating an overflow exception. The GNAT
compiler never takes advantage of this freedom, and the
expression ``A+B+C`` will be evaluated as ``(A+B)+C``.
If you need the other order, you can write the parentheses
explicitly ``A+(B+C)`` and GNAT will respect this order.

The use of ``ELIMINATED`` mode will cause the compiler to
automatically include an appropriate arbitrary precision
integer arithmetic package. The compiler will make calls
to this package, though only in cases where it cannot be
sure that ``Long_Long_Integer`` is sufficient to guard against
intermediate overflows. This package does not use dynamic
alllocation, but it does use the secondary stack, so an
appropriate secondary stack package must be present (this
is always true for standard full Ada, but may require
specific steps for restricted run times such as ZFP).

Although ``ELIMINATED`` mode causes expressions to use arbitrary
precision arithmetic, avoiding overflow, the final result
must be in an appropriate range. This is true even if the
final result is of type ``[Long_[Long_]]Integer'Base``, which
still has the same bounds as its associated constrained
type at run-time.

Currently, the ``ELIMINATED`` mode is only available on target
platforms for which ``Long_Long_Integer`` is 64-bits (nearly all GNAT
platforms).



.. _Performing_Dimensionality_Analysis_in_GNAT:

Performing Dimensionality Analysis in GNAT
==========================================

.. index:: Dimensionality analysis

The GNAT compiler supports dimensionality checking. The user can
specify physical units for objects, and the compiler will verify that uses
of these objects are compatible with their dimensions, in a fashion that is
familiar to engineering practice. The dimensions of algebraic expressions
(including powers with static exponents) are computed from their constituents.

.. index:: Dimension_System aspect
.. index:: Dimension aspect

This feature depends on Ada 2012 aspect specifications, and is available from
version 7.0.1 of GNAT onwards.
The GNAT-specific aspect ``Dimension_System``
allows you to define a system of units; the aspect ``Dimension``
then allows the user to declare dimensioned quantities within a given system.
(These aspects are described in the *Implementation Defined Aspects*
chapter of the *GNAT Reference Manual*).

The major advantage of this model is that it does not require the declaration of
multiple operators for all possible combinations of types: it is only necessary
to use the proper subtypes in object declarations.

.. index:: System.Dim.Mks package (GNAT library)
.. index:: MKS_Type type

The simplest way to impose dimensionality checking on a computation is to make
use of the package ``System.Dim.Mks``,
which is part of the GNAT library. This
package defines a floating-point type ``MKS_Type``,
for which a sequence of
dimension names are specified, together with their conventional abbreviations.
The following should be read together with the full specification of the
package, in file :file:`s-dimmks.ads`.

  .. index:: s-dimmks.ads file

  .. code-block:: ada

     type Mks_Type is new Long_Long_Float
       with
        Dimension_System => (
          (Unit_Name => Meter,    Unit_Symbol => 'm',   Dim_Symbol => 'L'),
          (Unit_Name => Kilogram, Unit_Symbol => "kg",  Dim_Symbol => 'M'),
          (Unit_Name => Second,   Unit_Symbol => 's',   Dim_Symbol => 'T'),
          (Unit_Name => Ampere,   Unit_Symbol => 'A',   Dim_Symbol => 'I'),
          (Unit_Name => Kelvin,   Unit_Symbol => 'K',   Dim_Symbol => "Theta"),
          (Unit_Name => Mole,     Unit_Symbol => "mol", Dim_Symbol => 'N'),
          (Unit_Name => Candela,  Unit_Symbol => "cd",  Dim_Symbol => 'J'));

The package then defines a series of subtypes that correspond to these
conventional units. For example:

  .. code-block:: ada

     subtype Length is Mks_Type
       with
        Dimension => (Symbol => 'm', Meter  => 1, others => 0);

and similarly for ``Mass``, ``Time``, ``Electric_Current``,
``Thermodynamic_Temperature``, ``Amount_Of_Substance``, and
``Luminous_Intensity`` (the standard set of units of the SI system).

The package also defines conventional names for values of each unit, for
example:

  .. code-block:: ada

     m   : constant Length           := 1.0;
     kg  : constant Mass             := 1.0;
     s   : constant Time             := 1.0;
     A   : constant Electric_Current := 1.0;

as well as useful multiples of these units:

  .. code-block:: ada

     cm  : constant Length := 1.0E-02;
     g   : constant Mass   := 1.0E-03;
     min : constant Time   := 60.0;
     day : constant Time   := 60.0 * 24.0 * min;
    ...

Using this package, you can then define a derived unit by
providing the aspect that
specifies its dimensions within the MKS system, as well as the string to
be used for output of a value of that unit:

  .. code-block:: ada

     subtype Acceleration is Mks_Type
       with Dimension => ("m/sec^2",
                          Meter => 1,
                          Second => -2,
                          others => 0);

Here is a complete example of use:

  .. code-block:: ada

     with System.Dim.MKS; use System.Dim.Mks;
     with System.Dim.Mks_IO; use System.Dim.Mks_IO;
     with Text_IO; use Text_IO;
     procedure Free_Fall is
       subtype Acceleration is Mks_Type
         with Dimension => ("m/sec^2", 1, 0, -2, others => 0);
       G : constant acceleration := 9.81 * m / (s ** 2);
       T : Time := 10.0*s;
       Distance : Length;

     begin
       Put ("Gravitational constant: ");
       Put (G, Aft => 2, Exp => 0); Put_Line ("");
       Distance := 0.5 * G * T ** 2;
       Put ("distance travelled in 10 seconds of free fall ");
       Put (Distance, Aft => 2, Exp => 0);
       Put_Line ("");
     end Free_Fall;

Execution of this program yields:

  ::

     Gravitational constant:  9.81 m/sec^2
     distance travelled in 10 seconds of free fall 490.50 m

However, incorrect assignments such as:

  .. code-block:: ada

       Distance := 5.0;
       Distance := 5.0 * kg;

are rejected with the following diagnoses:

 ::

     Distance := 5.0;
        >>> dimensions mismatch in assignment
        >>> left-hand side has dimension [L]
        >>> right-hand side is dimensionless

     Distance := 5.0 * kg:
        >>> dimensions mismatch in assignment
        >>> left-hand side has dimension [L]
        >>> right-hand side has dimension [M]

The dimensions of an expression are properly displayed, even if there is
no explicit subtype for it. If we add to the program:

  .. code-block:: ada

        Put ("Final velocity: ");
        Put (G * T, Aft =>2, Exp =>0);
        Put_Line ("");

then the output includes:

  ::

       Final velocity: 98.10 m.s**(-1)


  .. index:: Dimensionable type
  .. index:: Dimensioned subtype

The type ``Mks_Type`` is said to be a *dimensionable type* since it has a
``Dimension_System`` aspect, and the subtypes ``Length``, ``Mass``, etc.,
are said to be *dimensioned subtypes* since each one has a ``Dimension``
aspect.

  .. index:: Dimension Vector (for a dimensioned subtype)
  .. index:: Dimension aspect
  .. index:: Dimension_System aspect

The ``Dimension`` aspect of a dimensioned subtype ``S`` defines a mapping
from the base type's Unit_Names to integer (or, more generally, rational)
values. This mapping is the *dimension vector* (also referred to as the
*dimensionality*) for that subtype, denoted by ``DV(S)``, and thus for each
object of that subtype. Intuitively, the value specified for each
``Unit_Name`` is the exponent associated with that unit; a zero value
means that the unit is not used. For example:

   .. code-block:: ada

      declare
         Acc : Acceleration;
         ...
      begin
         ...
      end;

Here ``DV(Acc)`` = ``DV(Acceleration)`` =
``(Meter=>1, Kilogram=>0, Second=>-2, Ampere=>0, Kelvin=>0, Mole=>0, Candela=>0)``.
Symbolically, we can express this as ``Meter / Second**2``.

The dimension vector of an arithmetic expression is synthesized from the
dimension vectors of its components, with compile-time dimensionality checks
that help prevent mismatches such as using an ``Acceleration`` where a
``Length`` is required.

The dimension vector of the result of an arithmetic expression *expr*, or
:samp:`DV({expr})`, is defined as follows, assuming conventional
mathematical definitions for the vector operations that are used:

* If *expr* is of the type *universal_real*, or is not of a dimensioned subtype,
  then *expr* is dimensionless; :samp:`DV({expr})` is the empty vector.

* :samp:`DV({op expr})`, where *op* is a unary operator, is :samp:`DV({expr})`

* :samp:`DV({expr1 op expr2})` where *op* is "+" or "-" is :samp:`DV({expr1})`
  provided that :samp:`DV({expr1})` = :samp:`DV({expr2})`.
  If this condition is not met then the construct is illegal.

* :samp:`DV({expr1} * {expr2})` is :samp:`DV({expr1})` + :samp:`DV({expr2})`,
  and :samp:`DV({expr1} / {expr2})` = :samp:`DV({expr1})` - :samp:`DV({expr2})`.
  In this context if one of the *expr*\ s is dimensionless then its empty
  dimension vector is treated as ``(others => 0)``.

* :samp:`DV({expr} ** {power})` is *power* * :samp:`DV({expr})`,
  provided that *power* is a static rational value. If this condition is not
  met then the construct is illegal.

Note that, by the above rules, it is illegal to use binary "+" or "-" to
combine a dimensioned and dimensionless value.  Thus an expression such as
``acc-10.0`` is illegal, where ``acc`` is an object of subtype
``Acceleration``.

The dimensionality checks for relationals use the same rules as
for "+" and "-"; thus

  .. code-block:: ada

        acc > 10.0

is equivalent to

  .. code-block:: ada

       acc-10.0 > 0.0

and is thus illegal. Analogously a conditional expression
requires the same dimension vector for each branch.

The dimension vector of a type conversion :samp:`T({expr})` is defined
as follows, based on the nature of ``T``:

* If ``T`` is a dimensioned subtype then :samp:`DV(T({expr}))` is ``DV(T)``
  provided that either *expr* is dimensionless or
  :samp:`DV(T)` = :samp:`DV({expr})`. The conversion is illegal
  if *expr* is dimensioned and :samp:`DV({expr})` /= ``DV(T)``.
  Note that vector equality does not require that the corresponding
  Unit_Names be the same.

  As a consequence of the above rule, it is possible to convert between
  different dimension systems that follow the same international system
  of units, with the seven physical components given in the standard order
  (length, mass, time, etc.). Thus a length in meters can be converted to
  a length in inches (with a suitable conversion factor) but cannot be
  converted, for example, to a mass in pounds.

* If ``T`` is the base type for *expr* (and the dimensionless root type of
  the dimension system), then :samp:`DV(T({expr}))` is ``DV(expr)``.
  Thus, if *expr* is of a dimensioned subtype of ``T``, the conversion may
  be regarded as a "view conversion" that preserves dimensionality.

  This rule makes it possible to write generic code that can be instantiated
  with compatible dimensioned subtypes.  The generic unit will contain
  conversions that will consequently be present in instantiations, but
  conversions to the base type will preserve dimensionality and make it
  possible to write generic code that is correct with respect to
  dimensionality.

* Otherwise (i.e., ``T`` is neither a dimensioned subtype nor a dimensionable
  base type), :samp:`DV(T({expr}))` is the empty vector. Thus a dimensioned
  value can be explicitly converted to a non-dimensioned subtype, which
  of course then escapes dimensionality analysis.

The dimension vector for a type qualification :samp:`T'({expr})` is the same
as for the type conversion :samp:`T({expr})`.

An assignment statement

   .. code-block:: ada

         Source := Target;

requires ``DV(Source)`` = ``DV(Target)``, and analogously for parameter
passing (the dimension vector for the actual parameter must be equal to the
dimension vector for the formal parameter).


.. _Stack_Related_Facilities:

Stack Related Facilities
========================

This section describes some useful tools associated with stack
checking and analysis. In
particular, it deals with dynamic and static stack usage measurements.

.. _Stack_Overflow_Checking:

Stack Overflow Checking
-----------------------

.. index:: Stack Overflow Checking

.. index:: -fstack-check (gcc)

For most operating systems, ``gcc`` does not perform stack overflow
checking by default. This means that if the main environment task or
some other task exceeds the available stack space, then unpredictable
behavior will occur. Most native systems offer some level of protection by
adding a guard page at the end of each task stack. This mechanism is usually
not enough for dealing properly with stack overflow situations because
a large local variable could "jump" above the guard page.
Furthermore, when the
guard page is hit, there may not be any space left on the stack for executing
the exception propagation code. Enabling stack checking avoids
such situations.

To activate stack checking, compile all units with the ``gcc`` option
:switch:`-fstack-check`. For example:

  ::

     $ gcc -c -fstack-check package1.adb

Units compiled with this option will generate extra instructions to check
that any use of the stack (for procedure calls or for declaring local
variables in declare blocks) does not exceed the available stack space.
If the space is exceeded, then a ``Storage_Error`` exception is raised.

For declared tasks, the stack size is controlled by the size
given in an applicable ``Storage_Size`` pragma or by the value specified
at bind time with ``-d`` (:ref:`Switches_for_gnatbind`) or is set to
the default size as defined in the GNAT runtime otherwise.

.. index:: GNAT_STACK_LIMIT

For the environment task, the stack size depends on
system defaults and is unknown to the compiler. Stack checking
may still work correctly if a fixed
size stack is allocated, but this cannot be guaranteed.
To ensure that a clean exception is signalled for stack
overflow, set the environment variable
:envvar:`GNAT_STACK_LIMIT` to indicate the maximum
stack area that can be used, as in:

  ::

     $ SET GNAT_STACK_LIMIT 1600

The limit is given in kilobytes, so the above declaration would
set the stack limit of the environment task to 1.6 megabytes.
Note that the only purpose of this usage is to limit the amount
of stack used by the environment task. If it is necessary to
increase the amount of stack for the environment task, then this
is an operating systems issue, and must be addressed with the
appropriate operating systems commands.


.. _Static_Stack_Usage_Analysis:

Static Stack Usage Analysis
---------------------------

.. index:: Static Stack Usage Analysis

.. index:: -fstack-usage

A unit compiled with ``-fstack-usage`` will generate an extra file
that specifies
the maximum amount of stack used, on a per-function basis.
The file has the same
basename as the target object file with a :file:`.su` extension.
Each line of this file is made up of three fields:

* The name of the function.
* A number of bytes.
* One or more qualifiers: ``static``, ``dynamic``, ``bounded``.

The second field corresponds to the size of the known part of the function
frame.

The qualifier ``static`` means that the function frame size
is purely static.
It usually means that all local variables have a static size.
In this case, the second field is a reliable measure of the function stack
utilization.

The qualifier ``dynamic`` means that the function frame size is not static.
It happens mainly when some local variables have a dynamic size. When this
qualifier appears alone, the second field is not a reliable measure
of the function stack analysis. When it is qualified with  ``bounded``, it
means that the second field is a reliable maximum of the function stack
utilization.

A unit compiled with ``-Wstack-usage`` will issue a warning for each
subprogram whose stack usage might be larger than the specified amount of
bytes.  The wording is in keeping with the qualifier documented above.


.. _Dynamic_Stack_Usage_Analysis:

Dynamic Stack Usage Analysis
----------------------------

It is possible to measure the maximum amount of stack used by a task, by
adding a switch to ``gnatbind``, as:

  ::

      $ gnatbind -u0 file

With this option, at each task termination, its stack usage is  output on
:file:`stderr`.
It is not always convenient to output the stack usage when the program
is still running. Hence, it is possible to delay this output until program
termination. for a given number of tasks specified as the argument of the
``-u`` option. For instance:

  ::

     $ gnatbind -u100 file

will buffer the stack usage information of the first 100 tasks to terminate and
output this info at program termination. Results are displayed in four
columns:

  ::

     Index | Task Name | Stack Size | Stack Usage

where:

* *Index* is a number associated with each task.

* *Task Name* is the name of the task analyzed.

* *Stack Size* is the maximum size for the stack.

* *Stack Usage* is the measure done by the stack analyzer.
  In order to prevent overflow, the stack
  is not entirely analyzed, and it's not possible to know exactly how
  much has actually been used.

The environment task stack, e.g., the stack that contains the main unit, is
only processed when the environment variable GNAT_STACK_LIMIT is set.

The package ``GNAT.Task_Stack_Usage`` provides facilities to get
stack usage reports at run-time. See its body for the details.



.. _Memory_Management_Issues:

Memory Management Issues
========================

This section describes some useful memory pools provided in the GNAT library
and in particular the GNAT Debug Pool facility, which can be used to detect
incorrect uses of access values (including 'dangling references').

.. only:: PRO or GPL

  It also describes the ``gnatmem`` tool, which can be used to track down
  "memory leaks".

.. _Some_Useful_Memory_Pools:

Some Useful Memory Pools
------------------------

.. index:: Memory Pool
.. index:: storage, pool

The ``System.Pool_Global`` package offers the Unbounded_No_Reclaim_Pool
storage pool. Allocations use the standard system call ``malloc`` while
deallocations use the standard system call ``free``. No reclamation is
performed when the pool goes out of scope. For performance reasons, the
standard default Ada allocators/deallocators do not use any explicit storage
pools but if they did, they could use this storage pool without any change in
behavior. That is why this storage pool is used  when the user
manages to make the default implicit allocator explicit as in this example:

  .. code-block:: ada

       type T1 is access Something;
        -- no Storage pool is defined for T2

       type T2 is access Something_Else;
       for T2'Storage_Pool use T1'Storage_Pool;
       -- the above is equivalent to
       for T2'Storage_Pool use System.Pool_Global.Global_Pool_Object;

The ``System.Pool_Local`` package offers the ``Unbounded_Reclaim_Pool`` storage
pool. The allocation strategy is similar to ``Pool_Local``
except that the all
storage allocated with this pool is reclaimed when the pool object goes out of
scope. This pool provides a explicit mechanism similar to the implicit one
provided by several Ada 83 compilers for allocations performed through a local
access type and whose purpose was to reclaim memory when exiting the
scope of a given local access. As an example, the following program does not
leak memory even though it does not perform explicit deallocation:

  .. code-block:: ada

     with System.Pool_Local;
     procedure Pooloc1 is
        procedure Internal is
           type A is access Integer;
           X : System.Pool_Local.Unbounded_Reclaim_Pool;
           for A'Storage_Pool use X;
           v : A;
        begin
           for I in  1 .. 50 loop
              v := new Integer;
           end loop;
        end Internal;
     begin
        for I in  1 .. 100 loop
           Internal;
        end loop;
     end Pooloc1;

The ``System.Pool_Size`` package implements the ``Stack_Bounded_Pool`` used when
``Storage_Size`` is specified for an access type.
The whole storage for the pool is
allocated at once, usually on the stack at the point where the access type is
elaborated. It is automatically reclaimed when exiting the scope where the
access type is defined. This package is not intended to be used directly by the
user and it is implicitly used for each such declaration:

  .. code-block:: ada

     type T1 is access Something;
     for T1'Storage_Size use 10_000;


.. _The_GNAT_Debug_Pool_Facility:

The GNAT Debug Pool Facility
----------------------------

.. index:: Debug Pool
.. index:: storage, pool, memory corruption

The use of unchecked deallocation and unchecked conversion can easily
lead to incorrect memory references. The problems generated by such
references are usually difficult to tackle because the symptoms can be
very remote from the origin of the problem. In such cases, it is
very helpful to detect the problem as early as possible. This is the
purpose of the Storage Pool provided by ``GNAT.Debug_Pools``.

In order to use the GNAT specific debugging pool, the user must
associate a debug pool object with each of the access types that may be
related to suspected memory problems. See Ada Reference Manual 13.11.

  .. code-block:: ada

     type Ptr is access Some_Type;
     Pool : GNAT.Debug_Pools.Debug_Pool;
     for Ptr'Storage_Pool use Pool;

``GNAT.Debug_Pools`` is derived from a GNAT-specific kind of
pool: the ``Checked_Pool``. Such pools, like standard Ada storage pools,
allow the user to redefine allocation and deallocation strategies. They
also provide a checkpoint for each dereference, through the use of
the primitive operation ``Dereference`` which is implicitly called at
each dereference of an access value.

Once an access type has been associated with a debug pool, operations on
values of the type may raise four distinct exceptions,
which correspond to four potential kinds of memory corruption:

* ``GNAT.Debug_Pools.Accessing_Not_Allocated_Storage``
* ``GNAT.Debug_Pools.Accessing_Deallocated_Storage``
* ``GNAT.Debug_Pools.Freeing_Not_Allocated_Storage``
* ``GNAT.Debug_Pools.Freeing_Deallocated_Storage``

For types associated with a Debug_Pool, dynamic allocation is performed using
the standard GNAT allocation routine. References to all allocated chunks of
memory are kept in an internal dictionary. Several deallocation strategies are
provided, whereupon the user can choose to release the memory to the system,
keep it allocated for further invalid access checks, or fill it with an easily
recognizable pattern for debug sessions. The memory pattern is the old IBM
hexadecimal convention: ``16#DEADBEEF#``.

See the documentation in the file g-debpoo.ads for more information on the
various strategies.

Upon each dereference, a check is made that the access value denotes a
properly allocated memory location. Here is a complete example of use of
``Debug_Pools``, that includes typical instances of  memory corruption:

  .. code-block:: ada

      with Gnat.Io; use Gnat.Io;
      with Unchecked_Deallocation;
      with Unchecked_Conversion;
      with GNAT.Debug_Pools;
      with System.Storage_Elements;
      with Ada.Exceptions; use Ada.Exceptions;
      procedure Debug_Pool_Test is

         type T is access Integer;
         type U is access all T;

         P : GNAT.Debug_Pools.Debug_Pool;
         for T'Storage_Pool use P;

         procedure Free is new Unchecked_Deallocation (Integer, T);
         function UC is new Unchecked_Conversion (U, T);
         A, B : aliased T;

         procedure Info is new GNAT.Debug_Pools.Print_Info(Put_Line);

      begin
         Info (P);
         A := new Integer;
         B := new Integer;
         B := A;
         Info (P);
         Free (A);
         begin
            Put_Line (Integer'Image(B.all));
         exception
            when E : others => Put_Line ("raised: " & Exception_Name (E));
         end;
         begin
            Free (B);
         exception
            when E : others => Put_Line ("raised: " & Exception_Name (E));
         end;
         B := UC(A'Access);
         begin
            Put_Line (Integer'Image(B.all));
         exception
            when E : others => Put_Line ("raised: " & Exception_Name (E));
         end;
         begin
            Free (B);
         exception
            when E : others => Put_Line ("raised: " & Exception_Name (E));
         end;
         Info (P);
      end Debug_Pool_Test;

The debug pool mechanism provides the following precise diagnostics on the
execution of this erroneous program:

  ::

     Debug Pool info:
       Total allocated bytes :  0
       Total deallocated bytes :  0
       Current Water Mark:  0
       High Water Mark:  0

     Debug Pool info:
       Total allocated bytes :  8
       Total deallocated bytes :  0
       Current Water Mark:  8
       High Water Mark:  8

     raised: GNAT.DEBUG_POOLS.ACCESSING_DEALLOCATED_STORAGE
     raised: GNAT.DEBUG_POOLS.FREEING_DEALLOCATED_STORAGE
     raised: GNAT.DEBUG_POOLS.ACCESSING_NOT_ALLOCATED_STORAGE
     raised: GNAT.DEBUG_POOLS.FREEING_NOT_ALLOCATED_STORAGE
     Debug Pool info:
       Total allocated bytes :  8
       Total deallocated bytes :  4
       Current Water Mark:  4
       High Water Mark:  8

.. only:: PRO or GPL

  .. _The_gnatmem_Tool:

  The ``gnatmem`` Tool
  --------------------

  .. index:: ! gnatmem

  The ``gnatmem`` utility monitors dynamic allocation and
  deallocation activity in a program, and displays information about
  incorrect deallocations and possible sources of memory leaks.
  It is designed to work in association with a static runtime library
  only and in this context provides three types of information:

  * General information concerning memory management, such as the total
    number of allocations and deallocations, the amount of allocated
    memory and the high water mark, i.e., the largest amount of allocated
    memory in the course of program execution.

  * Backtraces for all incorrect deallocations, that is to say deallocations
    which do not correspond to a valid allocation.

  * Information on each allocation that is potentially the origin of a memory
    leak.

  .. _Running_gnatmem:

  Running ``gnatmem``
  ^^^^^^^^^^^^^^^^^^^

  ``gnatmem`` makes use of the output created by the special version of
  allocation and deallocation routines that record call information. This allows
  it to obtain accurate dynamic memory usage history at a minimal cost to the
  execution speed. Note however, that ``gnatmem`` is not supported on all
  platforms (currently, it is supported on AIX, HP-UX, GNU/Linux, Solaris and
  Windows).

  The ``gnatmem`` command has the form

    ::

       $ gnatmem [ switches ] user_program

  The program must have been linked with the instrumented version of the
  allocation and deallocation routines. This is done by linking with the
  :file:`libgmem.a` library. For correct symbolic backtrace information,
  the user program should be compiled with debugging options
  (see :ref:`Switches_for_gcc`). For example to build :file:`my_program`:

    ::

       $ gnatmake -g my_program -largs -lgmem

  As library :file:`libgmem.a` contains an alternate body for package
  ``System.Memory``, :file:`s-memory.adb` should not be compiled and linked
  when an executable is linked with library :file:`libgmem.a`. It is then not
  recommended to use ``gnatmake`` with switch :switch:`-a`.

  When :file:`my_program` is executed, the file :file:`gmem.out` is produced.
  This file contains information about all allocations and deallocations
  performed by the program. It is produced by the instrumented allocations and
  deallocations routines and will be used by ``gnatmem``.

  In order to produce symbolic backtrace information for allocations and
  deallocations performed by the GNAT run-time library, you need to use a
  version of that library that has been compiled with the :switch:`-g` switch
  (see :ref:`Rebuilding_the_GNAT_Run-Time_Library`).

  ``gnatmem`` must be supplied with the :file:`gmem.out` file and the executable to
  examine. If the location of :file:`gmem.out` file was not explicitly supplied by
  :switch:`-i` switch, gnatmem will assume that this file can be found in the
  current directory. For example, after you have executed :file:`my_program`,
  :file:`gmem.out` can be analyzed by ``gnatmem`` using the command:

    ::

       $ gnatmem my_program

  This will produce the output with the following format:

    ::

        $ gnatmem my_program

        Global information
        ------------------
           Total number of allocations        :  45
           Total number of deallocations      :   6
           Final Water Mark (non freed mem)   :  11.29 Kilobytes
           High Water Mark                    :  11.40 Kilobytes

        .
        .
        .
        Allocation Root # 2
        -------------------
         Number of non freed allocations    :  11
         Final Water Mark (non freed mem)   :   1.16 Kilobytes
         High Water Mark                    :   1.27 Kilobytes
         Backtrace                          :
           my_program.adb:23 my_program.alloc
        .
        .
        .

  The first block of output gives general information. In this case, the
  Ada construct ``new`` was executed 45 times, and only 6 calls to an
  Unchecked_Deallocation routine occurred.

  Subsequent paragraphs display  information on all allocation roots.
  An allocation root is a specific point in the execution of the program
  that generates some dynamic allocation, such as a ``new``
  construct. This root is represented by an execution backtrace (or subprogram
  call stack). By default the backtrace depth for allocations roots is 1, so
  that a root corresponds exactly to a source location. The backtrace can
  be made deeper, to make the root more specific.

  .. _Switches_for_gnatmem:

  Switches for ``gnatmem``
  ^^^^^^^^^^^^^^^^^^^^^^^^

  ``gnatmem`` recognizes the following switches:

  .. index:: -q (gnatmem)

  :samp:`-q`
    Quiet. Gives the minimum output needed to identify the origin of the
    memory leaks. Omits statistical information.


  .. index:: N switch (gnatmem)

  :samp:`{N}`
    ``N`` is an integer literal (usually between 1 and 10) which controls the
    depth of the backtraces defining allocation root. The default value for
    N is 1. The deeper the backtrace, the more precise the localization of
    the root. Note that the total number of roots can depend on this
    parameter. This parameter must be specified *before* the name of the
    executable to be analyzed, to avoid ambiguity.


  .. index:: -b (gnatmem)

  :samp:`-b {N}`
    This switch has the same effect as just a depth parameter ``N``.


  .. index:: -i (gnatmem)

  :samp:`-i {file}`
    Do the ``gnatmem`` processing starting from :file:`file`, rather than
    :file:`gmem.out` in the current directory.


  .. index:: -m (gnatmem)

  :samp:`-m {n}`
    This switch causes ``gnatmem`` to mask the allocation roots that have less
    than n leaks.  The default value is 1. Specifying the value of 0 will allow
    examination of even the roots that did not result in leaks.


  .. index:: -s (gnatmem)

  :samp:`-s {order}`
    This switch causes ``gnatmem`` to sort the allocation roots according to the
    specified order of sort criteria, each identified by a single letter. The
    currently supported criteria are ``n``, ``h``, and ``w`` standing respectively for
    number of unfreed allocations, high watermark, and final watermark
    corresponding to a specific root. The default order is ``nwh``.


  .. index:: -t (gnatmem)

  :samp:`-t`
    This switch causes memory allocated size to be always output in bytes.
    Default ``gnatmem`` behavior is to show memory sizes less then 1 kilobyte
    in bytes, from 1 kilobyte till 1 megabyte in kilobytes and the rest in
    megabytes.


  .. _Example_of_gnatmem_Usage:

  Example of ``gnatmem`` Usage
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  The following example shows the use of ``gnatmem``
  on a simple memory-leaking program.
  Suppose that we have the following Ada program:

    .. code-block:: ada

       with Unchecked_Deallocation;
       procedure Test_Gm is

          type T is array (1..1000) of Integer;
          type Ptr is access T;
          procedure Free is new Unchecked_Deallocation (T, Ptr);
          A : Ptr;

          procedure My_Alloc is
          begin
             A := new T;
          end My_Alloc;

          procedure My_DeAlloc is
             B : Ptr := A;
          begin
             Free (B);
          end My_DeAlloc;

       begin
          My_Alloc;
          for I in 1 .. 5 loop
             for J in I .. 5 loop
                My_Alloc;
             end loop;
             My_Dealloc;
          end loop;
       end;

  The program needs to be compiled with the debugging option and linked with
  the ``gmem`` library:

    ::

       $ gnatmake -g test_gm -largs -lgmem

  Then we execute the program as usual:

    ::

       $ test_gm

  Then ``gnatmem`` is invoked simply with

    ::

       $ gnatmem test_gm

  which produces the following output (result may vary on different platforms):

    ::

        Global information
        ------------------
           Total number of allocations        :  18
           Total number of deallocations      :   5
           Final Water Mark (non freed mem)   :  53.00 Kilobytes
           High Water Mark                    :  56.90 Kilobytes

        Allocation Root # 1
        -------------------
         Number of non freed allocations    :  11
         Final Water Mark (non freed mem)   :  42.97 Kilobytes
         High Water Mark                    :  46.88 Kilobytes
         Backtrace                          :
           test_gm.adb:11 test_gm.my_alloc

        Allocation Root # 2
        -------------------
         Number of non freed allocations    :   1
         Final Water Mark (non freed mem)   :  10.02 Kilobytes
         High Water Mark                    :  10.02 Kilobytes
         Backtrace                          :
           s-secsta.adb:81 system.secondary_stack.ss_init

        Allocation Root # 3
        -------------------
         Number of non freed allocations    :   1
         Final Water Mark (non freed mem)   :  12 Bytes
         High Water Mark                    :  12 Bytes
         Backtrace                          :
           s-secsta.adb:181 system.secondary_stack.ss_init


  Note that the GNAT runtime contains itself a certain number of
  allocations that have no  corresponding deallocation,
  as shown here for root #2 and root #3.
  This is a normal behavior when the number of non-freed allocations
  is one, it allocates dynamic data structures that the run time needs for
  the complete lifetime of the program. Note also that there is only one
  allocation root in the user program with a single line back trace:
  test_gm.adb:11 test_gm.my_alloc, whereas a careful analysis of the
  program shows that 'My_Alloc' is called at 2 different points in the
  source (line 21 and line 24). If those two allocation roots need to be
  distinguished, the backtrace depth parameter can be used:

    ::

       $ gnatmem 3 test_gm

  which will give the following output:


    ::

        Global information
        ------------------
           Total number of allocations        :  18
           Total number of deallocations      :   5
           Final Water Mark (non freed mem)   :  53.00 Kilobytes
           High Water Mark                    :  56.90 Kilobytes

        Allocation Root # 1
        -------------------
         Number of non freed allocations    :  10
         Final Water Mark (non freed mem)   :  39.06 Kilobytes
         High Water Mark                    :  42.97 Kilobytes
         Backtrace                          :
           test_gm.adb:11 test_gm.my_alloc
           test_gm.adb:24 test_gm
           b_test_gm.c:52 main

        Allocation Root # 2
        -------------------
         Number of non freed allocations    :   1
         Final Water Mark (non freed mem)   :  10.02 Kilobytes
         High Water Mark                    :  10.02 Kilobytes
         Backtrace                          :
           s-secsta.adb:81  system.secondary_stack.ss_init
           s-secsta.adb:283 <system__secondary_stack___elabb>
           b_test_gm.c:33   adainit

        Allocation Root # 3
        -------------------
         Number of non freed allocations    :   1
         Final Water Mark (non freed mem)   :   3.91 Kilobytes
         High Water Mark                    :   3.91 Kilobytes
         Backtrace                          :
           test_gm.adb:11 test_gm.my_alloc
           test_gm.adb:21 test_gm
           b_test_gm.c:52 main

        Allocation Root # 4
        -------------------
         Number of non freed allocations    :   1
         Final Water Mark (non freed mem)   :  12 Bytes
         High Water Mark                    :  12 Bytes
         Backtrace                          :
           s-secsta.adb:181 system.secondary_stack.ss_init
           s-secsta.adb:283 <system__secondary_stack___elabb>
           b_test_gm.c:33   adainit

  The allocation root #1 of the first example has been split in 2 roots #1
  and #3, thanks to the more precise associated backtrace.