This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[tree-ssa]: Another SSAPRE update
- From: Daniel Berlin <dberlin at dberlin dot org>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Diego Novillo <dnovillo at redhat dot com>,Jason Merrill <jason at redhat dot com>
- Date: Mon, 30 Sep 2002 19:29:38 -0400
- Subject: [tree-ssa]: Another SSAPRE update
Committed.
Fixes a few bugs in strength reduction, and keeps the SSA
representation up to date for strength reduction.
Adds a new TODO item for cleaning up remapping crud, so i don't forget.
I can easily expose a bug in insertion with this change:
Given
int main(void)
{
int i;
int a,b,c;
b = c = 5;
i = 0;
a = i * 5;
for (; i < 50; i++)
{
a = i * 5;
}
}
This simplifies to:
main()
{
int i;
int a;
int b;
int c;
c = 5;
b = c;
i = 0;
a = i * 5;
for (; i <= 49; i = i + 1)
{
a = i * 5;
}
}
Which we try to rewrite as:
main()
{
int i;
int a;
int b;
int c;
int pretmp.1;
c = 5;
b = c;
i = 0;
pretmp.1 = i * 5;
a = pretmp.1
for (; i <= 49; i = i + 1, pretmp.1 = pretmp.1 + 5)
{
a = pretmp.1;
}
}
I say *try* because the insertion after i = i + 1 causes an abort in
the insertion routines.
It tries to get the last executable statement in the "i = i + 1" block,
but the block is just a modify_expr, *not* a statement.
I think this is my fault, when i changed FOR_INIT insertions to
generate a compound expr, i changed FOR_EXPR to do the same, with the
same type of code.
One would think this would work at first thought.
Except, due to fun inconsistencies in the IR (not that I can't fathom
why it's done this way), FOR_INIT and FOR_BODY are statements, but
FOR_EXPR and FOR_COND are expressions.
If this were *not* true, we could share more code in the insertion
routines.
Is this fun type of inconsistency in the new IR, and thus, i should
change the insertion routine to do the right thing, or is it gone, and
thus, i should just ignore the problem for now, and do something about
it when the new simplifier goes in and the insertion routines get
updated/rewritten/whatever?
Anyway, i've commited the SSAPRE update.
2002-09-30 Daniel Berlin <dberlin@dberlin.org>
* tree-ssa-pre.c (repair_injury): Start work on updating SSA
representation for strength reduction injuries.
Print a new line after outputting tree node in debug statements.
Fix strength reduction of a candidate with two variables (IE a *
c).
Put the repair after the injuring statement, not at the end of the
block.
Break the RHS use lookup if it's defined by a phi.
(calculate_increment): Ditto on node printing.
(code_motion): Ditto on updating SSA rep for strength reduction
injuries.
(find_rhs_use_for_var): Rewrite to use maybe_find_rhs_use_for_var.
(maybe_find_rhs_use_for_var): Rename from find_rhs_use_for_var,
don't abort, return NULL.
(set_var_phis): Simplify break condition.
Make sure RHS *has* a use before we go and get it.
(rename2): Ditto on RHS checking.
When looking up injuring defs, break on phis.
(phi_opnd_from_res): Ditto.
(defs_y_dom_x): Ditto.
(TODO List): Add new TODO to fix the remapping crud.
2002-09-27 Daniel Berlin <dberlin@dberlin.org>
* tree-ssa-pre.c (tree_perform_ssapre): Move insertion into
splay tree inside the is_simple_modify_expr block, to prevent
tree check failure.
Index: tree-ssa-pre.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-pre.c,v
retrieving revision 1.1.4.21
diff -c -3 -p -w -B -b -r1.1.4.21 tree-ssa-pre.c
*** tree-ssa-pre.c 26 Sep 2002 19:01:07 -0000 1.1.4.21
--- tree-ssa-pre.c 30 Sep 2002 23:06:11 -0000
*************** Boston, MA 02111-1307, USA. */
*** 49,56 ****
#include "tree-inline.h"
#define EXTRANEOUS_EPHI_REMOVAL 0
! #define DEBUGGING_STRRED 0
! #define DEBUGGING_SSA_UPDATE 0
/* See http://citeseer.nj.nec.com/chow97new.html, and
http://citeseer.nj.nec.com/kennedy99partial.html for details of the
--- 49,56 ----
#include "tree-inline.h"
#define EXTRANEOUS_EPHI_REMOVAL 0
! #define DEBUGGING_STRRED 1
! #define DEBUGGING_SSA_UPDATE 1
/* See http://citeseer.nj.nec.com/chow97new.html, and
http://citeseer.nj.nec.com/kennedy99partial.html for details of the
*************** Boston, MA 02111-1307, USA. */
*** 69,76 ****
Get rid of hunting through statements for refs, now that
expressions have the refs we want as well -- This should
substantially
clean up the code, which was written when only statements had refs,
! becuase the expressions were not unshared.
Strength reduction improvements.
Register promotion.
*/
struct expr_info;
--- 69,84 ----
Get rid of hunting through statements for refs, now that
expressions have the refs we want as well -- This should
substantially
clean up the code, which was written when only statements had refs,
! because the expressions were not unshared.
!
! Remapping expression occurrences to the entire expression is a
pain, and is
! only done to avoid having to grab the first operand all the time
(the code
! was started before the change to include the *entire* expression
in the
! ref_expr was made). It would clean up the code a lot and remove a
lot of
! duplicated functions, whose only difference is one remaps and one
doesn't.
!
Strength reduction improvements.
+
Register promotion.
*/
struct expr_info;
*************** static void compute_domchildren PARAMS (
*** 81,86 ****
--- 89,95 ----
static inline bool a_dom_b PARAMS ((basic_block, basic_block));
static void set_var_phis PARAMS ((struct expr_info *, tree_ref, int));
static inline tree_ref find_rhs_use_for_var PARAMS ((tree_ref, tree));
+ static inline tree_ref maybe_find_rhs_use_for_var PARAMS ((tree_ref,
tree));
static inline tree_ref find_use_for_var PARAMS ((tree, tree));
static inline tree_ref find_def_for_stmt PARAMS ((tree));
static void expr_phi_insertion PARAMS ((sbitmap *, struct expr_info
*));
*************** static bool requires_edge_placement PARA
*** 115,121 ****
static bool is_injuring_def PARAMS ((struct expr_info *, tree));
static bool is_strred_cand PARAMS ((tree));
static tree calculate_increment PARAMS ((struct expr_info *, tree));
! static void repair_injury PARAMS ((struct expr_info *, tree_ref,
tree));
static void set_need_repair PARAMS ((struct expr_info *, tree_ref));
static void calculate_preorder PARAMS ((void));
static void update_phis_in_list PARAMS ((ref_list, tree_ref,
tree_ref));
--- 124,130 ----
static bool is_injuring_def PARAMS ((struct expr_info *, tree));
static bool is_strred_cand PARAMS ((tree));
static tree calculate_increment PARAMS ((struct expr_info *, tree));
! static void repair_injury PARAMS ((struct expr_info *, tree_ref,
tree, tree_ref));
static void set_need_repair PARAMS ((struct expr_info *, tree_ref));
static void calculate_preorder PARAMS ((void));
static void update_phis_in_list PARAMS ((ref_list, tree_ref,
tree_ref));
*************** static splay_tree orig_expr_map;
*** 135,141 ****
static splay_tree new_stmt_map;
static splay_tree need_repair_map;
! static bool strred_candidate;
/* sbitmap vector mapping blocks to the child blocks they dominate. */
static sbitmap *domchildren;
--- 144,150 ----
static splay_tree new_stmt_map;
static splay_tree need_repair_map;
!
/* sbitmap vector mapping blocks to the child blocks they dominate. */
static sbitmap *domchildren;
*************** set_var_phis (ei, phi, i)
*** 382,406 ****
curr_phi_operand++)
{
phi_operand = phi_arg_def (phi_arg (phi, curr_phi_operand));
! if (strred_candidate && !(ref_type (phi_operand) & V_PHI))
while (is_injuring_def (ei, ref_expr (phi_operand)))
{
phi_operand = find_rhs_use_for_var (phi_operand,
ref_var
(phi_operand));
! if (ref_type (imm_reaching_def (phi_operand)) & M_DEFAULT)
! {
! phi_operand = imm_reaching_def (phi_operand);
! break;
! }
! else if (ref_type (imm_reaching_def (phi_operand)) & V_PHI)
{
! phi_operand = imm_reaching_def (phi_operand);
break;
}
! phi_operand = find_rhs_use_for_var (imm_reaching_def (phi_operand),
! ref_var (phi_operand));
phi_operand = imm_reaching_def (phi_operand);
}
if (ref_type (phi_operand) & V_PHI)
--- 391,414 ----
curr_phi_operand++)
{
phi_operand = phi_arg_def (phi_arg (phi, curr_phi_operand));
! if (ei->strred_cand && !(ref_type (phi_operand) & V_PHI))
while (is_injuring_def (ei, ref_expr (phi_operand)))
{
+ tree_ref ird;
phi_operand = find_rhs_use_for_var (phi_operand,
ref_var
(phi_operand));
! ird = imm_reaching_def (phi_operand);
! if (ref_type (ird) & M_DEFAULT
! || ref_type (ird) & V_PHI
! || !maybe_find_rhs_use_for_var (ird,
! ref_var (phi_operand)))
{
! phi_operand = ird;
break;
}
! phi_operand = find_rhs_use_for_var (ird, ref_var (phi_operand));
phi_operand = imm_reaching_def (phi_operand);
}
if (ref_type (phi_operand) & V_PHI)
*************** find_def_for_stmt (stmt)
*** 431,443 ****
return NULL;
}
! /* Given the the def, and a variable,
! find the V_USE of the variable contained in that occurrence. */
static inline tree_ref
find_rhs_use_for_var ( def, var)
tree_ref def;
tree var;
{
struct ref_list_node *tmp;
tree_ref ref;
--- 439,464 ----
return NULL;
}
! /* Given the DEF, and a VAR, find the V_USE of VAR contained in the
expression
! of DEF. Abort if not found. */
static inline tree_ref
find_rhs_use_for_var (def, var)
tree_ref def;
tree var;
{
+ tree_ref ret = maybe_find_rhs_use_for_var (def, var);
+ if (!ret)
+ abort ();
+ return ret;
+ }
+
+ /* Given the the DEF, and a VAR, find the V_USE of the VAR contained
+ in that occurrence, if there is one. */
+ static inline tree_ref
+ maybe_find_rhs_use_for_var (def, var)
+ tree_ref def;
+ tree var;
+ {
struct ref_list_node *tmp;
tree_ref ref;
*************** find_rhs_use_for_var ( def, var)
*** 451,457 ****
continue;
return ref;
}
! abort();
}
/* Given the the real occurrence and a variable,
--- 472,478 ----
continue;
return ref;
}
! return NULL;
}
/* Given the the real occurrence and a variable,
*************** defs_y_dom_x (ei, y, x)
*** 511,521 ****
continue;
if (!imm_reaching_def (ref))
return false;
! if (strred_candidate)
while (is_injuring_def (ei, ref_expr (imm_reaching_def (ref))))
{
ref = find_rhs_use_for_var (imm_reaching_def (ref),
TREE_OPERAND (ref_expr (y), i));
ref = find_rhs_use_for_var (imm_reaching_def (ref),
TREE_OPERAND (ref_expr (y), i));
}
--- 532,545 ----
continue;
if (!imm_reaching_def (ref))
return false;
! if (ei->strred_cand)
while (is_injuring_def (ei, ref_expr (imm_reaching_def (ref))))
{
ref = find_rhs_use_for_var (imm_reaching_def (ref),
TREE_OPERAND (ref_expr (y), i));
+ if (ref_type (imm_reaching_def (ref)) & V_PHI
+ || ref_type (imm_reaching_def (ref)) & M_DEFAULT)
+ break;
ref = find_rhs_use_for_var (imm_reaching_def (ref),
TREE_OPERAND (ref_expr (y), i));
}
*************** defs_match_p (ei, t1, t2)
*** 554,560 ****
if (!use2)
return false;
/* Find the injuring definition, if one exists. */
! if (strred_candidate)
while (is_injuring_def (ei, ref_expr (imm_reaching_def (use1))))
{
/* First, we get the use in the *injuring definition*. */
--- 578,584 ----
if (!use2)
return false;
/* Find the injuring definition, if one exists. */
! if (ei->strred_cand)
while (is_injuring_def (ei, ref_expr (imm_reaching_def (use1))))
{
/* First, we get the use in the *injuring definition*. */
*************** phi_opnd_from_res (ei, Z, j, b)
*** 748,757 ****
FOR_EACH_REF (v, tmp, tree_refs (ref_stmt (Z)))
{
if (ref_type (v) & V_USE)
! if (strred_candidate)
while (is_injuring_def (ei, ref_expr (imm_reaching_def (v))))
{
v = find_rhs_use_for_var (imm_reaching_def (v), ref_var (v));
v = find_rhs_use_for_var (imm_reaching_def (v), ref_var (v));
}
/* If v is defined by phi in b */
--- 772,784 ----
FOR_EACH_REF (v, tmp, tree_refs (ref_stmt (Z)))
{
if (ref_type (v) & V_USE)
! if (ei->strred_cand)
while (is_injuring_def (ei, ref_expr (imm_reaching_def (v))))
{
v = find_rhs_use_for_var (imm_reaching_def (v), ref_var (v));
+ if (ref_type (imm_reaching_def (v)) & M_DEFAULT
+ || ref_type (imm_reaching_def (v)) & V_PHI)
+ break;
v = find_rhs_use_for_var (imm_reaching_def (v), ref_var (v));
}
/* If v is defined by phi in b */
*************** rename_2 (ei, rename2_set)
*** 861,871 ****
tree_ref op2;
if (!(ref_type (op1) & V_USE))
continue;
! if (strred_candidate)
while (is_injuring_def (ei, ref_expr (imm_reaching_def (op1))))
{
op1 = find_rhs_use_for_var (imm_reaching_def (op1),
ref_var (op1));
op1 = find_rhs_use_for_var (imm_reaching_def (op1),
ref_var (op1)) ;
}
--- 888,902 ----
tree_ref op2;
if (!(ref_type (op1) & V_USE))
continue;
! if (ei->strred_cand)
while (is_injuring_def (ei, ref_expr (imm_reaching_def (op1))))
{
op1 = find_rhs_use_for_var (imm_reaching_def (op1),
ref_var (op1));
+ if (ref_type (imm_reaching_def (op1)) & M_DEFAULT
+ || ref_type (imm_reaching_def (op1)) & V_PHI)
+ break;
+
op1 = find_rhs_use_for_var (imm_reaching_def (op1),
ref_var (op1)) ;
}
*************** rename_2 (ei, rename2_set)
*** 875,888 ****
if (op2 && ref_type (op2) & V_USE)
op2 = imm_reaching_def (op2);
! if (strred_candidate)
while (is_injuring_def (ei, ref_expr (op2)))
{
op2 = find_rhs_use_for_var (op2, ref_var
(op2));
! if (ref_type (imm_reaching_def (op2)) & M_DEFAULT)
{
! op2 = imm_reaching_def (op2);
break;
}
--- 906,924 ----
if (op2 && ref_type (op2) & V_USE)
op2 = imm_reaching_def (op2);
! if (ei->strred_cand)
while (is_injuring_def (ei, ref_expr (op2)))
{
+ tree_ref ird;
op2 = find_rhs_use_for_var (op2, ref_var
(op2));
! ird = imm_reaching_def (op2);
! if (ref_type (ird) & M_DEFAULT
! || ref_type (ird) & V_PHI
! || !maybe_find_rhs_use_for_var (ird,
! ref_var (op2)))
{
! op2 = ird;
break;
}
*************** expr_phi_insertion (dfs, ei)
*** 1537,1543 ****
int varcount = 0;
FOR_EACH_REF (ref, tmp, tree_refs (VARRAY_TREE (ei->realstmts, i)))
{
! if (strred_candidate)
while (ref_type (ref) & V_USE
&& ref_var (ref) == TREE_OPERAND (real, 0)
&& imm_reaching_def (ref)
--- 1572,1578 ----
int varcount = 0;
FOR_EACH_REF (ref, tmp, tree_refs (VARRAY_TREE (ei->realstmts, i)))
{
! if (ei->strred_cand)
while (ref_type (ref) & V_USE
&& ref_var (ref) == TREE_OPERAND (real, 0)
&& imm_reaching_def (ref)
*************** expr_phi_insertion (dfs, ei)
*** 1545,1550 ****
--- 1580,1589 ----
{
ref = find_rhs_use_for_var (imm_reaching_def (ref),
ref_var (ref));
+ if (ref_type (imm_reaching_def (ref)) & M_DEFAULT
+ || ref_type (imm_reaching_def (ref)) & V_PHI)
+ break;
+
ref = find_rhs_use_for_var (imm_reaching_def (ref),
ref_var (ref));
}
*************** expr_phi_insertion (dfs, ei)
*** 1552,1558 ****
work right? */
if (!(ref_type (ref) & V_USE )
|| !is_simple_modify_expr (ref_expr (ref))
! || TREE_OPERAND (ref_expr (ref), 1) != real)
continue;
if (ref_var (ref) != TREE_OPERAND (real, 0)
&& (TREE_OPERAND (real, 1) == NULL
--- 1591,1597 ----
work right? */
if (!(ref_type (ref) & V_USE )
|| !is_simple_modify_expr (ref_expr (ref))
! /*|| TREE_OPERAND (ref_expr (ref), 1) != real*/)
continue;
if (ref_var (ref) != TREE_OPERAND (real, 0)
&& (TREE_OPERAND (real, 1) == NULL
*************** calculate_increment (ei, expr)
*** 1862,1867 ****
--- 1901,1907 ----
{
fprintf (dump_file, "Increment calculated to be: ");
print_c_tree (dump_file, incr);
+ fprintf (dump_file, "\n");
}
#endif
return incr;
*************** calculate_increment (ei, expr)
*** 1869,1884 ****
}
/* Repair the injury for USE. Currently ugly as hell, i'm just making
it do
*something* so i can make sure we are choosing candidates and
renaming
! properly. */
static void
! repair_injury (ei, use, temp)
struct expr_info *ei;
tree_ref use;
tree temp;
{
int i;
tree expr, stmt;
basic_block bb;
for (i = 0; i < 2; i++)
{
tree incr = integer_zero_node;
--- 1909,1930 ----
}
/* Repair the injury for USE. Currently ugly as hell, i'm just making
it do
*something* so i can make sure we are choosing candidates and
renaming
! properly. It's uncommented so that you don't accidently try to
understand it
! or modify it, since it will be going away post-haste.*/
static void
! repair_injury (ei, use, temp, orig_euse)
struct expr_info *ei;
tree_ref use;
tree temp;
+ tree_ref orig_euse;
{
+
int i;
tree expr, stmt;
basic_block bb;
+ struct ref_list_node *tmp;
+ tree_ref tempref;
+
for (i = 0; i < 2; i++)
{
tree incr = integer_zero_node;
*************** repair_injury (ei, use, temp)
*** 1889,1896 ****
--- 1935,1948 ----
v = find_use_for_var (ref_expr (use), TREE_OPERAND (ei->expr, i));
else
v = use;
+
if (ref_type (v) & V_DEF)
{
+ /* If this isn't a def of *this* variable, ignore it, since it
can't
+ *possibly* injure it. */
+ if (ref_var (find_def_for_stmt (ref_stmt (v)))
+ != TREE_OPERAND (ei->expr, i))
+ continue;
while (is_injuring_def (ei, ref_expr (v)))
{
if (htab_find (ei->repaired, ref_expr (v)) == NULL)
*************** repair_injury (ei, use, temp)
*** 1900,1905 ****
--- 1952,1958 ----
{
fprintf (dump_file, "Injuring def to repair is: ");
print_c_tree (dump_file, ref_expr (v));
+ fprintf (dump_file, "\n");
}
#endif
incr = calculate_increment (ei, ref_expr (v));
*************** repair_injury (ei, use, temp)
*** 1910,1927 ****
stmt = build_stmt (EXPR_STMT, expr);
TREE_TYPE (stmt) = TREE_TYPE (expr);
bb = ref_bb (use);
! if (is_ctrl_altering_stmt (BLOCK_END_TREE (bb->index)))
! insert_stmt_tree_before (stmt, BLOCK_END_TREE (bb->index),
! bb);
! else
! insert_stmt_tree_after (stmt, BLOCK_END_TREE (bb->index),
! bb);
*(htab_find_slot (ei->repaired, ref_expr (v), INSERT)) = ref_expr
(v);
}
v = find_rhs_use_for_var (v, TREE_OPERAND (ei->expr, i));
! if (ref_type (imm_reaching_def (v)) & M_DEFAULT)
break;
v = find_rhs_use_for_var (imm_reaching_def (v),
TREE_OPERAND (ei->expr, i));
--- 1963,1995 ----
stmt = build_stmt (EXPR_STMT, expr);
TREE_TYPE (stmt) = TREE_TYPE (expr);
bb = ref_bb (use);
!
! insert_stmt_tree_after (stmt, ref_stmt (v), bb);
*(htab_find_slot (ei->repaired, ref_expr (v), INSERT)) = ref_expr
(v);
+ /* Update SSA for the repair.
+ 1. Find the refs in the statement.
+ 2. Updating the reaching defs of each use.
+ 3. Insert into new statement map the tuple (orig_euse,
+ repair stmt).
+ */
+ find_refs_in_stmt (stmt, bb);
+ FOR_EACH_REF (tempref, tmp, tree_refs (stmt))
+ {
+ if (!(ref_type (tempref) & V_USE))
+ continue;
+ find_reaching_def_of_var (tempref, bb, NULL);
+ }
+ splay_tree_insert (new_stmt_map,
+ (splay_tree_key) orig_euse,
+ (splay_tree_value) stmt);
}
v = find_rhs_use_for_var (v, TREE_OPERAND (ei->expr, i));
! if (ref_type (imm_reaching_def (v)) & M_DEFAULT
! || ref_type (imm_reaching_def (v)) & V_PHI
! || !maybe_find_rhs_use_for_var (imm_reaching_def (v),
! TREE_OPERAND (ei->expr, i)))
break;
v = find_rhs_use_for_var (imm_reaching_def (v),
TREE_OPERAND (ei->expr, i));
*************** repair_injury (ei, use, temp)
*** 1936,1942 ****
curr_phi_operand++)
{
tree_ref phi_op = phi_arg_def (phi_arg (phi,
curr_phi_operand));
! repair_injury (ei, phi_op, temp);
}
}
else
--- 2004,2013 ----
curr_phi_operand++)
{
tree_ref phi_op = phi_arg_def (phi_arg (phi,
curr_phi_operand));
! tree_ref ephi = phi_at_block (ei, ref_bb (phi));
! tree_ref ephi_op = phi_operand (ephi,
! phi_arg_edge (phi_arg (phi, curr_phi_operand))->src);
! repair_injury (ei, phi_op, temp, ephi_op);
}
}
else
*************** repair_injury (ei, use, temp)
*** 1952,1957 ****
--- 2023,2029 ----
{
fprintf (dump_file, "Injuring def to repair is: ");
print_c_node (dump_file,ref_expr (imm_reaching_def (v)));
+ fprintf (dump_file, "\n");
}
#endif
*************** repair_injury (ei, use, temp)
*** 1964,1983 ****
stmt = build_stmt (EXPR_STMT, expr);
TREE_TYPE (stmt) = TREE_TYPE (expr);
bb = ref_bb (use);
! if (is_ctrl_altering_stmt (BLOCK_END_TREE (bb->index)))
! insert_stmt_tree_before (stmt, BLOCK_END_TREE (bb->index),
! bb);
! else
! insert_stmt_tree_after (stmt, BLOCK_END_TREE (bb->index),
bb);
*(htab_find_slot (ei->repaired,
ref_expr (imm_reaching_def (v)), INSERT)) = imm_reaching_def
(v);
!
}
v = find_rhs_use_for_var (imm_reaching_def (v),
TREE_OPERAND (ei->expr, i));
! if (ref_type (imm_reaching_def (v)) & M_DEFAULT)
break;
v = find_rhs_use_for_var (imm_reaching_def (v),
TREE_OPERAND (ei->expr, i));
--- 2036,2071 ----
stmt = build_stmt (EXPR_STMT, expr);
TREE_TYPE (stmt) = TREE_TYPE (expr);
bb = ref_bb (use);
! insert_stmt_tree_after (stmt,
! ref_stmt (imm_reaching_def (v)),
bb);
*(htab_find_slot (ei->repaired,
ref_expr (imm_reaching_def (v)), INSERT)) = imm_reaching_def
(v);
! /* Update SSA for the repair.
! 1. Find the refs in the statement.
! 2. Updating the reaching defs of each use.
! 3. Insert into new statement map the tuple (orig_euse,
! repair stmt).
! */
! find_refs_in_stmt (stmt, bb);
! FOR_EACH_REF (tempref, tmp, tree_refs (stmt))
! {
! if (!(ref_type (tempref) & V_USE))
! continue;
! find_reaching_def_of_var (tempref, bb, NULL);
! }
! splay_tree_insert (new_stmt_map,
! (splay_tree_key) orig_euse,
! (splay_tree_value) stmt);
}
v = find_rhs_use_for_var (imm_reaching_def (v),
TREE_OPERAND (ei->expr, i));
! if (ref_type (imm_reaching_def (v)) & M_DEFAULT
! ||ref_type (imm_reaching_def (v)) & V_PHI
! || !maybe_find_rhs_use_for_var (imm_reaching_def (v),
! TREE_OPERAND (ei->expr, i)))
!
break;
v = find_rhs_use_for_var (imm_reaching_def (v),
TREE_OPERAND (ei->expr, i));
*************** code_motion (ei, temp)
*** 2218,2235 ****
need_repair_map = splay_tree_new (splay_tree_compare_pointers,
NULL, NULL);
exprs = fibheap_new ();
! if (strred_candidate)
{
insert_euse_in_preorder_dt_order (ei, exprs);
while (!fibheap_empty (exprs))
{
use = fibheap_extract_min (exprs);
! if (strred_candidate)
! if (ref_type (use) & E_USE
&& exprref_reload (use)
&& !exprref_inserted (use))
{
! repair_injury (ei, use, temp);
/* set_need_repair (ei, use);*/
}
}
--- 2306,2322 ----
need_repair_map = splay_tree_new (splay_tree_compare_pointers,
NULL, NULL);
exprs = fibheap_new ();
! if (ei->strred_cand)
{
insert_euse_in_preorder_dt_order (ei, exprs);
while (!fibheap_empty (exprs))
{
use = fibheap_extract_min (exprs);
! if ((ref_type (use) & E_USE)
&& exprref_reload (use)
&& !exprref_inserted (use))
{
! repair_injury (ei, use, temp, use);
/* set_need_repair (ei, use);*/
}
}
*************** code_motion (ei, temp)
*** 2315,2321 ****
if (dump_file)
{
fprintf (dump_file, "\nUpdated a save use:\n");
! dump_ref_list (dump_file, "", tree_refs (use_stmt), 0, 0);
}
#endif
--- 2402,2408 ----
if (dump_file)
{
fprintf (dump_file, "\nUpdated a save use:\n");
! dump_ref_list (dump_file, "", tree_refs (use_stmt), 0, 1);
}
#endif
*************** code_motion (ei, temp)
*** 2345,2351 ****
if (dump_file)
{
fprintf (dump_file, "\nUpdated a reload use:\n");
! dump_ref_list (dump_file, "", tree_refs (use_stmt), 0, 0);
}
#endif
}
--- 2432,2438 ----
if (dump_file)
{
fprintf (dump_file, "\nUpdated a reload use:\n");
! dump_ref_list (dump_file, "", tree_refs (use_stmt), 0, 1);
}
#endif
}
*************** code_motion (ei, temp)
*** 2356,2362 ****
tree_ref phi;
tree_ref phiop;
size_t i;
! splay_tree_node phidefnode;
phi = create_ref (temp, V_PHI, ref_bb (use),
BLOCK_HEAD_TREE (ref_bb (use)->index),
--- 2443,2449 ----
tree_ref phi;
tree_ref phiop;
size_t i;
! splay_tree_node phidefnode, defbynode;
phi = create_ref (temp, V_PHI, ref_bb (use),
BLOCK_HEAD_TREE (ref_bb (use)->index),
*************** code_motion (ei, temp)
*** 2381,2402 ****
}
if (!pred)
abort();
! defby = expruse_def (phiop);
! if (ref_type (expruse_def (phiop)) & E_USE)
{
tree_ref tempdef;
phidefnode = splay_tree_lookup (new_stmt_map,
(splay_tree_key) ref_expr (defby));
-
if (!phidefnode)
abort();
tempdef = find_def_for_stmt ((tree) phidefnode->value);
-
add_phi_arg (phi, tempdef, pred);
-
-
if (find_list_node (reached_uses (tempdef), phi) == NULL)
add_ref_to_list_end (reached_uses (tempdef), phi);
if (find_list_node (imm_uses (tempdef), phi) == NULL)
--- 2468,2503 ----
}
if (!pred)
abort();
! /* Sigh. For strength reduction, the ephi can quite possibly
! have arguments that are all the same (since the injuries are
! transparent). Thus, for these cases, we store the
! new phi def in the map under the key of the phi operand,
! rather than the phi operand's definition.
! So, we see if we have something in the map for the phiop, and,
! if so, use that node.
! */
! defbynode = splay_tree_lookup (new_stmt_map,
! (splay_tree_key) phiop);
! defby = defbynode ? phiop : expruse_def (phiop);
! if (!expruse_phiop (defby)
! && !exprref_inserted (defby)
! && !exprref_save (defby))
! continue;
! if (ref_type (defby) & E_USE)
{
tree_ref tempdef;
+ if (expruse_phiop (defby))
phidefnode = splay_tree_lookup (new_stmt_map,
+ (splay_tree_key) defby);
+ else
+ phidefnode = splay_tree_lookup (new_stmt_map,
(splay_tree_key) ref_expr (defby));
if (!phidefnode)
abort();
tempdef = find_def_for_stmt ((tree) phidefnode->value);
add_phi_arg (phi, tempdef, pred);
if (find_list_node (reached_uses (tempdef), phi) == NULL)
add_ref_to_list_end (reached_uses (tempdef), phi);
if (find_list_node (imm_uses (tempdef), phi) == NULL)
*************** code_motion (ei, temp)
*** 2412,2420 ****
add_phi_arg (phi, (tree_ref) phidefnode->value, pred);
}
-
}
-
}
}
free (avdefs);
--- 2513,2519 ----
*************** pre_part_1_trav (slot, data)
*** 2455,2461 ****
struct expr_info *ei = (struct expr_info *) slot;
if (VARRAY_ACTIVE_SIZE (ei->reals) < 2)
return 0;
! strred_candidate = ei->strred_cand;
expr_phi_insertion ((sbitmap *)data, ei);
rename_1 (ei);
if (dump_file)
--- 2554,2560 ----
struct expr_info *ei = (struct expr_info *) slot;
if (VARRAY_ACTIVE_SIZE (ei->reals) < 2)
return 0;
!
expr_phi_insertion ((sbitmap *)data, ei);
rename_1 (ei);
if (dump_file)
*************** tree_perform_ssapre ()
*** 2603,2617 ****
continue;
if (htab_find (seen, expr) != NULL)
continue;
splay_tree_insert (orig_expr_map,
(splay_tree_key) TREE_OPERAND (expr, 1),
(splay_tree_value) expr);
! if (is_simple_modify_expr (expr))
expr = TREE_OPERAND (expr, 1);
if ((is_simple_binary_expr (expr)
/* || is_simple_cast (expr)
|| is_simple_unary_expr (expr)*/)
! && TREE_CODE (expr) != INDIRECT_REF)
{
struct expr_info *slot;
size_t k;
--- 2702,2720 ----
continue;
if (htab_find (seen, expr) != NULL)
continue;
+ if (is_simple_modify_expr (expr))
+ {
splay_tree_insert (orig_expr_map,
(splay_tree_key) TREE_OPERAND (expr, 1),
(splay_tree_value) expr);
!
expr = TREE_OPERAND (expr, 1);
+ }
if ((is_simple_binary_expr (expr)
/* || is_simple_cast (expr)
|| is_simple_unary_expr (expr)*/)
! && TREE_CODE (expr) != INDIRECT_REF
! && !is_simple_condexpr (expr))
{
struct expr_info *slot;
size_t k;