aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyrylo Tkachov <kyrylo.tkachov@arm.com>2014-10-24 11:30:42 +0000
committerKyrylo Tkachov <ktkachov@gcc.gnu.org>2014-10-24 11:30:42 +0000
commit8baff86e5610fc7351bfb3abfb75f17305e7edd3 (patch)
treeb98b7cf1873d829f4c4aea496c6edad522530bf6
parent1f59b31508e341ef159d56a679e0e8a76e6d0b2e (diff)
downloadgcc-8baff86e5610fc7351bfb3abfb75f17305e7edd3.zip
gcc-8baff86e5610fc7351bfb3abfb75f17305e7edd3.tar.gz
gcc-8baff86e5610fc7351bfb3abfb75f17305e7edd3.tar.bz2
[AArch64] Cleanup logic around aarch64_final_prescan
* config/aarch64/aarch64.h (ADJUST_INSN_LENGTH): Wrap definition in do while (0). * config/aarch64/aarch64.c (is_mem_p): Delete. (is_memory_op): Rename to... (has_memory_op): ... This. Use FOR_EACH_SUBRTX. (dep_between_memop_and_curr): Assert that the input is a SET. (aarch64_madd_needs_nop): Add comment. Do not call dep_between_memop_and_curr on NULL body. (aarch64_final_prescan_insn): Add comment. Include rtl-iter.h. From-SVN: r216637
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/config/aarch64/aarch64.c46
-rw-r--r--gcc/config/aarch64/aarch64.h7
3 files changed, 46 insertions, 20 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 683edcc..918426d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+2014-10-24 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/aarch64/aarch64.h (ADJUST_INSN_LENGTH): Wrap definition in
+ do while (0).
+ * config/aarch64/aarch64.c (is_mem_p): Delete.
+ (is_memory_op): Rename to...
+ (has_memory_op): ... This. Use FOR_EACH_SUBRTX.
+ (dep_between_memop_and_curr): Assert that the input is a SET.
+ (aarch64_madd_needs_nop): Add comment. Do not call
+ dep_between_memop_and_curr on NULL body.
+ (aarch64_final_prescan_insn): Add comment.
+ Include rtl-iter.h.
+
2014-10-24 Richard Biener <rguenther@suse.de>
* Makefile.in (BUILD_CPPLIB): Move $(LIBINTL) $(LIBICONV)
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index b94f450..de53c94 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -68,6 +68,7 @@
#include "aarch64-cost-tables.h"
#include "dumpfile.h"
#include "builtins.h"
+#include "rtl-iter.h"
/* Defined for convenience. */
#define POINTER_BYTES (POINTER_SIZE / BITS_PER_UNIT)
@@ -7658,17 +7659,19 @@ aarch64_mangle_type (const_tree type)
return NULL;
}
-static int
-is_mem_p (rtx *x, void *data ATTRIBUTE_UNUSED)
-{
- return MEM_P (*x);
-}
+
+/* Return true if the rtx_insn contains a MEM RTX somewhere
+ in it. */
static bool
-is_memory_op (rtx_insn *mem_insn)
+has_memory_op (rtx_insn *mem_insn)
{
- rtx pattern = PATTERN (mem_insn);
- return for_each_rtx (&pattern, is_mem_p, NULL);
+ subrtx_iterator::array_type array;
+ FOR_EACH_SUBRTX (iter, array, PATTERN (mem_insn), ALL)
+ if (MEM_P (*iter))
+ return true;
+
+ return false;
}
/* Find the first rtx_insn before insn that will generate an assembly
@@ -7718,14 +7721,13 @@ dep_between_memop_and_curr (rtx memop)
rtx load_reg;
int opno;
- if (!memop)
- return false;
+ gcc_assert (GET_CODE (memop) == SET);
if (!REG_P (SET_DEST (memop)))
return false;
load_reg = SET_DEST (memop);
- for (opno = 0; opno < recog_data.n_operands; opno++)
+ for (opno = 1; opno < recog_data.n_operands; opno++)
{
rtx operand = recog_data.operand[opno];
if (REG_P (operand)
@@ -7736,6 +7738,12 @@ dep_between_memop_and_curr (rtx memop)
return false;
}
+
+/* When working around the Cortex-A53 erratum 835769,
+ given rtx_insn INSN, return true if it is a 64-bit multiply-accumulate
+ instruction and has a preceding memory instruction such that a NOP
+ should be inserted between them. */
+
bool
aarch64_madd_needs_nop (rtx_insn* insn)
{
@@ -7754,24 +7762,26 @@ aarch64_madd_needs_nop (rtx_insn* insn)
return false;
prev = aarch64_prev_real_insn (insn);
- if (!prev)
+ if (!prev || !has_memory_op (prev))
return false;
body = single_set (prev);
/* If the previous insn is a memory op and there is no dependency between
- it and the madd, emit a nop between them. If we know the previous insn is
- a memory op but body is NULL, emit the nop to be safe, it's probably a
- load/store pair insn. */
- if (is_memory_op (prev)
- && GET_MODE (recog_data.operand[0]) == DImode
- && (!dep_between_memop_and_curr (body)))
+ it and the DImode madd, emit a NOP between them. If body is NULL then we
+ have a complex memory operation, probably a load/store pair.
+ Be conservative for now and emit a NOP. */
+ if (GET_MODE (recog_data.operand[0]) == DImode
+ && (!body || !dep_between_memop_and_curr (body)))
return true;
return false;
}
+
+/* Implement FINAL_PRESCAN_INSN. */
+
void
aarch64_final_prescan_insn (rtx_insn *insn)
{
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index 11aa10b..749c19d 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -503,8 +503,11 @@ enum target_cpus
/* If inserting NOP before a mult-accumulate insn remember to adjust the
length so that conditional branching code is updated appropriately. */
#define ADJUST_INSN_LENGTH(insn, length) \
- if (aarch64_madd_needs_nop (insn)) \
- length += 4;
+ do \
+ { \
+ if (aarch64_madd_needs_nop (insn)) \
+ length += 4; \
+ } while (0)
#define FINAL_PRESCAN_INSN(INSN, OPVEC, NOPERANDS) \
aarch64_final_prescan_insn (INSN); \