This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Propagation of pointer alignment information
- To: Joern Rennecke <amylaar at cygnus dot co dot uk>
- Subject: Re: Propagation of pointer alignment information
- From: Richard Earnshaw <rearnsha at arm dot com>
- Date: Wed, 16 Dec 1998 13:54:08 +0000
- Cc: egcs at egcs dot cygnus dot com
- Cc: richard dot earnshaw at arm dot com
- Organization: ARM Ltd.
- Reply-To: richard dot earnshaw at arm dot com
> > Would it be reasonable to make the compiler not propagate alignment
> > through a cast? This would still leave the case where the alignment is
> > derived from the layout of a struct.
>
> I don't think that should be the default. If this is really needed
> for some programs, you could make a new invokation options that
> disables these alignment propagations, just like -fvolatile caters
> for programs that really mean volatile even they don't say so.
This makes sense, but taking that route, I think it then makes sense when
the flag is unset to then turn off all alignment assumptions that are
inferred via REGNO_POINTER_ALIGN. The patch below does this.
Jeff, is the following patch OK to install?
<date> Richard Earnshaw (rearnsha@arm.com)
* toplev.c (flag_infer_align): New flag.
(lang_independent_options): Add -finfer-align to list of flags.
(main): Turn it on when optimizing.
* flags.h (flag_infer_align): Declare it.
* emit-rtl.c (mark_reg_pointer): Only set REGNO_POINTER_ALIGN if
flag_infer_align.
(init_emit): Note that alignments of stack and frame regs are well
known, even if flag_infer_align is unset.
* invoke.texi: Document -finfer-align.
Index: emit-rtl.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/emit-rtl.c,v
retrieving revision 1.45
diff -p -r1.45 emit-rtl.c
*** emit-rtl.c 1998/12/15 11:56:36 1.45
--- emit-rtl.c 1998/12/16 13:34:39
*************** mark_reg_pointer (reg, align)
*** 590,596 ****
{
REGNO_POINTER_FLAG (REGNO (reg)) = 1;
! if (align)
REGNO_POINTER_ALIGN (REGNO (reg)) = align;
}
--- 590,596 ----
{
REGNO_POINTER_FLAG (REGNO (reg)) = 1;
! if (align && flag_infer_align)
REGNO_POINTER_ALIGN (REGNO (reg)) = align;
}
*************** init_emit ()
*** 3370,3375 ****
--- 3370,3376 ----
REGNO_POINTER_FLAG (VIRTUAL_CFA_REGNUM) = 1;
#ifdef STACK_BOUNDARY
+ /* These alignments can safely be used even if flag_infer_align is off */
REGNO_POINTER_ALIGN (STACK_POINTER_REGNUM) = STACK_BOUNDARY / BITS_PER_UNIT;
REGNO_POINTER_ALIGN (FRAME_POINTER_REGNUM) = STACK_BOUNDARY / BITS_PER_UNIT;
REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM)
Index: flags.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/flags.h,v
retrieving revision 1.22
diff -p -r1.22 flags.h
*** flags.h 1998/11/23 16:41:10 1.22
--- flags.h 1998/12/16 13:34:40
*************** extern int flag_regmove;
*** 456,461 ****
--- 456,467 ----
/* Instrument functions with calls at entry and exit, for profiling. */
extern int flag_instrument_function_entry_exit;
+
+ /* Infer alignment of pointers from the context of their declaration,
+ for example a short inside a struct containing an int may well be
+ int-aligned. */
+ extern int flag_infer_align;
+
/* Other basic status info about current function. */
Index: invoke.texi
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/invoke.texi,v
retrieving revision 1.80
diff -p -r1.80 invoke.texi
*** invoke.texi 1998/12/06 01:56:01 1.80
--- invoke.texi 1998/12/16 13:34:45
*************** in the following sections.
*** 159,164 ****
--- 159,165 ----
-fschedule-insns2 -fstrength-reduce -fthread-jumps
-funroll-all-loops -funroll-loops
-fmove-all-movables -freduce-all-givs -fstrict-aliasing
+ -finfer-align
-O -O0 -O1 -O2 -O3 -Os
@end smallexample
*************** With @samp{-O}, the compiler tries to re
*** 2140,2150 ****
time.
When you specify @samp{-O}, the compiler turns on @samp{-fthread-jumps}
! and @samp{-fdefer-pop} on all machines. The compiler turns on
! @samp{-fdelayed-branch} on machines that have delay slots, and
! @samp{-fomit-frame-pointer} on machines that can support debugging even
! without a frame pointer. On some machines the compiler also turns
! on other flags.@refill
@item -O2
Optimize even more. GNU CC performs nearly all supported optimizations
--- 2141,2152 ----
time.
When you specify @samp{-O}, the compiler turns on @samp{-fthread-jumps}
! @samp{-finfer-align} and @samp{-fdefer-pop} on all machines. The
! compiler turns on @samp{-fdelayed-branch} on machines that have delay
! slots, and @samp{-fomit-frame-pointer} on machines that can support
! debugging even without a frame pointer. On some machines the compiler
! also turns on other flags.
! @refill
@item -O2
Optimize even more. GNU CC performs nearly all supported optimizations
*************** Always pop the arguments to each functio
*** 2208,2213 ****
--- 2210,2224 ----
returns. For machines which must pop arguments after a function call,
the compiler normally lets arguments accumulate on the stack for several
function calls and pops them all at once.
+
+ @item -finfer-align
+ Infer additional alignment information from the context of the
+ declaration of a pointer. GCC can generate more efficient code for some
+ machines if a pointer is known to be more strictly aligned than the
+ minimum requirements for addressing a particular type. However, some
+ non-portable programs may generate unexpected results if they use unsafe
+ pointer casts or assume too much about the layout of structures; using
+ @samp{-fno-infer-align} may allow these programs to work as expected.
@item -fforce-mem
Force memory operands to be copied into registers before doing
Index: toplev.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/toplev.c,v
retrieving revision 1.136
diff -p -r1.136 toplev.c
*** toplev.c 1998/12/13 00:59:38 1.136
--- toplev.c 1998/12/16 13:34:48
*************** int flag_strict_aliasing = 0;
*** 732,738 ****
--- 732,743 ----
/* Instrument functions with calls at entry and exit, for profiling. */
int flag_instrument_function_entry_exit = 0;
+ /* Infer alignment of pointers from the context of their declaration,
+ for example a short inside a struct containing an int may well be
+ int-aligned. */
+ int flag_infer_align = 0;
+
/* Table of supported debugging formats. */
static struct
{
*************** lang_independent_options f_options[] =
*** 935,940 ****
--- 940,947 ----
"Suppress output of instruction numbers and line number notes in debugging dumps"},
{"instrument-functions", &flag_instrument_function_entry_exit, 1,
"Instrument function entry/exit with profiling calls"},
+ {"infer-align", &flag_infer_align, 1,
+ "Infer the alignment of pointers from the context of their declaration"},
{"leading-underscore", &flag_leading_underscore, 1,
"External symbols have a leading underscore" }
};
*************** main (argc, argv)
*** 4586,4591 ****
--- 4593,4599 ----
{
flag_defer_pop = 1;
flag_thread_jumps = 1;
+ flag_infer_align = 1;
#ifdef DELAY_SLOTS
flag_delayed_branch = 1;
#endif