[PATCH] powerpc: Make BUG_ON & WARN_ON play nice with compile-time optimisations

Michael Ellerman michael at ellerman.id.au
Tue Feb 7 16:22:00 EST 2006


Currently if you do BUG_ON(0) you'll still get a trap instruction in your
object, although it'll never trigger. That's ok, but a bit ugly, it'd be nice
if the compiler could completely eliminate any trace of the BUG_ON.

So update the BUG_ON & WARN_ON macros to make this possible. From the comment
in the patch:

 The if statement in BUG_ON and WARN_ON gives the compiler a chance to do
 compile-time optimisation and possibly elide the entire block. The check
 for !__builtin_constant(x) has the oppposite effect, if we must do the
 test at runtime then we avoid a spurious compare and branch by ensuring
 the if condition is always true.

I've confirmed it works in both cases, if the condition is false at compile
time we get no code emitted for the BUG statement. If the condition needs to
be evaluated at runtime we get the same code we used to, ie. only one test
in the trap instruction.

It's not clear from the patch due to the whitespace changes, but there's no
changes to the inline asm whatsoever.

For consideration for 2.6.17 I guess.

Signed-off-by: Michael Ellerman <michael at ellerman.id.au>
---

 include/asm-powerpc/bug.h |   46 +++++++++++++++++++++++++++++-----------------
 1 files changed, 29 insertions(+), 17 deletions(-)

Index: iseries/include/asm-powerpc/bug.h
===================================================================
--- iseries.orig/include/asm-powerpc/bug.h
+++ iseries/include/asm-powerpc/bug.h
@@ -39,25 +39,37 @@ struct bug_entry *find_bug(unsigned long
 		: : "i" (__LINE__), "i" (__FILE__), "i" (__FUNCTION__)); \
 } while (0)
 
-#define BUG_ON(x) do {						\
-	__asm__ __volatile__(					\
-		"1:	"PPC_TLNEI"	%0,0\n"			\
-		".section __bug_table,\"a\"\n"			\
-		"\t"PPC_LONG"	1b,%1,%2,%3\n"		\
-		".previous"					\
-		: : "r" ((long)(x)), "i" (__LINE__),		\
-		    "i" (__FILE__), "i" (__FUNCTION__));	\
+/*
+ * The if statement in BUG_ON and WARN_ON gives the compiler a chance to do
+ * compile-time optimisation and possibly elide the entire block. The check
+ * for !__builtin_constant(x) has the oppposite effect, if we must do the
+ * test at runtime then we avoid a spurious compare and branch by ensuring
+ * the if condition is always true.
+ */
+
+#define BUG_ON(x) do {							\
+	if (!__builtin_constant_p(x) || (x)) {				\
+		__asm__ __volatile__(					\
+			"1:	"PPC_TLNEI"	%0,0\n"			\
+			".section __bug_table,\"a\"\n"			\
+			"\t"PPC_LONG"	1b,%1,%2,%3\n"			\
+			".previous"					\
+			: : "r" ((long)(x)), "i" (__LINE__),		\
+			    "i" (__FILE__), "i" (__FUNCTION__));	\
+	}								\
 } while (0)
 
-#define WARN_ON(x) do {						\
-	__asm__ __volatile__(					\
-		"1:	"PPC_TLNEI"	%0,0\n"			\
-		".section __bug_table,\"a\"\n"			\
-		"\t"PPC_LONG"	1b,%1,%2,%3\n"		\
-		".previous"					\
-		: : "r" ((long)(x)),				\
-		    "i" (__LINE__ + BUG_WARNING_TRAP),		\
-		    "i" (__FILE__), "i" (__FUNCTION__));	\
+#define WARN_ON(x) do {							\
+	if (!__builtin_constant_p(x) || (x)) {				\
+		__asm__ __volatile__(					\
+			"1:	"PPC_TLNEI"	%0,0\n"			\
+			".section __bug_table,\"a\"\n"			\
+			"\t"PPC_LONG"	1b,%1,%2,%3\n"			\
+			".previous"					\
+			: : "r" ((long)(x)),				\
+			    "i" (__LINE__ + BUG_WARNING_TRAP),		\
+			    "i" (__FILE__), "i" (__FUNCTION__));	\
+	}								\
 } while (0)
 
 #define HAVE_ARCH_BUG



More information about the Linuxppc64-dev mailing list