This patch has bootstrapped and tested on powerpc64le-unknown-linux-gnu with no regressions. Is this ok for the trunk?

See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48344 for the original problem report. The error resulted because gcc's processing of command-line options within gcc initialization code originally preceded the processing of target-specific configuration hooks.

In the unpatched gcc implementation, the Pmode (pointer mode) variable has not been initialized at the time the -fstack-limit-register command-line option is processed. As a consequence, the stack-limiting register is not assigned a proper mode. Thus, rtl instructions that make use of this stack-limiting register have an unspecified mode, and are therefore not matched by any known instructions.

The fix represented in this patch is to defer the command-line processing related to command-line specification of a stack-limiting register until after target-specific initialization has been completed.

Some questions and issues raised in response to version 2 of this patch are addressed below:

1. Concerns regarding possible unintended consequences that might result from moving all target-specific initialization to precede the invocation of the handle_common_deferred_options () function are addressed by preserving the original initialization order and moving the relevant command-line processing to follow the target-specific initialization.

2. A question was raised as to whether Pmode can change with attribute target. It cannot.

An issue raised in response to version 3 of this patch is addressed as follows:

1.  Abbreviated comments.

2. Fixed spacing following periods within comments.

3. Moved stack_limit_rtx initialization code into init_emit_once(void) and eliminated special initialization function that had been proposed in the V3 patch.


gcc/testsuite/ChangeLog:

2016-02-11  Kelvin Nilsen  <kel...@gcc.gnu.org>

        * gcc.target/powerpc/pr48344-1.c: New test.

gcc/ChangeLog:

2016-02-11  Kelvin Nilsen  <kel...@gcc.gnu.org>

        * opts-global.c (handle_common_deferred_options): Introduce and
        initialize two global variables to remember command-line options
        specifying a stack-limiting register.
        * opts.h: Add extern declarations of the two new global variables. 
        * emit-rtl.c (init_emit_once): Initialize the stack_limit_rtx
        variable based on the values of the two new global variables.


Index: gcc/testsuite/gcc.target/powerpc/pr48344-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/pr48344-1.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/pr48344-1.c	(revision 232633)
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-fstack-limit-register=r2" } */
+void foo ()
+{
+  int N = 2;
+  int slots[N];
+
+}
+
Index: gcc/emit-rtl.c
===================================================================
--- gcc/emit-rtl.c	(revision 232135)
+++ gcc/emit-rtl.c	(working copy)
@@ -57,6 +57,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "builtins.h"
 #include "rtl-iter.h"
 #include "stor-layout.h"
+#include "opts.h"
 
 struct target_rtl default_target_rtl;
 #if SWITCHABLE_TARGET
@@ -5895,6 +5896,13 @@ init_emit_once (void)
 
   /* Create the unique rtx's for certain rtx codes and operand values.  */
 
+  /* Process stack-limiting command-line options.  */
+  if (opt_fstack_limit_symbol_arg != NULL)
+    stack_limit_rtx 
+      = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (opt_fstack_limit_symbol_arg));
+  if (opt_fstack_limit_register_no >= 0)
+    stack_limit_rtx = gen_rtx_REG (Pmode, opt_fstack_limit_register_no);
+
   /* Don't use gen_rtx_CONST_INT here since gen_rtx_CONST_INT in this case
      tries to use these variables.  */
   for (i = - MAX_SAVED_CONST_INT; i <= MAX_SAVED_CONST_INT; i++)
Index: gcc/opts.h
===================================================================
--- gcc/opts.h	(revision 232135)
+++ gcc/opts.h	(working copy)
@@ -296,6 +296,10 @@ struct cl_option_handlers
   struct cl_option_handler_func handlers[3];
 };
 
+/* Hold command-line options associated with stack limitation.  */
+extern const char *opt_fstack_limit_symbol_arg;
+extern int opt_fstack_limit_register_no;
+
 /* Input file names.  */
 
 extern const char **in_fnames;
Index: gcc/opts-global.c
===================================================================
--- gcc/opts-global.c	(revision 232135)
+++ gcc/opts-global.c	(working copy)
@@ -310,6 +310,10 @@ decode_options (struct gcc_options *opts, struct g
   finish_options (opts, opts_set, loc);
 }
 
+/* Hold command-line options associated with stack limitation.  */
+const char *opt_fstack_limit_symbol_arg = NULL;
+int opt_fstack_limit_register_no = -1;
+
 /* Process common options that have been deferred until after the
    handlers have been called for all options.  */
 
@@ -417,12 +421,18 @@ handle_common_deferred_options (void)
 	    if (reg < 0)
 	      error ("unrecognized register name %qs", opt->arg);
 	    else
-	      stack_limit_rtx = gen_rtx_REG (Pmode, reg);
+	      {
+		/* Deactivate previous OPT_fstack_limit_symbol_ options.  */
+		opt_fstack_limit_symbol_arg = NULL;
+		opt_fstack_limit_register_no = reg;
+	      }
 	  }
 	  break;
 
 	case OPT_fstack_limit_symbol_:
-	  stack_limit_rtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (opt->arg));
+	  /* Deactivate previous OPT_fstack_limit_register_ options.  */
+	  opt_fstack_limit_register_no = -1;
+	  opt_fstack_limit_symbol_arg = opt->arg;
 	  break;
 
 	case OPT_fasan_shadow_offset_:
@@ -442,3 +452,4 @@ handle_common_deferred_options (void)
 	}
     }
 }
+

Reply via email to