This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
case where gcc generates bigger binaries than MSVC
- To: gcc at gcc dot gnu dot org
- Subject: case where gcc generates bigger binaries than MSVC
- From: Mat Hostetter <mat at lcs dot mit dot edu>
- Date: 05 May 2000 11:35:18 -0400
gcc-2.95.2/i686-linux generates binaries for my program that are
noticeably bigger than those generated by MSVC++ (by ~15%), even when
I specify -Os (optimize for space).
After poking around with nm and objdump I tracked the problem down to
how gcc aligns static data structures. If those structures are at
least 32 bytes in size, gcc aligns them mod 32, to attempt to get
better cache line locality.
Since my program has tens of thousands of machine-generated static
structs, many of which are (for example) 36 bytes in size, this size
roundup wastes a great deal of memory. Even the `aligned' attribute
doesn't help, as that only lets me increase the alignment, not
decrease it.
I can change my C code generator to emit these structs into various
arrays to try to reduce the alignment overhead, but I shouldn't have
to, and it's a pain, as they are split over many files.
Instead I suggest that if the user specifies "-Os", then gcc should
disable the "cache-line alignment roundup" behavior. That's a
one-line change which is clearly consistent with the intent of the
"-Os" flag.
For reference, I've appended the macro that currently makes the
alignment decision, from i386/i386.h.
-Mat
/* If defined, a C expression to compute the alignment for a static
variable. TYPE is the data type, and ALIGN is the alignment that
the object would ordinarily have. The value of this macro is used
instead of that alignment to align the object.
If this macro is not defined, then ALIGN is used.
One use of this macro is to increase alignment of medium-size
data to make it all fit in fewer cache lines. Another is to
cause character arrays to be word-aligned so that `strcpy' calls
that copy constants to character arrays can be done inline. */
#define DATA_ALIGNMENT(TYPE, ALIGN) \
((AGGREGATE_TYPE_P (TYPE) \
&& TYPE_SIZE (TYPE) \
&& TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST \
&& (TREE_INT_CST_LOW (TYPE_SIZE (TYPE)) >= 256 \
|| TREE_INT_CST_HIGH (TYPE_SIZE (TYPE))) && (ALIGN) < 256) \
? 256 \
: TREE_CODE (TYPE) == ARRAY_TYPE \
? ((TYPE_MODE (TREE_TYPE (TYPE)) == DFmode && (ALIGN) < 64) \
? 64 \
: (TYPE_MODE (TREE_TYPE (TYPE)) == XFmode && (ALIGN) < 128) \
? 128 \
: (ALIGN)) \
: TREE_CODE (TYPE) == COMPLEX_TYPE \
? ((TYPE_MODE (TYPE) == DCmode && (ALIGN) < 64) \
? 64 \
: (TYPE_MODE (TYPE) == XCmode && (ALIGN) < 128) \
? 128 \
: (ALIGN)) \
: ((TREE_CODE (TYPE) == RECORD_TYPE \
|| TREE_CODE (TYPE) == UNION_TYPE \
|| TREE_CODE (TYPE) == QUAL_UNION_TYPE) \
&& TYPE_FIELDS (TYPE)) \
? ((DECL_MODE (TYPE_FIELDS (TYPE)) == DFmode && (ALIGN) < 64) \
? 64 \
: (DECL_MODE (TYPE_FIELDS (TYPE)) == XFmode && (ALIGN) < 128) \
? 128 \
: (ALIGN)) \
: TREE_CODE (TYPE) == REAL_TYPE \
? ((TYPE_MODE (TYPE) == DFmode && (ALIGN) < 64) \
? 64 \
: (TYPE_MODE (TYPE) == XFmode && (ALIGN) < 128) \
? 128 \
: (ALIGN)) \
: (ALIGN))