summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Kenner <kenner@gcc.gnu.org>1996-11-16 06:18:33 -0500
committerRichard Kenner <kenner@gcc.gnu.org>1996-11-16 06:18:33 -0500
commit839c47964ea35b14d873a5c0774d85bcc0c5cbd9 (patch)
tree42803204ac925bc7d93705741acb3cc7be69ef88 /gcc
parentaacdb8bb8f5da389ed202ca0a8ba448cfe1dd849 (diff)
downloadgcc-839c47964ea35b14d873a5c0774d85bcc0c5cbd9.tar.gz
(get_inner_reference): Add new arg PALIGNMENT and compute it.
(expand_assignment, do_jump): Pass new arg to get_inner_reference. (expand_expr, case COMPONENT_REF): Likewise. From-SVN: r13187
Diffstat (limited to 'gcc')
-rw-r--r--gcc/expr.c36
1 files changed, 27 insertions, 9 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index 15e036b465e..834b5a1bfe6 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -2791,8 +2791,8 @@ expand_assignment (to, from, want_value, suggest_reg)
int alignment;
push_temp_slots ();
- tem = get_inner_reference (to, &bitsize, &bitpos, &offset,
- &mode1, &unsignedp, &volatilep);
+ tem = get_inner_reference (to, &bitsize, &bitpos, &offset, &mode1,
+ &unsignedp, &volatilep, &alignment);
/* If we are going to use store_bit_field and extract_bit_field,
make sure to_rtx will be safe for multiple use. */
@@ -2800,7 +2800,6 @@ expand_assignment (to, from, want_value, suggest_reg)
if (mode1 == VOIDmode && want_value)
tem = stabilize_reference (tem);
- alignment = TYPE_ALIGN (TREE_TYPE (tem)) / BITS_PER_UNIT;
to_rtx = expand_expr (tem, NULL_RTX, VOIDmode, 0);
if (offset != 0)
{
@@ -4188,6 +4187,9 @@ get_inner_unaligned_p (exp)
giving the variable offset (in units) in *POFFSET.
This offset is in addition to the bit position.
If the position is not variable, we store 0 in *POFFSET.
+ We set *PALIGNMENT to the alignment in bytes of the address that will be
+ computed. This is the alignment of the thing we return if *POFFSET
+ is zero, but can be more less strictly aligned if *POFFSET is nonzero.
If any of the extraction expressions is volatile,
we store 1 in *PVOLATILEP. Otherwise we don't change that.
@@ -4198,11 +4200,11 @@ get_inner_unaligned_p (exp)
If the field describes a variable-sized object, *PMODE is set to
VOIDmode and *PBITSIZE is set to -1. An access cannot be made in
- this case, but the address of the object can be found. */
+ this case, but the address of the object can be found. */
tree
get_inner_reference (exp, pbitsize, pbitpos, poffset, pmode,
- punsignedp, pvolatilep)
+ punsignedp, pvolatilep, palignment)
tree exp;
int *pbitsize;
int *pbitpos;
@@ -4210,11 +4212,13 @@ get_inner_reference (exp, pbitsize, pbitpos, poffset, pmode,
enum machine_mode *pmode;
int *punsignedp;
int *pvolatilep;
+ int *palignment;
{
tree orig_exp = exp;
tree size_tree = 0;
enum machine_mode mode = VOIDmode;
tree offset = integer_zero_node;
+ int alignment = BIGGEST_ALIGNMENT;
if (TREE_CODE (exp) == COMPONENT_REF)
{
@@ -4323,9 +4327,20 @@ get_inner_reference (exp, pbitsize, pbitpos, poffset, pmode,
/* If any reference in the chain is volatile, the effect is volatile. */
if (TREE_THIS_VOLATILE (exp))
*pvolatilep = 1;
+
+ /* If the offset is non-constant already, then we can't assume any
+ alignment more than the alignment here. */
+ if (! integer_zerop (offset))
+ alignment = MIN (alignment, TYPE_ALIGN (TREE_TYPE (exp)));
+
exp = TREE_OPERAND (exp, 0);
}
+ if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'd')
+ alignment = MIN (alignment, DECL_ALIGN (exp));
+ else
+ alignment = MIN (alignment, TYPE_ALIGN (TREE_TYPE (exp)));
+
if (integer_zerop (offset))
offset = 0;
@@ -4334,6 +4349,7 @@ get_inner_reference (exp, pbitsize, pbitpos, poffset, pmode,
*pmode = mode;
*poffset = offset;
+ *palignment = alignment / BITS_PER_UNIT;
return exp;
}
@@ -5461,9 +5477,10 @@ expand_expr (exp, target, tmode, modifier)
int bitpos;
tree offset;
int volatilep = 0;
- tree tem = get_inner_reference (exp, &bitsize, &bitpos, &offset,
- &mode1, &unsignedp, &volatilep);
int alignment;
+ tree tem = get_inner_reference (exp, &bitsize, &bitpos, &offset,
+ &mode1, &unsignedp, &volatilep,
+ &alignment);
/* If we got back the original object, something is wrong. Perhaps
we are evaluating an expression too early. In any event, don't
@@ -5494,7 +5511,6 @@ expand_expr (exp, target, tmode, modifier)
op0 = validize_mem (force_const_mem (mode, op0));
}
- alignment = TYPE_ALIGN (TREE_TYPE (tem)) / BITS_PER_UNIT;
if (offset != 0)
{
rtx offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode, 0);
@@ -10154,11 +10170,13 @@ do_jump (exp, if_false_label, if_true_label)
tree type;
tree offset;
int volatilep = 0;
+ int alignment;
/* Get description of this reference. We don't actually care
about the underlying object here. */
get_inner_reference (exp, &bitsize, &bitpos, &offset,
- &mode, &unsignedp, &volatilep);
+ &mode, &unsignedp, &volatilep,
+ &alignment);
type = type_for_size (bitsize, unsignedp);
if (! SLOW_BYTE_ACCESS