From dda49b66a42edfaec8b1e8a88ab17902725cc2a2 Mon Sep 17 00:00:00 2001 From: Steven Bosscher Date: Wed, 10 Nov 2004 09:28:29 +0000 Subject: [PATCH] basic-block.h (XMALLOC_REG_SET, [...]): New. * basic-block.h (XMALLOC_REG_SET, XFREE_REG_SET): New. (struct basic_block_def): Remove local_set and cond_local_set fields. Update comment for global_live_at_start. * flow.c (calculate_global_regs_live): Allocate local_sets and cond_local_sets here as arrays of bitmaps previously stored in bb->local_set and bb->cond_local_set. Use xmalloc instead of obstack allocated bitmaps. From-SVN: r90390 --- gcc/ChangeLog | 10 ++++++ gcc/basic-block.h | 21 +++++-------- gcc/flow.c | 78 +++++++++++++++++++++++++++++++---------------- 3 files changed, 70 insertions(+), 39 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 24fc6c247ed9..a83ec6ebaedd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2004-11-10 Steven Bosscher + + * basic-block.h (XMALLOC_REG_SET, XFREE_REG_SET): New. + (struct basic_block_def): Remove local_set and cond_local_set + fields. Update comment for global_live_at_start. + * flow.c (calculate_global_regs_live): Allocate local_sets and + cond_local_sets here as arrays of bitmaps previously stored in + bb->local_set and bb->cond_local_set. Use xmalloc instead of + obstack allocated bitmaps. + 2004-11-09 H.J. Lu PR target/18380 diff --git a/gcc/basic-block.h b/gcc/basic-block.h index 7e61a1ad33e7..7ef4a46cb3d5 100644 --- a/gcc/basic-block.h +++ b/gcc/basic-block.h @@ -110,6 +110,12 @@ typedef bitmap_iterator reg_set_iterator; /* Do any cleanup needed on a regset when it is no longer used. */ #define FREE_REG_SET(REGSET) BITMAP_FREE(REGSET) +/* Allocate a register set with xmalloc. */ +#define XMALLOC_REG_SET() BITMAP_XMALLOC () + +/* Free a register set. */ +#define XFREE_REG_SET(REGSET) BITMAP_XFREE (REGSET) + /* Do any one-time initializations needed for regsets. */ #define INIT_ONCE_REG_SET() BITMAP_INIT_ONCE () @@ -229,20 +235,9 @@ struct basic_block_def GTY((chain_next ("%h.next_bb"), chain_prev ("%h.prev_bb") VEC(edge) *preds; VEC(edge) *succs; - /* Liveness info. */ - - /* The registers that are modified within this in block. */ - bitmap GTY ((skip (""))) local_set; - /* The registers that are conditionally modified within this block. - In other words, registers that are set only as part of a - COND_EXEC. */ - bitmap GTY ((skip (""))) cond_local_set; - /* The registers that are live on entry to this block. - - Note that in SSA form, global_live_at_start does not reflect the - use of regs in phi functions, since the liveness of these regs - may depend on which edge was taken into the block. */ + /* The registers that are live on entry to this block. */ bitmap GTY ((skip (""))) global_live_at_start; + /* The registers that are live on exit from this block. */ bitmap GTY ((skip (""))) global_live_at_end; diff --git a/gcc/flow.c b/gcc/flow.c index 86587cc2edd2..2ccd7554ca93 100644 --- a/gcc/flow.c +++ b/gcc/flow.c @@ -112,7 +112,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA /* TODO: Split out from life_analysis: - - local property discovery (bb->local_live, bb->local_set) + - local property discovery - global property computation - log links creation - pre/post modify transformation @@ -1018,6 +1018,14 @@ calculate_global_regs_live (sbitmap blocks_in, sbitmap blocks_out, int flags) regset tmp, new_live_at_end, invalidated_by_call; regset_head tmp_head, invalidated_by_call_head; regset_head new_live_at_end_head; + + /* The registers that are modified within this in block. */ + regset *local_sets; + + /* The registers that are conditionally modified within this block. + In other words, regs that are set only as part of a COND_EXEC. */ + regset *cond_local_sets; + int i; /* Some passes used to forget clear aux field of basic block causing @@ -1036,12 +1044,18 @@ calculate_global_regs_live (sbitmap blocks_in, sbitmap blocks_out, int flags) if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i)) SET_REGNO_REG_SET (invalidated_by_call, i); + /* Allocate space for the sets of local properties. */ + local_sets = xcalloc (last_basic_block - (INVALID_BLOCK + 1), + sizeof (regset)); + cond_local_sets = xcalloc (last_basic_block - (INVALID_BLOCK + 1), + sizeof (regset)); + /* Create a worklist. Allocate an extra slot for ENTRY_BLOCK, and one because the `head == tail' style test for an empty queue doesn't work with a full queue. */ - queue = xmalloc ((n_basic_blocks + 2) * sizeof (*queue)); + queue = xmalloc ((n_basic_blocks - (INVALID_BLOCK + 1)) * sizeof (*queue)); qtail = queue; - qhead = qend = queue + n_basic_blocks + 2; + qhead = qend = queue + n_basic_blocks - (INVALID_BLOCK + 1); /* Queue the blocks set in the initial mask. Do this in reverse block number order so that we are more likely for the first round to do @@ -1171,13 +1185,14 @@ calculate_global_regs_live (sbitmap blocks_in, sbitmap blocks_out, int flags) } /* On our first pass through this block, we'll go ahead and continue. - Recognize first pass by local_set NULL. On subsequent passes, we - get to skip out early if live_at_end wouldn't have changed. */ + Recognize first pass by checking if local_set is NULL for this + basic block. On subsequent passes, we get to skip out early if + live_at_end wouldn't have changed. */ - if (bb->local_set == NULL) + if (local_sets[bb->index - (INVALID_BLOCK + 1)] == NULL) { - bb->local_set = OBSTACK_ALLOC_REG_SET (&flow_obstack); - bb->cond_local_set = OBSTACK_ALLOC_REG_SET (&flow_obstack); + local_sets[bb->index - (INVALID_BLOCK + 1)] = XMALLOC_REG_SET (); + cond_local_sets[bb->index - (INVALID_BLOCK + 1)] = XMALLOC_REG_SET (); rescan = 1; } else @@ -1190,28 +1205,35 @@ calculate_global_regs_live (sbitmap blocks_in, sbitmap blocks_out, int flags) new_live_at_end); if (!rescan) - /* If any of the registers in the new live_at_end set are - conditionally set in this basic block, we must rescan. - This is because conditional lifetimes at the end of the - block do not just take the live_at_end set into - account, but also the liveness at the start of each - successor block. We can miss changes in those sets if - we only compare the new live_at_end against the - previous one. */ - rescan = bitmap_intersect_p (new_live_at_end, - bb->cond_local_set); + { + regset cond_local_set; + + /* If any of the registers in the new live_at_end set are + conditionally set in this basic block, we must rescan. + This is because conditional lifetimes at the end of the + block do not just take the live_at_end set into + account, but also the liveness at the start of each + successor block. We can miss changes in those sets if + we only compare the new live_at_end against the + previous one. */ + cond_local_set = cond_local_sets[bb->index - (INVALID_BLOCK + 1)]; + rescan = bitmap_intersect_p (new_live_at_end, cond_local_set); + } if (!rescan) { + regset local_set; + /* Find the set of changed bits. Take this opportunity to notice that this set is empty and early out. */ bitmap_xor (tmp, bb->global_live_at_end, new_live_at_end); if (bitmap_empty_p (tmp)) continue; - /* If any of the changed bits overlap with local_set, + /* If any of the changed bits overlap with local_sets[bb], we'll have to rescan the block. */ - rescan = bitmap_intersect_p (tmp, bb->local_set); + local_set = local_sets[bb->index - (INVALID_BLOCK + 1)]; + rescan = bitmap_intersect_p (tmp, local_set); } } @@ -1238,8 +1260,10 @@ calculate_global_regs_live (sbitmap blocks_in, sbitmap blocks_out, int flags) /* Rescan the block insn by insn to turn (a copy of) live_at_end into live_at_start. */ - propagate_block (bb, new_live_at_end, bb->local_set, - bb->cond_local_set, flags); + propagate_block (bb, new_live_at_end, + local_sets[bb->index - (INVALID_BLOCK + 1)], + cond_local_sets[bb->index - (INVALID_BLOCK + 1)], + flags); /* If live_at start didn't change, no need to go farther. */ if (REG_SET_EQUAL_P (bb->global_live_at_start, new_live_at_end)) @@ -1272,20 +1296,22 @@ calculate_global_regs_live (sbitmap blocks_in, sbitmap blocks_out, int flags) EXECUTE_IF_SET_IN_SBITMAP (blocks_out, 0, i, { basic_block bb = BASIC_BLOCK (i); - FREE_REG_SET (bb->local_set); - FREE_REG_SET (bb->cond_local_set); + XFREE_REG_SET (local_sets[bb->index - (INVALID_BLOCK + 1)]); + XFREE_REG_SET (cond_local_sets[bb->index - (INVALID_BLOCK + 1)]); }); } else { FOR_EACH_BB (bb) { - FREE_REG_SET (bb->local_set); - FREE_REG_SET (bb->cond_local_set); + XFREE_REG_SET (local_sets[bb->index - (INVALID_BLOCK + 1)]); + XFREE_REG_SET (cond_local_sets[bb->index - (INVALID_BLOCK + 1)]); } } free (queue); + free (cond_local_sets); + free (local_sets); } -- 2.43.5