[PATCH v2] scripts: coccinelle: check for !(un)?likely usage

From: Denis Efremov
Date: Thu Aug 29 2019 - 13:10:28 EST


This patch adds coccinelle script for detecting !likely and
!unlikely usage. These notations are confusing. It's better
to replace !likely(x) with unlikely(!x) and !unlikely(x) with
likely(!x) for readability.

The rule transforms !likely(x) to unlikely(!x) based on this logic:
!likely(x) iff
!__builtin_expect(!!(x), 1) iff
__builtin_expect(!!!(x), 0) iff
unlikely(!x)

For !unlikely(x) to likely(!x):
!unlikely(x) iff
!__builtin_expect(!!(x), 0) iff
__builtin_expect(!!!(x), 1) iff
likely(!x)

Signed-off-by: Denis Efremov <efremov@xxxxxxxxx>
Cc: Julia Lawall <Julia.Lawall@xxxxxxx>
Cc: Gilles Muller <Gilles.Muller@xxxxxxx>
Cc: Nicolas Palix <nicolas.palix@xxxxxxx>
Cc: Michal Marek <michal.lkml@xxxxxxxxxxx>
Cc: Markus Elfring <Markus.Elfring@xxxxxx>
Cc: Joe Perches <joe@xxxxxxxxxxx>
Cc: Rasmus Villemoes <linux@xxxxxxxxxxxxxxxxxx>
---
scripts/coccinelle/misc/neg_unlikely.cocci | 89 ++++++++++++++++++++++
1 file changed, 89 insertions(+)
create mode 100644 scripts/coccinelle/misc/neg_unlikely.cocci

diff --git a/scripts/coccinelle/misc/neg_unlikely.cocci b/scripts/coccinelle/misc/neg_unlikely.cocci
new file mode 100644
index 000000000000..9aac0a7ff042
--- /dev/null
+++ b/scripts/coccinelle/misc/neg_unlikely.cocci
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/// Use unlikely(!x) instead of !likely(x) and vice versa.
+/// Notations !unlikely(x) and !likely(x) are confusing.
+//
+// Confidence: High
+// Copyright: (C) 2019 Denis Efremov, ISPRAS.
+// Options: --no-includes --include-headers
+
+virtual patch
+virtual context
+virtual org
+virtual report
+
+//----------------------------------------------------------
+// For context mode
+//----------------------------------------------------------
+
+@depends on context disable unlikely@
+expression E;
+@@
+
+*! \( likely \| unlikely \) (E)
+
+//----------------------------------------------------------
+// For patch mode
+//----------------------------------------------------------
+
+@depends on patch disable unlikely@
+expression E;
+@@
+
+(
+-!likely(!E)
++unlikely(E)
+|
+-!likely(E)
++unlikely(!E)
+|
+-!unlikely(!E)
++likely(E)
+|
+-!unlikely(E)
++likely(!E)
+)
+
+//----------------------------------------------------------
+// For org and report mode
+//----------------------------------------------------------
+
+@r1 depends on (org || report) disable unlikely@
+expression E;
+position p;
+@@
+
+!likely@p(E)
+
+@r2 depends on (org || report) disable unlikely@
+expression E;
+position p;
+@@
+
+!unlikely@p(E)
+
+@script:python depends on org && r1@
+p << r1.p;
+@@
+
+coccilib.org.print_todo(p[0], "unlikely(!x) is more readable than !likely(x)")
+
+@script:python depends on org && r2@
+p << r2.p;
+@@
+
+coccilib.org.print_todo(p[0], "likely(!x) is more readable than !unlikely(x)")
+
+@script:python depends on report && r1@
+p << r1.p;
+@@
+
+coccilib.report.print_report(p[0],
+ "unlikely(!x) is more readable than !likely(x)")
+
+@script:python depends on report && r2@
+p << r2.p;
+@@
+
+coccilib.report.print_report(p[0],
+ "likely(!x) is more readable than !unlikely(x)")
+
--
2.21.0