This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: update_life_info stuff
- To: Jeffrey A Law <law at cygnus dot com>
- Subject: Re: update_life_info stuff
- From: Richard Henderson <rth at cygnus dot com>
- Date: Mon, 18 Oct 1999 15:18:38 -0700
- Cc: gcc at gcc dot gnu dot org, gcc-patches at gcc dot gnu dot org
- References: <7072.940192586@upchuck.cygnus.com>
On Sun, Oct 17, 1999 at 02:36:26PM -0600, Jeffrey A Law wrote:
> We really need to fix the REG_BASIC_BLOCK, REG_LIVE_LENGTH, etc etc
> stuff that broke when you revamped haifa's life stuff.
I'll try to get to that shortly....
> That work has also significantly slowed down compilation on the x86.
> compute_bb_for_insn accounts for half of the total compilation time via
> the call to update_flow_info from sched.c
Fixed thus.
r~
* basic-block.h (set_block_num): Declare.
* flow.c (update_life_info): Don't call compute_bb_for_insn
or free_basic_block_vars.
* haifa-sched.c (remove_dependence): Conditionalize on HAVE_cc0.
(insn_orig_block): Remove.
(INSN_BLOCK): Remove. Update all callers to use BLOCK_NUM.
(schedule_block): Keep BLOCK_NUM up-to-date.
(schedule_insns): Use compute_bb_for_insn.
* recog.c (split_all_insns): Likewise.
(peephole2_optimize): Likewise.
Index: basic-block.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/basic-block.h,v
retrieving revision 1.33
diff -c -p -d -r1.33 basic-block.h
*** basic-block.h 1999/10/17 09:21:25 1.33
--- basic-block.h 1999/10/18 22:15:19
*************** extern varray_type basic_block_for_insn;
*** 245,250 ****
--- 245,251 ----
extern void compute_bb_for_insn PROTO ((int));
extern void set_block_for_insn PROTO ((rtx, basic_block));
+ extern void set_block_num PROTO ((rtx, int));
extern void dump_bb_data PROTO ((FILE *, int_list_ptr *,
int_list_ptr *, int));
Index: flow.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/flow.c,v
retrieving revision 1.170
diff -c -p -d -r1.170 flow.c
*** flow.c 1999/10/14 23:31:25 1.170
--- flow.c 1999/10/18 22:15:19
*************** verify_local_live_at_start (new_live_at_
*** 2544,2549 ****
--- 2544,2551 ----
If we find registers removed from live_at_start, that means we have
a broken peephole that is killing a register it shouldn't.
+ BLOCK_FOR_INSN is assumed to be correct.
+
??? This is not true in one situation -- when a pre-reload splitter
generates subregs of a multi-word pseudo, current life analysis will
lose the kill. So we _can_ have a pseudo go live. How irritating. */
*************** update_life_info (blocks, extent)
*** 2556,2562 ****
regset tmp;
int i;
- compute_bb_for_insn (get_max_uid ());
tmp = ALLOCA_REG_SET ();
/* For a global update, we go through the relaxation process again. */
--- 2558,2563 ----
*************** update_life_info (blocks, extent)
*** 2584,2590 ****
});
FREE_REG_SET (tmp);
- free_basic_block_vars (1);
}
/* Free the variables allocated by find_basic_blocks.
--- 2585,2590 ----
Index: haifa-sched.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/haifa-sched.c,v
retrieving revision 1.119
diff -c -p -d -r1.119 haifa-sched.c
*** haifa-sched.c 1999/10/17 21:46:36 1.119
--- haifa-sched.c 1999/10/18 22:15:19
*************** static int *insn_tick;
*** 397,403 ****
--- 397,405 ----
/* Forward declarations. */
static void add_dependence PROTO ((rtx, rtx, enum reg_note));
+ #ifdef HAVE_cc0
static void remove_dependence PROTO ((rtx, rtx));
+ #endif
static rtx find_insn_list PROTO ((rtx, rtx));
static int insn_unit PROTO ((rtx));
static unsigned int blockage_range PROTO ((int, rtx));
*************** static char *safe_concat PROTO ((char *,
*** 425,434 ****
static int insn_issue_delay PROTO ((rtx));
static void adjust_priority PROTO ((rtx));
- /* Mapping of insns to their original block prior to scheduling. */
- static int *insn_orig_block;
- #define INSN_BLOCK(insn) (insn_orig_block[INSN_UID (insn)])
-
/* Some insns (e.g. call) are not allowed to move across blocks. */
static char *cant_move;
#define CANT_MOVE(insn) (cant_move[INSN_UID (insn)])
--- 427,432 ----
*************** static edgeset *ancestor_edges;
*** 637,645 ****
static void compute_dom_prob_ps PROTO ((int));
#define ABS_VALUE(x) (((x)<0)?(-(x)):(x))
! #define INSN_PROBABILITY(INSN) (SRC_PROB (BLOCK_TO_BB (INSN_BLOCK (INSN))))
! #define IS_SPECULATIVE_INSN(INSN) (IS_SPECULATIVE (BLOCK_TO_BB (INSN_BLOCK (INSN))))
! #define INSN_BB(INSN) (BLOCK_TO_BB (INSN_BLOCK (INSN)))
/* Parameters affecting the decision of rank_for_schedule(). */
#define MIN_DIFF_PRIORITY 2
--- 635,643 ----
static void compute_dom_prob_ps PROTO ((int));
#define ABS_VALUE(x) (((x)<0)?(-(x)):(x))
! #define INSN_PROBABILITY(INSN) (SRC_PROB (BLOCK_TO_BB (BLOCK_NUM (INSN))))
! #define IS_SPECULATIVE_INSN(INSN) (IS_SPECULATIVE (BLOCK_TO_BB (BLOCK_NUM (INSN))))
! #define INSN_BB(INSN) (BLOCK_TO_BB (BLOCK_NUM (INSN)))
/* Parameters affecting the decision of rank_for_schedule(). */
#define MIN_DIFF_PRIORITY 2
*************** add_dependence (insn, elem, dep_type)
*** 828,833 ****
--- 826,832 ----
PUT_REG_NOTE_KIND (link, dep_type);
}
+ #ifdef HAVE_cc0
/* Remove ELEM wrapped in an INSN_LIST from the LOG_LINKS
of INSN. Abort if not found. */
*************** remove_dependence (insn, elem)
*** 867,872 ****
--- 866,872 ----
abort ();
return;
}
+ #endif /* HAVE_cc0 */
#ifndef INSN_SCHEDULING
void
*************** find_conditional_protection (insn, load_
*** 2333,2339 ****
for (link = INSN_DEPEND (insn); link; link = XEXP (link, 1))
{
rtx next = XEXP (link, 0);
! if ((CONTAINING_RGN (INSN_BLOCK (next)) ==
CONTAINING_RGN (BB_TO_BLOCK (load_insn_bb)))
&& IS_REACHABLE (INSN_BB (next), load_insn_bb)
&& load_insn_bb != INSN_BB (next)
--- 2333,2339 ----
for (link = INSN_DEPEND (insn); link; link = XEXP (link, 1))
{
rtx next = XEXP (link, 0);
! if ((CONTAINING_RGN (BLOCK_NUM (next)) ==
CONTAINING_RGN (BB_TO_BLOCK (load_insn_bb)))
&& IS_REACHABLE (INSN_BB (next), load_insn_bb)
&& load_insn_bb != INSN_BB (next)
*************** is_conditionally_protected (load_insn, b
*** 2377,2383 ****
/* Must exist a path: region-entry -> ... -> bb_trg -> ... load_insn. */
if (INSN_BB (insn1) == bb_src
! || (CONTAINING_RGN (INSN_BLOCK (insn1))
!= CONTAINING_RGN (BB_TO_BLOCK (bb_src)))
|| (!IS_REACHABLE (bb_trg, INSN_BB (insn1))
&& !IS_REACHABLE (INSN_BB (insn1), bb_trg)))
--- 2377,2383 ----
/* Must exist a path: region-entry -> ... -> bb_trg -> ... load_insn. */
if (INSN_BB (insn1) == bb_src
! || (CONTAINING_RGN (BLOCK_NUM (insn1))
!= CONTAINING_RGN (BB_TO_BLOCK (bb_src)))
|| (!IS_REACHABLE (bb_trg, INSN_BB (insn1))
&& !IS_REACHABLE (INSN_BB (insn1), bb_trg)))
*************** is_pfree (load_insn, bb_src, bb_trg)
*** 2448,2454 ****
/* insn2 is the similar load, in the target block. */
return 1;
! if (*(candp->split_bbs.first_member) == INSN_BLOCK (insn2))
/* insn2 is a similar load, in a split-block. */
return 1;
}
--- 2448,2454 ----
/* insn2 is the similar load, in the target block. */
return 1;
! if (*(candp->split_bbs.first_member) == BLOCK_NUM (insn2))
/* insn2 is a similar load, in a split-block. */
return 1;
}
*************** priority (insn)
*** 3108,3114 ****
next = XEXP (link, 0);
/* Critical path is meaningful in block boundaries only. */
! if (INSN_BLOCK (next) != INSN_BLOCK (insn))
continue;
next_priority = insn_cost (insn, link, next) + priority (next);
--- 3108,3114 ----
next = XEXP (link, 0);
/* Critical path is meaningful in block boundaries only. */
! if (BLOCK_NUM (next) != BLOCK_NUM (insn))
continue;
next_priority = insn_cost (insn, link, next) + priority (next);
*************** sched_analyze_insn (x, insn, loop_notes)
*** 3738,3743 ****
--- 3738,3744 ----
for (i = 0; i < maxreg; i++)
{
free_INSN_LIST_list (®_last_sets[i]);
+ free_INSN_LIST_list (®_last_clobbers[i]);
reg_last_sets[i] = alloc_INSN_LIST (insn, NULL_RTX);
}
*************** queue_insn (insn, n_cycles)
*** 4087,4093 ****
fprintf (dump, ";;\t\tReady-->Q: insn %d: ", INSN_UID (insn));
if (INSN_BB (insn) != target_bb)
! fprintf (dump, "(b%d) ", INSN_BLOCK (insn));
fprintf (dump, "queued for %d cycles.\n", n_cycles);
}
--- 4088,4094 ----
fprintf (dump, ";;\t\tReady-->Q: insn %d: ", INSN_UID (insn));
if (INSN_BB (insn) != target_bb)
! fprintf (dump, "(b%d) ", BLOCK_NUM (insn));
fprintf (dump, "queued for %d cycles.\n", n_cycles);
}
*************** schedule_insn (insn, ready, n_ready, clo
*** 4185,4191 ****
INSN_UID (next));
if (current_nr_blocks > 1 && INSN_BB (next) != target_bb)
! fprintf (dump, "/b%d ", INSN_BLOCK (next));
if (effective_cost < 1)
fprintf (dump, "into ready\n");
--- 4186,4192 ----
INSN_UID (next));
if (current_nr_blocks > 1 && INSN_BB (next) != target_bb)
! fprintf (dump, "/b%d ", BLOCK_NUM (next));
if (effective_cost < 1)
fprintf (dump, "into ready\n");
*************** queue_to_ready (ready, n_ready)
*** 4630,4636 ****
fprintf (dump, ";;\t\tQ-->Ready: insn %d: ", INSN_UID (insn));
if (sched_verbose >= 2 && INSN_BB (insn) != target_bb)
! fprintf (dump, "(b%d) ", INSN_BLOCK (insn));
ready[n_ready++] = insn;
if (sched_verbose >= 2)
--- 4631,4637 ----
fprintf (dump, ";;\t\tQ-->Ready: insn %d: ", INSN_UID (insn));
if (sched_verbose >= 2 && INSN_BB (insn) != target_bb)
! fprintf (dump, "(b%d) ", BLOCK_NUM (insn));
ready[n_ready++] = insn;
if (sched_verbose >= 2)
*************** queue_to_ready (ready, n_ready)
*** 4657,4663 ****
fprintf (dump, ";;\t\tQ-->Ready: insn %d: ", INSN_UID (insn));
if (sched_verbose >= 2 && INSN_BB (insn) != target_bb)
! fprintf (dump, "(b%d) ", INSN_BLOCK (insn));
ready[n_ready++] = insn;
if (sched_verbose >= 2)
--- 4658,4664 ----
fprintf (dump, ";;\t\tQ-->Ready: insn %d: ", INSN_UID (insn));
if (sched_verbose >= 2 && INSN_BB (insn) != target_bb)
! fprintf (dump, "(b%d) ", BLOCK_NUM (insn));
ready[n_ready++] = insn;
if (sched_verbose >= 2)
*************** debug_ready_list (ready, n_ready)
*** 4691,4697 ****
{
fprintf (dump, " %d", INSN_UID (ready[i]));
if (current_nr_blocks > 1 && INSN_BB (ready[i]) != target_bb)
! fprintf (dump, "/b%d", INSN_BLOCK (ready[i]));
}
fprintf (dump, "\n");
}
--- 4692,4698 ----
{
fprintf (dump, " %d", INSN_UID (ready[i]));
if (current_nr_blocks > 1 && INSN_BB (ready[i]) != target_bb)
! fprintf (dump, "/b%d", BLOCK_NUM (ready[i]));
}
fprintf (dump, "\n");
}
*************** schedule_block (bb, rgn_n_insns)
*** 5895,5902 ****
/* Loop until all the insns in BB are scheduled. */
while (sched_target_n_insns < target_n_insns)
{
- int b1;
-
clock_var++;
/* Add to the ready list all pending insns that can be issued now.
--- 5896,5901 ----
*************** schedule_block (bb, rgn_n_insns)
*** 5949,5954 ****
--- 5948,5954 ----
if (INSN_BB (insn) != target_bb)
{
rtx temp;
+ basic_block b1;
if (IS_SPECULATIVE_INSN (insn))
{
*************** schedule_block (bb, rgn_n_insns)
*** 5964,5998 ****
}
nr_inter++;
temp = insn;
! while (SCHED_GROUP_P (temp))
! temp = PREV_INSN (temp);
/* Update source block boundaries. */
! b1 = INSN_BLOCK (temp);
! if (temp == BLOCK_HEAD (b1)
! && insn == BLOCK_END (b1))
{
/* We moved all the insns in the basic block.
Emit a note after the last insn and update the
begin/end boundaries to point to the note. */
! emit_note_after (NOTE_INSN_DELETED, insn);
! BLOCK_END (b1) = NEXT_INSN (insn);
! BLOCK_HEAD (b1) = NEXT_INSN (insn);
}
! else if (insn == BLOCK_END (b1))
{
/* We took insns from the end of the basic block,
so update the end of block boundary so that it
points to the first insn we did not move. */
! BLOCK_END (b1) = PREV_INSN (temp);
}
! else if (temp == BLOCK_HEAD (b1))
{
/* We took insns from the start of the basic block,
so update the start of block boundary so that
it points to the first insn we did not move. */
! BLOCK_HEAD (b1) = NEXT_INSN (insn);
}
}
else
--- 5964,6003 ----
}
nr_inter++;
+ /* Find the beginning of the scheduling group; update the
+ containing block number for the insns. */
temp = insn;
! set_block_num (temp, target_bb);
! while (SCHED_GROUP_P (insn))
! {
! temp = PREV_INSN (temp);
! set_block_num (temp, target_bb);
! }
/* Update source block boundaries. */
! b1 = BLOCK_FOR_INSN (temp);
! if (temp == b1->head && insn == b1->end)
{
/* We moved all the insns in the basic block.
Emit a note after the last insn and update the
begin/end boundaries to point to the note. */
! rtx note = emit_note_after (NOTE_INSN_DELETED, insn);
! b1->head = note;
! b1->end = note;
}
! else if (insn == b1->end)
{
/* We took insns from the end of the basic block,
so update the end of block boundary so that it
points to the first insn we did not move. */
! b1->end = PREV_INSN (temp);
}
! else if (temp == b1->head)
{
/* We took insns from the start of the basic block,
so update the start of block boundary so that
it points to the first insn we did not move. */
! b1->head = NEXT_INSN (insn);
}
}
else
*************** schedule_insns (dump_file)
*** 6858,6882 ****
split_all_insns (1);
! max_uid = (get_max_uid () + 1);
cant_move = xcalloc (max_uid, sizeof (char));
fed_by_spec_load = xcalloc (max_uid, sizeof (char));
is_load_insn = xcalloc (max_uid, sizeof (char));
- insn_orig_block = (int *) xmalloc (max_uid * sizeof (int));
insn_luid = (int *) xmalloc (max_uid * sizeof (int));
- /* We use LUID 0 for the fake insn (UID 0) which holds dependencies for
- pseudos which do not cross calls. */
insn_luid[0] = 0;
luid = 1;
for (b = 0; b < n_basic_blocks; b++)
for (insn = BLOCK_HEAD (b);; insn = NEXT_INSN (insn))
{
- INSN_BLOCK (insn) = b;
INSN_LUID (insn) = luid++;
-
if (insn == BLOCK_END (b))
break;
}
--- 6863,6884 ----
split_all_insns (1);
! /* We use LUID 0 for the fake insn (UID 0) which holds dependencies for
! pseudos which do not cross calls. */
! max_uid = get_max_uid () + 1;
cant_move = xcalloc (max_uid, sizeof (char));
fed_by_spec_load = xcalloc (max_uid, sizeof (char));
is_load_insn = xcalloc (max_uid, sizeof (char));
insn_luid = (int *) xmalloc (max_uid * sizeof (int));
insn_luid[0] = 0;
luid = 1;
for (b = 0; b < n_basic_blocks; b++)
for (insn = BLOCK_HEAD (b);; insn = NEXT_INSN (insn))
{
INSN_LUID (insn) = luid++;
if (insn == BLOCK_END (b))
break;
}
*************** schedule_insns (dump_file)
*** 6899,6904 ****
--- 6901,6908 ----
block_to_bb = (int *) alloca ((n_basic_blocks) * sizeof (int));
containing_rgn = (int *) alloca ((n_basic_blocks) * sizeof (int));
+ compute_bb_for_insn (max_uid);
+
/* Compute regions for scheduling. */
if (reload_completed
|| n_basic_blocks == 1
*************** schedule_insns (dump_file)
*** 7068,7074 ****
free (cant_move);
free (fed_by_spec_load);
free (is_load_insn);
- free (insn_orig_block);
free (insn_luid);
free (insn_priority);
--- 7072,7077 ----
Index: recog.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/recog.c,v
retrieving revision 1.46
diff -c -p -d -r1.46 recog.c
*** recog.c 1999/10/15 01:52:29 1.46
--- recog.c 1999/10/18 22:15:19
*************** split_all_insns (upd_life)
*** 2659,2664 ****
--- 2659,2665 ----
if (changed && upd_life)
{
+ compute_bb_for_insn (get_max_uid ());
count_or_remove_death_notes (blocks, 1);
update_life_info (blocks, UPDATE_LIFE_LOCAL);
}
*************** peephole2_optimize (dump_file)
*** 2759,2764 ****
--- 2760,2766 ----
free_resource_info ();
+ compute_bb_for_insn (get_max_uid ());
count_or_remove_death_notes (blocks, 1);
update_life_info (blocks, UPDATE_LIFE_LOCAL);
}