)]}'
{
  "commit": "8545dfb3ea301f5c77626a046d4756ef9f2e4970",
  "tree": "4353f440ea882278a76fedaaabdf2085687af6a5",
  "parents": [
    "efadf67a124528389b7faa5ed75a358528dbae22"
  ],
  "author": {
    "name": "Alexander Popov",
    "email": "alexgpg@gmail.com",
    "time": "Mon Jun 20 09:12:58 2022"
  },
  "committer": {
    "name": "GitHub",
    "email": "noreply@github.com",
    "time": "Mon Jun 20 09:12:58 2022"
  },
  "message": "Fix DoNotOptimize() GCC copy overhead (#1340) (#1410)\n\n* Fix DoNotOptimize() GCC copy overhead (#1340)\r\n\r\nThe issue is that GCC DoNotOptimize() does a full copy of an argument\r\nif it\u0027s not a pointer and it slows down a benchmark. If an argument is big\r\nenough there is a memcpy() call for copying the argument. An argument\r\nobject can be a big object so DoNotOptimize() could add sufficient\r\noverhead and affects benchmark results.\r\n\r\nThe cause is in GCC behavior with asm volatile constraints. Looks like GCC\r\ntrying to use r(register) constraint for all cases despite object size.\r\nSee: https://gcc.gnu.org/bugzilla/show_bug.cgi?id\u003d105519\r\n\r\nThe solution is the split DoNotOptimize() in two cases - value fits\r\nin register and value doesn\u0027t fit in register. And use case specific\r\nasm constraint. std::is_trivially_copyable trait is needed because\r\n\"+r\" constraint doesn\u0027t work with non trivial copyable objects.\r\n\r\n- Fix requires support C++11 feature std::is_trivially_copyable from GCC\r\n  compiler. The feature has been supported since GCC 5\r\n- Fallback for GCC version \u003c 5 still exists but it uses \"m\" constraint\r\n  which means a little bit more overhead in some cases\r\n- Add assembly tests for issued cases\r\n\r\nFixes #1340\r\n\r\n* Add supported compiler versions info for assembly tests\r\n\r\n- Assembly tests are inherently non-portable. So explicitly add GCC\r\n  and Clang versions required for reliable tests passed\r\n- Write a warning message if the current compiler version isn\u0027t supported",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "42c04cc32433f862204912632ae411e6883106c2",
      "old_mode": 33188,
      "old_path": "include/benchmark/benchmark.h",
      "new_id": "a4fc52df6fecd3e63ef1cccfd4a08890c1536971",
      "new_mode": 33188,
      "new_path": "include/benchmark/benchmark.h"
    },
    {
      "type": "modify",
      "old_id": "48318bdda2dc60c6efceb49bc24497b0987b77de",
      "old_mode": 33188,
      "old_path": "test/AssemblyTests.cmake",
      "new_id": "c43c711faf87e9cdc4c8864a050433aece8cb936",
      "new_mode": 33188,
      "new_path": "test/AssemblyTests.cmake"
    },
    {
      "type": "modify",
      "old_id": "2e86a51e223423535107817162a11bc9fa9b6f50",
      "old_mode": 33188,
      "old_path": "test/donotoptimize_assembly_test.cc",
      "new_id": "70e780a5f097261e58eb8a818fc720774444ef9b",
      "new_mode": 33188,
      "new_path": "test/donotoptimize_assembly_test.cc"
    }
  ]
}
