Patchwork [MIPS,committed] Tweak r10k cache barrier code

login
register
mail settings
Submitter Richard Sandiford
Date Aug. 26, 2012, 7:20 p.m.
Message ID <87harp31fb.fsf@talisman.home>
Download mbox | patch
Permalink /patch/180081/
State New
Headers show

Comments

Richard Sandiford - Aug. 26, 2012, 7:20 p.m.
r10k_safe_mem_expr_p couldn't cope with a MEM_REF of an ADDR_EXPR,
which for some reason is produced for r10k-cache-barrier-8.c when
compiled with -O2 -lto but not when compiled with just -O2.

This function is still much too conservative, but I wanted to be
safe for kernel code that plays clever tricks with link-time symbol
definitions.  A trivial example is:

    extern char _region_start[];

where _region_start is defined in the linker script.
_region_start[1] can't be seen as an in-range access to an object
as far as the -mr10k-cache-barrier= option is concerned.

Tested on mipsisa64-elf, mips64-elf and mips64-linux-gnu.  Applied.
Will be tested once gcc.target/mips uses gcc-dg.

Richard


gcc/
	* config/mips/mips.c (r10k_safe_mem_expr_p): Use get_inner_reference.

Patch

Index: gcc/config/mips/mips.c
===================================================================
--- gcc/config/mips/mips.c	2012-08-26 11:35:15.000000000 +0100
+++ gcc/config/mips/mips.c	2012-08-26 11:36:43.667807911 +0100
@@ -14446,17 +14446,18 @@  r10k_safe_address_p (rtx x, rtx insn)
 static bool
 r10k_safe_mem_expr_p (tree expr, HOST_WIDE_INT offset)
 {
-  if (offset < 0 || offset >= int_size_in_bytes (TREE_TYPE (expr)))
-    return false;
+  HOST_WIDE_INT bitoffset, bitsize;
+  tree inner, var_offset;
+  enum machine_mode mode;
+  int unsigned_p, volatile_p;
 
-  while (TREE_CODE (expr) == COMPONENT_REF)
-    {
-      expr = TREE_OPERAND (expr, 0);
-      if (expr == NULL_TREE)
-	return false;
-    }
+  inner = get_inner_reference (expr, &bitsize, &bitoffset, &var_offset, &mode,
+			       &unsigned_p, &volatile_p, false);
+  if (!DECL_P (inner) || !DECL_SIZE_UNIT (inner) || var_offset)
+    return false;
 
-  return DECL_P (expr);
+  offset += bitoffset / BITS_PER_UNIT;
+  return offset >= 0 && offset < tree_low_cst (DECL_SIZE_UNIT (inner), 1);
 }
 
 /* A for_each_rtx callback for which DATA points to the instruction