{"action":"created","issue":{"url":"https://api.github.com/repos/ocaml/ocaml/issues/226","labels_url":"https://api.github.com/repos/ocaml/ocaml/issues/226/labels{/name}","comments_url":"https://api.github.com/repos/ocaml/ocaml/issues/226/comments","events_url":"https://api.github.com/repos/ocaml/ocaml/issues/226/events","html_url":"https://github.com/ocaml/ocaml/pull/226","id":98962597,"number":226,"title":"Compiling the run-time system at higher levels of C optimization","user":{"login":"xavierleroy","id":3845810,"avatar_url":"https://avatars.githubusercontent.com/u/3845810?v=3","gravatar_id":"","url":"https://api.github.com/users/xavierleroy","html_url":"https://github.com/xavierleroy","followers_url":"https://api.github.com/users/xavierleroy/followers","following_url":"https://api.github.com/users/xavierleroy/following{/other_user}","gists_url":"https://api.github.com/users/xavierleroy/gists{/gist_id}","starred_url":"https://api.github.com/users/xavierleroy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/xavierleroy/subscriptions","organizations_url":"https://api.github.com/users/xavierleroy/orgs","repos_url":"https://api.github.com/users/xavierleroy/repos","events_url":"https://api.github.com/users/xavierleroy/events{/privacy}","received_events_url":"https://api.github.com/users/xavierleroy/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":6,"created_at":"2015-08-04T12:59:09Z","updated_at":"2015-08-06T07:22:21Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/ocaml/ocaml/pulls/226","html_url":"https://github.com/ocaml/ocaml/pull/226","diff_url":"https://github.com/ocaml/ocaml/pull/226.diff","patch_url":"https://github.com/ocaml/ocaml/pull/226.patch"},"body":"Currently, the run-time system and the C stub code are compiled at a conservative `-O` (= `-O1`) optimization level.  This pull request investigates the use of higher optimization levels.\r\n\r\n### Optimization level\r\n\r\nHigh optimization levels are risky, because optimizing C compilers assume that the C source is free of undefined behaviors w.r.t. the ISO C standards, and optimize accordingly.  There are two main sources of such undefined behaviors in the OCaml sources:\r\n- Overflow in signed integer arithmetic is undefined in ISO C.  OCaml (esp. the bytecode interpreter) assumes defined behavior, with wrap around on overflow, like in Java.\r\n- Wild pointer casts.  For conforming programs, the C compiler can assume that e.g. a `double *` pointer and an `int *` pointer never alias.  This may not be safe for the OCaml runtime system, because it makes a lot of casts between the `value` type and various pointer types.\r\n\r\nConsequently, I propose to use `-O3` optimization level but tame it by selecting\r\n- `-fwrapv` to tell the compiler we expect signed integer arithmetic to overflow and to wrap around;\r\n- `-fno-strict-aliasing` to turn off type-based aliasing analysis and tolerate wild pointer casts.\r\n\r\nThese options are supported by Clang and by GCC (since version 3.4).  On other compilers, the configure script selects `-O` optimization, like before.\r\n\r\n### Performance impact\r\n\r\nThe impact of these optimizations on OCaml performance is important for the bytecode interpreter, and barely noticeable for natively-compiled programs.\r\n\r\nCompiling `ocamlrun` with `gcc -O3` instead of `gcc -O` speeds up bytecode interpretation by a factor 1.2 to 2.2 (!) on small bytecoded benchmarks, 1.3 on a larger program (CompCert).  This is primarily due to better code being generated for the `Next` macro of the bytecode interpreter.  (`gcc -O` pessimizes this macro; higher optimization levels do the right thing.)  With `gcc -O2`, performance is almost as good.\r\n\r\nThe same small set of benchmarks compiled in native code show no significant speedup or slowdown when the runtime system is compiled with `gcc -O2`, and a barely significant 1.03 speedup when the runtime system is compiled with `gcc -O3`.\r\n\r\nMy small set of benchmarks doesn't exercise much of the runtime system.  Other measurements are needed.\r\n\r\n### Other proposed changes\r\n\r\nThese changes are unrelated to optimization but affect the `configure` script as well.\r\n- Fail if GCC version 1.x or 2.x is used.  We used to detect the 2.x versions that are known to cause problems.  1.x and 2.x are too old anyway.\r\n- Put GCC in `gnu99` (= ISO C99 + GNU extensions) mode instead of the default `gnu89` (= ANSI C + GNU extensions) mode.  I want to encourage the use of C99.  Besides, clang is `gnu99` or even `gnu11` by default, so GCC/Clang portability is increased.  As to why GNU extensions and not strict ISO C mode, some useful libc functions are not declared in standard includes in strict ISO C mode.\r\n- For GCC and Clang, add `-Werror` (treat warnings as errors).  The warnings emitted by GCC and Clang in `-Wall` mode are almost always indicative of a C programming error.  I'm tired to see these warnings ignored by OCaml developers who touch the runtime system. \r\n- In accordance with Doligez's law of warnings, `-Werror` is selected only for development versions of OCaml (with `+dev` in the version string), but is turned off for released versions.  We must fix warnings during OCaml development, but released versions may be compiled in nonstandard C environments that we never tried, so they should have a chance to compile even with some warnings.\r\n\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/ocaml/ocaml/issues/comments/128275772","html_url":"https://github.com/ocaml/ocaml/pull/226#issuecomment-128275772","issue_url":"https://api.github.com/repos/ocaml/ocaml/issues/226","id":128275772,"user":{"login":"xavierleroy","id":3845810,"avatar_url":"https://avatars.githubusercontent.com/u/3845810?v=3","gravatar_id":"","url":"https://api.github.com/users/xavierleroy","html_url":"https://github.com/xavierleroy","followers_url":"https://api.github.com/users/xavierleroy/followers","following_url":"https://api.github.com/users/xavierleroy/following{/other_user}","gists_url":"https://api.github.com/users/xavierleroy/gists{/gist_id}","starred_url":"https://api.github.com/users/xavierleroy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/xavierleroy/subscriptions","organizations_url":"https://api.github.com/users/xavierleroy/orgs","repos_url":"https://api.github.com/users/xavierleroy/repos","events_url":"https://api.github.com/users/xavierleroy/events{/privacy}","received_events_url":"https://api.github.com/users/xavierleroy/received_events","type":"User","site_admin":false},"created_at":"2015-08-06T07:22:20Z","updated_at":"2015-08-06T07:22:20Z","body":"Concerning `-Werror`, I agree the ideal situation would be to stop on errors of the \"default\" or \"-Wall\" categories, and keep other warnings as warnings.  I don't know how to do that in GCC or  Clang, however.  `-Werror=all` doesn't seem to do anything, only `-Werror=xxx` where `xxx` is a specific warning name.  If you know the correct incantation, let me know.\r\n\r\nAt any rate, I am adamant that no C code that triggers a `-Wall` warning should enter the Caml sources, and I've seen too many counterexamples recently.  So, I prefer a catch-all `-Werror` to nothing.  Remember that this is just for the working sources: releases will not activate `-Werror`.\r\n"}}