This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH]: transform builtin isdigit [take 2]


As eventually discussed in this thread:
http://gcc.gnu.org/ml/gcc-patches/2004-04/msg00521.html
transforming isdigit is okay even in the presence of alternate
locales.

Changes in the patch from last time are:

1.  I added a TARGET_DIGIT0.
2.  I added documentation  (also, TARGET_BS was missing from docs.)
3.  I added testcases.

I did some timing tests on sparc-sun-solaris2.9 where I filled an
array with the results of isdigit passed various values.  I tried one
run with the library call, one with a table lookup and a third with my
builtin transformation.  Here are the timing results in seconds:

lib	6.75
builtin	1.23
table	0.90

While my builtin transformation is not quite as fast as a table
lookup, it's certainly much better than calling the lib func.

Note: I never bypass the table lookup macro if ctype.h provides one.


Bootstrapped on sparc-sun-solaris2.9, no regressions and the new cases
pass.

Ok for mainline?

		Thanks,
		--Kaveh


2004-04-12  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>

	* builtins.c (fold_builtin_isdigit): New.
	(fold_builtin): Handle BUILT_IN_ISDIGIT.
	* defaults.h: Add TARGET_DIGIT0 and sort.
	* doc/tm.texi: Add TARGET_BS and TARGET_DIGIT0.

testsuite:
	* gcc.dg/torture/builtin-ctype-2.c: Test builtin isdigit.

diff -rup orig/egcc-CVS20040412/gcc/builtins.c egcc-CVS20040412/gcc/builtins.c
--- orig/egcc-CVS20040412/gcc/builtins.c	Fri Apr  9 17:03:58 2004
+++ egcc-CVS20040412/gcc/builtins.c	Mon Apr 12 20:44:29 2004
@@ -6778,6 +6778,28 @@ fold_builtin_toascii (tree arglist)
     }
 }
 
+/* Fold a call to builtin isdigit.  */
+
+static tree
+fold_builtin_isdigit (tree arglist)
+{
+  if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
+    return 0;
+  else
+    {
+      /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9.  */
+      /* According to the C standard, isdigit is unaffected by locale.  */
+      tree arg = TREE_VALUE (arglist);
+      arg = build1 (NOP_EXPR, unsigned_type_node, arg);
+      arg = build (MINUS_EXPR, unsigned_type_node, arg,
+		   fold (build1 (NOP_EXPR, unsigned_type_node,
+				 build_int_2 (TARGET_DIGIT0, 0))));
+      arg = build (LE_EXPR, integer_type_node, arg,
+		   fold (build1 (NOP_EXPR, unsigned_type_node,
+				 build_int_2 (9, 0))));
+      return fold (arg);
+    }
+}
 
 /* Used by constant folding to eliminate some builtin calls early.  EXP is
    the CALL_EXPR of a call to a builtin function.  */
@@ -7277,6 +7299,9 @@ fold_builtin (tree exp)
 
     case BUILT_IN_TOASCII:
       return fold_builtin_toascii (arglist);
+
+    case BUILT_IN_ISDIGIT:
+      return fold_builtin_isdigit (arglist);
 
     default:
       break;
diff -rup orig/egcc-CVS20040412/gcc/defaults.h egcc-CVS20040412/gcc/defaults.h
--- orig/egcc-CVS20040412/gcc/defaults.h	Sun Apr 11 07:23:07 2004
+++ egcc-CVS20040412/gcc/defaults.h	Mon Apr 12 20:45:39 2004
@@ -39,12 +39,13 @@ Software Foundation, 59 Temple Place - S
 #ifndef TARGET_BELL
 #  define TARGET_BELL 007
 #  define TARGET_BS 010
-#  define TARGET_TAB 011
-#  define TARGET_NEWLINE 012
-#  define TARGET_VT 013
-#  define TARGET_FF 014
 #  define TARGET_CR 015
+#  define TARGET_DIGIT0 060
 #  define TARGET_ESC 033
+#  define TARGET_FF 014
+#  define TARGET_NEWLINE 012
+#  define TARGET_TAB 011
+#  define TARGET_VT 013
 #endif
 
 /* Store in OUTPUT a string (made with alloca) containing an
diff -rup orig/egcc-CVS20040412/gcc/doc/tm.texi egcc-CVS20040412/gcc/doc/tm.texi
--- orig/egcc-CVS20040412/gcc/doc/tm.texi	Sun Apr 11 07:23:17 2004
+++ egcc-CVS20040412/gcc/doc/tm.texi	Mon Apr 12 20:58:28 2004
@@ -1787,13 +1787,16 @@ of words in each data entry.
 @section Target Character Escape Sequences
 @cindex escape sequences
 
-By default, GCC assumes that the C character escape sequences take on
-their ASCII values for the target.  If this is not correct, you must
-explicitly define all of the macros below.  All of them must evaluate
-to constants; they are used in @code{case} statements.
+By default, GCC assumes that the C character escape sequences and other
+characters take on their ASCII values for the target.  If this is not
+correct, you must explicitly define all of the macros below.  All of
+them must evaluate to constants; they are used in @code{case}
+statements.
 
 @findex TARGET_BELL
+@findex TARGET_BS
 @findex TARGET_CR
+@findex TARGET_DIGIT0
 @findex TARGET_ESC
 @findex TARGET_FF
 @findex TARGET_NEWLINE
@@ -1802,7 +1805,9 @@ to constants; they are used in @code{cas
 @multitable {@code{TARGET_NEWLINE}} {Escape} {ASCII character}
 @item Macro                 @tab Escape             @tab ASCII character
 @item @code{TARGET_BELL}    @tab @kbd{\a}           @tab @code{07}, @code{BEL}
+@item @code{TARGET_BS}      @tab @kbd{\b}           @tab @code{08}, @code{BS}
 @item @code{TARGET_CR}      @tab @kbd{\r}           @tab @code{0D}, @code{CR}
+@item @code{TARGET_DIGIT0}  @tab @kbd{0}            @tab @code{30}, @code{ZERO}
 @item @code{TARGET_ESC}     @tab @kbd{\e}, @kbd{\E} @tab @code{1B}, @code{ESC}
 @item @code{TARGET_FF}      @tab @kbd{\f}           @tab @code{0C}, @code{FF}
 @item @code{TARGET_NEWLINE} @tab @kbd{\n}           @tab @code{0A}, @code{LF}
diff -rup orig/egcc-CVS20040412/gcc/testsuite/gcc.dg/torture/builtin-ctype-2.c egcc-CVS20040412/gcc/testsuite/gcc.dg/torture/builtin-ctype-2.c
--- orig/egcc-CVS20040412/gcc/testsuite/gcc.dg/torture/builtin-ctype-2.c	Thu Apr  8 10:42:30 2004
+++ egcc-CVS20040412/gcc/testsuite/gcc.dg/torture/builtin-ctype-2.c	Mon Apr 12 20:44:29 2004
@@ -75,6 +75,29 @@ void test(int i)
   if (toascii(i) != (i & 0x7f))
     link_failure_var();
 
+  TEST_CTYPE_CST_TRUE (isdigit, '0');
+  TEST_CTYPE_CST_TRUE (isdigit, '1');
+  TEST_CTYPE_CST_TRUE (isdigit, '2');
+  TEST_CTYPE_CST_TRUE (isdigit, '3');
+  TEST_CTYPE_CST_TRUE (isdigit, '4');
+  TEST_CTYPE_CST_TRUE (isdigit, '5');
+  TEST_CTYPE_CST_TRUE (isdigit, '6');
+  TEST_CTYPE_CST_TRUE (isdigit, '7');
+  TEST_CTYPE_CST_TRUE (isdigit, '8');
+  TEST_CTYPE_CST_TRUE (isdigit, '9');
+
+  TEST_CTYPE_CST_FALSE (isdigit, '0'-1);
+  TEST_CTYPE_CST_FALSE (isdigit, '9'+1);
+  TEST_CTYPE_CST_FALSE (isdigit, -1);
+  TEST_CTYPE_CST_FALSE (isdigit, 0);
+  TEST_CTYPE_CST_FALSE (isdigit, 255);
+  TEST_CTYPE_CST_FALSE (isdigit, 256);
+  TEST_CTYPE_CST_FALSE (isdigit, 10000);
+  TEST_CTYPE_CST_FALSE (isdigit, __INT_MAX__);
+  
+  /* This ctype call should transform into another expression.  */
+  if (isdigit(i) != ((unsigned)i - '0' <= 9))
+    link_failure_var();
 #endif /* __OPTIMIZE__ */
 }
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]