blob: 231c9e18ad1e330173c5fa2ba5d692cedde7ae45 [file] [log] [blame]
Karl Wiberg3d452cf2020-09-11 16:09:46 +02001/*
2 * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#ifndef RTC_BASE_SYSTEM_ASSUME_H_
12#define RTC_BASE_SYSTEM_ASSUME_H_
13
14// Possibly evaluate `p`, promising the compiler that the result is true; the
15// compiler is allowed (but not required) to use this information when
16// optimizing the code. USE WITH CAUTION! If you promise the compiler things
17// that aren't true, it will build a broken binary for you.
18//
19// As a simple example, the compiler is allowed to transform this
20//
21// RTC_ASSUME(x == 4);
22// return x;
23//
24// into this
25//
26// return 4;
27//
28// It is even allowed to propagate the assumption "backwards in time", if it can
29// prove that it must have held at some earlier time. For example, the compiler
30// is allowed to transform this
31//
32// int Add(int x, int y) {
33// if (x == 17)
34// y += 1;
35// RTC_ASSUME(x != 17);
36// return x + y;
37// }
38//
39// into this
40//
41// int Add(int x, int y) {
42// return x + y;
43// }
44//
45// since if `x` isn't 17 on the third line of the function body, the test of `x
46// == 17` on the first line must fail since nothing can modify the local
47// variable `x` in between.
48//
49// The intended use is to allow the compiler to optimize better. For example,
50// here we allow the compiler to omit an instruction that ensures correct
51// rounding of negative arguments:
52//
53// int DivBy2(int x) {
54// RTC_ASSUME(x >= 0);
55// return x / 2;
56// }
57//
58// and here we allow the compiler to possibly omit a null check:
59//
60// void Delete(int* p) {
61// RTC_ASSUME(p != nullptr);
62// delete p;
63// }
64//
65// clang-format off
66#if defined(__GNUC__)
67#define RTC_ASSUME(p) do { if (!(p)) __builtin_unreachable(); } while (0)
68#else
69#define RTC_ASSUME(p) do {} while (0)
70#endif
71// clang-format on
72
73#endif // RTC_BASE_SYSTEM_ASSUME_H_