lcm.c (output.h): #include.

* lcm.c (output.h): #include.
	(compute_earliest): Remove hack to treat renumbered EXIT_BLOCK
	as an ordinary block.
	(optimize_mode_switching): Don't pretend that the exit block is
	an ordinary block, or handle sucessors of entry block specially.
	Instead, split edges from entry block and to exit block, and
	put a computing definition on the thus gained post-entry-block,
	and a need on the pre-exit-block.

From-SVN: r54064
This commit is contained in:
J"orn Rennecke 2002-05-30 18:58:31 +00:00 committed by Joern Rennecke
parent b1c12c4ba1
commit 81b40b72d1
2 changed files with 62 additions and 106 deletions

View File

@ -1,3 +1,14 @@
Thu May 30 19:54:30 2002 J"orn Rennecke <joern.rennecke@superh.com>
* lcm.c (output.h): #include.
(compute_earliest): Remove hack to treat renumbered EXIT_BLOCK
as an ordinary block.
(optimize_mode_switching): Don't pretend that the exit block is
an ordinary block, or handle sucessors of entry block specially.
Instead, split edges from entry block and to exit block, and
put a computing definition on the thus gained post-entry-block,
and a need on the pre-exit-block.
Thu May 30 20:28:01 CEST 2002 Jan Hubicka <jh@suse.cz>
* gengenrtl.c (type_from_format, accessor_from_format): Support 'B'.

157
gcc/lcm.c
View File

@ -59,6 +59,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "insn-config.h"
#include "recog.h"
#include "basic-block.h"
#include "output.h"
#include "tm_p.h"
/* We want target macros for the mode switching code to be able to refer
@ -207,11 +208,7 @@ compute_earliest (edge_list, n_exprs, antin, antout, avout, kill, earliest)
sbitmap_copy (earliest[x], antin[succ->index]);
else
{
/* We refer to the EXIT_BLOCK index, instead of testing for
EXIT_BLOCK_PTR, so that EXIT_BLOCK_PTR's index can be
changed so as to pretend it's a regular block, so that
its antin can be taken into account. */
if (succ->index == EXIT_BLOCK)
if (succ == EXIT_BLOCK_PTR)
sbitmap_zero (earliest[x]);
else
{
@ -1027,43 +1024,54 @@ optimize_mode_switching (file)
int n_entities;
int max_num_modes = 0;
bool emited = false;
basic_block post_entry, pre_exit ATTRIBUTE_UNUSED;
clear_bb_flags ();
#ifdef NORMAL_MODE
/* Increment last_basic_block before allocating bb_info. */
last_basic_block++;
#endif
for (e = N_ENTITIES - 1, n_entities = 0; e >= 0; e--)
if (OPTIMIZE_MODE_SWITCHING (e))
{
/* Create the list of segments within each basic block. */
int entry_exit_extra = 0;
/* Create the list of segments within each basic block.
If NORMAL_MODE is defined, allow for two extra
blocks split from the entry and exit block. */
#ifdef NORMAL_MODE
entry_exit_extra = 2;
#endif
bb_info[n_entities]
= (struct bb_info *) xcalloc (last_basic_block, sizeof **bb_info);
= (struct bb_info *) xcalloc (last_basic_block + entry_exit_extra,
sizeof **bb_info);
entity_map[n_entities++] = e;
if (num_modes[e] > max_num_modes)
max_num_modes = num_modes[e];
}
#ifdef NORMAL_MODE
/* Decrement it back in case we return below. */
last_basic_block--;
#endif
if (! n_entities)
return 0;
#ifdef NORMAL_MODE
/* We're going to pretend the EXIT_BLOCK is a regular basic block,
so that switching back to normal mode when entering the
EXIT_BLOCK isn't optimized away. We do this by incrementing the
basic block count, growing the VARRAY of basic_block_info and
appending the EXIT_BLOCK_PTR to it. */
last_basic_block++;
if (VARRAY_SIZE (basic_block_info) < last_basic_block)
VARRAY_GROW (basic_block_info, last_basic_block);
BASIC_BLOCK (last_basic_block - 1) = EXIT_BLOCK_PTR;
EXIT_BLOCK_PTR->index = last_basic_block - 1;
{
/* Split the edge from the entry block and the fallthrough edge to the
exit block, so that we can note that there NORMAL_MODE is supplied /
required. */
edge eg;
post_entry = split_edge (ENTRY_BLOCK_PTR->succ);
/* The only non-call predecessor at this stage is a block with a
fallthrough edge; there can be at most one, but there could be
none at all, e.g. when exit is called. */
for (pre_exit = 0, eg = EXIT_BLOCK_PTR->pred; eg; eg = eg->pred_next)
if (eg->flags & EDGE_FALLTHRU)
{
regset live_at_end = eg->src->global_live_at_end;
if (pre_exit)
abort ();
pre_exit = split_edge (eg);
COPY_REG_SET (pre_exit->global_live_at_start, live_at_end);
COPY_REG_SET (pre_exit->global_live_at_end, live_at_end);
}
}
#endif
/* Create the bitmap vectors. */
@ -1124,7 +1132,7 @@ optimize_mode_switching (file)
/* Check for blocks without ANY mode requirements. */
if (last_mode == no_mode)
{
ptr = new_seginfo (no_mode, insn, bb->index, live_now);
ptr = new_seginfo (no_mode, bb->end, bb->index, live_now);
add_seginfo (info + bb->index, ptr);
}
}
@ -1134,36 +1142,21 @@ optimize_mode_switching (file)
if (mode != no_mode)
{
edge eg;
bb = post_entry;
for (eg = ENTRY_BLOCK_PTR->succ; eg; eg = eg->succ_next)
{
bb = eg->dest;
/* By always making this nontransparent, we save
an extra check in make_preds_opaque. We also
need this to avoid confusing pre_edge_lcm when
antic is cleared but transp and comp are set. */
RESET_BIT (transp[bb->index], j);
/* By always making this nontransparent, we save
an extra check in make_preds_opaque. We also
need this to avoid confusing pre_edge_lcm when
antic is cleared but transp and comp are set. */
RESET_BIT (transp[bb->index], j);
/* Insert a fake computing definition of MODE into entry
blocks which compute no mode. This represents the mode on
entry. */
info[bb->index].computing = mode;
/* If the block already has MODE, pretend it
has none (because we don't need to set it),
but retain whatever mode it computes. */
if (info[bb->index].seginfo->mode == mode)
info[bb->index].seginfo->mode = no_mode;
/* Insert a fake computing definition of MODE into entry
blocks which compute no mode. This represents the mode on
entry. */
else if (info[bb->index].computing == no_mode)
{
info[bb->index].computing = mode;
info[bb->index].seginfo->mode = no_mode;
}
}
bb = EXIT_BLOCK_PTR;
info[bb->index].seginfo->mode = mode;
if (pre_exit)
info[pre_exit->index].seginfo->mode = mode;
}
}
#endif /* NORMAL_MODE */
@ -1288,63 +1281,11 @@ optimize_mode_switching (file)
free_edge_list (edge_list);
}
#ifdef NORMAL_MODE
/* Restore the special status of EXIT_BLOCK. */
last_basic_block--;
VARRAY_POP (basic_block_info);
EXIT_BLOCK_PTR->index = EXIT_BLOCK;
#endif
/* Now output the remaining mode sets in all the segments. */
for (j = n_entities - 1; j >= 0; j--)
{
int no_mode = num_modes[entity_map[j]];
#ifdef NORMAL_MODE
if (bb_info[j][last_basic_block].seginfo->mode != no_mode)
{
edge eg;
struct seginfo *ptr = bb_info[j][last_basic_block].seginfo;
for (eg = EXIT_BLOCK_PTR->pred; eg; eg = eg->pred_next)
{
rtx mode_set;
if (bb_info[j][eg->src->index].computing == ptr->mode)
continue;
start_sequence ();
EMIT_MODE_SET (entity_map[j], ptr->mode, ptr->regs_live);
mode_set = gen_sequence ();
end_sequence ();
/* Do not bother to insert empty sequence. */
if (GET_CODE (mode_set) == SEQUENCE
&& !XVECLEN (mode_set, 0))
continue;
/* If this is an abnormal edge, we'll insert at the end of the
previous block. */
if (eg->flags & EDGE_ABNORMAL)
{
emited = true;
if (GET_CODE (eg->src->end) == JUMP_INSN)
emit_insn_before (mode_set, eg->src->end);
else if (GET_CODE (eg->src->end) == INSN)
emit_insn_after (mode_set, eg->src->end);
else
abort ();
}
else
{
need_commit = 1;
insert_insn_on_edge (mode_set, eg);
}
}
}
#endif
FOR_EACH_BB_REVERSE (bb)
{
struct seginfo *ptr, *next;
@ -1393,8 +1334,12 @@ optimize_mode_switching (file)
if (need_commit)
commit_edge_insertions ();
#ifdef NORMAL_MODE
cleanup_cfg (CLEANUP_NO_INSN_DEL);
#else
if (!need_commit && !emited)
return 0;
#endif
max_regno = max_reg_num ();
allocate_reg_info (max_regno, FALSE, FALSE);