This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH: PR target/39942: Nonoptimal code - leaveq; xchg %ax,%ax; retq
- From: "H.J. Lu" <hongjiu dot lu at intel dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: ubizjak at gmail dot com
- Date: Fri, 15 May 2009 07:08:21 -0700
- Subject: PATCH: PR target/39942: Nonoptimal code - leaveq; xchg %ax,%ax; retq
ix86_avoid_jump_misspredicts use "align" pattern to pad to a 16byte
boundary. "align" pattern uses ASM_OUTPUT_MAX_SKIP_ALIGN. For Linux,
it
#define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE,LOG,MAX_SKIP) \
do { \
if ((LOG) != 0) { \
if ((MAX_SKIP) == 0) fprintf ((FILE), "\t.p2align %d\n", (LOG)); \
else { \
fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP)); \
/* Make sure that we have at least 8 byte alignment if > 8 byte * \
alignment is preferred. */ \
if ((LOG) > 3 && (1 << (LOG)) > ((MAX_SKIP) + 1)) \
fprintf ((FILE), "\t.p2align 3\n"); \
} \
} \
} while (0)
It is good to align label, but bad for padding since ".p2align 3" isn't
needed for padding to a 16byte boundary. This patch adds
ASM_OUTPUT_MAX_SKIP_PAD and uses it for padding. OK for trunk?
Thanks.
H.J.
----
2009-05-15 H.J. Lu <hongjiu.lu@intel.com>
PR target/39942
* config/i386/i386.c (ix86_avoid_jump_misspredicts): Replace
gen_align with gen_pad.
* config/i386/i386.md (align): Renamed to ...
(pad): This. Replace ASM_OUTPUT_MAX_SKIP_ALIGN with
ASM_OUTPUT_MAX_SKIP_PAD.
* config/i386/freebsd.h (ASM_OUTPUT_MAX_SKIP_PAD): New.
* config/i386/gas.h (ASM_OUTPUT_MAX_SKIP_PAD): Likewise.
* config/i386/linux.h (ASM_OUTPUT_MAX_SKIP_PAD): Likewise.
* config/i386/lynx.h (ASM_OUTPUT_MAX_SKIP_PAD): Likewise.
* config/i386/netbsd-elf.h (ASM_OUTPUT_MAX_SKIP_PAD): Likewise.
* config/i386/openbsdelf.h (ASM_OUTPUT_MAX_SKIP_PAD): Likewise.
* config/i386/x86-64.h (ASM_OUTPUT_MAX_SKIP_PAD): Likewise.
Index: config/i386/linux.h
===================================================================
--- config/i386/linux.h (revision 147459)
+++ config/i386/linux.h (working copy)
@@ -142,7 +142,10 @@ along with GCC; see the file COPYING3.
command to advance the location counter to a multiple of 1<<LOG
bytes if it is within MAX_SKIP bytes.
- This is used to align code labels according to Intel recommendations. */
+ This is used to align code labels according to Intel recommendations.
+
+ ASM_OUTPUT_MAX_SKIP_PAD is similar to ASM_OUTPUT_MAX_SKIP_ALIGN, but
+ only pads to 1<<LOG bytes. */
#ifdef HAVE_GAS_MAX_SKIP_P2ALIGN
#define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE,LOG,MAX_SKIP) \
@@ -158,6 +161,12 @@ along with GCC; see the file COPYING3.
} \
} \
} while (0)
+#undef ASM_OUTPUT_MAX_SKIP_PAD
+#define ASM_OUTPUT_MAX_SKIP_PAD(FILE, LOG, MAX_SKIP) \
+ if ((LOG) != 0) { \
+ if ((MAX_SKIP) == 0) fprintf ((FILE), "\t.p2align %d\n", (LOG)); \
+ else fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP)); \
+ }
#endif
/* Handle special EH pointer encodings. Absolute, pc-relative, and
Index: config/i386/i386.md
===================================================================
--- config/i386/i386.md (revision 147459)
+++ config/i386/i386.md (working copy)
@@ -15519,16 +15519,16 @@
(set_attr "length_immediate" "0")
(set_attr "modrm" "0")])
-;; Align to 16-byte boundary, max skip in op0. Used to avoid
+;; Pad to 16-byte boundary, max skip in op0. Used to avoid
;; branch prediction penalty for the third jump in a 16-byte
;; block on K8.
-(define_insn "align"
+(define_insn "pad"
[(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
""
{
-#ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
- ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
+#ifdef ASM_OUTPUT_MAX_SKIP_PAD
+ ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
#else
/* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
The align insn is used to avoid 3 jump instructions in the row to improve
Index: config/i386/gas.h
===================================================================
--- config/i386/gas.h (revision 147459)
+++ config/i386/gas.h (working copy)
@@ -68,7 +68,9 @@ along with GCC; see the file COPYING3.
command to advance the location counter to a multiple of 1<<LOG
bytes if it is within MAX_SKIP bytes.
- This is used to align code labels according to Intel recommendations. */
+ This is used to align code labels according to Intel recommendations.
+
+ ASM_OUTPUT_MAX_SKIP_PAD is the same as ASM_OUTPUT_MAX_SKIP_ALIGN. */
#ifdef HAVE_GAS_MAX_SKIP_P2ALIGN
# define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE,LOG,MAX_SKIP) \
@@ -76,6 +78,9 @@ along with GCC; see the file COPYING3.
if ((MAX_SKIP) == 0) fprintf ((FILE), "\t.p2align %d\n", (LOG)); \
else fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP)); \
}
+#undef ASM_OUTPUT_MAX_SKIP_PAD
+#define ASM_OUTPUT_MAX_SKIP_PAD(FILE, LOG, MAX_SKIP) \
+ ASM_OUTPUT_MAX_SKIP_ALIGN((FILE), (LOG), (MAX_SKIP))
#endif
/* A C statement or statements which output an assembler instruction
Index: config/i386/x86-64.h
===================================================================
--- config/i386/x86-64.h (revision 147459)
+++ config/i386/x86-64.h (working copy)
@@ -79,6 +79,12 @@ see the files COPYING3 and COPYING.RUNTI
} \
} \
} while (0)
+#undef ASM_OUTPUT_MAX_SKIP_PAD
+#define ASM_OUTPUT_MAX_SKIP_PAD(FILE, LOG, MAX_SKIP) \
+ if ((LOG) != 0) { \
+ if ((MAX_SKIP) == 0) fprintf ((FILE), "\t.p2align %d\n", (LOG)); \
+ else fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP)); \
+ }
#endif
Index: config/i386/lynx.h
===================================================================
--- config/i386/lynx.h (revision 147459)
+++ config/i386/lynx.h (working copy)
@@ -58,7 +58,9 @@ along with GCC; see the file COPYING3.
command to advance the location counter to a multiple of 1<<LOG
bytes if it is within MAX_SKIP bytes.
- This is used to align code labels according to Intel recommendations. */
+ This is used to align code labels according to Intel recommendations.
+
+ ASM_OUTPUT_MAX_SKIP_PAD is the same as ASM_OUTPUT_MAX_SKIP_ALIGN. */
#ifdef HAVE_GAS_MAX_SKIP_P2ALIGN
#define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE,LOG,MAX_SKIP) \
@@ -68,6 +70,9 @@ along with GCC; see the file COPYING3.
else fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP)); \
} \
} while (0)
+#undef ASM_OUTPUT_MAX_SKIP_PAD
+#define ASM_OUTPUT_MAX_SKIP_PAD(FILE, LOG, MAX_SKIP) \
+ ASM_OUTPUT_MAX_SKIP_ALIGN((FILE), (LOG), (MAX_SKIP))
#endif
/* Undefine SUBTARGET_EXTRA_SPECS it is empty anyway. We define it in
Index: config/i386/netbsd-elf.h
===================================================================
--- config/i386/netbsd-elf.h (revision 147459)
+++ config/i386/netbsd-elf.h (working copy)
@@ -99,7 +99,9 @@ along with GCC; see the file COPYING3.
command to advance the location counter to a multiple of 1<<LOG
bytes if it is within MAX_SKIP bytes.
- This is used to align code labels according to Intel recommendations. */
+ This is used to align code labels according to Intel recommendations.
+
+ ASM_OUTPUT_MAX_SKIP_PAD is the same as ASM_OUTPUT_MAX_SKIP_ALIGN. */
#ifdef HAVE_GAS_MAX_SKIP_P2ALIGN
#define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE, LOG, MAX_SKIP) \
@@ -107,6 +109,9 @@ along with GCC; see the file COPYING3.
if ((MAX_SKIP) == 0) fprintf ((FILE), "\t.p2align %d\n", (LOG)); \
else fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP)); \
}
+#undef ASM_OUTPUT_MAX_SKIP_PAD
+#define ASM_OUTPUT_MAX_SKIP_PAD(FILE, LOG, MAX_SKIP) \
+ ASM_OUTPUT_MAX_SKIP_ALIGN((FILE), (LOG), (MAX_SKIP))
#endif
/* We always use gas here, so we don't worry about ECOFF assembler
Index: config/i386/openbsdelf.h
===================================================================
--- config/i386/openbsdelf.h (revision 147459)
+++ config/i386/openbsdelf.h (working copy)
@@ -98,6 +98,9 @@ along with GCC; see the file COPYING3.
if ((MAX_SKIP) == 0) fprintf ((FILE), "\t.p2align %d\n", (LOG)); \
else fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP)); \
}
+#undef ASM_OUTPUT_MAX_SKIP_PAD
+#define ASM_OUTPUT_MAX_SKIP_PAD(FILE, LOG, MAX_SKIP) \
+ ASM_OUTPUT_MAX_SKIP_ALIGN((FILE), (LOG), (MAX_SKIP))
#endif
/* Stack & calling: profiling. */
Index: config/i386/freebsd.h
===================================================================
--- config/i386/freebsd.h (revision 147459)
+++ config/i386/freebsd.h (working copy)
@@ -115,15 +115,20 @@ along with GCC; see the file COPYING3.
command to advance the location counter to a multiple of 1<<LOG
bytes if it is within MAX_SKIP bytes.
- This is used to align code labels according to Intel recommendations. */
+ This is used to align code labels according to Intel recommendations.
+
+ ASM_OUTPUT_MAX_SKIP_PAD is the same as ASM_OUTPUT_MAX_SKIP_ALIGN. */
#ifdef HAVE_GAS_MAX_SKIP_P2ALIGN
#undef ASM_OUTPUT_MAX_SKIP_ALIGN
-#define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE, LOG, MAX_SKIP) \
- if ((LOG) != 0) { \
+#define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE, LOG, MAX_SKIP) \
+ if ((LOG) != 0) { \
if ((MAX_SKIP) == 0) fprintf ((FILE), "\t.p2align %d\n", (LOG)); \
else fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP)); \
}
+#undef ASM_OUTPUT_MAX_SKIP_PAD
+#define ASM_OUTPUT_MAX_SKIP_PAD(FILE, LOG, MAX_SKIP) \
+ ASM_OUTPUT_MAX_SKIP_ALIGN((FILE), (LOG), (MAX_SKIP))
#endif
/* Don't default to pcc-struct-return, we want to retain compatibility with
Index: config/i386/i386.c
===================================================================
--- config/i386/i386.c (revision 147459)
+++ config/i386/i386.c (working copy)
@@ -27298,7 +27298,7 @@ ix86_avoid_jump_misspredicts (void)
if (dump_file)
fprintf (dump_file, "Padding insn %i by %i bytes!\n",
INSN_UID (insn), padsize);
- emit_insn_before (gen_align (GEN_INT (padsize)), insn);
+ emit_insn_before (gen_pad (GEN_INT (padsize)), insn);
}
}
}