summaryrefslogtreecommitdiff
path: root/gcc/sese.c
diff options
context:
space:
mode:
authorbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2010-01-13 09:19:24 +0000
committerbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2010-01-13 09:19:24 +0000
commit5db0dcd07146bd2515187aba61037bd4eac97f90 (patch)
tree9a0ae1da3b521275708a5dde9ad949db9df6db66 /gcc/sese.c
parent9d3b5f98f208b2e4489e9bc1530dd6a67874f7ad (diff)
downloadgcc-5db0dcd07146bd2515187aba61037bd4eac97f90.tar.gz
2010-01-13 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 155849 git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@155852 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/sese.c')
-rw-r--r--gcc/sese.c74
1 files changed, 58 insertions, 16 deletions
diff --git a/gcc/sese.c b/gcc/sese.c
index e59fdf667d0..50ac698ec0f 100644
--- a/gcc/sese.c
+++ b/gcc/sese.c
@@ -874,7 +874,20 @@ expand_scalar_variables_expr (tree type, tree op0, enum tree_code code,
return expand_scalar_variables_ssa_name (op0, bb, region, map, gsi);
if (code == ADDR_EXPR)
- return op0;
+ {
+ tree op00 = TREE_OPERAND (op0, 0);
+
+ if (handled_component_p (op00)
+ && TREE_CODE (op00) == ARRAY_REF)
+ {
+ tree e = expand_scalar_variables_expr (TREE_TYPE (op00), op00,
+ TREE_CODE (op00),
+ NULL, bb, region, map, gsi);
+ return fold_build1 (code, TREE_TYPE (op0), e);
+ }
+
+ return op0;
+ }
gcc_unreachable ();
return NULL;
@@ -1024,13 +1037,41 @@ get_false_edge_from_guard_bb (basic_block bb)
/* Returns true when NAME is defined in LOOP. */
static bool
-defined_in_loop_p (tree name, loop_p loop)
+name_defined_in_loop_p (tree name, loop_p loop)
{
gimple stmt = SSA_NAME_DEF_STMT (name);
return (gimple_bb (stmt)->loop_father == loop);
}
+/* Returns true when EXPR contains SSA_NAMEs defined in LOOP. */
+
+static bool
+expr_defined_in_loop_p (tree expr, loop_p loop)
+{
+ switch (TREE_CODE_LENGTH (TREE_CODE (expr)))
+ {
+ case 3:
+ return expr_defined_in_loop_p (TREE_OPERAND (expr, 0), loop)
+ || expr_defined_in_loop_p (TREE_OPERAND (expr, 1), loop)
+ || expr_defined_in_loop_p (TREE_OPERAND (expr, 2), loop);
+
+ case 2:
+ return expr_defined_in_loop_p (TREE_OPERAND (expr, 0), loop)
+ || expr_defined_in_loop_p (TREE_OPERAND (expr, 1), loop);
+
+ case 1:
+ return expr_defined_in_loop_p (TREE_OPERAND (expr, 0), loop);
+
+ case 0:
+ return TREE_CODE (expr) == SSA_NAME
+ && name_defined_in_loop_p (expr, loop);
+
+ default:
+ return false;
+ }
+}
+
/* Returns the gimple statement that uses NAME outside the loop it is
defined in, returns NULL if there is no such loop close phi node.
An invariant of the loop closed SSA form is that the only use of a
@@ -1087,26 +1128,34 @@ add_loop_exit_phis (void **slot, void *data)
struct rename_map_elt_s *entry;
alep_p a;
loop_p loop;
- tree expr, new_name;
+ tree expr, new_name, old_name;
bool def_in_loop_p, used_outside_p, need_close_phi_p;
gimple old_close_phi;
- if (!slot || !data)
+ if (!slot || !*slot || !data)
return 1;
entry = (struct rename_map_elt_s *) *slot;
a = (alep_p) data;
loop = a->loop;
- expr = entry->expr;
+ new_name = expr = entry->expr;
+ old_name = entry->old_name;
+
+ def_in_loop_p = expr_defined_in_loop_p (expr, loop);
+ if (!def_in_loop_p)
+ return 1;
+
+ /* Remove the old rename from the map when the expression is defined
+ in the loop that we're closing. */
+ free (*slot);
+ *slot = NULL;
if (TREE_CODE (expr) != SSA_NAME)
return 1;
- new_name = expr;
- def_in_loop_p = defined_in_loop_p (new_name, loop);
- old_close_phi = alive_after_loop (entry->old_name);
+ old_close_phi = alive_after_loop (old_name);
used_outside_p = (old_close_phi != NULL);
- need_close_phi_p = (def_in_loop_p && used_outside_p
+ need_close_phi_p = (used_outside_p
&& close_phi_not_yet_inserted_p (loop, new_name));
/* Insert a loop close phi node. */
@@ -1123,13 +1172,6 @@ add_loop_exit_phis (void **slot, void *data)
new_res));
}
- /* Remove the old rename from the map. */
- if (def_in_loop_p && *slot)
- {
- free (*slot);
- *slot = NULL;
- }
-
return 1;
}