resource.c (find_basic_block): Use BLOCK_FOR_INSN to look up a label's basic block.
* resource.c (find_basic_block): Use BLOCK_FOR_INSN to look up a label's basic block. (mark_target_live_regs): Tidy and rework obsolete comments. Change back DF problem to LIVE. If a label starts a basic block, assume that all registers that used to be live then still are. (init_resource_info): If a label starts a basic block, set its BLOCK_FOR_INSN accordingly. (fini_resource_info): Undo the setting of BLOCK_FOR_INSN. From-SVN: r146829
This commit is contained in:
parent
33b223c0a6
commit
a1fa3e7944
4 changed files with 83 additions and 19 deletions
|
@ -1,3 +1,15 @@
|
|||
2009-04-27 Richard Sandiford <rdsandiford@googlemail.com>
|
||||
Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* resource.c (find_basic_block): Use BLOCK_FOR_INSN to look up
|
||||
a label's basic block.
|
||||
(mark_target_live_regs): Tidy and rework obsolete comments.
|
||||
Change back DF problem to LIVE. If a label starts a basic block,
|
||||
assume that all registers that used to be live then still are.
|
||||
(init_resource_info): If a label starts a basic block, set its
|
||||
BLOCK_FOR_INSN accordingly.
|
||||
(fini_resource_info): Undo the setting of BLOCK_FOR_INSN.
|
||||
|
||||
2009-04-27 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
* tree-flow-inline.h (function_ann): Remove.
|
||||
|
|
|
@ -135,8 +135,6 @@ update_live_status (rtx dest, const_rtx x, void *data ATTRIBUTE_UNUSED)
|
|||
static int
|
||||
find_basic_block (rtx insn, int search_limit)
|
||||
{
|
||||
basic_block bb;
|
||||
|
||||
/* Scan backwards to the previous BARRIER. Then see if we can find a
|
||||
label that starts a basic block. Return the basic block number. */
|
||||
for (insn = prev_nonnote_insn (insn);
|
||||
|
@ -157,11 +155,8 @@ find_basic_block (rtx insn, int search_limit)
|
|||
for (insn = next_nonnote_insn (insn);
|
||||
insn && LABEL_P (insn);
|
||||
insn = next_nonnote_insn (insn))
|
||||
{
|
||||
FOR_EACH_BB (bb)
|
||||
if (insn == BB_HEAD (bb))
|
||||
return bb->index;
|
||||
}
|
||||
if (BLOCK_FOR_INSN (insn))
|
||||
return BLOCK_FOR_INSN (insn)->index;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
@ -848,13 +843,12 @@ return_insn_p (const_rtx insn)
|
|||
(with no intervening active insns) to see if any of them start a basic
|
||||
block. If we hit the start of the function first, we use block 0.
|
||||
|
||||
Once we have found a basic block and a corresponding first insns, we can
|
||||
accurately compute the live status from basic_block_live_regs and
|
||||
reg_renumber. (By starting at a label following a BARRIER, we are immune
|
||||
to actions taken by reload and jump.) Then we scan all insns between
|
||||
that point and our target. For each CLOBBER (or for call-clobbered regs
|
||||
when we pass a CALL_INSN), mark the appropriate registers are dead. For
|
||||
a SET, mark them as live.
|
||||
Once we have found a basic block and a corresponding first insn, we can
|
||||
accurately compute the live status (by starting at a label following a
|
||||
BARRIER, we are immune to actions taken by reload and jump.) Then we
|
||||
scan all insns between that point and our target. For each CLOBBER (or
|
||||
for call-clobbered regs when we pass a CALL_INSN), mark the appropriate
|
||||
registers are dead. For a SET, mark them as live.
|
||||
|
||||
We have to be careful when using REG_DEAD notes because they are not
|
||||
updated by such things as find_equiv_reg. So keep track of registers
|
||||
|
@ -954,13 +948,10 @@ mark_target_live_regs (rtx insns, rtx target, struct resources *res)
|
|||
TARGET. Otherwise, we must assume everything is live. */
|
||||
if (b != -1)
|
||||
{
|
||||
regset regs_live = DF_LR_IN (BASIC_BLOCK (b));
|
||||
regset regs_live = df_get_live_in (BASIC_BLOCK (b));
|
||||
rtx start_insn, stop_insn;
|
||||
|
||||
/* Compute hard regs live at start of block -- this is the real hard regs
|
||||
marked live, plus live pseudo regs that have been renumbered to
|
||||
hard regs. */
|
||||
|
||||
/* Compute hard regs live at start of block. */
|
||||
REG_SET_TO_HARD_REG_SET (current_live_regs, regs_live);
|
||||
|
||||
/* Get starting and ending insn, handling the case where each might
|
||||
|
@ -1046,10 +1037,24 @@ mark_target_live_regs (rtx insns, rtx target, struct resources *res)
|
|||
|
||||
else if (LABEL_P (real_insn))
|
||||
{
|
||||
basic_block bb;
|
||||
|
||||
/* A label clobbers the pending dead registers since neither
|
||||
reload nor jump will propagate a value across a label. */
|
||||
AND_COMPL_HARD_REG_SET (current_live_regs, pending_dead_regs);
|
||||
CLEAR_HARD_REG_SET (pending_dead_regs);
|
||||
|
||||
/* We must conservatively assume that all registers that used
|
||||
to be live here still are. The fallthrough edge may have
|
||||
left a live register uninitialized. */
|
||||
bb = BLOCK_FOR_INSN (real_insn);
|
||||
if (bb)
|
||||
{
|
||||
HARD_REG_SET extra_live;
|
||||
|
||||
REG_SET_TO_HARD_REG_SET (extra_live, df_get_live_in (bb));
|
||||
IOR_HARD_REG_SET (current_live_regs, extra_live);
|
||||
}
|
||||
}
|
||||
|
||||
/* The beginning of the epilogue corresponds to the end of the
|
||||
|
@ -1121,6 +1126,7 @@ void
|
|||
init_resource_info (rtx epilogue_insn)
|
||||
{
|
||||
int i;
|
||||
basic_block bb;
|
||||
|
||||
/* Indicate what resources are required to be valid at the end of the current
|
||||
function. The condition code never is and memory always is. If the
|
||||
|
@ -1189,6 +1195,11 @@ init_resource_info (rtx epilogue_insn)
|
|||
/* Allocate and initialize the tables used by mark_target_live_regs. */
|
||||
target_hash_table = XCNEWVEC (struct target_info *, TARGET_HASH_PRIME);
|
||||
bb_ticks = XCNEWVEC (int, last_basic_block);
|
||||
|
||||
/* Set the BLOCK_FOR_INSN of each label that starts a basic block. */
|
||||
FOR_EACH_BB (bb)
|
||||
if (LABEL_P (BB_HEAD (bb)))
|
||||
BLOCK_FOR_INSN (BB_HEAD (bb)) = bb;
|
||||
}
|
||||
|
||||
/* Free up the resources allocated to mark_target_live_regs (). This
|
||||
|
@ -1197,6 +1208,8 @@ init_resource_info (rtx epilogue_insn)
|
|||
void
|
||||
free_resource_info (void)
|
||||
{
|
||||
basic_block bb;
|
||||
|
||||
if (target_hash_table != NULL)
|
||||
{
|
||||
int i;
|
||||
|
@ -1222,6 +1235,10 @@ free_resource_info (void)
|
|||
free (bb_ticks);
|
||||
bb_ticks = NULL;
|
||||
}
|
||||
|
||||
FOR_EACH_BB (bb)
|
||||
if (LABEL_P (BB_HEAD (bb)))
|
||||
BLOCK_FOR_INSN (BB_HEAD (bb)) = NULL;
|
||||
}
|
||||
|
||||
/* Clear any hashed information that we have stored for INSN. */
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2009-04-27 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* gnat.dg/opt2.adb: New test.
|
||||
|
||||
2009-04-27 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/39875
|
||||
|
|
31
gcc/testsuite/gnat.dg/opt2.adb
Normal file
31
gcc/testsuite/gnat.dg/opt2.adb
Normal file
|
@ -0,0 +1,31 @@
|
|||
-- { dg-do run }
|
||||
-- { dg-options "-O2 -fno-inline" }
|
||||
|
||||
procedure Opt2 is
|
||||
function Get return String is
|
||||
begin
|
||||
return "[]";
|
||||
end Get;
|
||||
|
||||
Message : String := Get;
|
||||
|
||||
F, L : Integer;
|
||||
begin
|
||||
for J in Message'Range loop
|
||||
if Message (J) = '[' then
|
||||
F := J;
|
||||
elsif Message (J) = ']' then
|
||||
L := J;
|
||||
exit;
|
||||
end if;
|
||||
end loop;
|
||||
|
||||
declare
|
||||
M : String :=
|
||||
Message (Message'First .. F) & Message (L .. Message'Last);
|
||||
begin
|
||||
if M /= "[]" then
|
||||
raise Program_Error;
|
||||
end if;
|
||||
end;
|
||||
end;
|
Loading…
Add table
Reference in a new issue