aboutsummaryrefslogtreecommitdiff
path: root/gcc/cfgrtl.c
diff options
context:
space:
mode:
authorMichael Matz <matz@suse.de>2009-04-26 19:35:04 +0000
committerMichael Matz <matz@gcc.gnu.org>2009-04-26 19:35:04 +0000
commit4e3825dba91bb719284b07b90aefc273705399f2 (patch)
tree8d709f227ad75b658f3487e9483a960234342733 /gcc/cfgrtl.c
parent5846213b872f73949db3a85c7da529aa8941dd99 (diff)
downloadgcc-4e3825dba91bb719284b07b90aefc273705399f2.zip
gcc-4e3825dba91bb719284b07b90aefc273705399f2.tar.gz
gcc-4e3825dba91bb719284b07b90aefc273705399f2.tar.bz2
Expand from SSA.
gcc/ Expand from SSA. * builtins.c (fold_builtin_next_arg): Handle SSA names. * tree-ssa-copyrename.c (rename_ssa_copies): Use ssa_name() directly. * tree-ssa-coalesce.c (create_outofssa_var_map): Mark only useful SSA names. (compare_pairs): Swap cost comparison. (coalesce_ssa_name): Don't use change_partition_var. * tree-nrv.c (struct nrv_data): Add modified member. (finalize_nrv_r): Set it. (tree_nrv): Use it to update statements. (pass_nrv): Require PROP_ssa. * tree-mudflap.c (mf_decl_cache_locals, mf_build_check_statement_for): Use make_rename_temp. (pass_mudflap_2): Require PROP_ssa, run ssa update at finish. * alias.c (find_base_decl): Handle SSA names. * emit-rtl (set_reg_attrs_for_parm): Make non-static. (component_ref_for_mem_expr): Don't leak SSA names into RTL. * rtl.h (set_reg_attrs_for_parm): Declare. * tree-optimize.c (pass_cleanup_cfg_post_optimizing): Rename to "optimized", remove unused locals at finish. (execute_free_datastructures): Make global, call delete_tree_cfg_annotations. (execute_free_cfg_annotations): Don't call delete_tree_cfg_annotations. * ssaexpand.h: New file. * expr.c (toplevel): Include ssaexpand.h. (expand_assignment): Handle SSA names the same as register variables. (expand_expr_real_1): Expand SSA names. * cfgexpand.c (toplevel): Include ssaexpand.h. (SA): New global variable. (gimple_cond_pred_to_tree): Fold TERed comparisons into predicates. (SSAVAR): New macro. (set_rtl): New helper function. (add_stack_var): Deal with SSA names, use set_rtl. (expand_one_stack_var_at): Likewise. (expand_one_stack_var): Deal with SSA names. (stack_var_size_cmp): Use code (SSA_NAME / DECL) as tie breaker before unique numbers. (expand_stack_vars): Use set_rtl. (expand_one_var): Accept SSA names, add asserts for them, feed them to above subroutines. (expand_used_vars): Expand all partitions (without default defs), then only the local decls (ignoring those expanded already). (expand_gimple_cond): Remove edges when jumpif() expands an unconditional jump. (expand_gimple_basic_block): Don't clear EDGE_EXECUTABLE here, or remove abnormal edges. Ignore insns setting the LHS of a TERed SSA name. (gimple_expand_cfg): Call into rewrite_out_of_ssa, initialize members of SA; deal with PARM_DECL partitions here; expand all PHI nodes, free tree datastructures and SA. Commit instructions on edges, clear EDGE_EXECUTABLE and remove abnormal edges here. (pass_expand): Require and destroy PROP_ssa, verify SSA form, flow info and statements at start, collect garbage at finish. * tree-ssa-live.h (struct _var_map): Remove partition_to_var member. (VAR_ANN_PARTITION) Remove. (change_partition_var): Don't declare. (partition_to_var): Always return SSA names. (var_to_partition): Only accept SSA names. (register_ssa_partition): Only check argument. * tree-ssa-live.c (init_var_map): Don't allocate partition_to_var member. (delete_var_map): Don't free it. (var_union): Only accept SSA names, simplify. (partition_view_init): Mark only useful SSA names as used. (partition_view_fini): Only deal with SSA names. (change_partition_var): Remove. (dump_var_map): Use ssa_name instead of partition_to_var member. * tree-ssa.c (delete_tree_ssa): Don't remove PHI nodes on RTL basic blocks. * tree-outof-ssa.c (toplevel): Include ssaexpand.h and expr.h. (struct _elim_graph): New member const_dests; nodes member vector of ints. (set_location_for_edge): New static helper. (create_temp): Remove. (insert_partition_copy_on_edge, insert_part_to_rtx_on_edge, insert_value_copy_on_edge, insert_rtx_to_part_on_edge): New functions. (new_elim_graph): Allocate const_dests member. (clean_elim_graph): Truncate const_dests member. (delete_elim_graph): Free const_dests member. (elim_graph_size): Adapt to new type of nodes member. (elim_graph_add_node): Likewise. (eliminate_name): Likewise. (eliminate_build): Don't take basic block argument, deal only with partition numbers, not variables. (get_temp_reg): New static helper. (elim_create): Use it, deal with RTL temporaries instead of trees. (eliminate_phi): Adjust all calls to new signature. (assign_vars, replace_use_variable, replace_def_variable): Remove. (rewrite_trees): Only do checking. (edge_leader, stmt_list, leader_has_match, leader_match): Remove. (same_stmt_list_p, identical_copies_p, identical_stmt_lists_p, init_analyze_edges_for_bb, fini_analyze_edges_for_bb, contains_tree_r, MAX_STMTS_IN_LATCH, process_single_block_loop_latch, analyze_edges_for_bb, perform_edge_inserts): Remove. (expand_phi_nodes): New global function. (remove_ssa_form): Take ssaexpand parameter. Don't call removed functions, initialize new parameter, remember partitions having a default def. (finish_out_of_ssa): New global function. (rewrite_out_of_ssa): Make global. Adjust call to remove_ssa_form, don't reset in_ssa_p here, don't disable TER when mudflap. (pass_del_ssa): Remove. * tree-flow.h (struct var_ann_d): Remove out_of_ssa_tag and partition members. (execute_free_datastructures): Declare. * Makefile.in (SSAEXPAND_H): New variable. (tree-outof-ssa.o, expr.o, cfgexpand.o): Depend on SSAEXPAND_H. * basic-block.h (commit_one_edge_insertion): Declare. * passes.c (init_optimization_passes): Move pass_nrv and pass_mudflap2 before pass_cleanup_cfg_post_optimizing, remove pass_del_ssa, pass_free_datastructures, pass_free_cfg_annotations. * cfgrtl.c (commit_one_edge_insertion): Make global, don't declare. (redirect_branch_edge): Deal with super block when expanding, split out jump patching itself into ... (patch_jump_insn): ... here, new static helper. testsuite/ Expand from SSA. * gcc.dg/tree-ssa/20030728-1.c: Use -rtl-expand-details dump and change regexps. * gcc.target/i386/pr37248-1.c: Modified. * gcc.target/i386/pr37248-3.c: Modified. * gcc.target/i386/pr37248-2.c: Modified. * gnat.dg/aliasing1.adb: Modified. * gnat.dg/pack9.adb: Modified. * gnat.dg/aliasing2.adb: Modified. * gcc.dg/strict-overflow-2.c: Modified. * gcc.dg/autopar/reduc-1char.c: Modified. * gcc.dg/autopar/reduc-2char.c: Modified. * gcc.dg/autopar/reduc-1.c: Modified. * gcc.dg/autopar/reduc-2.c: Modified. * gcc.dg/autopar/reduc-3.c: Modified. * gcc.dg/autopar/reduc-6.c: Modified. * gcc.dg/autopar/reduc-7.c: Modified. * gcc.dg/autopar/reduc-8.c: Modified. * gcc.dg/autopar/reduc-9.c: Modified. * gcc.dg/autopar/reduc-1short.c: Modified. * gcc.dg/autopar/reduc-2short.c: Modified. * gcc.dg/autopar/parallelization-1.c: Modified. * gcc.dg/strict-overflow-4.c: Modified. * gcc.dg/strict-overflow-6.c: Modified. * gcc.dg/gomp/combined-1.c: Modified. * gcc.dg/no-strict-overflow-1.c: Modified. * gcc.dg/no-strict-overflow-3.c: Modified. * gcc.dg/no-strict-overflow-5.c: Modified. * gcc.dg/tree-ssa/reassoc-13.c: Modified. * gcc.dg/tree-ssa/pr18134.c: Modified. * gcc.dg/tree-ssa/20030824-1.c: Modified. * gcc.dg/tree-ssa/vector-2.c: Modified. * gcc.dg/tree-ssa/forwprop-9.c: Modified. * gcc.dg/tree-ssa/loop-21.c: Modified. * gcc.dg/tree-ssa/20030824-2.c: Modified. * gcc.dg/tree-ssa/vector-3.c: Modified. * gcc.dg/tree-ssa/asm-3.c: Modified. * gcc.dg/tree-ssa/pr23294.c: Modified. * gcc.dg/tree-ssa/loop-22.c: Modified. * gcc.dg/tree-ssa/loop-15.c: Modified. * gcc.dg/tree-ssa/prefetch-4.c: Modified. * gcc.dg/tree-ssa/pr22051-1.c: Modified. * gcc.dg/tree-ssa/pr20139.c: Modified. * gcc.dg/tree-ssa/scev-cast.c: Modified. * gcc.dg/tree-ssa/pr22051-2.c: Modified. * gcc.dg/tree-ssa/reassoc-1.c: Modified. * gcc.dg/tree-ssa/loop-5.c: Modified. * gcc.dg/tree-ssa/pr19431.c: Modified. * gcc.dg/tree-ssa/pr32044.c: Modified. * gcc.dg/tree-ssa/prefetch-7.c: Modified. * gcc.dg/tree-ssa/loop-19.c: Modified. * gcc.dg/tree-ssa/loop-28.c: Modified. * gcc.dg/tree-ssa/ssa-pre-15.c: Modified. * gcc.dg/tree-ssa/divide-1.c: Modified. * gcc.dg/tree-ssa/inline-1.c: Modified. * gcc.dg/tree-ssa/divide-3.c: Modified. * gcc.dg/tree-ssa/pr30978.c: Modified. * gcc.dg/tree-ssa/alias-6.c: Modified. * gcc.dg/tree-ssa/divide-4.c: Modified. * gcc.dg/tree-ssa/alias-11.c: Modified. * gcc.dg/no-strict-overflow-7.c: Modified. * gcc.dg/strict-overflow-1.c: Modified. * gcc.dg/pr15784-4.c: Modified. * gcc.dg/pr34263.c: Modified. * gcc.dg/strict-overflow-3.c: Modified. * gcc.dg/tree-prof/stringop-1.c: Modified. * gcc.dg/tree-prof/val-prof-1.c: Modified. * gcc.dg/tree-prof/val-prof-2.c: Modified. * gcc.dg/tree-prof/val-prof-3.c: Modified. * gcc.dg/tree-prof/val-prof-4.c: Modified. * gcc.dg/no-strict-overflow-2.c: Modified. * gcc.dg/no-strict-overflow-4.c: Modified. * gcc.dg/no-strict-overflow-6.c: Modified. * g++.dg/tree-ssa/pr27090.C: Modified. * g++.dg/tree-ssa/tmmti-2.C: Modified. * g++.dg/tree-ssa/ptrmemfield.C: Modified. * g++.dg/tree-ssa/pr19807.C: Modified. * g++.dg/opt/pr30965.C: Modified. * g++.dg/init/new17.C: Modified. * gfortran.dg/whole_file_6.f90: Modified. * gfortran.dg/whole_file_5.f90: Modified. * gfortran.dg/reassoc_1.f90: Modified. * gfortran.dg/reassoc_3.f90: Modified. From-SVN: r146817
Diffstat (limited to 'gcc/cfgrtl.c')
-rw-r--r--gcc/cfgrtl.c86
1 files changed, 57 insertions, 29 deletions
diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c
index c6436bf..36bc865 100644
--- a/gcc/cfgrtl.c
+++ b/gcc/cfgrtl.c
@@ -64,7 +64,6 @@ along with GCC; see the file COPYING3. If not see
static int can_delete_note_p (const_rtx);
static int can_delete_label_p (const_rtx);
-static void commit_one_edge_insertion (edge);
static basic_block rtl_split_edge (edge);
static bool rtl_move_block_after (basic_block, basic_block);
static int rtl_verify_flow_info (void);
@@ -856,31 +855,25 @@ try_redirect_by_replacing_jump (edge e, basic_block target, bool in_cfglayout)
return e;
}
-/* Redirect edge representing branch of (un)conditional jump or tablejump,
- NULL on failure */
-static edge
-redirect_branch_edge (edge e, basic_block target)
+/* Subroutine of redirect_branch_edge that tries to patch the jump
+ instruction INSN so that it reaches block NEW. Do this
+ only when it originally reached block OLD. Return true if this
+ worked or the original target wasn't OLD, return false if redirection
+ doesn't work. */
+
+static bool
+patch_jump_insn (rtx insn, rtx old_label, basic_block new_bb)
{
rtx tmp;
- rtx old_label = BB_HEAD (e->dest);
- basic_block src = e->src;
- rtx insn = BB_END (src);
-
- /* We can only redirect non-fallthru edges of jump insn. */
- if (e->flags & EDGE_FALLTHRU)
- return NULL;
- else if (!JUMP_P (insn))
- return NULL;
-
/* Recognize a tablejump and adjust all matching cases. */
if (tablejump_p (insn, NULL, &tmp))
{
rtvec vec;
int j;
- rtx new_label = block_label (target);
+ rtx new_label = block_label (new_bb);
- if (target == EXIT_BLOCK_PTR)
- return NULL;
+ if (new_bb == EXIT_BLOCK_PTR)
+ return false;
if (GET_CODE (PATTERN (tmp)) == ADDR_VEC)
vec = XVEC (PATTERN (tmp), 0);
else
@@ -915,20 +908,55 @@ redirect_branch_edge (edge e, basic_block target)
if (computed_jump_p (insn)
/* A return instruction can't be redirected. */
|| returnjump_p (insn))
- return NULL;
-
- /* If the insn doesn't go where we think, we're confused. */
- gcc_assert (JUMP_LABEL (insn) == old_label);
+ return false;
- /* If the substitution doesn't succeed, die. This can happen
- if the back end emitted unrecognizable instructions or if
- target is exit block on some arches. */
- if (!redirect_jump (insn, block_label (target), 0))
+ if (!currently_expanding_to_rtl || JUMP_LABEL (insn) == old_label)
{
- gcc_assert (target == EXIT_BLOCK_PTR);
- return NULL;
+ /* If the insn doesn't go where we think, we're confused. */
+ gcc_assert (JUMP_LABEL (insn) == old_label);
+
+ /* If the substitution doesn't succeed, die. This can happen
+ if the back end emitted unrecognizable instructions or if
+ target is exit block on some arches. */
+ if (!redirect_jump (insn, block_label (new_bb), 0))
+ {
+ gcc_assert (new_bb == EXIT_BLOCK_PTR);
+ return false;
+ }
}
}
+ return true;
+}
+
+
+/* Redirect edge representing branch of (un)conditional jump or tablejump,
+ NULL on failure */
+static edge
+redirect_branch_edge (edge e, basic_block target)
+{
+ rtx old_label = BB_HEAD (e->dest);
+ basic_block src = e->src;
+ rtx insn = BB_END (src);
+
+ /* We can only redirect non-fallthru edges of jump insn. */
+ if (e->flags & EDGE_FALLTHRU)
+ return NULL;
+ else if (!JUMP_P (insn) && !currently_expanding_to_rtl)
+ return NULL;
+
+ if (!currently_expanding_to_rtl)
+ {
+ if (!patch_jump_insn (insn, old_label, target))
+ return NULL;
+ }
+ else
+ /* When expanding this BB might actually contain multiple
+ jumps (i.e. not yet split by find_many_sub_basic_blocks).
+ Redirect all of those that match our label. */
+ for (insn = BB_HEAD (src); insn != NEXT_INSN (BB_END (src));
+ insn = NEXT_INSN (insn))
+ if (JUMP_P (insn) && !patch_jump_insn (insn, old_label, target))
+ return NULL;
if (dump_file)
fprintf (dump_file, "Edge %i->%i redirected to %i\n",
@@ -1313,7 +1341,7 @@ insert_insn_on_edge (rtx pattern, edge e)
/* Update the CFG for the instructions queued on edge E. */
-static void
+void
commit_one_edge_insertion (edge e)
{
rtx before = NULL_RTX, after = NULL_RTX, insns, tmp, last;