This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[lno] Some bugfixes and improvements
- From: Zdenek Dvorak <rakdver at atrey dot karlin dot mff dot cuni dot cz>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 13 May 2004 23:13:18 +0200
- Subject: [lno] Some bugfixes and improvements
Hello,
this patch
-- prevents loss of aliasing information during strength reduction
(by keeping the original reference for alias analysis)
-- makes chrec_contains_symbols_defined_in_loop not to fail on invariant
addresses
-- makes tree_split_block not to mark statements moved to the newly
created block as modified.
Zdenek
Index: ChangeLog.lno
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/ChangeLog.lno,v
retrieving revision 1.1.2.157
diff -c -3 -p -r1.1.2.157 ChangeLog.lno
*** ChangeLog.lno 12 May 2004 10:10:19 -0000 1.1.2.157
--- ChangeLog.lno 13 May 2004 21:07:59 -0000
***************
*** 1,3 ****
--- 1,20 ----
+ 2004-05-13 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * expr.c (expand_expr_real_1): Use REF_ORIGINAL information
+ from INDIRECT_REFS.
+ * tree-flow.h (force_gimple_operand, rewrite_address_base): Declare.
+ * tree-ssa-loop-ivopts.c (force_gimple_operand): Expand.
+ (add_address_candidates): Add candidates with constant offset
+ stripped.
+ (idx_remove_ssa_names, unshare_and_remove_ssa_names,
+ rewrite_address_base): New.
+ (rewrite_use_address): Use rewrite_address_base.
+ * tree-into-ssa.c (register_new_def): Remove unused code.
+ * tree-scalar-evolution.c (chrec_contains_symbols_defined_in_loop):
+ Handle invariants correctly.
+ * tree-cfg.c (tree_split_block): Do not modify the statements.
+ * tree.h (REF_ORIGINAL): New macro.
+
2004-05-12 Sebastian Pop <pop@cri.ensmp.fr>
* tree-chrec.c (chrec_evaluate): Use the type of the chrec
Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.c,v
retrieving revision 1.467.2.70.2.6
diff -c -3 -p -r1.467.2.70.2.6 expr.c
*** expr.c 25 Apr 2004 20:33:25 -0000 1.467.2.70.2.6
--- expr.c 13 May 2004 21:07:59 -0000
*************** expand_expr_real_1 (tree exp, rtx target
*** 6965,6970 ****
--- 6965,6971 ----
case INDIRECT_REF:
{
tree exp1 = TREE_OPERAND (exp, 0);
+ tree orig;
if (modifier != EXPAND_WRITE)
{
*************** expand_expr_real_1 (tree exp, rtx target
*** 6978,6984 ****
op0 = expand_expr (exp1, NULL_RTX, VOIDmode, EXPAND_SUM);
op0 = memory_address (mode, op0);
temp = gen_rtx_MEM (mode, op0);
! set_mem_attributes (temp, exp, 0);
/* If we are writing to this object and its type is a record with
readonly fields, we must mark it as readonly so it will
--- 6979,6989 ----
op0 = expand_expr (exp1, NULL_RTX, VOIDmode, EXPAND_SUM);
op0 = memory_address (mode, op0);
temp = gen_rtx_MEM (mode, op0);
!
! orig = REF_ORIGINAL (exp);
! if (!orig)
! orig = exp;
! set_mem_attributes (temp, orig, 0);
/* If we are writing to this object and its type is a record with
readonly fields, we must mark it as readonly so it will
Index: tree-cfg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-cfg.c,v
retrieving revision 1.1.4.244.2.16
diff -c -3 -p -r1.1.4.244.2.16 tree-cfg.c
*** tree-cfg.c 25 Apr 2004 20:33:40 -0000 1.1.4.244.2.16
--- tree-cfg.c 13 May 2004 21:07:59 -0000
*************** tree_split_block (basic_block bb, void *
*** 4009,4017 ****
--- 4009,4022 ----
bsi_tgt = bsi_start (new_bb);
while (!bsi_end_p (bsi))
{
+ bool was_modified;
+
act = bsi_stmt (bsi);
+ was_modified = stmt_modified_p (act);
bsi_remove (&bsi);
bsi_insert_after (&bsi_tgt, act, BSI_NEW_STMT);
+ if (!was_modified)
+ unmodify_stmt (act);
}
return new_bb;
Index: tree-flow.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-flow.h,v
retrieving revision 1.1.4.177.2.26
diff -c -3 -p -r1.1.4.177.2.26 tree-flow.h
*** tree-flow.h 30 Apr 2004 23:38:49 -0000 1.1.4.177.2.26
--- tree-flow.h 13 May 2004 21:07:59 -0000
*************** unsigned estimate_loop_size (struct loop
*** 635,640 ****
--- 635,643 ----
void rewrite_into_loop_closed_ssa (void);
void verify_loop_closed_ssa (void);
void compute_phi_arg_on_exit (edge, tree, tree);
+ tree force_gimple_operand (tree, tree *, bool, tree);
+ void rewrite_address_base (block_stmt_iterator *, tree *, tree);
+
/* Description of number of iterations of a loop. */
struct tree_niter_desc
Index: tree-into-ssa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-into-ssa.c,v
retrieving revision 1.1.4.6
diff -c -3 -p -r1.1.4.6 tree-into-ssa.c
*** tree-into-ssa.c 25 Apr 2004 20:33:42 -0000 1.1.4.6
--- tree-into-ssa.c 13 May 2004 21:07:59 -0000
*************** register_new_def (tree def, varray_type
*** 1277,1287 ****
if (! *block_defs_p)
VARRAY_TREE_INIT (*block_defs_p, 20, "block_defs");
- /* If we are rewriting ssa names, record the variable whose value must be
- be restored. */
- if (TREE_CODE (var) == SSA_NAME)
- VARRAY_PUSH_TREE (*block_defs_p, var);
-
/* Push the current reaching definition into *BLOCK_DEFS_P. This stack is
later used by the dominator tree callbacks to restore the reaching
definitions for all the variables defined in the block after a recursive
--- 1277,1282 ----
Index: tree-scalar-evolution.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-scalar-evolution.c,v
retrieving revision 1.1.2.46
diff -c -3 -p -r1.1.2.46 tree-scalar-evolution.c
*** tree-scalar-evolution.c 12 May 2004 10:10:19 -0000 1.1.2.46
--- tree-scalar-evolution.c 13 May 2004 21:07:59 -0000
*************** chrec_contains_symbols_defined_in_loop (
*** 401,406 ****
--- 401,409 ----
if (chrec == NULL_TREE)
return false;
+ if (TREE_INVARIANT (chrec))
+ return false;
+
if (TREE_CODE (chrec) == VAR_DECL
|| TREE_CODE (chrec) == PARM_DECL
|| TREE_CODE (chrec) == FUNCTION_DECL
Index: tree-ssa-loop-ivopts.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-loop-ivopts.c,v
retrieving revision 1.1.2.32
diff -c -3 -p -r1.1.2.32 tree-ssa-loop-ivopts.c
*** tree-ssa-loop-ivopts.c 30 Apr 2004 23:38:49 -0000 1.1.2.32
--- tree-ssa-loop-ivopts.c 13 May 2004 21:07:59 -0000
*************** static unsigned spill_cost; /* The cost
*** 243,250 ****
static varray_type decl_rtl_to_reset;
- static tree force_gimple_operand (tree, tree *, bool, tree);
-
/* Number of uses recorded in DATA. */
static inline unsigned
--- 243,248 ----
*************** update_addressable_flag (tree expr)
*** 632,638 ****
to be either ssa_name or integer constant. If VAR is not NULL, make the
base variable of the final destination be VAR if possible. */
! static tree
force_gimple_operand (tree expr, tree *stmts, bool simple, tree var)
{
enum tree_code code;
--- 630,636 ----
to be either ssa_name or integer constant. If VAR is not NULL, make the
base variable of the final destination be VAR if possible. */
! tree
force_gimple_operand (tree expr, tree *stmts, bool simple, tree var)
{
enum tree_code code;
*************** static void
*** 1959,1965 ****
add_address_candidates (struct ivopts_data *data,
struct iv *iv, struct iv_use *use)
{
! tree base, type;
/* First, the trivial choices. */
add_iv_value_candidates (data, iv, use);
--- 1957,1963 ----
add_address_candidates (struct ivopts_data *data,
struct iv *iv, struct iv_use *use)
{
! tree base, type, abase, tmp, *act;
/* First, the trivial choices. */
add_iv_value_candidates (data, iv, use);
*************** add_address_candidates (struct ivopts_da
*** 1983,1988 ****
--- 1981,2009 ----
add_candidate (data, base, iv->step, false, use);
}
}
+
+ /* Third, try removing the constant offset. */
+ abase = iv->base;
+ while (TREE_CODE (abase) == PLUS_EXPR
+ && TREE_CODE (TREE_OPERAND (abase, 1)) != INTEGER_CST)
+ abase = TREE_OPERAND (abase, 0);
+ /* We found the offset, so make the copy of the non-shared part and
+ remove it. */
+ if (TREE_CODE (abase) == PLUS_EXPR)
+ {
+ tmp = iv->base;
+ act = &base;
+
+ for (tmp = iv->base; tmp != abase; tmp = TREE_OPERAND (tmp, 0))
+ {
+ *act = build (PLUS_EXPR, TREE_TYPE (tmp),
+ NULL_TREE, TREE_OPERAND (tmp, 1));
+ act = &TREE_OPERAND (*act, 0);
+ }
+ *act = TREE_OPERAND (tmp, 0);
+
+ add_candidate (data, base, iv->step, false, use);
+ }
}
/* Possibly adds pseudocandidate for replacing the final value of USE by
*************** rewrite_use_nonlinear_expr (struct ivopt
*** 4113,4118 ****
--- 4134,4221 ----
}
}
+ /* Replaces ssa name in index IDX by its basic variable. Callback for
+ for_each_index. */
+
+ static bool
+ idx_remove_ssa_names (tree base ATTRIBUTE_UNUSED, tree *idx,
+ void *data ATTRIBUTE_UNUSED)
+ {
+ if (TREE_CODE (*idx) == SSA_NAME)
+ *idx = SSA_NAME_VAR (*idx);
+ return true;
+ }
+
+ /* Unshares REF and replaces ssa names inside it by their basic variables. */
+
+ static tree
+ unshare_and_remove_ssa_names (tree ref)
+ {
+ ref = unshare_expr (ref);
+ for_each_index (&ref, idx_remove_ssa_names, NULL);
+
+ return ref;
+ }
+
+ /* Rewrites base of memory access OP with expression WITH in statement
+ pointed to by BSI. */
+
+ void
+ rewrite_address_base (block_stmt_iterator *bsi, tree *op, tree with)
+ {
+ tree var = get_base_address (*op), new_var, new_name, copy, name;
+ tree orig;
+
+ if (!var || TREE_CODE (with) != SSA_NAME)
+ goto do_rewrite;
+
+ if (TREE_CODE (var) == INDIRECT_REF)
+ var = TREE_OPERAND (var, 0);
+ if (TREE_CODE (var) == SSA_NAME)
+ {
+ name = var;
+ var = SSA_NAME_VAR (var);
+ }
+ else if (DECL_P (var))
+ name = NULL_TREE;
+ else
+ goto do_rewrite;
+
+ if (var_ann (var)->type_mem_tag)
+ var = var_ann (var)->type_mem_tag;
+
+ /* We need to add a memory tag for the variable. But we do not want
+ to add it to the temporary used for the computations, since this leads
+ to problems in redundancy elimination when there are common parts
+ in two computations refering to the different arrays. So we copy
+ the variable to a new temporary. */
+ copy = build (MODIFY_EXPR, void_type_node, NULL_TREE, with);
+ if (name)
+ new_name = duplicate_ssa_name (name, copy);
+ else
+ {
+ new_var = create_tmp_var (TREE_TYPE (with), "ruatmp");
+ add_referenced_tmp_var (new_var);
+ var_ann (new_var)->type_mem_tag = var;
+ new_name = make_ssa_name (new_var, copy);
+ }
+ TREE_OPERAND (copy, 0) = new_name;
+ bsi_insert_before (bsi, copy, BSI_SAME_STMT);
+ with = new_name;
+
+ do_rewrite:
+
+ orig = NULL_TREE;
+ if (TREE_CODE (*op) == INDIRECT_REF)
+ orig = REF_ORIGINAL (*op);
+ if (!orig)
+ orig = unshare_and_remove_ssa_names (*op);
+
+ *op = build1 (INDIRECT_REF, TREE_TYPE (*op), with);
+ /* Record the original reference, for purposes of alias analysis. */
+ REF_ORIGINAL (*op) = orig;
+ }
+
/* Rewrites USE (address that is an iv) using candidate CAND. */
static void
*************** rewrite_use_address (struct ivopts_data
*** 4124,4170 ****
block_stmt_iterator bsi = stmt_bsi (use->stmt);
tree stmts;
tree op = force_gimple_operand (comp, &stmts, false, NULL_TREE);
- tree var, new_var, new_name, copy, name;
if (stmts)
bsi_insert_before (&bsi, stmts, BSI_SAME_STMT);
! if (TREE_CODE (op) == SSA_NAME)
! {
! var = get_base_address (*use->op_p);
! if (TREE_CODE (var) == INDIRECT_REF)
! var = TREE_OPERAND (var, 0);
! if (TREE_CODE (var) == SSA_NAME)
! {
! name = var;
! var = SSA_NAME_VAR (var);
! }
! else
! name = NULL_TREE;
! if (var_ann (var)->type_mem_tag)
! var = var_ann (var)->type_mem_tag;
!
! /* We need to add a memory tag for the variable. But we do not want
! to add it to the temporary used for the computations, since this leads
! to problems in redundancy elimination when there are common parts
! in two computations refering to the different arrays. So we copy
! the variable to a new temporary. */
! copy = build (MODIFY_EXPR, void_type_node, NULL_TREE, op);
! if (name)
! new_name = duplicate_ssa_name (name, copy);
! else
! {
! new_var = create_tmp_var (TREE_TYPE (op), "ruatmp");
! add_referenced_tmp_var (new_var);
! var_ann (new_var)->type_mem_tag = var;
! new_name = make_ssa_name (new_var, copy);
! }
! TREE_OPERAND (copy, 0) = new_name;
! bsi_insert_before (&bsi, copy, BSI_SAME_STMT);
! op = new_name;
! }
!
! *use->op_p = build1 (INDIRECT_REF, TREE_TYPE (*use->op_p), op);
}
/* Rewrites USE (the condition such that one of the arguments is an iv) using
--- 4227,4237 ----
block_stmt_iterator bsi = stmt_bsi (use->stmt);
tree stmts;
tree op = force_gimple_operand (comp, &stmts, false, NULL_TREE);
if (stmts)
bsi_insert_before (&bsi, stmts, BSI_SAME_STMT);
! rewrite_address_base (&bsi, use->op_p, op);
}
/* Rewrites USE (the condition such that one of the arguments is an iv) using
Index: tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.342.2.154.2.12
diff -c -3 -p -r1.342.2.154.2.12 tree.h
*** tree.h 27 Apr 2004 14:10:15 -0000 1.342.2.154.2.12
--- tree.h 13 May 2004 21:07:59 -0000
*************** struct tree_vec GTY(())
*** 1042,1047 ****
--- 1042,1050 ----
#define TREE_OPERAND(NODE, I) TREE_OPERAND_CHECK (NODE, I)
#define TREE_COMPLEXITY(NODE) (EXPR_CHECK (NODE)->exp.complexity)
+ /* In INDIRECT_REF. */
+ #define REF_ORIGINAL(NODE) TREE_CHAIN (TREE_CHECK (NODE, INDIRECT_REF))
+
/* In a LABELED_BLOCK_EXPR node. */
#define LABELED_BLOCK_LABEL(NODE) \
TREE_OPERAND_CHECK_CODE (NODE, LABELED_BLOCK_EXPR, 0)