Mercurial > hg > CbC > CbC_gcc
diff gcc/sese.c @ 63:b7f97abdc517 gcc-4.6-20100522
update gcc from gcc-4.5.0 to gcc-4.6
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 24 May 2010 12:47:05 +0900 |
parents | 77e2b8dfacca |
children | f6334be47118 |
line wrap: on
line diff
--- a/gcc/sese.c Fri Feb 12 23:41:23 2010 +0900 +++ b/gcc/sese.c Mon May 24 12:47:05 2010 +0900 @@ -1,5 +1,6 @@ /* Single entry single exit control flow regions. - Copyright (C) 2008, 2009 Free Software Foundation, Inc. + Copyright (C) 2008, 2009, 2010 + Free Software Foundation, Inc. Contributed by Jan Sjodin <jan.sjodin@amd.com> and Sebastian Pop <sebastian.pop@amd.com>. @@ -28,6 +29,7 @@ #include "rtl.h" #include "basic-block.h" #include "diagnostic.h" +#include "tree-pretty-print.h" #include "tree-flow.h" #include "toplev.h" #include "tree-dump.h" @@ -78,7 +80,7 @@ hashval_t rename_map_elt_info (const void *elt) { - return htab_hash_pointer (((const struct rename_map_elt_s *) elt)->old_name); + return SSA_NAME_VERSION (((const struct rename_map_elt_s *) elt)->old_name); } /* Compares database elements E1 and E2. */ @@ -486,7 +488,7 @@ } } -/* Returns the name associated to OLD_NAME in MAP. */ +/* Returns the expression associated to OLD_NAME in MAP. */ static tree get_rename (htab_t map, tree old_name) @@ -494,6 +496,7 @@ struct rename_map_elt_s tmp; PTR *slot; + gcc_assert (TREE_CODE (old_name) == SSA_NAME); tmp.old_name = old_name; slot = htab_find_slot (map, &tmp, NO_INSERT); @@ -503,7 +506,7 @@ return old_name; } -/* Register in MAP the rename tuple (old_name, expr). */ +/* Register in MAP the rename tuple (OLD_NAME, EXPR). */ void set_rename (htab_t map, tree old_name, tree expr) @@ -526,6 +529,62 @@ *slot = new_rename_map_elt (old_name, expr); } +/* Renames the expression T following the tuples (OLD_NAME, EXPR) in + the rename map M. Returns the expression T after renaming. */ + +static tree +rename_variables_in_expr (htab_t m, tree t) +{ + if (!t) + return t; + + if (TREE_CODE (t) == SSA_NAME) + return get_rename (m, t); + + switch (TREE_CODE_LENGTH (TREE_CODE (t))) + { + case 3: + TREE_OPERAND (t, 2) = rename_variables_in_expr (m, TREE_OPERAND (t, 2)); + + case 2: + TREE_OPERAND (t, 1) = rename_variables_in_expr (m, TREE_OPERAND (t, 1)); + + case 1: + TREE_OPERAND (t, 0) = rename_variables_in_expr (m, TREE_OPERAND (t, 0)); + + default: + return t; + } +} + +/* Renames all the loop->nb_iterations expressions following the + tuples (OLD_NAME, EXPR) in RENAME_MAP. */ + +void +rename_nb_iterations (htab_t rename_map) +{ + loop_iterator li; + struct loop *loop; + + FOR_EACH_LOOP (li, loop, 0) + loop->nb_iterations = rename_variables_in_expr (rename_map, + loop->nb_iterations); +} + +/* Renames all the parameters of SESE following the tuples (OLD_NAME, + EXPR) in RENAME_MAP. */ + +void +rename_sese_parameters (htab_t rename_map, sese region) +{ + int i; + tree p; + + for (i = 0; VEC_iterate (tree, SESE_PARAMS (region), i, p); i++) + VEC_replace (tree, SESE_PARAMS (region), i, + rename_variables_in_expr (rename_map, p)); +} + /* Adjusts the phi nodes in the block BB for variables defined in SCOP_REGION and used outside the SCOP_REGION. The code generation moves SCOP_REGION in the else clause of an "if (1)" and generates @@ -550,8 +609,9 @@ unsigned i; unsigned false_i = 0; gimple phi = gsi_stmt (si); + tree res = gimple_phi_result (phi); - if (!is_gimple_reg (PHI_RESULT (phi))) + if (!is_gimple_reg (res)) { sese_adjust_vphi (region, phi, true_e); continue; @@ -585,6 +645,7 @@ } SET_PHI_ARG_DEF (phi, i, expr); + set_rename (rename_map, old_name, res); } } } @@ -600,14 +661,19 @@ FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_ALL_USES) { tree use = USE_FROM_PTR (use_p); - tree expr = get_rename (map, use); - tree type_use = TREE_TYPE (use); - tree type_expr = TREE_TYPE (expr); + tree expr, type_use, type_expr; gimple_seq stmts; + if (TREE_CODE (use) != SSA_NAME) + continue; + + expr = get_rename (map, use); if (use == expr) continue; + type_use = TREE_TYPE (use); + type_expr = TREE_TYPE (expr); + if (type_use != type_expr || (TREE_CODE (expr) != SSA_NAME && is_gimple_reg (use))) @@ -714,7 +780,7 @@ to translate the names of induction variables. */ static tree -expand_scalar_variables_ssa_name (tree op0, basic_block bb, +expand_scalar_variables_ssa_name (tree type, tree op0, basic_block bb, sese region, htab_t map, gimple_stmt_iterator *gsi) { @@ -723,7 +789,7 @@ if (is_parameter (region, op0) || is_iv (op0)) - return get_rename (map, op0); + return fold_convert (type, get_rename (map, op0)); def_stmt = SSA_NAME_DEF_STMT (op0); @@ -732,7 +798,7 @@ if (new_op != op0 && gimple_bb (SSA_NAME_DEF_STMT (new_op)) == bb) - return new_op; + return fold_convert (type, new_op); if (gimple_bb (def_stmt) == bb) { @@ -740,13 +806,13 @@ we do not need to create a new expression for it, we only need to ensure its operands are expanded. */ expand_scalar_variables_stmt (def_stmt, bb, region, map, gsi); - return new_op; + return fold_convert (type, new_op); } else { if (!gimple_bb (def_stmt) || !bb_in_sese_p (gimple_bb (def_stmt), region)) - return new_op; + return fold_convert (type, new_op); switch (gimple_code (def_stmt)) { @@ -807,7 +873,7 @@ { tree old_name = TREE_OPERAND (op0, 0); tree expr = expand_scalar_variables_ssa_name - (old_name, bb, region, map, gsi); + (type, old_name, bb, region, map, gsi); if (TREE_CODE (expr) != SSA_NAME && is_gimple_reg (old_name)) @@ -839,6 +905,9 @@ return build4 (ARRAY_REF, type, base, subscript, op02, op03); } + case COMPONENT_REF: + return op0; + default: /* The above cases should catch everything. */ gcc_unreachable (); @@ -871,10 +940,23 @@ } if (code == SSA_NAME) - return expand_scalar_variables_ssa_name (op0, bb, region, map, gsi); + return expand_scalar_variables_ssa_name (type, 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,11 +1106,38 @@ /* 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) +{ + return !SSA_NAME_IS_DEFAULT_DEF (name) + && gimple_bb (SSA_NAME_DEF_STMT (name))->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) { - gimple stmt = SSA_NAME_DEF_STMT (name); + 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); - return (gimple_bb (stmt)->loop_father == 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 @@ -1087,26 +1196,34 @@ 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 +1240,6 @@ new_res)); } - /* Remove the old rename from the map. */ - if (def_in_loop_p && *slot) - { - free (*slot); - *slot = NULL; - } - return 1; } @@ -1399,7 +1509,7 @@ /* Creates an IFSESE with CONDITION on edge ENTRY. */ -ifsese +static ifsese create_if_region_on_edge (edge entry, tree condition) { edge e; @@ -1453,6 +1563,34 @@ return if_region; } +/* Replaces the condition of the IF_REGION with CONDITION: + | if (CONDITION) + | true_region; + | else + | false_region; +*/ + +void +set_ifsese_condition (ifsese if_region, tree condition) +{ + sese region = if_region->region; + edge entry = region->entry; + basic_block bb = entry->dest; + gimple last = last_stmt (bb); + gimple_stmt_iterator gsi = gsi_last_bb (bb); + gimple cond_stmt; + + gcc_assert (gimple_code (last) == GIMPLE_COND); + + gsi_remove (&gsi, true); + gsi = gsi_last_bb (bb); + condition = force_gimple_operand_gsi (&gsi, condition, true, NULL, + false, GSI_NEW_STMT); + cond_stmt = gimple_build_cond_from_tree (condition, NULL_TREE, NULL_TREE); + gsi = gsi_last_bb (bb); + gsi_insert_after (&gsi, cond_stmt, GSI_NEW_STMT); +} + /* Returns the scalar evolution of T in REGION. Every variable that is not defined in the REGION is considered a parameter. */