aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/compiler.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/compiler.h')
-rw-r--r--include/linux/compiler.h92
1 files changed, 84 insertions, 8 deletions
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 98115d9d04da..d95da1020f1c 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -36,12 +36,8 @@ extern void __chk_io_ptr(const volatile void __iomem *);
36 36
37#ifdef __KERNEL__ 37#ifdef __KERNEL__
38 38
39#if __GNUC__ >= 4 39#ifdef __GNUC__
40# include <linux/compiler-gcc4.h> 40#include <linux/compiler-gcc.h>
41#elif __GNUC__ == 3 && __GNUC_MINOR__ >= 2
42# include <linux/compiler-gcc3.h>
43#else
44# error Sorry, your compiler is too old/not recognized.
45#endif 41#endif
46 42
47#define notrace __attribute__((no_instrument_function)) 43#define notrace __attribute__((no_instrument_function))
@@ -59,8 +55,88 @@ extern void __chk_io_ptr(const volatile void __iomem *);
59 * specific implementations come from the above header files 55 * specific implementations come from the above header files
60 */ 56 */
61 57
62#define likely(x) __builtin_expect(!!(x), 1) 58struct ftrace_branch_data {
63#define unlikely(x) __builtin_expect(!!(x), 0) 59 const char *func;
60 const char *file;
61 unsigned line;
62 union {
63 struct {
64 unsigned long correct;
65 unsigned long incorrect;
66 };
67 struct {
68 unsigned long miss;
69 unsigned long hit;
70 };
71 };
72};
73
74/*
75 * Note: DISABLE_BRANCH_PROFILING can be used by special lowlevel code
76 * to disable branch tracing on a per file basis.
77 */
78#if defined(CONFIG_TRACE_BRANCH_PROFILING) && !defined(DISABLE_BRANCH_PROFILING)
79void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
80
81#define likely_notrace(x) __builtin_expect(!!(x), 1)
82#define unlikely_notrace(x) __builtin_expect(!!(x), 0)
83
84#define __branch_check__(x, expect) ({ \
85 int ______r; \
86 static struct ftrace_branch_data \
87 __attribute__((__aligned__(4))) \
88 __attribute__((section("_ftrace_annotated_branch"))) \
89 ______f = { \
90 .func = __func__, \
91 .file = __FILE__, \
92 .line = __LINE__, \
93 }; \
94 ______r = likely_notrace(x); \
95 ftrace_likely_update(&______f, ______r, expect); \
96 ______r; \
97 })
98
99/*
100 * Using __builtin_constant_p(x) to ignore cases where the return
101 * value is always the same. This idea is taken from a similar patch
102 * written by Daniel Walker.
103 */
104# ifndef likely
105# define likely(x) (__builtin_constant_p(x) ? !!(x) : __branch_check__(x, 1))
106# endif
107# ifndef unlikely
108# define unlikely(x) (__builtin_constant_p(x) ? !!(x) : __branch_check__(x, 0))
109# endif
110
111#ifdef CONFIG_PROFILE_ALL_BRANCHES
112/*
113 * "Define 'is'", Bill Clinton
114 * "Define 'if'", Steven Rostedt
115 */
116#define if(cond) if (__builtin_constant_p((cond)) ? !!(cond) : \
117 ({ \
118 int ______r; \
119 static struct ftrace_branch_data \
120 __attribute__((__aligned__(4))) \
121 __attribute__((section("_ftrace_branch"))) \
122 ______f = { \
123 .func = __func__, \
124 .file = __FILE__, \
125 .line = __LINE__, \
126 }; \
127 ______r = !!(cond); \
128 if (______r) \
129 ______f.hit++; \
130 else \
131 ______f.miss++; \
132 ______r; \
133 }))
134#endif /* CONFIG_PROFILE_ALL_BRANCHES */
135
136#else
137# define likely(x) __builtin_expect(!!(x), 1)
138# define unlikely(x) __builtin_expect(!!(x), 0)
139#endif
64 140
65/* Optimization barrier */ 141/* Optimization barrier */
66#ifndef barrier 142#ifndef barrier