summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/local-alloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gcc/local-alloc.c')
-rw-r--r--contrib/gcc/local-alloc.c93
1 files changed, 38 insertions, 55 deletions
diff --git a/contrib/gcc/local-alloc.c b/contrib/gcc/local-alloc.c
index 05d0bde..c2d6c0c 100644
--- a/contrib/gcc/local-alloc.c
+++ b/contrib/gcc/local-alloc.c
@@ -61,10 +61,10 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "hard-reg-set.h"
#include "rtl.h"
#include "tm_p.h"
#include "flags.h"
-#include "hard-reg-set.h"
#include "basic-block.h"
#include "regs.h"
#include "function.h"
@@ -144,12 +144,6 @@ struct qty
or -1 if none was found. */
short phys_reg;
-
- /* Nonzero if this quantity has been used in a SUBREG in some
- way that is illegal. */
-
- char changes_mode;
-
};
static struct qty *qty;
@@ -328,7 +322,6 @@ alloc_qty (regno, mode, size, birth)
qty[qtyno].alternate_class = reg_alternate_class (regno);
qty[qtyno].n_refs = REG_N_REFS (regno);
qty[qtyno].freq = REG_FREQ (regno);
- qty[qtyno].changes_mode = REG_CHANGES_MODE (regno);
}
/* Main entry point of this file. */
@@ -336,8 +329,9 @@ alloc_qty (regno, mode, size, birth)
int
local_alloc ()
{
- int b, i;
+ int i;
int max_qty;
+ basic_block b;
/* We need to keep track of whether or not we recorded a LABEL_REF so
that we know if the jump optimizer needs to be rerun. */
@@ -352,7 +346,8 @@ local_alloc ()
/* Promote REG_EQUAL notes to REG_EQUIV notes and adjust status of affected
registers. */
- update_equiv_regs ();
+ if (optimize)
+ update_equiv_regs ();
/* This sets the maximum number of quantities we can have. Quantity
numbers start at zero and we can have one for each pseudo. */
@@ -393,7 +388,7 @@ local_alloc ()
/* Allocate each block's local registers, block by block. */
- for (b = 0; b < n_basic_blocks; b++)
+ FOR_EACH_BB (b)
{
/* NEXT_QTY indicates which elements of the `qty_...'
vectors might need to be initialized because they were used
@@ -425,7 +420,7 @@ local_alloc ()
next_qty = 0;
- block_alloc (b);
+ block_alloc (b->index);
}
free (qty);
@@ -575,7 +570,7 @@ equiv_init_varies_p (x)
return 0;
}
-/* Returns non-zero if X (used to initialize register REGNO) is movable.
+/* Returns nonzero if X (used to initialize register REGNO) is movable.
X is only movable if the registers it uses have equivalent initializations
which appear to be within the same loop (or in an inner loop) and movable
or if they are not candidates for local_alloc and don't vary. */
@@ -814,7 +809,7 @@ static void
update_equiv_regs ()
{
rtx insn;
- int block;
+ basic_block bb;
int loop_depth;
regset_head cleared_regs;
int clear_regnos = 0;
@@ -827,9 +822,8 @@ update_equiv_regs ()
/* Scan the insns and find which registers have equivalences. Do this
in a separate scan of the insns because (due to -fcse-follow-jumps)
a register can be set below its use. */
- for (block = 0; block < n_basic_blocks; block++)
+ FOR_EACH_BB (bb)
{
- basic_block bb = BASIC_BLOCK (block);
loop_depth = bb->loop_depth;
for (insn = bb->head; insn != NEXT_INSN (bb->end); insn = NEXT_INSN (insn))
@@ -1043,10 +1037,8 @@ update_equiv_regs ()
within the same loop (or in an inner loop), then move the register
initialization just before the use, so that they are in the same
basic block. */
- for (block = n_basic_blocks - 1; block >= 0; block--)
+ FOR_EACH_BB_REVERSE (bb)
{
- basic_block bb = BASIC_BLOCK (block);
-
loop_depth = bb->loop_depth;
for (insn = bb->end; insn != PREV_INSN (bb->head); insn = PREV_INSN (insn))
{
@@ -1116,7 +1108,7 @@ update_equiv_regs ()
REG_N_REFS (regno) = 0;
REG_FREQ (regno) = 0;
delete_insn (equiv_insn);
-
+
reg_equiv[regno].init_insns
= XEXP (reg_equiv[regno].init_insns, 1);
}
@@ -1138,12 +1130,12 @@ update_equiv_regs ()
XEXP (reg_equiv[regno].init_insns, 0) = new_insn;
- REG_BASIC_BLOCK (regno) = block >= 0 ? block : 0;
+ REG_BASIC_BLOCK (regno) = bb->index;
REG_N_CALLS_CROSSED (regno) = 0;
REG_LIVE_LENGTH (regno) = 2;
- if (block >= 0 && insn == BLOCK_HEAD (block))
- BLOCK_HEAD (block) = PREV_INSN (insn);
+ if (insn == bb->head)
+ bb->head = PREV_INSN (insn);
/* Remember to clear REGNO from all basic block's live
info. */
@@ -1158,24 +1150,22 @@ update_equiv_regs ()
/* Clear all dead REGNOs from all basic block's live info. */
if (clear_regnos)
{
- int j, l;
+ int j;
if (clear_regnos > 8)
- {
- for (l = 0; l < n_basic_blocks; l++)
+ {
+ FOR_EACH_BB (bb)
{
- AND_COMPL_REG_SET (BASIC_BLOCK (l)->global_live_at_start,
- &cleared_regs);
- AND_COMPL_REG_SET (BASIC_BLOCK (l)->global_live_at_end,
- &cleared_regs);
+ AND_COMPL_REG_SET (bb->global_live_at_start, &cleared_regs);
+ AND_COMPL_REG_SET (bb->global_live_at_end, &cleared_regs);
}
}
else
- EXECUTE_IF_SET_IN_REG_SET (&cleared_regs, 0, j,
- {
- for (l = 0; l < n_basic_blocks; l++)
+ EXECUTE_IF_SET_IN_REG_SET (&cleared_regs, 0, j,
+ {
+ FOR_EACH_BB (bb)
{
- CLEAR_REGNO_REG_SET (BASIC_BLOCK (l)->global_live_at_start, j);
- CLEAR_REGNO_REG_SET (BASIC_BLOCK (l)->global_live_at_end, j);
+ CLEAR_REGNO_REG_SET (bb->global_live_at_start, j);
+ CLEAR_REGNO_REG_SET (bb->global_live_at_end, j);
}
});
}
@@ -1345,7 +1335,8 @@ block_alloc (b)
/* If the operand is an address, find a register in it.
There may be more than one register, but we only try one
of them. */
- if (recog_data.constraints[i][0] == 'p')
+ if (recog_data.constraints[i][0] == 'p'
+ || EXTRA_ADDRESS_CONSTRAINT (recog_data.constraints[i][0]))
while (GET_CODE (r1) == PLUS || GET_CODE (r1) == MULT)
r1 = XEXP (r1, 0);
@@ -1780,11 +1771,11 @@ qty_sugg_compare_1 (q1p, q2p)
If we really combined them, we could lose if the pseudo lives
across an insn that clobbers the hard reg (eg, movstr).
- ALREADY_DEAD is non-zero if USEDREG is known to be dead even though
+ ALREADY_DEAD is nonzero if USEDREG is known to be dead even though
there is no REG_DEAD note on INSN. This occurs during the processing
of REG_NO_CONFLICT blocks.
- MAY_SAVE_COPYCOPY is non-zero if this insn is simply copying USEDREG to
+ MAY_SAVE_COPYCOPY is nonzero if this insn is simply copying USEDREG to
SETREG or if the input and output must share a register.
In that case, we record a hard reg suggestion in QTY_PHYS_COPY_SUGG.
@@ -2028,9 +2019,6 @@ update_qty_class (qtyno, reg)
rclass = reg_alternate_class (reg);
if (reg_class_subset_p (rclass, qty[qtyno].alternate_class))
qty[qtyno].alternate_class = rclass;
-
- if (REG_CHANGES_MODE (reg))
- qty[qtyno].changes_mode = 1;
}
/* Handle something which alters the value of an rtx REG.
@@ -2101,7 +2089,7 @@ reg_is_born (reg, birth)
}
}
-/* Record the death of REG in the current insn. If OUTPUT_P is non-zero,
+/* Record the death of REG in the current insn. If OUTPUT_P is nonzero,
REG is an output that is dying (i.e., it is never used), otherwise it
is an input (the normal case).
If OUTPUT_P is 1, then we extend the life past the end of this insn. */
@@ -2170,7 +2158,7 @@ wipe_dead_reg (reg, output_p)
If QTYNO crosses calls, insist on a register preserved by calls,
unless ACCEPT_CALL_CLOBBERED is nonzero.
- If JUST_TRY_SUGGESTED is non-zero, only try to see if the suggested
+ If JUST_TRY_SUGGESTED is nonzero, only try to see if the suggested
register is available. If not, return -1. */
static int
@@ -2184,11 +2172,7 @@ find_free_reg (class, mode, qtyno, accept_call_clobbered, just_try_suggested,
int born_index, dead_index;
{
int i, ins;
-#ifdef HARD_REG_SET
- /* Declare it register if it's a scalar. */
- register
-#endif
- HARD_REG_SET used, first_used;
+ HARD_REG_SET first_used, used;
#ifdef ELIMINABLE_REGS
static const struct {const int from, to; } eliminables[] = ELIMINABLE_REGS;
#endif
@@ -2236,10 +2220,8 @@ find_free_reg (class, mode, qtyno, accept_call_clobbered, just_try_suggested,
SET_HARD_REG_BIT (used, FRAME_POINTER_REGNUM);
#endif
-#ifdef CLASS_CANNOT_CHANGE_MODE
- if (qty[qtyno].changes_mode)
- IOR_HARD_REG_SET (used,
- reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE]);
+#ifdef CANNOT_CHANGE_MODE_CLASS
+ cannot_change_mode_set_regs (&used, mode, qty[qtyno].first_reg);
#endif
/* Normally, the registers that can be used for the first register in
@@ -2329,7 +2311,7 @@ find_free_reg (class, mode, qtyno, accept_call_clobbered, just_try_suggested,
}
/* Mark that REGNO with machine-mode MODE is live starting from the current
- insn (if LIFE is non-zero) or dead starting at the current insn (if LIFE
+ insn (if LIFE is nonzero) or dead starting at the current insn (if LIFE
is zero). */
static void
@@ -2348,7 +2330,7 @@ mark_life (regno, mode, life)
}
/* Mark register number REGNO (with machine-mode MODE) as live (if LIFE
- is non-zero) or dead (if LIFE is zero) from insn number BIRTH (inclusive)
+ is nonzero) or dead (if LIFE is zero) from insn number BIRTH (inclusive)
to insn number DEATH (exclusive). */
static void
@@ -2475,7 +2457,8 @@ requires_inout (p)
break;
default:
- if (REG_CLASS_FROM_LETTER (c) == NO_REGS)
+ if (REG_CLASS_FROM_LETTER (c) == NO_REGS
+ && !EXTRA_ADDRESS_CONSTRAINT (c))
break;
/* FALLTHRU */
case 'p':
OpenPOWER on IntegriCloud