aboutsummaryrefslogtreecommitdiff
path: root/contrib/gcc/function.c
diff options
context:
space:
mode:
authorAlexander Kabaev <kan@FreeBSD.org>2005-06-03 04:02:20 +0000
committerAlexander Kabaev <kan@FreeBSD.org>2005-06-03 04:02:20 +0000
commitc3cbf7fdb9688e4d8d9cf93e9561eadd45f1cd78 (patch)
treedc04596dd574786e48bfdb08626f8333c6aa3e3c /contrib/gcc/function.c
parentd14a0017703951109256ce8eb36590ba20331baa (diff)
downloadsrc-c3cbf7fdb9688e4d8d9cf93e9561eadd45f1cd78.tar.gz
src-c3cbf7fdb9688e4d8d9cf93e9561eadd45f1cd78.zip
Merge conflicts for GCC 3.4.4.
Notes
Notes: svn path=/head/; revision=146908
Diffstat (limited to 'contrib/gcc/function.c')
-rw-r--r--contrib/gcc/function.c81
1 files changed, 50 insertions, 31 deletions
diff --git a/contrib/gcc/function.c b/contrib/gcc/function.c
index 0ecde22223be..4ff8f6a1d015 100644
--- a/contrib/gcc/function.c
+++ b/contrib/gcc/function.c
@@ -238,7 +238,7 @@ static rtx assign_stack_local_1 (enum machine_mode, HOST_WIDE_INT, int,
struct function *);
static struct temp_slot *find_temp_slot_from_address (rtx);
static void put_reg_into_stack (struct function *, rtx, tree, enum machine_mode,
- enum machine_mode, int, unsigned int, int, htab_t);
+ unsigned int, bool, bool, bool, htab_t);
static void schedule_fixup_var_refs (struct function *, rtx, tree, enum machine_mode,
htab_t);
static void fixup_var_refs (rtx, enum machine_mode, int, rtx, htab_t);
@@ -508,6 +508,7 @@ get_frame_size (void)
ALIGN controls the amount of alignment for the address of the slot:
0 means according to MODE,
-1 means use BIGGEST_ALIGNMENT and round size to multiple of that,
+ -2 means use BITS_PER_UNIT,
positive specifies alignment boundary in bits.
We do not round to stack_boundary here.
@@ -545,6 +546,8 @@ assign_stack_local_1 (enum machine_mode mode, HOST_WIDE_INT size, int align,
alignment = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
size = CEIL_ROUND (size, alignment);
}
+ else if (align == -2)
+ alignment = 1; /* BITS_PER_UNIT / BITS_PER_UNIT */
else
alignment = align / BITS_PER_UNIT;
@@ -1293,9 +1296,9 @@ put_var_into_stack (tree decl, int rescan)
enum machine_mode promoted_mode, decl_mode;
struct function *function = 0;
tree context;
- int can_use_addressof;
- int volatilep = TREE_CODE (decl) != SAVE_EXPR && TREE_THIS_VOLATILE (decl);
- int usedp = (TREE_USED (decl)
+ bool can_use_addressof_p;
+ bool volatile_p = TREE_CODE (decl) != SAVE_EXPR && TREE_THIS_VOLATILE (decl);
+ bool used_p = (TREE_USED (decl)
|| (TREE_CODE (decl) != SAVE_EXPR && DECL_INITIAL (decl) != 0));
context = decl_function_context (decl);
@@ -1342,7 +1345,7 @@ put_var_into_stack (tree decl, int rescan)
/* If this variable lives in the current function and we don't need to put it
in the stack for the sake of setjmp or the non-locality, try to keep it in
a register until we know we actually need the address. */
- can_use_addressof
+ can_use_addressof_p
= (function == 0
&& ! (TREE_CODE (decl) != SAVE_EXPR && DECL_NONLOCAL (decl))
&& optimize > 0
@@ -1355,7 +1358,8 @@ put_var_into_stack (tree decl, int rescan)
/* If we can't use ADDRESSOF, make sure we see through one we already
generated. */
- if (! can_use_addressof && GET_CODE (reg) == MEM
+ if (! can_use_addressof_p
+ && GET_CODE (reg) == MEM
&& GET_CODE (XEXP (reg, 0)) == ADDRESSOF)
reg = XEXP (XEXP (reg, 0), 0);
@@ -1363,11 +1367,11 @@ put_var_into_stack (tree decl, int rescan)
if (GET_CODE (reg) == REG)
{
- if (can_use_addressof)
+ if (can_use_addressof_p)
gen_mem_addressof (reg, decl, rescan);
else
- put_reg_into_stack (function, reg, TREE_TYPE (decl), promoted_mode,
- decl_mode, volatilep, 0, usedp, 0);
+ put_reg_into_stack (function, reg, TREE_TYPE (decl), decl_mode,
+ 0, volatile_p, used_p, false, 0);
}
else if (GET_CODE (reg) == CONCAT)
{
@@ -1383,14 +1387,14 @@ put_var_into_stack (tree decl, int rescan)
#ifdef FRAME_GROWS_DOWNWARD
/* Since part 0 should have a lower address, do it second. */
put_reg_into_stack (function, hipart, part_type, part_mode,
- part_mode, volatilep, 0, 0, 0);
+ 0, volatile_p, false, false, 0);
put_reg_into_stack (function, lopart, part_type, part_mode,
- part_mode, volatilep, 0, 0, 0);
+ 0, volatile_p, false, true, 0);
#else
put_reg_into_stack (function, lopart, part_type, part_mode,
- part_mode, volatilep, 0, 0, 0);
+ 0, volatile_p, false, false, 0);
put_reg_into_stack (function, hipart, part_type, part_mode,
- part_mode, volatilep, 0, 0, 0);
+ 0, volatile_p, false, true, 0);
#endif
/* Change the CONCAT into a combined MEM for both parts. */
@@ -1411,7 +1415,7 @@ put_var_into_stack (tree decl, int rescan)
/* Prevent sharing of rtl that might lose. */
if (GET_CODE (XEXP (reg, 0)) == PLUS)
XEXP (reg, 0) = copy_rtx (XEXP (reg, 0));
- if (usedp && rescan)
+ if (used_p && rescan)
{
schedule_fixup_var_refs (function, reg, TREE_TYPE (decl),
promoted_mode, 0);
@@ -1425,20 +1429,24 @@ put_var_into_stack (tree decl, int rescan)
/* Subroutine of put_var_into_stack. This puts a single pseudo reg REG
into the stack frame of FUNCTION (0 means the current function).
+ TYPE is the user-level data type of the value hold in the register.
DECL_MODE is the machine mode of the user-level data type.
- PROMOTED_MODE is the machine mode of the register.
- VOLATILE_P is nonzero if this is for a "volatile" decl.
- USED_P is nonzero if this reg might have already been used in an insn. */
+ ORIGINAL_REGNO must be set if the real regno is not visible in REG.
+ VOLATILE_P is true if this is for a "volatile" decl.
+ USED_P is true if this reg might have already been used in an insn.
+ CONSECUTIVE_P is true if the stack slot assigned to reg must be
+ consecutive with the previous stack slot. */
static void
put_reg_into_stack (struct function *function, rtx reg, tree type,
- enum machine_mode promoted_mode,
- enum machine_mode decl_mode, int volatile_p,
- unsigned int original_regno, int used_p, htab_t ht)
+ enum machine_mode decl_mode, unsigned int original_regno,
+ bool volatile_p, bool used_p, bool consecutive_p,
+ htab_t ht)
{
struct function *func = function ? function : cfun;
- rtx new = 0;
+ enum machine_mode mode = GET_MODE (reg);
unsigned int regno = original_regno;
+ rtx new = 0;
if (regno == 0)
regno = REGNO (reg);
@@ -1451,7 +1459,8 @@ put_reg_into_stack (struct function *function, rtx reg, tree type,
}
if (new == 0)
- new = assign_stack_local_1 (decl_mode, GET_MODE_SIZE (decl_mode), 0, func);
+ new = assign_stack_local_1 (decl_mode, GET_MODE_SIZE (decl_mode),
+ consecutive_p ? -2 : 0, func);
PUT_CODE (reg, MEM);
PUT_MODE (reg, decl_mode);
@@ -1473,7 +1482,7 @@ put_reg_into_stack (struct function *function, rtx reg, tree type,
}
if (used_p)
- schedule_fixup_var_refs (function, reg, type, promoted_mode, ht);
+ schedule_fixup_var_refs (function, reg, type, mode, ht);
}
/* Make sure that all refs to the variable, previously made
@@ -1641,7 +1650,7 @@ fixup_var_refs_insns_with_hash (htab_t ht, rtx var, enum machine_mode promoted_m
tmp.key = var;
ime = htab_find (ht, &tmp);
for (insn_list = ime->insns; insn_list != 0; insn_list = XEXP (insn_list, 1))
- if (INSN_P (XEXP (insn_list, 0)))
+ if (INSN_P (XEXP (insn_list, 0)) && !INSN_DELETED_P (XEXP (insn_list, 0)))
fixup_var_refs_insn (XEXP (insn_list, 0), var, promoted_mode,
unsignedp, 1, may_share);
}
@@ -2909,7 +2918,7 @@ static void
put_addressof_into_stack (rtx r, htab_t ht)
{
tree decl, type;
- int volatile_p, used_p;
+ bool volatile_p, used_p;
rtx reg = XEXP (r, 0);
@@ -2928,12 +2937,12 @@ put_addressof_into_stack (rtx r, htab_t ht)
else
{
type = NULL_TREE;
- volatile_p = 0;
- used_p = 1;
+ volatile_p = false;
+ used_p = true;
}
- put_reg_into_stack (0, reg, type, GET_MODE (reg), GET_MODE (reg),
- volatile_p, ADDRESSOF_REGNO (r), used_p, ht);
+ put_reg_into_stack (0, reg, type, GET_MODE (reg), ADDRESSOF_REGNO (r),
+ volatile_p, used_p, false, ht);
}
/* List of replacements made below in purge_addressof_1 when creating
@@ -3653,10 +3662,20 @@ instantiate_decl (rtx x, HOST_WIDE_INT size, int valid_only)
enum machine_mode mode;
rtx addr;
+ if (x == 0)
+ return;
+
+ /* If this is a CONCAT, recurse for the pieces. */
+ if (GET_CODE (x) == CONCAT)
+ {
+ instantiate_decl (XEXP (x, 0), size / 2, valid_only);
+ instantiate_decl (XEXP (x, 1), size / 2, valid_only);
+ return;
+ }
+
/* If this is not a MEM, no need to do anything. Similarly if the
address is a constant or a register that is not a virtual register. */
-
- if (x == 0 || GET_CODE (x) != MEM)
+ if (GET_CODE (x) != MEM)
return;
addr = XEXP (x, 0);