Bob Manson <manson@charmed.cygnus.com>

Bob Manson  <manson@charmed.cygnus.com>
        * resource.c, resource.h: New files.
        * haifa-sched.c (regno_use_in): Moved to rtlanal.c.
        (split_block_insns): Moved to recog.c.
        (update_flow_info): Make public.
        * reorg.c: Moved the functions dealing with computing resource
        usage to resource.c.
        * sched.c (regno_use_in): Moved to rtlanal.c.
        (update_flow_info): Make public.
        (schedule_insns): Use split_block_insns.
        * recog.c (split_block_insns): New function.

From-SVN: r24982
This commit is contained in:
Bob Manson 1999-02-02 21:22:52 +00:00 committed by Richard Henderson
parent ee0d2cf322
commit ca545bb569
7 changed files with 1403 additions and 1365 deletions

View File

@ -1,3 +1,20 @@
Fri Jan 29 21:00:56 1999 Bob Manson <manson@charmed.cygnus.com>
* resource.c, resource.h: New files.
* haifa-sched.c (regno_use_in): Moved to rtlanal.c.
(split_block_insns): Moved to recog.c.
(update_flow_info): Make public.
* reorg.c: Moved the functions dealing with computing resource
usage to resource.c.
* sched.c (regno_use_in): Moved to rtlanal.c.
(update_flow_info): Make public.
(schedule_insns): Use split_block_insns.
* recog.c (split_block_insns): New function.
Tue Feb 2 22:03:26 1999 David Edelsohn <edelsohn@mhpcc.edu>
* rs6000/linux.h (LINK_START_DEFAULT_SPEC): Delete, unused.

View File

@ -448,11 +448,9 @@ static void attach_deaths_insn PROTO ((rtx));
static int new_sometimes_live PROTO ((struct sometimes *, int, int));
static void finish_sometimes_live PROTO ((struct sometimes *, int));
static int schedule_block PROTO ((int, int));
static rtx regno_use_in PROTO ((int, rtx));
static void split_hard_reg_notes PROTO ((rtx, rtx, rtx));
static void new_insn_dead_notes PROTO ((rtx, rtx, rtx, rtx));
static void update_n_sets PROTO ((rtx, int));
static void update_flow_info PROTO ((rtx, rtx, rtx, rtx));
static char *safe_concat PROTO ((char *, char *, char *));
static int insn_issue_delay PROTO ((rtx));
static int birthing_insn_p PROTO ((rtx));
@ -765,7 +763,6 @@ static rtx group_leader PROTO ((rtx));
static int set_priorities PROTO ((int));
static void init_rtx_vector PROTO ((rtx **, rtx *, int, int));
static void schedule_region PROTO ((int));
static void split_block_insns PROTO ((int));
#endif /* INSN_SCHEDULING */
@ -7699,39 +7696,6 @@ schedule_region (rgn)
FREE_REG_SET (reg_pending_sets);
}
/* Subroutine of split_hard_reg_notes. Searches X for any reference to
REGNO, returning the rtx of the reference found if any. Otherwise,
returns 0. */
static rtx
regno_use_in (regno, x)
int regno;
rtx x;
{
register char *fmt;
int i, j;
rtx tem;
if (GET_CODE (x) == REG && REGNO (x) == regno)
return x;
fmt = GET_RTX_FORMAT (GET_CODE (x));
for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
{
if (fmt[i] == 'e')
{
if ((tem = regno_use_in (regno, XEXP (x, i))))
return tem;
}
else if (fmt[i] == 'E')
for (j = XVECLEN (x, i) - 1; j >= 0; j--)
if ((tem = regno_use_in (regno, XVECEXP (x, i, j))))
return tem;
}
return 0;
}
/* Subroutine of update_flow_info. Determines whether any new REG_NOTEs are
needed for the hard register mentioned in the note. This can happen
if the reference to the hard register in the original insn was split into
@ -7918,7 +7882,7 @@ update_n_sets (x, inc)
the insns from FIRST to LAST inclusive that were created by splitting
ORIG_INSN. NOTES are the original REG_NOTES. */
static void
void
update_flow_info (notes, first, last, orig_insn)
rtx notes;
rtx first, last;
@ -8409,79 +8373,6 @@ update_flow_info (notes, first, last, orig_insn)
}
}
/* Do the splitting of insns in the block b. */
static void
split_block_insns (b)
int b;
{
rtx insn, next;
for (insn = BLOCK_HEAD (b);; insn = next)
{
rtx set, last, first, notes;
/* Can't use `next_real_insn' because that
might go across CODE_LABELS and short-out basic blocks. */
next = NEXT_INSN (insn);
if (GET_CODE (insn) != INSN)
{
if (insn == BLOCK_END (b))
break;
continue;
}
/* Don't split no-op move insns. These should silently disappear
later in final. Splitting such insns would break the code
that handles REG_NO_CONFLICT blocks. */
set = single_set (insn);
if (set && rtx_equal_p (SET_SRC (set), SET_DEST (set)))
{
if (insn == BLOCK_END (b))
break;
/* Nops get in the way while scheduling, so delete them now if
register allocation has already been done. It is too risky
to try to do this before register allocation, and there are
unlikely to be very many nops then anyways. */
if (reload_completed)
{
PUT_CODE (insn, NOTE);
NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
NOTE_SOURCE_FILE (insn) = 0;
}
continue;
}
/* Split insns here to get max fine-grain parallelism. */
first = PREV_INSN (insn);
notes = REG_NOTES (insn);
last = try_split (PATTERN (insn), insn, 1);
if (last != insn)
{
/* try_split returns the NOTE that INSN became. */
first = NEXT_INSN (first);
update_flow_info (notes, first, last, insn);
PUT_CODE (insn, NOTE);
NOTE_SOURCE_FILE (insn) = 0;
NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
if (insn == BLOCK_HEAD (b))
BLOCK_HEAD (b) = first;
if (insn == BLOCK_END (b))
{
BLOCK_END (b) = last;
break;
}
}
if (insn == BLOCK_END (b))
break;
}
}
/* The one entry point in this file. DUMP_FILE is the dump file for
this pass. */
@ -8535,7 +8426,7 @@ schedule_insns (dump_file)
/* do the splitting first for all blocks */
for (b = 0; b < n_basic_blocks; b++)
split_block_insns (b);
split_block_insns (b, 1);
max_uid = (get_max_uid () + 1);

View File

@ -32,6 +32,7 @@ Boston, MA 02111-1307, USA. */
#include "flags.h"
#include "real.h"
#include "toplev.h"
#include "basic-block.h"
#ifndef STACK_PUSH_CODE
#ifdef STACK_GROWS_DOWNWARD
@ -2596,3 +2597,83 @@ reg_fits_class_p (operand, class, offset, mode)
}
#endif /* REGISTER_CONSTRAINTS */
/* Do the splitting of insns in the block B. Only try to actually split if
DO_SPLIT is true; otherwise, just remove nops. */
void
split_block_insns (b, do_split)
int b;
int do_split;
{
rtx insn, next;
for (insn = BLOCK_HEAD (b);; insn = next)
{
rtx set;
/* Can't use `next_real_insn' because that
might go across CODE_LABELS and short-out basic blocks. */
next = NEXT_INSN (insn);
if (GET_CODE (insn) != INSN)
{
if (insn == BLOCK_END (b))
break;
continue;
}
/* Don't split no-op move insns. These should silently disappear
later in final. Splitting such insns would break the code
that handles REG_NO_CONFLICT blocks. */
set = single_set (insn);
if (set && rtx_equal_p (SET_SRC (set), SET_DEST (set)))
{
if (insn == BLOCK_END (b))
break;
/* Nops get in the way while scheduling, so delete them now if
register allocation has already been done. It is too risky
to try to do this before register allocation, and there are
unlikely to be very many nops then anyways. */
if (reload_completed)
{
PUT_CODE (insn, NOTE);
NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
NOTE_SOURCE_FILE (insn) = 0;
}
continue;
}
if (do_split)
{
/* Split insns here to get max fine-grain parallelism. */
rtx first = PREV_INSN (insn);
rtx notes = REG_NOTES (insn);
rtx last = try_split (PATTERN (insn), insn, 1);
if (last != insn)
{
/* try_split returns the NOTE that INSN became. */
first = NEXT_INSN (first);
update_flow_info (notes, first, last, insn);
PUT_CODE (insn, NOTE);
NOTE_SOURCE_FILE (insn) = 0;
NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
if (insn == BLOCK_HEAD (b))
BLOCK_HEAD (b) = first;
if (insn == BLOCK_END (b))
{
BLOCK_END (b) = last;
break;
}
}
}
if (insn == BLOCK_END (b))
break;
}
}

File diff suppressed because it is too large Load Diff

1239
gcc/resource.c Normal file

File diff suppressed because it is too large Load Diff

46
gcc/resource.h Normal file
View File

@ -0,0 +1,46 @@
/* Definitions for computing resource usage of specific insns.
Copyright (C) 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC 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.
GNU CC 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 GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* Macro to clear all resources. */
#define CLEAR_RESOURCE(RES) \
do { (RES)->memory = (RES)->unch_memory = (RES)->volatil = (RES)->cc = 0; \
CLEAR_HARD_REG_SET ((RES)->regs); } while (0)
/* The resources used by a given insn. */
struct resources
{
char memory; /* Insn sets or needs a memory location. */
char unch_memory; /* Insn sets of needs a "unchanging" MEM. */
char volatil; /* Insn sets or needs a volatile memory loc. */
char cc; /* Insn sets or needs the condition codes. */
HARD_REG_SET regs; /* Which registers are set or needed. */
};
extern void mark_target_live_regs PROTO((rtx, rtx, struct resources *));
extern void mark_set_resources PROTO((rtx, struct resources *, int,
int));
extern void mark_referenced_resources PROTO((rtx, struct resources *, int));
extern void clear_hashed_info_for_insn PROTO((rtx));
extern void incr_ticks_for_insn PROTO((rtx));
extern void mark_end_of_function_resources PROTO ((rtx, int));
extern void init_resource_info PROTO((rtx));
extern void free_resource_info PROTO((void));
extern rtx find_free_register PROTO((rtx, char *, int,
HARD_REG_SET *));

View File

@ -342,11 +342,9 @@ static int new_sometimes_live PROTO((struct sometimes *, int, int));
static void finish_sometimes_live PROTO((struct sometimes *, int));
static rtx reemit_notes PROTO((rtx, rtx));
static void schedule_block PROTO((int, FILE *));
static rtx regno_use_in PROTO((int, rtx));
static void split_hard_reg_notes PROTO((rtx, rtx, rtx));
static void new_insn_dead_notes PROTO((rtx, rtx, rtx, rtx));
static void update_n_sets PROTO((rtx, int));
static void update_flow_info PROTO((rtx, rtx, rtx, rtx));
/* Main entry point of this file. */
void schedule_insns PROTO((FILE *));
@ -3533,39 +3531,6 @@ ret:
return;
}
/* Subroutine of split_hard_reg_notes. Searches X for any reference to
REGNO, returning the rtx of the reference found if any. Otherwise,
returns 0. */
static rtx
regno_use_in (regno, x)
int regno;
rtx x;
{
register char *fmt;
int i, j;
rtx tem;
if (GET_CODE (x) == REG && REGNO (x) == regno)
return x;
fmt = GET_RTX_FORMAT (GET_CODE (x));
for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
{
if (fmt[i] == 'e')
{
if ((tem = regno_use_in (regno, XEXP (x, i))))
return tem;
}
else if (fmt[i] == 'E')
for (j = XVECLEN (x, i) - 1; j >= 0; j--)
if ((tem = regno_use_in (regno , XVECEXP (x, i, j))))
return tem;
}
return 0;
}
/* Subroutine of update_flow_info. Determines whether any new REG_NOTEs are
needed for the hard register mentioned in the note. This can happen
if the reference to the hard register in the original insn was split into
@ -3760,7 +3725,7 @@ update_n_sets (x, inc)
the insns from FIRST to LAST inclusive that were created by splitting
ORIG_INSN. NOTES are the original REG_NOTES. */
static void
void
update_flow_info (notes, first, last, orig_insn)
rtx notes;
rtx first, last;
@ -4366,78 +4331,7 @@ schedule_insns (dump_file)
note_list = 0;
for (insn = BLOCK_HEAD (b); ; insn = next)
{
rtx prev;
rtx set;
/* Can't use `next_real_insn' because that
might go across CODE_LABELS and short-out basic blocks. */
next = NEXT_INSN (insn);
if (GET_CODE (insn) != INSN)
{
if (insn == BLOCK_END (b))
break;
continue;
}
/* Don't split no-op move insns. These should silently disappear
later in final. Splitting such insns would break the code
that handles REG_NO_CONFLICT blocks. */
set = single_set (insn);
if (set && rtx_equal_p (SET_SRC (set), SET_DEST (set)))
{
if (insn == BLOCK_END (b))
break;
/* Nops get in the way while scheduling, so delete them now if
register allocation has already been done. It is too risky
to try to do this before register allocation, and there are
unlikely to be very many nops then anyways. */
if (reload_completed)
{
PUT_CODE (insn, NOTE);
NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
NOTE_SOURCE_FILE (insn) = 0;
}
continue;
}
/* Split insns here to get max fine-grain parallelism. */
prev = PREV_INSN (insn);
/* It is probably not worthwhile to try to split again in the
second pass. However, if flag_schedule_insns is not set,
the first and only (if any) scheduling pass is after reload. */
if (reload_completed == 0 || ! flag_schedule_insns)
{
rtx last, first = PREV_INSN (insn);
rtx notes = REG_NOTES (insn);
last = try_split (PATTERN (insn), insn, 1);
if (last != insn)
{
/* try_split returns the NOTE that INSN became. */
first = NEXT_INSN (first);
update_flow_info (notes, first, last, insn);
PUT_CODE (insn, NOTE);
NOTE_SOURCE_FILE (insn) = 0;
NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
if (insn == BLOCK_HEAD (b))
BLOCK_HEAD (b) = first;
if (insn == BLOCK_END (b))
{
BLOCK_END (b) = last;
break;
}
}
}
if (insn == BLOCK_END (b))
break;
}
split_block_insns (b, reload_completed == 0 || ! flag_schedule_insns);
schedule_block (b, dump_file);