This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH]: transform builtin isdigit [take 2]
- From: "Kaveh R. Ghazi" <ghazi at caip dot rutgers dot edu>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 14 Apr 2004 07:38:14 -0400 (EDT)
- Subject: [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__ */
}