function.c (FLOOR_ROUND, CEIL_ROUND): Fix.

* 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
This commit is contained in:
Jan Hubicka 2003-06-06 11:24:26 +02:00 committed by Jan Hubicka
parent 7654db1b66
commit 9ee634e345
14 changed files with 427 additions and 140 deletions

View 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.

View 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

View 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 */

View File

@ -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 ();
}

View 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;
}
}

48
gcc/cfghooks.c Normal file
View File

@ -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;
}

70
gcc/cfghooks.h Normal file
View File

@ -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 */

View 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));
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 ());
}
/* 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 ();

View 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));

View 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)

View 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 *));
/* 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;
}
/* 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. */
};

View 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++;

View File

@ -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));

View 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;