This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[tree-ssa] FIx 20030807-9.c, factor some code
- From: law at redhat dot com
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 24 Sep 2003 02:02:14 -0600
- Subject: [tree-ssa] FIx 20030807-9.c, factor some code
- Reply-to: law at redhat dot com
This fixes the additional test recently added to 20030807-9.c and
factors the code to optimize reads from readonly strings into a common
function. Now if someone wants to add wide character support there's
only one place to change :-)
* fold-const.c (fold_read_from_constant_string): New function.
* tree.h (fold_read_from_constant_string): Prototype.
* expr.c (expand_expr, case INDIRECT_REF): Use it.
(expand_expr, case ARRAY_REF): Likewise. Put checking code
inside an ENABLE_CHECKING.
* tree-ssa-ccp.c (fold_stmt): Use fold_read_from_constant_string.
* tree-ssa-dom.c (simplify_rhs_and_lookup_avail_expr): Likewise.
Index: fold-const.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fold-const.c,v
retrieving revision 1.213.2.46
diff -c -3 -p -r1.213.2.46 fold-const.c
*** fold-const.c 18 Sep 2003 18:25:20 -0000 1.213.2.46
--- fold-const.c 24 Sep 2003 07:59:40 -0000
*************** nondestructive_fold_unary_to_constant (e
*** 9215,9218 ****
--- 9215,9267 ----
}
}
+ /* If EXP represents referencing an element in a constant string
+ (either via pointer arithmetic or array indexing), return the
+ tree representing the value accessed, otherwise return NULL. */
+
+ tree
+ fold_read_from_constant_string (tree exp)
+ {
+ if (TREE_CODE (exp) == INDIRECT_REF || TREE_CODE (exp) == ARRAY_REF)
+ {
+ tree exp1 = TREE_OPERAND (exp, 0);
+ tree index;
+ tree string;
+
+ if (TREE_CODE (exp) == INDIRECT_REF)
+ {
+ string = string_constant (exp1, &index);
+ }
+ else
+ {
+ tree domain = TYPE_DOMAIN (TREE_TYPE (exp1));
+ tree low_bound = domain ? TYPE_MIN_VALUE (domain) : integer_zero_node;
+ index = convert (sizetype, TREE_OPERAND (exp, 1));
+
+ /* Optimize the special-case of a zero lower bound.
+
+ We convert the low_bound to sizetype to avoid some problems
+ with constant folding. (E.g. suppose the lower bound is 1,
+ and its mode is QI. Without the conversion,l (ARRAY
+ +(INDEX-(unsigned char)1)) becomes ((ARRAY+(-(unsigned char)1))
+ +INDEX), which becomes (ARRAY+255+INDEX). Opps!) */
+ if (! integer_zerop (low_bound))
+ index = size_diffop (index, convert (sizetype, low_bound));
+
+ string = exp1;
+ }
+
+ if (string
+ && TREE_CODE (string) == STRING_CST
+ && TREE_CODE (index) == INTEGER_CST
+ && compare_tree_int (index, TREE_STRING_LENGTH (string)) < 0
+ && (GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (TREE_TYPE (string))))
+ == MODE_INT)
+ && (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (TREE_TYPE (string)))) == 1))
+ return build_int_2 ((TREE_STRING_POINTER (string)
+ [TREE_INT_CST_LOW (index)]), 0);
+ }
+ return NULL;
+ }
+
#include "gt-fold-const.h"
Index: tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.342.2.101
diff -c -3 -p -r1.342.2.101 tree.h
*** tree.h 21 Sep 2003 22:14:28 -0000 1.342.2.101
--- tree.h 24 Sep 2003 07:59:48 -0000
*************** extern tree omit_one_operand (tree, tree
*** 3167,3172 ****
--- 3167,3173 ----
extern tree invert_truthvalue (tree);
extern tree nondestructive_fold_unary_to_constant (enum tree_code, tree,
tree);
extern tree nondestructive_fold_binary_to_constant (enum tree_code, tree,
tree, tree);
+ extern tree fold_read_from_constant_string (tree);
/* In builtins.c */
extern tree fold_builtin (tree);
Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.c,v
retrieving revision 1.467.2.49
diff -c -3 -p -r1.467.2.49 expr.c
*** expr.c 22 Sep 2003 16:54:29 -0000 1.467.2.49
--- expr.c 24 Sep 2003 08:00:15 -0000
*************** expand_expr (tree exp, rtx target, enum
*** 7322,7340 ****
case INDIRECT_REF:
{
tree exp1 = TREE_OPERAND (exp, 0);
- tree index;
- tree string = string_constant (exp1, &index);
! /* Try to optimize reads from const strings. */
! if (string
! && TREE_CODE (string) == STRING_CST
! && TREE_CODE (index) == INTEGER_CST
! && compare_tree_int (index, TREE_STRING_LENGTH (string)) < 0
! && GET_MODE_CLASS (mode) == MODE_INT
! && GET_MODE_SIZE (mode) == 1
! && modifier != EXPAND_WRITE)
! return gen_int_mode (TREE_STRING_POINTER (string)
! [TREE_INT_CST_LOW (index)], mode);
op0 = expand_expr (exp1, NULL_RTX, VOIDmode, EXPAND_SUM);
op0 = memory_address (mode, op0);
--- 7322,7336 ----
case INDIRECT_REF:
{
tree exp1 = TREE_OPERAND (exp, 0);
! if (modifier != EXPAND_WRITE)
! {
! tree t;
!
! t = fold_read_from_constant_string (exp);
! if (t)
! return expand_expr (t, target, tmode, modifier);
! }
op0 = expand_expr (exp1, NULL_RTX, VOIDmode, EXPAND_SUM);
op0 = memory_address (mode, op0);
*************** expand_expr (tree exp, rtx target, enum
*** 7351,7358 ****
--- 7347,7357 ----
}
case ARRAY_REF:
+
+ #ifdef ENABLE_CHECKING
if (TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) != ARRAY_TYPE)
abort ();
+ #endif
{
tree array = TREE_OPERAND (exp, 0);
*************** expand_expr (tree exp, rtx target, enum
*** 7379,7392 ****
if (modifier != EXPAND_CONST_ADDRESS
&& modifier != EXPAND_INITIALIZER
! && modifier != EXPAND_MEMORY
! && TREE_CODE (array) == STRING_CST
! && TREE_CODE (index) == INTEGER_CST
! && compare_tree_int (index, TREE_STRING_LENGTH (array)) < 0
! && GET_MODE_CLASS (mode) == MODE_INT
! && GET_MODE_SIZE (mode) == 1)
! return gen_int_mode (TREE_STRING_POINTER (array)
! [TREE_INT_CST_LOW (index)], mode);
/* If this is a constant index into a constant array,
just get the value from the array. Handle both the cases when
--- 7378,7390 ----
if (modifier != EXPAND_CONST_ADDRESS
&& modifier != EXPAND_INITIALIZER
! && modifier != EXPAND_MEMORY)
! {
! tree t = fold_read_from_constant_string (exp);
!
! if (t)
! return expand_expr (t, target, tmode, modifier);
! }
/* If this is a constant index into a constant array,
just get the value from the array. Handle both the cases when
Index: tree-ssa-ccp.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-ccp.c,v
retrieving revision 1.1.2.94
diff -c -3 -p -r1.1.2.94 tree-ssa-ccp.c
*** tree-ssa-ccp.c 21 Sep 2003 22:14:27 -0000 1.1.2.94
--- tree-ssa-ccp.c 24 Sep 2003 08:00:17 -0000
*************** fold_stmt (tree *stmt_p)
*** 1411,1435 ****
/* Optimize *"foo" into 'f'. This is done here rather than
in fold to avoid problems with stuff like &*"foo". */
! if (TREE_CODE (rhs) == INDIRECT_REF)
! {
! tree exp1 = TREE_OPERAND (rhs, 0);
! tree index;
! tree string = string_constant (exp1, &index);
!
! if (string
! && TREE_CODE (string) == STRING_CST
! && TREE_CODE (index) == INTEGER_CST
! && compare_tree_int (index, TREE_STRING_LENGTH (string)) < 0
! && TREE_CODE (TREE_TYPE (string)) == ARRAY_TYPE
! && (GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (TREE_TYPE (string))))
! == MODE_INT)
! && (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (TREE_TYPE (string))))
! == 1))
! result = build_int_2 ((TREE_STRING_POINTER (string)
! [TREE_INT_CST_LOW (index)]), 0);
! }
!
/* If we couldn't fold the RHS, hand it over to the generic fold
routines. */
--- 1411,1418 ----
/* Optimize *"foo" into 'f'. This is done here rather than
in fold to avoid problems with stuff like &*"foo". */
! if (TREE_CODE (rhs) == INDIRECT_REF || TREE_CODE (rhs) == ARRAY_REF)
! result = fold_read_from_constant_string (rhs);
/* If we couldn't fold the RHS, hand it over to the generic fold
routines. */
Index: tree-ssa-dom.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-dom.c,v
retrieving revision 1.1.2.45
diff -c -3 -p -r1.1.2.45 tree-ssa-dom.c
*** tree-ssa-dom.c 23 Sep 2003 13:37:56 -0000 1.1.2.45
--- tree-ssa-dom.c 24 Sep 2003 08:00:23 -0000
*************** simplify_rhs_and_lookup_avail_expr (tree
*** 947,952 ****
--- 947,966 ----
ann, insert);
}
}
+
+ /* Optimize *"foo" into 'f'. This is done here rather than
+ in fold to avoid problems with stuff like &*"foo". */
+ if (TREE_CODE (rhs) == INDIRECT_REF || TREE_CODE (rhs) == ARRAY_REF)
+ {
+ tree t = fold_read_from_constant_string (rhs);
+
+ if (t)
+ result = update_rhs_and_lookup_avail_expr (stmt, t,
+ block_avail_exprs_p,
+ const_and_copies,
+ ann, insert);
+ }
+
return result;
}