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:
parent
ee0d2cf322
commit
ca545bb569
@ -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.
|
||||
|
@ -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);
|
||||
|
||||
|
81
gcc/recog.c
81
gcc/recog.c
@ -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;
|
||||
}
|
||||
}
|
||||
|
1162
gcc/reorg.c
1162
gcc/reorg.c
File diff suppressed because it is too large
Load Diff
1239
gcc/resource.c
Normal file
1239
gcc/resource.c
Normal file
File diff suppressed because it is too large
Load Diff
46
gcc/resource.h
Normal file
46
gcc/resource.h
Normal 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 *));
|
110
gcc/sched.c
110
gcc/sched.c
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user