diff mbox

[2/2,PR78561] Recalculate constant pool size before emitting it

Message ID 1480606157-29525-3-git-send-email-james.greenhalgh@arm.com
State New
Headers show

Commit Message

James Greenhalgh Dec. 1, 2016, 3:29 p.m. UTC
Hi,

In PR78561, we try to make use of stale constant pool offset data when
making decisions as to whether to output an alignment directive after
the AArch64 constant pool. The offset data goes stale as we only ever
increment it when adding new constants to the pool (it represents an
upper bound on the size of the pool).

To fix that, we should recompute the offset values shortly after
sweeping through insns looking for valid constant.

I'm not totally sure about this code so I'd appreciate comments on whether
this is a sensible idea.

Bootstrapped on aarch64-none-linux-gnu and x86-64-none-linux-gnu and
checked with aarch64-none-elf with no issues.

OK?

Thanks,
James

gcc/

2016-12-01  James Greenhalgh  <james.greenhalgh@arm.com>

	PR rtl-optimization/78561
	* varasm.c (recompute_pool_offsets): New.
	(output_constant_pool): Call it.

gcc/testsuite/

2016-12-01  James Greenhalgh  <james.greenhalgh@arm.com>

	PR rtl-optimization/78561
	* gcc.target/aarch64/pr78561.c: New.
diff mbox

Patch

diff --git a/gcc/testsuite/gcc.target/aarch64/pr78561.c b/gcc/testsuite/gcc.target/aarch64/pr78561.c
new file mode 100644
index 0000000..048d2d7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr78561.c
@@ -0,0 +1,9 @@ 
+/* { dg-do compile } */
+/* { dg-options "-Og -O3 -mcmodel=tiny" } */
+
+int
+main (__fp16 x)
+{
+  __fp16 a = 6.5504e4;
+  return (x <= a);
+}
diff --git a/gcc/varasm.c b/gcc/varasm.c
index f8af0c1..f3cd70a 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -3942,6 +3942,29 @@  output_constant_pool_1 (struct constant_descriptor_rtx *desc,
   return;
 }
 
+/* Recompute the offsets of entries in POOL, and the overall size of
+   POOL.  Do this after calling mark_constant_pool to ensure that we
+   are computing the offset values for the pool which we will actually
+   emit.  */
+
+static void
+recompute_pool_offsets (struct rtx_constant_pool *pool)
+{
+  struct constant_descriptor_rtx *desc;
+  pool->offset = 0;
+
+  for (desc = pool->first; desc ; desc = desc->next)
+    if (desc->mark)
+      {
+	  /* Recalculate offset.  */
+	unsigned int align = desc->align;
+	pool->offset += (align / BITS_PER_UNIT) - 1;
+	pool->offset &= ~ ((align / BITS_PER_UNIT) - 1);
+	desc->offset = pool->offset;
+	pool->offset += GET_MODE_SIZE (desc->mode);
+      }
+}
+
 /* Mark all constants that are referenced by SYMBOL_REFs in X.
    Emit referenced deferred strings.  */
 
@@ -4060,6 +4083,11 @@  output_constant_pool (const char *fnname ATTRIBUTE_UNUSED,
      case we do not need to output the constant.  */
   mark_constant_pool ();
 
+  /* Having marked the constant pool entries we'll actually emit, we
+     now need to rebuild the offset information, which may have become
+     stale.  */
+  recompute_pool_offsets (pool);
+
 #ifdef ASM_OUTPUT_POOL_PROLOGUE
   ASM_OUTPUT_POOL_PROLOGUE (asm_out_file, fnname, fndecl, pool->offset);
 #endif