This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] S/390: Fix varargs alias set


Hello,

this patch was on my todo list for a long time now.
rth made me aware that we have a problem with the alias sets
of our vararg instructions: 
http://gcc.gnu.org/ml/gcc-patches/2004-12/msg01317.html

The memory locations in the vararg writes and the vararg reads
must be in the same alias set. On S/390 we both put them in the
s390_sr_alias_set as well as all frame related instructions.

For the vararg read instructions we have imposed the alias set
using DECL_POINTER_ALIAS_SET on the pointer to the stack location.
But this does not need to be the pointer which is used in the
INDIRECT_REF because the gimple code could have added temporaries
holding that value. So if you disable tree-ter you could see a modified
alias set for the memory location because get_alias_set may have used
type based aliasing. As the result the vararg read and write
instructions would have different alias sets unequal to 0 and the scheduler could
potentially exchange them. Of course also an alias set of 0 for
the vararg reads (as currently returned by get_varargs_alias_set)
wouldn't help here because it would get lost the same way.

The problem in the S/390 back end is that the vararg writes aren't
set to get_varargs_alias_set (). Which would help because independently
on what the type base aliasing returnes for the vararg read memory
location the returned alias set 0 would match it. Done with the
attached patch.

The patch ist bootstrapped on s390 and s390x.
Testsuite run without regressions.

OK for mainline?

Bye,

-Andreas-

2005-09-08  Andreas Krebbel  <krebbel1@de.ibm.com>

	* config/s390/s390.c (s390_sr_alias_set): Variable removed.
	(override_options): Setting s390_sr_alias_set removed.
	(save_fpr, save_gprs): Set alias set to vararg or frame.
	(restore_fpr, restore_gprs, s390_emit_prologue): Replace 
	s390_sr_alias_set with get_frame_alias_set ().
	(s390_gimplify_va_arg): Replace s390_sr_alias_set with
	get_varargs_alias_set ().


Index: gcc/config/s390/s390.c
===================================================================
--- gcc/config/s390/s390.c.orig	2005-09-08 09:59:02.000000000 +0200
+++ gcc/config/s390/s390.c	2005-09-08 10:06:56.000000000 +0200
@@ -186,9 +186,6 @@ struct processor_costs z9_109_cost = 
 
 extern int reload_completed;
 
-/* The alias set for prologue/epilogue register save/restore.  */
-static int s390_sr_alias_set = 0;
-
 /* Save information from a "cmpxx" operation until the branch or scc is
    emitted.  */
 rtx s390_compare_op0, s390_compare_op1;
@@ -1296,9 +1293,6 @@ s390_handle_option (size_t code, const c
 void
 override_options (void)
 {
-  /* Acquire a unique set number for our register saves and restores.  */
-  s390_sr_alias_set = new_alias_set ();
-
   /* Set up function hooks.  */
   init_machine_status = s390_init_machine_status;
 
@@ -6272,7 +6266,11 @@ save_fpr (rtx base, int offset, int regn
 {
   rtx addr;
   addr = gen_rtx_MEM (DFmode, plus_constant (base, offset));
-  set_mem_alias_set (addr, s390_sr_alias_set);
+
+  if (regnum >= 16 && regnum <= (16 + (TARGET_64BIT ? 4 : 2)))
+    set_mem_alias_set (addr, get_varargs_alias_set ());
+  else
+    set_mem_alias_set (addr, get_frame_alias_set ());
 
   return emit_move_insn (addr, gen_rtx_REG (DFmode, regnum));
 }
@@ -6285,7 +6283,7 @@ restore_fpr (rtx base, int offset, int r
 {
   rtx addr;
   addr = gen_rtx_MEM (DFmode, plus_constant (base, offset));
-  set_mem_alias_set (addr, s390_sr_alias_set);
+  set_mem_alias_set (addr, get_frame_alias_set ());
 
   return emit_move_insn (gen_rtx_REG (DFmode, regnum), addr);
 }
@@ -6302,7 +6300,8 @@ save_gprs (rtx base, int offset, int fir
 
   addr = plus_constant (base, offset);
   addr = gen_rtx_MEM (Pmode, addr);
-  set_mem_alias_set (addr, s390_sr_alias_set);
+
+  set_mem_alias_set (addr, get_frame_alias_set ());
 
   /* Special-case single register.  */
   if (first == last)
@@ -6321,6 +6320,16 @@ save_gprs (rtx base, int offset, int fir
 			     gen_rtx_REG (Pmode, first),
 			     GEN_INT (last - first + 1));
 
+  if (first <= 6 && current_function_stdarg)
+    for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
+      {
+	rtx mem = XEXP (XVECEXP (PATTERN (insn), 0, i), 0);
+	
+	if (first + i <= 6)
+	  set_mem_alias_set (mem, get_varargs_alias_set ());
+	else
+	  set_mem_alias_set (mem, get_frame_alias_set ());
+      }
 
   /* We need to set the FRAME_RELATED flag on all SETs
      inside the store-multiple pattern.
@@ -6377,7 +6386,7 @@ restore_gprs (rtx base, int offset, int 
 
   addr = plus_constant (base, offset);
   addr = gen_rtx_MEM (Pmode, addr);
-  set_mem_alias_set (addr, s390_sr_alias_set);
+  set_mem_alias_set (addr, get_frame_alias_set ());
 
   /* Special-case single register.  */
   if (first == last)
@@ -6617,7 +6626,7 @@ s390_emit_prologue (void)
 				  cfun_frame_layout.backchain_offset));
 	  else
 	    addr = gen_rtx_MEM (Pmode, stack_pointer_rtx);  
-	  set_mem_alias_set (addr, s390_sr_alias_set);
+	  set_mem_alias_set (addr, get_frame_alias_set ());
 	  insn = emit_insn (gen_move_insn (addr, temp_reg));
 	}
 
@@ -6836,7 +6845,7 @@ s390_emit_epilogue (bool sibcall)
 				    + (i - cfun_frame_layout.first_save_gpr)
 				    * UNITS_PER_WORD);
 	      addr = gen_rtx_MEM (Pmode, addr);
-	      set_mem_alias_set (addr, s390_sr_alias_set);
+	      set_mem_alias_set (addr, get_frame_alias_set ());
 	      emit_move_insn (addr, gen_rtx_REG (Pmode, i));
 	    }
 	}
@@ -6861,7 +6870,7 @@ s390_emit_epilogue (bool sibcall)
 				       - cfun_frame_layout.first_save_gpr)
 				    * UNITS_PER_WORD);
 	      addr = gen_rtx_MEM (Pmode, addr);
-	      set_mem_alias_set (addr, s390_sr_alias_set);
+	      set_mem_alias_set (addr, get_frame_alias_set ());
 	      emit_move_insn (return_reg, addr);
 	    }
 	}
@@ -7399,7 +7408,7 @@ s390_gimplify_va_arg (tree valist, tree 
   lab_false = create_artificial_label ();
   lab_over = create_artificial_label ();
   addr = create_tmp_var (ptr_type_node, "addr");
-  DECL_POINTER_ALIAS_SET (addr) = s390_sr_alias_set;
+  DECL_POINTER_ALIAS_SET (addr) = get_varargs_alias_set ();
 
   t = fold_convert (TREE_TYPE (reg), size_int (max_reg));
   t = build2 (GT_EXPR, boolean_type_node, reg, t);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]