function.c (FLOOR_ROUND, CEIL_ROUND): Fix.
authorJan Hubicka <jh@suse.cz>
Fri, 6 Jun 2003 09:24:26 +0000 (11:24 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Fri, 6 Jun 2003 09:24:26 +0000 (09:24 +0000)
* function.c (FLOOR_ROUND, CEIL_ROUND): Fix.
* i386.md (gen_pro_epilogue_adjust_stack): Deal with gigantic stack frames.
(pro_epilogue_adjust_stack_rex64_2): New pattern

* cfghooks.h, cfghooks.c: New files.
* Makefile.in (BASIC_BLOCK_H): Depends on cfghooks.h.
(OBJS): Add cfghooks.o.
(cfghooks.o): New rule.
* basic-block.h (split_edge): Rename to rtl_split_edge.
(verify_flow_info): Rename to rtl_verify_flow_info.
(cfghooks.h): Included here.
* cfgrtl.c (split_edge): Renamed rtl_split_edge.
(verify_flow_info): Renamed rtl_verify_flow_info.
* toplev.c (rest_of_compilation): Call rtl_register_cfg_hooks.

* basic-block.h (split_block, split_edge, flow_delete_block,
redirect_edge_and_branch, redirect_edge_and_branch_force): Delete.
(flow_delete_block_noexpunge):  Return void.
* cfg.c (verify_flow_info): New function.
* cfgcleanup.c (try_simplify_condjump, outgoing_edges_match,
try_crossjump_to_edge, try_optimize_cfg, delete_unreachable_blocks):
Use delete_block.
* cfglayout.c (function_footer): Rename to...
(cfg_layout_function_footer): ... this variable
(unlink_insn_chain): Make global.
(fixup_reorder_chain, record_effective_endpoints): Update.
(cleanup_unconditional_jumps): Use delete_block.
(cfg_layout_redirect_edge, cfg_layout_split_block): Move to cfgrtl.c
(cfg_layout_duplicate_bb): Use redirect_edge_and_branch_force.
(cfg_layout_initialize, cfg_layout_finalize): Update hooks.
* cfglayout.h (cfg_layout_redirect_edge, cfg_layout_split_block):  Delete.
(cfg_layout_function_footer): Declare.
* cfgloopmanip (split_loop_bb): Do not update RBI.
(remove_bbs): Use delete_block.
(loop_reidrect_edge, loop_delete_branch_edge): Use
redirect_edge_and_branch.
(create_preheader): Use split_block and redirect_edge_and_branch_force.
(split_edge_with): Likewise.
* cfgrtl.c: Include cfglayout.h
(split_edge): Rename to ...
(rtl_split_edge) ... this one; make local.
(redirect_edge_and_branch): Rename to ...
(rtl_redirect_edge_and_branch) ... this one; make local.
(redirect_edge_and_branch_force): Rename to ...
(rtl_redirect_edge_and_branch_force) ... this one; make local.
(cfg_layout_delete_block, cfg_layout_delete_edge_and_branch_force): New.
(cfg_layout_redirect_edge_and_branch, cfg_layout_split_block): Move here from
cfglayout.c; update to directly call RTL counterparts.
(rtl_cfg_hooks, cfg_layout_rtl_cfg_hooks): New functions.
* ifcvt.c (find_cond_trap): Use delete_block.
(find_if_case_1): Use delete_block.
(find_if_case_2): Use delete_block.
* rtl.h (unlink_insn_chain): Declare.
* toplev.c (rtl_reigster_cfg_hooks): New.

From-SVN: r67535

14 files changed:
gcc/ChangeLog
gcc/Makefile.in
gcc/basic-block.h
gcc/cfg.c
gcc/cfgcleanup.c
gcc/cfghooks.c [new file with mode: 0644]
gcc/cfghooks.h [new file with mode: 0644]
gcc/cfglayout.c
gcc/cfglayout.h
gcc/cfgloopmanip.c
gcc/cfgrtl.c
gcc/ifcvt.c
gcc/rtl.h
gcc/toplev.c

index 85e1b989a3a2800ea38645648a36d275720feca7..af477d2eed60c16586b96f2879ad608377aa33c3 100644 (file)
@@ -1,3 +1,64 @@
+Fri Jun  6 11:02:35 CEST 2003  Jan Hubicka  <jh@suse.cz>
+
+       * function.c (FLOOR_ROUND, CEIL_ROUND): Fix.
+       * i386.md (gen_pro_epilogue_adjust_stack): Deal with gigantic stack frames.
+       (pro_epilogue_adjust_stack_rex64_2): New pattern
+
+Fri Jun  6 11:03:14 CEST 2003  Jan Hubicka  <jh@suse.cz>
+                              Pop Sebastian
+                              Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+       * cfghooks.h, cfghooks.c: New files.
+       * Makefile.in (BASIC_BLOCK_H): Depends on cfghooks.h.
+       (OBJS): Add cfghooks.o.
+       (cfghooks.o): New rule.
+       * basic-block.h (split_edge): Rename to rtl_split_edge.
+       (verify_flow_info): Rename to rtl_verify_flow_info.
+       (cfghooks.h): Included here.
+       * cfgrtl.c (split_edge): Renamed rtl_split_edge.
+       (verify_flow_info): Renamed rtl_verify_flow_info.
+       * toplev.c (rest_of_compilation): Call rtl_register_cfg_hooks.
+
+       * basic-block.h (split_block, split_edge, flow_delete_block,
+       redirect_edge_and_branch, redirect_edge_and_branch_force): Delete.
+       (flow_delete_block_noexpunge):  Return void.
+       * cfg.c (verify_flow_info): New function.
+       * cfgcleanup.c (try_simplify_condjump, outgoing_edges_match,
+       try_crossjump_to_edge, try_optimize_cfg, delete_unreachable_blocks):
+       Use delete_block.
+       * cfglayout.c (function_footer): Rename to...
+       (cfg_layout_function_footer): ... this variable
+       (unlink_insn_chain): Make global.
+       (fixup_reorder_chain, record_effective_endpoints): Update.
+       (cleanup_unconditional_jumps): Use delete_block.
+       (cfg_layout_redirect_edge, cfg_layout_split_block): Move to cfgrtl.c
+       (cfg_layout_duplicate_bb): Use redirect_edge_and_branch_force.
+       (cfg_layout_initialize, cfg_layout_finalize): Update hooks.
+       * cfglayout.h (cfg_layout_redirect_edge, cfg_layout_split_block):  Delete.
+       (cfg_layout_function_footer): Declare.
+       * cfgloopmanip (split_loop_bb): Do not update RBI.
+       (remove_bbs): Use delete_block.
+       (loop_reidrect_edge, loop_delete_branch_edge): Use
+       redirect_edge_and_branch.
+       (create_preheader): Use split_block and redirect_edge_and_branch_force.
+       (split_edge_with): Likewise.
+       * cfgrtl.c: Include cfglayout.h
+       (split_edge): Rename to ...
+       (rtl_split_edge) ... this one; make local.
+       (redirect_edge_and_branch): Rename to ...
+       (rtl_redirect_edge_and_branch) ... this one; make local.
+       (redirect_edge_and_branch_force): Rename to ...
+       (rtl_redirect_edge_and_branch_force) ... this one; make local.
+       (cfg_layout_delete_block, cfg_layout_delete_edge_and_branch_force): New.
+       (cfg_layout_redirect_edge_and_branch, cfg_layout_split_block): Move here from
+       cfglayout.c; update to directly call RTL counterparts.
+       (rtl_cfg_hooks, cfg_layout_rtl_cfg_hooks): New functions.
+       * ifcvt.c (find_cond_trap): Use delete_block.
+       (find_if_case_1): Use delete_block.
+       (find_if_case_2): Use delete_block.
+       * rtl.h (unlink_insn_chain): Declare.
+       * toplev.c (rtl_reigster_cfg_hooks): New.
+
 2003-06-05  Richard Henderson  <rth@redhat.com>
 
        * recog.c (peephole2_optimize): Revert last change.
index f755afd1a0dd7ed1e02cedeea4a0bf42392e1bbe..396744a1849242eaacfa22a0fc971cb0b161bd35 100644 (file)
@@ -635,7 +635,7 @@ PARAMS_H = params.h params.def
 TREE_H = tree.h tree.def $(MACHMODE_H) tree-check.h version.h builtins.def \
           input.h
 BASIC_BLOCK_H = basic-block.h bitmap.h sbitmap.h varray.h $(PARTITION_H) \
-          hard-reg-set.h
+          hard-reg-set.h cfghooks.h
 COVERAGE_H = coverage.h gcov-io.h gcov-iov.h
 DEMANGLE_H = $(srcdir)/../include/demangle.h
 RECOG_H = recog.h
@@ -820,7 +820,7 @@ OBJS = alias.o bb-reorder.o bitmap.o builtins.o caller-save.o calls.o          \
  sibcall.o simplify-rtx.o sreal.o ssa.o ssa-ccp.o ssa-dce.o stmt.o        \
  stor-layout.o stringpool.o timevar.o toplev.o tracer.o tree.o tree-dump.o \
  tree-inline.o unroll.o varasm.o varray.o version.o vmsdbgout.o xcoffout.o \
- alloc-pool.o et-forest.o cgraph.o cgraphunit.o                                   \
+ alloc-pool.o et-forest.o cgraph.o cgraphunit.o cfghooks.o                \
  $(GGC) $(out_object_file) $(EXTRA_OBJS) $(host_hook_obj)
 
 BACKEND = main.o libbackend.a
@@ -1650,6 +1650,8 @@ flow.o : flow.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
 cfg.o : cfg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) flags.h insn-config.h \
    $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h $(RECOG_H) \
    function.h except.h $(GGC_H) $(TM_P_H) alloc-pool.h
+cfghooks.o: cfghooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
+   $(BASIC_BLOCK_H) cfglayout.h
 cfgrtl.o : cfgrtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) flags.h \
    insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h $(RECOG_H) \
    function.h except.h $(GGC_H) $(TM_P_H) insn-config.h
index 4c8d5e34dec0a64fc083633b98e97cabb1b9dbd2..a229367c9ec858ed3d997973208015b382584e09 100644 (file)
@@ -338,8 +338,6 @@ extern void update_bb_for_insn              PARAMS ((basic_block));
 
 extern void free_basic_block_vars      PARAMS ((int));
 
-extern edge split_block                        PARAMS ((basic_block, rtx));
-extern basic_block split_edge          PARAMS ((edge));
 extern void insert_insn_on_edge                PARAMS ((rtx, edge));
 
 extern void commit_edge_insertions     PARAMS ((void));
@@ -363,8 +361,7 @@ extern edge redirect_edge_succ_nodup        PARAMS ((edge, basic_block));
 extern void redirect_edge_pred         PARAMS ((edge, basic_block));
 extern basic_block create_basic_block_structure PARAMS ((rtx, rtx, rtx, basic_block));
 extern basic_block create_basic_block  PARAMS ((rtx, rtx, basic_block));
-extern int flow_delete_block           PARAMS ((basic_block));
-extern int flow_delete_block_noexpunge PARAMS ((basic_block));
+extern void flow_delete_block_noexpunge        PARAMS ((basic_block));
 extern void clear_bb_flags             PARAMS ((void));
 extern void merge_blocks_nomove                PARAMS ((basic_block, basic_block));
 extern void tidy_fallthru_edge         PARAMS ((edge, basic_block,
@@ -560,9 +557,7 @@ extern void compact_blocks          PARAMS ((void));
 extern basic_block alloc_block         PARAMS ((void));
 extern void find_unreachable_blocks    PARAMS ((void));
 extern int delete_noop_moves           PARAMS ((rtx));
-extern basic_block redirect_edge_and_branch_force PARAMS ((edge, basic_block));
 extern basic_block force_nonfallthru   PARAMS ((edge));
-extern bool redirect_edge_and_branch   PARAMS ((edge, basic_block));
 extern rtx block_label                 PARAMS ((basic_block));
 extern bool forwarder_block_p          PARAMS ((basic_block));
 extern bool purge_all_dead_edges       PARAMS ((int));
@@ -649,4 +644,7 @@ extern void redirect_immediate_dominators PARAMS ((dominance_info, basic_block,
                                                 basic_block));
 void iterate_fix_dominators PARAMS ((dominance_info, basic_block *, int));
 extern void verify_dominators PARAMS ((dominance_info));
+
+#include "cfghooks.h"
+
 #endif /* GCC_BASIC_BLOCK_H */
index fe40007af4116037e5bd4d560eb3ffda15112432..7e4aa4035dc38b84b8bca90dcaadb0eee3e820a8 100644 (file)
--- a/gcc/cfg.c
+++ b/gcc/cfg.c
@@ -828,3 +828,11 @@ free_aux_for_edges ()
 
   clear_aux_for_edges ();
 }
+
+/* Verify the CFG consistency.  
+   ??? In the future move IL idepdendent checks here.  */
+void
+verify_flow_info ()
+{
+  cfg_hooks->cfgh_verify_flow_info ();
+}
index cfb838cf1f2f2648946d104cf1b2f16f5dd186fd..b61d287bca40753f6082a41bd6811416e799facf 100644 (file)
@@ -180,7 +180,7 @@ try_simplify_condjump (cbranch_block)
   update_br_prob_note (cbranch_block);
 
   /* Delete the block with the unconditional jump, and clean up the mess.  */
-  flow_delete_block (jump_block);
+  delete_block (jump_block);
   tidy_fallthru_edge (cbranch_jump_edge, cbranch_block, cbranch_dest_block);
 
   return true;
@@ -1271,7 +1271,7 @@ outgoing_edges_match (mode, bb1, bb2)
          /* The labels should never be the same rtx.  If they really are same
             the jump tables are same too. So disable crossjumping of blocks BB1
             and BB2 because when deleting the common insns in the end of BB1
-            by flow_delete_block () the jump table would be deleted too.  */
+            by delete_block () the jump table would be deleted too.  */
          /* If LABEL2 is referenced in BB1->END do not do anything
             because we would loose information when replacing
             LABEL1 by LABEL2 and then LABEL2 by LABEL1 in BB1->END.  */
@@ -1568,7 +1568,7 @@ try_crossjump_to_edge (mode, e1, e2)
   to_remove = redirect_from->succ->dest;
 
   redirect_edge_and_branch_force (redirect_from->succ, redirect_to);
-  flow_delete_block (to_remove);
+  delete_block (to_remove);
 
   update_forwarder_flag (redirect_from);
 
@@ -1721,7 +1721,7 @@ try_optimize_cfg (mode)
                    fprintf (rtl_dump_file, "Deleting block %i.\n",
                             b->index);
 
-                 flow_delete_block (b);
+                 delete_block (b);
                  changed = true;
                  b = c;
                }
@@ -1772,7 +1772,7 @@ try_optimize_cfg (mode)
 
                  c = b->prev_bb == ENTRY_BLOCK_PTR ? b->next_bb : b->prev_bb;
                  redirect_edge_succ_nodup (b->pred, b->succ->dest);
-                 flow_delete_block (b);
+                 delete_block (b);
                  changed = true;
                  b = c;
                }
@@ -1871,7 +1871,7 @@ delete_unreachable_blocks ()
 
       if (!(b->flags & BB_REACHABLE))
        {
-         flow_delete_block (b);
+         delete_block (b);
          changed = true;
        }
     }
diff --git a/gcc/cfghooks.c b/gcc/cfghooks.c
new file mode 100644 (file)
index 0000000..d5815a1
--- /dev/null
@@ -0,0 +1,48 @@
+/* Hooks for cfg representation specific functions.
+   Copyright (C) 2003 Free Software Foundation, Inc.
+   Contributed by Sebastian Pop <s.pop@laposte.net>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "rtl.h"
+#include "basic-block.h"
+
+extern struct cfg_hooks rtl_cfg_hooks;
+extern struct cfg_hooks cfg_layout_rtl_cfg_hooks;
+
+/* A pointer to one of the hooks containers.  */
+struct cfg_hooks *cfg_hooks;
+
+/* Initialization of functions specific to the rtl IR.  */
+void 
+rtl_register_cfg_hooks ()
+{
+  cfg_hooks = &rtl_cfg_hooks;
+}
+
+/* Initialization of functions specific to the rtl IR.  */
+void 
+cfg_layout_rtl_register_cfg_hooks ()
+{
+  cfg_hooks = &cfg_layout_rtl_cfg_hooks;
+}
diff --git a/gcc/cfghooks.h b/gcc/cfghooks.h
new file mode 100644 (file)
index 0000000..c214b64
--- /dev/null
@@ -0,0 +1,70 @@
+/* Hooks for cfg representation specific functions.
+   Copyright (C) 2003 Free Software Foundation, Inc.
+   Contributed by Sebastian Pop <s.pop@laposte.net>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#ifndef GCC_CFGHOOKS_H
+#define GCC_CFGHOOKS_H
+
+struct cfg_hooks
+{
+  /* Debugging.  Do not use macros to hook these so they can be called from
+     debugger!  */
+  void (*cfgh_verify_flow_info)                PARAMS ((void));
+
+  /* Basic CFG manipulation.  */
+
+  /* Redirect edge E to the given basic block B and update underlying program
+     representation.  Returns false when edge is not easilly redirectable for
+     whatever reason.  */
+  bool (*redirect_edge_and_branch)      PARAMS ((edge e, basic_block b));
+
+  /* Same as the above but allows redirecting of fallthru edges.  In that case
+     newly created forwarder basic block is returned.  It aborts when called
+     on abnormal edge.  */
+  basic_block (*redirect_edge_and_branch_force)PARAMS ((edge, basic_block));
+
+  /* Remove given basic block and all edges possibly pointing into it.  */
+  void (*delete_block)PARAMS ((basic_block));
+
+  /* Split basic block B after specified instruction I.  */
+  edge (*split_block)                  PARAMS ((basic_block b, void * i));
+
+  /* Higher level functions representable by primitive operations above if
+     we didn't have some oddities in RTL and Tree representations.  */
+  basic_block (*cfgh_split_edge)        PARAMS ((edge));
+};
+
+#define redirect_edge_and_branch(e,b)        cfg_hooks->redirect_edge_and_branch (e,b)
+#define redirect_edge_and_branch_force(e,b)  cfg_hooks->redirect_edge_and_branch_force (e,b)
+#define split_block(e,i)                     cfg_hooks->split_block (e,i)
+#define delete_block(b)                             cfg_hooks->delete_block (b)
+#define split_edge(e)                        cfg_hooks->cfgh_split_edge (e)
+
+/* Hooks containers.  */
+extern struct cfg_hooks rtl_cfg_hooks;
+
+/* A pointer to one of the hooks containers.  */
+extern struct cfg_hooks *cfg_hooks;
+
+/* Declarations.  */
+extern void rtl_register_cfg_hooks     PARAMS ((void));
+extern void cfg_layout_rtl_register_cfg_hooks PARAMS ((void));
+
+#endif  /* GCC_CFGHOOKS_H */
index 9c5b85aec16144d3005db6e118739f34cbb5acd8..bf41013b9eb0686cf79e500c71e2c7fb2e871799 100644 (file)
@@ -39,7 +39,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 extern struct obstack flow_obstack;
 
 /* Holds the interesting trailing notes for the function.  */
-static rtx function_footer;
+rtx cfg_layout_function_footer;
 
 static rtx skip_insns_after_block      PARAMS ((basic_block));
 static void record_effective_endpoints PARAMS ((void));
@@ -52,11 +52,10 @@ static void change_scope            PARAMS ((rtx, tree, tree));
 void verify_insn_chain                 PARAMS ((void));
 static void cleanup_unconditional_jumps        PARAMS ((struct loops *));
 static void fixup_fallthru_exit_predecessor PARAMS ((void));
-static rtx unlink_insn_chain PARAMS ((rtx, rtx));
 static rtx duplicate_insn_chain PARAMS ((rtx, rtx));
 static void break_superblocks PARAMS ((void));
 \f
-static rtx
+rtx
 unlink_insn_chain (first, last)
      rtx first;
      rtx last;
@@ -208,9 +207,9 @@ record_effective_endpoints ()
       next_insn = NEXT_INSN (bb->end);
     }
 
-  function_footer = next_insn;
-  if (function_footer)
-    function_footer = unlink_insn_chain (function_footer, get_last_insn ());
+  cfg_layout_function_footer = next_insn;
+  if (cfg_layout_function_footer)
+    cfg_layout_function_footer = unlink_insn_chain (cfg_layout_function_footer, get_last_insn ());
 }
 \f
 /* Build a varray mapping INSN_UID to lexical block.  Return it.  */
@@ -423,9 +422,9 @@ fixup_reorder_chain ()
   if (index != n_basic_blocks)
     abort ();
 
-  NEXT_INSN (insn) = function_footer;
-  if (function_footer)
-    PREV_INSN (function_footer) = insn;
+  NEXT_INSN (insn) = cfg_layout_function_footer;
+  if (cfg_layout_function_footer)
+    PREV_INSN (cfg_layout_function_footer) = insn;
 
   while (NEXT_INSN (insn))
     insn = NEXT_INSN (insn);
@@ -696,7 +695,7 @@ cleanup_unconditional_jumps (loops)
                }
 
              redirect_edge_succ_nodup (bb->pred, bb->succ->dest);
-             flow_delete_block (bb);
+             delete_block (bb);
              bb = prev;
            }
          else if (simplejump_p (bb->end))
@@ -888,75 +887,6 @@ duplicate_insn_chain (from, to)
   delete_insn (last);
   return insn;
 }
-
-/* Redirect Edge to DEST.  */
-bool
-cfg_layout_redirect_edge (e, dest)
-     edge e;
-     basic_block dest;
-{
-  basic_block src = e->src;
-  basic_block old_next_bb = src->next_bb;
-  bool ret;
-
-  /* Redirect_edge_and_branch may decide to turn branch into fallthru edge
-     in the case the basic block appears to be in sequence.  Avoid this
-     transformation.  */
-
-  src->next_bb = NULL;
-  if (e->flags & EDGE_FALLTHRU)
-    {
-      /* Redirect any branch edges unified with the fallthru one.  */
-      if (GET_CODE (src->end) == JUMP_INSN
-         && JUMP_LABEL (src->end) == e->dest->head)
-       {
-          if (!redirect_jump (src->end, block_label (dest), 0))
-           abort ();
-       }
-      /* In case we are redirecting fallthru edge to the branch edge
-         of conditional jump, remove it.  */
-      if (src->succ->succ_next
-         && !src->succ->succ_next->succ_next)
-       {
-         edge s = e->succ_next ? e->succ_next : src->succ;
-         if (s->dest == dest
-             && any_condjump_p (src->end)
-             && onlyjump_p (src->end))
-           delete_insn (src->end);
-       }
-      redirect_edge_succ_nodup (e, dest);
-
-      ret = true;
-    }
-  else
-    ret = redirect_edge_and_branch (e, dest);
-
-  /* We don't want simplejumps in the insn stream during cfglayout.  */
-  if (simplejump_p (src->end))
-    {
-      delete_insn (src->end);
-      delete_barrier (NEXT_INSN (src->end));
-      src->succ->flags |= EDGE_FALLTHRU;
-    }
-  src->next_bb = old_next_bb;
-
-  return ret;
-}
-
-/* Same as split_block but update cfg_layout structures.  */
-edge
-cfg_layout_split_block (bb, insn)
-     basic_block bb;
-     rtx insn;
-{
-  edge fallthru = split_block (bb, insn);
-
-  alloc_aux_for_block (fallthru->dest, sizeof (struct reorder_block_def));
-  RBI (fallthru->dest)->footer = RBI (fallthru->src)->footer;
-  RBI (fallthru->src)->footer = NULL;
-  return fallthru;
-}
-
 /* Create a duplicate of the basic block BB and redirect edge E into it.  */
 
 basic_block
@@ -1037,7 +967,7 @@ cfg_layout_duplicate_bb (bb, e)
       new_bb->frequency = EDGE_FREQUENCY (e);
       bb->frequency -= EDGE_FREQUENCY (e);
 
-      cfg_layout_redirect_edge (e, new_bb);
+      redirect_edge_and_branch_force (e, new_bb);
     }
 
   if (bb->count < 0)
@@ -1060,6 +990,7 @@ cfg_layout_initialize (loops)
   /* Our algorithm depends on fact that there are now dead jumptables
      around the code.  */
   alloc_aux_for_blocks (sizeof (struct reorder_block_def));
+  cfg_layout_rtl_register_cfg_hooks ();
 
   cleanup_unconditional_jumps (loops);
 
@@ -1101,6 +1032,7 @@ break_superblocks ()
 void
 cfg_layout_finalize ()
 {
+  rtl_register_cfg_hooks ();
   fixup_fallthru_exit_predecessor ();
   fixup_reorder_chain ();
 
index aec5e7ebba319c2e362045a76f5caef7abfffe29..48f11af753bb15c63e66200547411a0e0710772e 100644 (file)
@@ -35,11 +35,11 @@ typedef struct reorder_block_def
 
 #define RBI(BB)        ((reorder_block_def) (BB)->aux)
 
+extern rtx cfg_layout_function_footer;
+
 extern void cfg_layout_initialize      PARAMS ((struct loops *));
 extern void cfg_layout_finalize                PARAMS ((void));
 extern bool cfg_layout_can_duplicate_bb_p PARAMS ((basic_block));
 extern basic_block cfg_layout_duplicate_bb PARAMS ((basic_block, edge));
 extern void scope_to_insns_initialize  PARAMS ((void));
 extern void scope_to_insns_finalize    PARAMS ((void));
-extern bool cfg_layout_redirect_edge   PARAMS ((edge, basic_block));
-extern edge cfg_layout_split_block     PARAMS ((basic_block, rtx));
index 70926f2ab7d3595f44c196ec4f64c48dce9921c4..1e878a5b7d46ac2f50c85fa31aa6fcfbfbf0ffed 100644 (file)
@@ -86,9 +86,6 @@ split_loop_bb (loops, bb, insn)
   free (dom_bbs);
   set_immediate_dominator (loops->cfg.dom, e->dest, e->src);
 
-  /* Take care of RBI.  */
-  alloc_aux_for_block (e->dest, sizeof (struct reorder_block_def));
-
   return e;
 }
 
@@ -123,7 +120,7 @@ remove_bbs (dom, bbs, nbbs)
     {
       remove_bb_from_loops (bbs[i]);
       delete_from_dominance_info (dom, bbs[i]);
-      flow_delete_block (bbs[i]);
+      delete_block (bbs[i]);
     }
 }
 
@@ -828,7 +825,7 @@ loop_redirect_edge (e, dest)
   if (e->dest == dest)
     return;
 
-  cfg_layout_redirect_edge (e, dest);
+  redirect_edge_and_branch_force (e, dest);
 }
 
 /* Deletes edge E from a branch if possible.  Unless REALLY_DELETE is set,
@@ -865,7 +862,7 @@ loop_delete_branch_edge (e, really_delete)
       /* Redirecting behaves wrongly wrto this flag.  */
       irr = snd->flags & EDGE_IRREDUCIBLE_LOOP;
       
-      if (!cfg_layout_redirect_edge (e, newdest))
+      if (!redirect_edge_and_branch (e, newdest))
        return false;
       src->succ->flags &= ~EDGE_IRREDUCIBLE_LOOP;
       src->succ->flags |= irr;
@@ -1396,10 +1393,7 @@ create_preheader (loop, dom, flags)
       /* Split_block would not split block after its end.  */
       emit_note_after (NOTE_INSN_DELETED, insn);
     }
-  if (flags & CP_INSIDE_CFGLAYOUT)
-    fallthru = cfg_layout_split_block (loop->header, insn);
-  else
-    fallthru = split_block (loop->header, insn);
+  fallthru = split_block (loop->header, insn);
   dummy = fallthru->src;
   loop->header = fallthru->dest;
 
@@ -1424,18 +1418,13 @@ create_preheader (loop, dom, flags)
   dummy->frequency -= EDGE_FREQUENCY (e);
   dummy->count -= e->count;
   fallthru->count -= e->count;
-  if (flags & CP_INSIDE_CFGLAYOUT)
-    cfg_layout_redirect_edge (e, loop->header);
-  else
+  jump = redirect_edge_and_branch_force (e, loop->header);
+  if (jump)
     {
-      jump = redirect_edge_and_branch_force (e, loop->header);
-      if (jump)
-       {
-         add_to_dominance_info (dom, jump);
-         set_immediate_dominator (dom, jump, src);
-         add_bb_to_loop (jump, loop);
-         loop->latch = jump;
-       }
+      add_to_dominance_info (dom, jump);
+      set_immediate_dominator (dom, jump, src);
+      add_bb_to_loop (jump, loop);
+      loop->latch = jump;
     }
 
   /* Update structures.  */
@@ -1524,7 +1513,7 @@ loop_split_edge_with (e, insns, loops)
 
   new_bb->count = e->count;
   new_bb->frequency = EDGE_FREQUENCY (e);
-  cfg_layout_redirect_edge (e, new_bb);
+  redirect_edge_and_branch_force (e, new_bb);
 
   alloc_aux_for_block (new_bb, sizeof (struct reorder_block_def));
   if (insns)
index 0ba32c5782ea3c86b66926aebee289e68d41c129..b0678f09f1cc0a0cc79d1b91aa98cfc5434601bc 100644 (file)
@@ -26,7 +26,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
      - CFG-aware instruction chain manipulation
         delete_insn, delete_insn_chain
      - Basic block manipulation
-        create_basic_block, flow_delete_block, split_block,
+        create_basic_block, rtl_delete_block,rtl_split_block,
         merge_blocks_nomove
      - Infrastructure to determine quickly basic block for insn
         compute_bb_for_insn, update_bb_for_insn, set_block_for_insn,
@@ -59,6 +59,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "tm_p.h"
 #include "obstack.h"
 #include "insn-config.h"
+#include "cfglayout.h"
 
 /* Stubs in case we don't have a return insn.  */
 #ifndef HAVE_return
@@ -79,6 +80,16 @@ static bool try_redirect_by_replacing_jump PARAMS ((edge, basic_block));
 static rtx last_loop_beg_note          PARAMS ((rtx));
 static bool back_edge_of_syntactic_loop_p PARAMS ((basic_block, basic_block));
 basic_block force_nonfallthru_and_redirect PARAMS ((edge, basic_block));
+static basic_block rtl_split_edge      PARAMS ((edge));
+static void rtl_verify_flow_info       PARAMS ((void));
+static edge cfg_layout_split_block     PARAMS ((basic_block, void *));
+static bool cfg_layout_redirect_edge_and_branch        PARAMS ((edge, basic_block));
+static basic_block cfg_layout_redirect_edge_and_branch_force PARAMS ((edge, basic_block));
+static void cfg_layout_delete_block    PARAMS ((basic_block));
+static void rtl_delete_block           PARAMS ((basic_block));
+static basic_block rtl_redirect_edge_and_branch_force PARAMS ((edge, basic_block));
+static bool rtl_redirect_edge_and_branch PARAMS ((edge, basic_block));
+static edge rtl_split_block            PARAMS ((basic_block, void *));
 \f
 /* Return true if NOTE is not one of the ones that must be kept paired,
    so that we may simply delete it.  */
@@ -348,11 +359,10 @@ create_basic_block (head, end, after)
 /* ??? Preserving all such notes strikes me as wrong.  It would be nice
    to post-process the stream to remove empty blocks, loops, ranges, etc.  */
 
-int
+void
 flow_delete_block_noexpunge (b)
      basic_block b;
 {
-  int deleted_handler = 0;
   rtx insn, end, tmp;
 
   /* If the head of this block is a CODE_LABEL, then it might be the
@@ -404,20 +414,16 @@ flow_delete_block_noexpunge (b)
 
   b->pred = NULL;
   b->succ = NULL;
-
-  return deleted_handler;
 }
 
-int
-flow_delete_block (b)
+static void
+rtl_delete_block (b)
      basic_block b;
 {
-  int deleted_handler = flow_delete_block_noexpunge (b);
+  flow_delete_block_noexpunge (b);
 
   /* Remove the basic block from the array.  */
   expunge_block (b);
-
-  return deleted_handler;
 }
 \f
 /* Records the basic block struct in BLOCK_FOR_INSN for every insn.  */
@@ -474,14 +480,15 @@ update_bb_for_insn (bb)
    this function renumbers all the basic blocks so that the new
    one has a number one greater than the block split.  */
 
-edge
-split_block (bb, insn)
+static edge
+rtl_split_block (bb, insnp)
      basic_block bb;
-     rtx insn;
+     void *insnp;
 {
   basic_block new_bb;
   edge new_edge;
   edge e;
+  rtx insn = insnp;
 
   /* There is no point splitting the block after its end.  */
   if (bb->end == insn)
@@ -811,8 +818,8 @@ last_loop_beg_note (insn)
    already destinated TARGET and we didn't managed to simplify instruction
    stream.  */
 
-bool
-redirect_edge_and_branch (e, target)
+static bool
+rtl_redirect_edge_and_branch (e, target)
      edge e;
      basic_block target;
 {
@@ -1076,8 +1083,8 @@ force_nonfallthru (e)
    basic block.  Return new basic block if created, NULL otherwise.
    Abort if conversion is impossible.  */
 
-basic_block
-redirect_edge_and_branch_force (e, target)
+static basic_block
+rtl_redirect_edge_and_branch_force (e, target)
      edge e;
      basic_block target;
 {
@@ -1230,7 +1237,7 @@ back_edge_of_syntactic_loop_p (bb1, bb2)
    block with multiple predecessors is not handled optimally.  */
 
 basic_block
-split_edge (edge_in)
+rtl_split_edge (edge_in)
      edge edge_in;
 {
   basic_block bb;
@@ -1741,7 +1748,7 @@ update_br_prob_note (bb)
    (reachability of basic blocks, life information, etc. etc.).  */
 
 void
-verify_flow_info ()
+rtl_verify_flow_info ()
 {
   const int max_uid = get_max_uid ();
   const rtx rtx_first = get_insns ();
@@ -2363,3 +2370,171 @@ purge_all_dead_edges (update_life_p)
     sbitmap_free (blocks);
   return purged;
 }
+
+/* Same as split_block but update cfg_layout structures.  */
+static edge
+cfg_layout_split_block (bb, insnp)
+     basic_block bb;
+     void *insnp;
+{
+  rtx insn = insnp;
+
+  edge fallthru = rtl_split_block (bb, insn);
+
+  alloc_aux_for_block (fallthru->dest, sizeof (struct reorder_block_def));
+  RBI (fallthru->dest)->footer = RBI (fallthru->src)->footer;
+  RBI (fallthru->src)->footer = NULL;
+  return fallthru;
+}
+
+
+/* Redirect Edge to DEST.  */
+static bool
+cfg_layout_redirect_edge_and_branch (e, dest)
+     edge e;
+     basic_block dest;
+{
+  basic_block src = e->src;
+  basic_block old_next_bb = src->next_bb;
+  bool ret;
+
+  /* Redirect_edge_and_branch may decide to turn branch into fallthru edge
+     in the case the basic block appears to be in sequence.  Avoid this
+     transformation.  */
+
+  src->next_bb = NULL;
+  if (e->flags & EDGE_FALLTHRU)
+    {
+      /* Redirect any branch edges unified with the fallthru one.  */
+      if (GET_CODE (src->end) == JUMP_INSN
+         && JUMP_LABEL (src->end) == e->dest->head)
+       {
+          if (!redirect_jump (src->end, block_label (dest), 0))
+           abort ();
+       }
+      /* In case we are redirecting fallthru edge to the branch edge
+         of conditional jump, remove it.  */
+      if (src->succ->succ_next
+         && !src->succ->succ_next->succ_next)
+       {
+         edge s = e->succ_next ? e->succ_next : src->succ;
+         if (s->dest == dest
+             && any_condjump_p (src->end)
+             && onlyjump_p (src->end))
+           delete_insn (src->end);
+       }
+      redirect_edge_succ_nodup (e, dest);
+
+      ret = true;
+    }
+  else
+    ret = rtl_redirect_edge_and_branch (e, dest);
+
+  /* We don't want simplejumps in the insn stream during cfglayout.  */
+  if (simplejump_p (src->end))
+    {
+      delete_insn (src->end);
+      delete_barrier (NEXT_INSN (src->end));
+      src->succ->flags |= EDGE_FALLTHRU;
+    }
+  src->next_bb = old_next_bb;
+
+  return ret;
+}
+
+/* Simple wrapper as we always can redirect fallthru edges.  */
+static basic_block
+cfg_layout_redirect_edge_and_branch_force (e, dest)
+     edge e;
+     basic_block dest;
+{
+  if (!cfg_layout_redirect_edge_and_branch (e, dest))
+    abort ();
+  return NULL;
+}
+
+/* Same as flow_delete_block but update cfg_layout structures.  */
+static void
+cfg_layout_delete_block (bb)
+     basic_block bb;
+{
+  rtx insn, next, prev = PREV_INSN (bb->head), *to, remaints;
+
+  if (RBI (bb)->header)
+    {
+      next = bb->head;
+      if (prev)
+       NEXT_INSN (prev) = RBI (bb)->header;
+      else
+       set_first_insn (RBI (bb)->header);
+      PREV_INSN (RBI (bb)->header) = prev;
+      insn = RBI (bb)->header;
+      while (NEXT_INSN (insn))
+       insn = NEXT_INSN (insn);
+      NEXT_INSN (insn) = next;
+      PREV_INSN (next) = insn;
+    }
+  next = NEXT_INSN (bb->end);
+  if (RBI (bb)->footer)
+    {
+      insn = bb->end;
+      NEXT_INSN (insn) = RBI (bb)->footer;
+      PREV_INSN (RBI (bb)->footer) = insn;
+      while (NEXT_INSN (insn))
+       insn = NEXT_INSN (insn);
+      NEXT_INSN (insn) = next;
+      if (next)
+       PREV_INSN (next) = insn;
+      else
+       set_last_insn (insn);
+    }
+  if (bb->next_bb != EXIT_BLOCK_PTR)
+    to = &RBI(bb->next_bb)->header;
+  else
+    to = &cfg_layout_function_footer;
+  rtl_delete_block (bb);
+
+  if (prev)
+    prev = NEXT_INSN (prev);
+  else 
+    prev = get_insns ();
+  if (next)
+    next = PREV_INSN (next);
+  else 
+    next = get_last_insn ();
+
+  if (next && NEXT_INSN (next) != prev)
+    {
+      remaints = unlink_insn_chain (prev, next);
+      insn = remaints;
+      while (NEXT_INSN (insn))
+       insn = NEXT_INSN (insn);
+      NEXT_INSN (insn) = *to;
+      if (*to)
+       PREV_INSN (*to) = insn;
+      *to = remaints;
+    }
+}
+
+/* Implementation of CFG manipulation for linearized RTL.  */
+struct cfg_hooks rtl_cfg_hooks = {
+  rtl_verify_flow_info,
+  rtl_redirect_edge_and_branch,
+  rtl_redirect_edge_and_branch_force,
+  rtl_delete_block,
+  rtl_split_block,
+  rtl_split_edge
+};
+
+/* Implementation of CFG manipulation for cfg layout RTL, where
+   basic block connected via fallthru edges does not have to be adjacent.
+   This representation will hopefully become the default one in future
+   version of the compiler.  */
+struct cfg_hooks cfg_layout_rtl_cfg_hooks = {
+  NULL,   /* verify_flow_info.  */
+  cfg_layout_redirect_edge_and_branch,
+  cfg_layout_redirect_edge_and_branch_force,
+  cfg_layout_delete_block,
+  cfg_layout_split_block,
+  NULL  /* split_edge.  */
+};
index caa54c56b1379d400ea2a2729bd4eda70e9c99f0..baac0413176498a7385d217105ded2400aff73a6 100644 (file)
@@ -2547,7 +2547,7 @@ find_cond_trap (test_bb, then_edge, else_edge)
     {
       if (post_dominators)
        delete_from_dominance_info (post_dominators, trap_bb);
-      flow_delete_block (trap_bb);
+      delete_block (trap_bb);
       num_removed_blocks++;
     }
 
@@ -2736,7 +2736,7 @@ find_if_case_1 (test_bb, then_edge, else_edge)
   then_bb_index = then_bb->index;
   if (post_dominators)
     delete_from_dominance_info (post_dominators, then_bb);
-  flow_delete_block (then_bb);
+  delete_block (then_bb);
 
   /* Make rest of code believe that the newly created block is the THEN_BB
      block we removed.  */
@@ -2818,7 +2818,7 @@ find_if_case_2 (test_bb, then_edge, else_edge)
   
   if (post_dominators)
     delete_from_dominance_info (post_dominators, else_bb);
-  flow_delete_block (else_bb);
+  delete_block (else_bb);
 
   num_removed_blocks++;
   num_updated_if_blocks++;
index 8a76fe2a2675676a6ab13eeec087d81fd4688f57..21998a605ff78e977d1c27054a0c8de3bc4ff223 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -2082,6 +2082,7 @@ extern void renumber_insns                      PARAMS ((FILE *));
 extern void remove_unnecessary_notes             PARAMS ((void));
 extern rtx delete_insn                 PARAMS ((rtx));
 extern void delete_insn_chain          PARAMS ((rtx, rtx));
+extern rtx unlink_insn_chain           PARAMS ((rtx, rtx));
 extern rtx delete_insn_and_edges       PARAMS ((rtx));
 extern void delete_insn_chain_and_edges        PARAMS ((rtx, rtx));
 
index f005f0418ff933c3156fab64e47f67df931e404f..1a82946a8a683c57b6e5e718c2c79528d0b76a9f 100644 (file)
@@ -3472,6 +3472,9 @@ rest_of_compilation (tree decl)
 
   timevar_push (TV_REST_OF_COMPILATION);
 
+  /* Register rtl specific functions for cfg.  */
+  rtl_register_cfg_hooks ();
+  
   /* Now that we're out of the frontend, we shouldn't have any more
      CONCATs anywhere.  */
   generating_concat_p = 0;