diff mbox

6 backported patches for 4.5 branch

Message ID 20120209214258.GW18768@tyan-ft48-01.lab.bos.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek Feb. 9, 2012, 9:42 p.m. UTC
Hi!

I've committed these backports to 4.5 branch after bootstrapping/regtesting
them on x86_64-linux and i686-linux.

	Jakub
2012-02-09  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2012-01-26  Jakub Jelinek  <jakub@redhat.com>

	* make-relative-prefix.c (make_relative_prefix_1): Avoid warning
	about using preprocessor directives inside of macro arguments.

	2012-01-02  Jakub Jelinek  <jakub@redhat.com>

	* make-relative-prefix.c (make_relative_prefix_1): Avoid
	stack overflow if PATH contains just a single entry and
	HOST_EXECUTABLE_SUFFIX needs to be used.

	PR driver/48306
	* make-relative-prefix.c: Include sys/stat.h.
	(make_relative_prefix_1): If access succeeds, check also stat
	if nstore is a regular file.
2012-02-09  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2012-01-05  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/51768
	* stmt.c (check_unique_operand_names): Don't ICE during error
	reporting if i is from labels chain.

	* c-c++-common/pr51768.c: New test.

--- gcc/stmt.c	(revision 182920)
+++ gcc/stmt.c	(revision 182921)
@@ -1253,11 +1253,11 @@ check_operand_nalternatives (tree output
 static bool
 check_unique_operand_names (tree outputs, tree inputs, tree labels)
 {
-  tree i, j;
+  tree i, j, i_name = NULL_TREE;
 
   for (i = outputs; i ; i = TREE_CHAIN (i))
     {
-      tree i_name = TREE_PURPOSE (TREE_PURPOSE (i));
+      i_name = TREE_PURPOSE (TREE_PURPOSE (i));
       if (! i_name)
 	continue;
 
@@ -1268,7 +1268,7 @@ check_unique_operand_names (tree outputs
 
   for (i = inputs; i ; i = TREE_CHAIN (i))
     {
-      tree i_name = TREE_PURPOSE (TREE_PURPOSE (i));
+      i_name = TREE_PURPOSE (TREE_PURPOSE (i));
       if (! i_name)
 	continue;
 
@@ -1282,7 +1282,7 @@ check_unique_operand_names (tree outputs
 
   for (i = labels; i ; i = TREE_CHAIN (i))
     {
-      tree i_name = TREE_PURPOSE (i);
+      i_name = TREE_PURPOSE (i);
       if (! i_name)
 	continue;
 
@@ -1297,8 +1297,7 @@ check_unique_operand_names (tree outputs
   return true;
 
  failure:
-  error ("duplicate asm operand name %qs",
-	 TREE_STRING_POINTER (TREE_PURPOSE (TREE_PURPOSE (i))));
+  error ("duplicate asm operand name %qs", TREE_STRING_POINTER (i_name));
   return false;
 }
 
--- gcc/testsuite/c-c++-common/pr51768.c	(revision 0)
+++ gcc/testsuite/c-c++-common/pr51768.c	(revision 182921)
@@ -0,0 +1,25 @@
+/* PR middle-end/51768 */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+void
+foo (void)
+{
+  asm goto ("" : : : : lab, lab, lab2, lab);	/* { dg-error "duplicate asm operand name" } */
+lab:;
+lab2:;
+}
+
+void
+bar (void)
+{
+  asm goto ("" : : [lab] "i" (0) : : lab);	/* { dg-error "duplicate asm operand name" } */
+lab:;
+}
+
+void
+baz (void)
+{
+  int x;
+  asm ("" : [lab] "=r" (x) : [lab] "r" (x));	/* { dg-error "duplicate asm operand name" } */
+}
2012-02-09  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2012-01-05  Jakub Jelinek  <jakub@redhat.com>

	PR rtl-optimization/51767
	* cfgrtl.c (force_nonfallthru_and_redirect): Force addition
	of jump_block and add an extra edge for degenerated asm gotos.

	* gcc.c-torture/compile/pr51767.c: New test.

--- gcc/cfgrtl.c	(revision 182921)
+++ gcc/cfgrtl.c	(revision 182922)
@@ -1129,6 +1129,7 @@ force_nonfallthru_and_redirect (edge e, 
   rtx note;
   edge new_edge;
   int abnormal_edge_flags = 0;
+  bool asm_goto_edge = false;
   int loc;
 
   /* In the case the last instruction is conditional jump to the next
@@ -1208,8 +1209,28 @@ force_nonfallthru_and_redirect (edge e, 
 	}
     }
 
-  if (EDGE_COUNT (e->src->succs) >= 2 || abnormal_edge_flags)
+  /* If e->src ends with asm goto, see if any of the ASM_OPERANDS_LABELs
+     don't point to target label.  */
+  if (JUMP_P (BB_END (e->src))
+      && target != EXIT_BLOCK_PTR
+      && e->dest == target
+      && (e->flags & EDGE_FALLTHRU)
+      && (note = extract_asm_operands (PATTERN (BB_END (e->src)))))
     {
+      int i, n = ASM_OPERANDS_LABEL_LENGTH (note);
+
+      for (i = 0; i < n; ++i)
+	if (XEXP (ASM_OPERANDS_LABEL (note, i), 0) == BB_HEAD (target))
+	  {
+	    asm_goto_edge = true;
+	    break;
+	  }
+    }
+
+  if (EDGE_COUNT (e->src->succs) >= 2 || abnormal_edge_flags || asm_goto_edge)
+    {
+      gcov_type count = e->count;
+      int probability = e->probability;
       /* Create the new structures.  */
 
       /* If the old block ended with a tablejump, skip its table
@@ -1220,7 +1241,7 @@ force_nonfallthru_and_redirect (edge e, 
       note = NEXT_INSN (note);
 
       jump_block = create_basic_block (note, NULL, e->src);
-      jump_block->count = e->count;
+      jump_block->count = count;
       jump_block->frequency = EDGE_FREQUENCY (e);
       jump_block->loop_depth = target->loop_depth;
 
@@ -1236,13 +1257,27 @@ force_nonfallthru_and_redirect (edge e, 
 
       /* Wire edge in.  */
       new_edge = make_edge (e->src, jump_block, EDGE_FALLTHRU);
-      new_edge->probability = e->probability;
-      new_edge->count = e->count;
+      new_edge->probability = probability;
+      new_edge->count = count;
 
       /* Redirect old edge.  */
       redirect_edge_pred (e, jump_block);
       e->probability = REG_BR_PROB_BASE;
 
+      /* If asm goto has any label refs to target's label,
+	 add also edge from asm goto bb to target.  */
+      if (asm_goto_edge)
+	{
+	  new_edge->probability /= 2;
+	  new_edge->count /= 2;
+	  jump_block->count /= 2;
+	  jump_block->frequency /= 2;
+	  new_edge = make_edge (new_edge->src, target,
+				e->flags & ~EDGE_FALLTHRU);
+	  new_edge->probability = probability - probability / 2;
+	  new_edge->count = count - count / 2;
+	}
+
       new_bb = jump_block;
     }
   else
--- gcc/testsuite/gcc.c-torture/compile/pr51767.c	(revision 0)
+++ gcc/testsuite/gcc.c-torture/compile/pr51767.c	(revision 182922)
@@ -0,0 +1,23 @@
+/* PR rtl-optimization/51767 */
+
+extern void fn1 (void), fn2 (void);
+
+static inline __attribute__((always_inline)) int
+foo (int *x, long y)
+{
+  asm goto ("" : : "r" (x), "r" (y) : "memory" : lab);
+  return 0;
+lab:
+  return 1;
+}
+
+void
+bar (int *x)
+{
+  if (foo (x, 23))
+    fn1 ();
+  else
+    fn2 ();
+
+  foo (x, 2);
+}
2012-02-09  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2012-01-19  Jakub Jelinek  <jakub@redhat.com>

	PR libmudflap/40778
	* tree-mudflap.c (mf_artificial): New function.
	(execute_mudflap_function_ops, execute_mudflap_function_decls,
	mx_register_decls, mudflap_enqueue_decl): Use it.

	* testsuite/libmudflap.c/fail68-frag.c: New test.

--- gcc/tree-mudflap.c	(revision 183306)
+++ gcc/tree-mudflap.c	(revision 183307)
@@ -69,6 +69,13 @@ static tree mx_xfn_xform_decls (gimple_s
 static gimple_seq mx_register_decls (tree, gimple_seq, location_t);
 static unsigned int execute_mudflap_function_decls (void);
 
+/* Return true if DECL is artificial stub that shouldn't be instrumented by
+   mf.  We should instrument clones of non-artificial functions.  */
+static inline bool
+mf_artificial (const_tree decl)
+{
+  return DECL_ARTIFICIAL (DECL_ORIGIN (decl));
+}
 
 /* ------------------------------------------------------------------------ */
 /* Some generally helpful functions for mudflap instrumentation.  */
@@ -412,8 +419,8 @@ execute_mudflap_function_ops (void)
 
   /* Don't instrument functions such as the synthetic constructor
      built during mudflap_finish_file.  */
-  if (mf_marked_p (current_function_decl) ||
-      DECL_ARTIFICIAL (current_function_decl))
+  if (mf_marked_p (current_function_decl)
+      || mf_artificial (current_function_decl))
     return 0;
 
   push_gimplify_context (&gctx);
@@ -994,8 +1001,8 @@ execute_mudflap_function_decls (void)
 
   /* Don't instrument functions such as the synthetic constructor
      built during mudflap_finish_file.  */
-  if (mf_marked_p (current_function_decl) ||
-      DECL_ARTIFICIAL (current_function_decl))
+  if (mf_marked_p (current_function_decl)
+      || mf_artificial (current_function_decl))
     return 0;
 
   push_gimplify_context (&gctx);
@@ -1078,7 +1085,7 @@ mx_register_decls (tree decl, gimple_seq
           /* Add the __mf_register call at the current appending point.  */
           if (gsi_end_p (initially_stmts))
 	    {
-	      if (!DECL_ARTIFICIAL (decl))
+	      if (!mf_artificial (decl))
 		warning (OPT_Wmudflap,
 			 "mudflap cannot track %qE in stub function",
 			 DECL_NAME (decl));
@@ -1249,7 +1256,7 @@ mudflap_enqueue_decl (tree obj)
      during mudflap_finish_file ().  That would confuse the user,
      since the text would refer to variables that don't show up in the
      user's source code.  */
-  if (DECL_P (obj) && DECL_EXTERNAL (obj) && DECL_ARTIFICIAL (obj))
+  if (DECL_P (obj) && DECL_EXTERNAL (obj) && mf_artificial (obj))
     return;
 
   VEC_safe_push (tree, gc, deferred_static_decls, obj);
--- libmudflap/testsuite/libmudflap.c/fail68-frag.c	(revision 0)
+++ libmudflap/testsuite/libmudflap.c/fail68-frag.c	(revision 183307)
@@ -0,0 +1,27 @@
+/* PR libmudflap/40778 */
+
+char p[32];
+static int j;
+
+__attribute__((noinline))
+static void foo (int i)
+{
+  if (j++ == 0)
+    p[i + 4] = 12;
+  else
+    p[i - 4] = 13;
+}
+
+int
+main ()
+{
+  foo (30);
+  foo (30);
+  foo (30);
+  return 0;
+}
+
+/* { dg-output "mudflap violation 1.*" } */
+/* { dg-output "Nearby object 1.*" } */
+/* { dg-output "mudflap object.*name.*p" } */
+/* { dg-do run { xfail *-*-* } } */
2012-02-09  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2012-02-08  Jakub Jelinek  <jakub@redhat.com>

	PR rtl-optimization/52139
	* cfgrtl.c (cfg_layout_merge_blocks): If BB_END
	is a BARRIER after emit_insn_after_noloc, move BB_END
	to the last non-BARRIER insn before it.

	* gcc.dg/pr52139.c: New test.

--- gcc/cfgrtl.c	(revision 184004)
+++ gcc/cfgrtl.c	(revision 184005)
@@ -2871,6 +2871,11 @@ cfg_layout_merge_blocks (basic_block a, 
       rtx first = BB_END (a), last;
 
       last = emit_insn_after_noloc (b->il.rtl->header, BB_END (a), a);
+      /* The above might add a BARRIER as BB_END, but as barriers
+	 aren't valid parts of a bb, remove_insn doesn't update
+	 BB_END if it is a barrier.  So adjust BB_END here.  */
+      while (BB_END (a) != first && BARRIER_P (BB_END (a)))
+	BB_END (a) = PREV_INSN (BB_END (a));
       delete_insn_chain (NEXT_INSN (first), last, false);
       b->il.rtl->header = NULL;
     }
--- gcc/testsuite/gcc.dg/pr52139.c	(revision 0)
+++ gcc/testsuite/gcc.dg/pr52139.c	(revision 184005)
@@ -0,0 +1,49 @@
+/* PR rtl-optimization/52139 */
+/* { dg-do compile } */
+/* { dg-options "-O -fno-tree-dominator-opts -fno-tree-fre" } */
+/* { dg-options "-O -fno-tree-dominator-opts -fno-tree-fre -fpic" { target fpic } } */
+
+void *p;
+
+void
+foo (int a)
+{
+  switch (a)
+    {
+    case 0:
+    a0:
+    case 1:
+    a1:
+      p = &&a1;
+    case 2:
+    a2:
+      p = &&a2;
+    case 3:
+    a3:
+      p = &&a3;
+    case 4:
+    a4:
+      p = &&a4;
+    case 5:
+    a5:
+      p = &&a5;
+    case 6:
+    a6:
+      p = &&a6;
+    case 7:
+    a7:
+      p = &&a7;
+    case 8:
+    a8:
+      p = &&a8;
+    case 9:
+    a9:
+      p = &&a9;
+    case 10:
+    a10:
+      p = &&a10;
+    default:
+      p = &&a0;
+    }
+  goto *p;
+}
2012-02-09  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2012-01-05  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/44777
	* profile.c (branch_prob): Split bbs that have exit edge
	and need a fake entry edge too.

	* gcc.dg/tree-prof/pr44777.c: New test.

--- gcc/profile.c	(revision 182919)
+++ gcc/profile.c	(revision 182920)
@@ -989,6 +989,45 @@ branch_prob (void)
 	    fprintf (dump_file, "Adding fake entry edge to bb %i\n",
 		     bb->index);
 	  make_edge (ENTRY_BLOCK_PTR, bb, EDGE_FAKE);
+	  /* Avoid bbs that have both fake entry edge and also some
+	     exit edge.  One of those edges wouldn't be added to the
+	     spanning tree, but we can't instrument any of them.  */
+	  if (have_exit_edge || need_exit_edge)
+	    {
+	      gimple_stmt_iterator gsi;
+	      gimple first;
+	      tree fndecl;
+
+	      gsi = gsi_after_labels (bb);
+#ifdef ENABLE_CHECKING
+	      gcc_assert (!gsi_end_p (gsi));
+#endif
+	      first = gsi_stmt (gsi);
+	      if (is_gimple_debug (first))
+		{
+		  gsi_next_nondebug (&gsi);
+#ifdef ENABLE_CHECKING
+		  gcc_assert (!gsi_end_p (gsi));
+#endif
+		  first = gsi_stmt (gsi);
+		}
+	      /* Don't split the bbs containing __builtin_setjmp_receiver
+		 or __builtin_setjmp_dispatcher calls.  These are very
+		 special and don't expect anything to be inserted before
+		 them.  */
+	      if (!is_gimple_call (first)
+		  || (fndecl = gimple_call_fndecl (first)) == NULL
+		  || DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL
+		  || (DECL_FUNCTION_CODE (fndecl) != BUILT_IN_SETJMP_RECEIVER
+		      && (DECL_FUNCTION_CODE (fndecl)
+			  != BUILT_IN_SETJMP_DISPATCHER)))
+		{
+		  if (dump_file)
+		    fprintf (dump_file, "Splitting bb %i after labels\n",
+			     bb->index);
+		  split_block_after_labels (bb);
+		}
+	    }
 	}
     }
 
--- gcc/testsuite/gcc.dg/tree-prof/pr44777.c	(revision 0)
+++ gcc/testsuite/gcc.dg/tree-prof/pr44777.c	(revision 182920)
@@ -0,0 +1,43 @@
+/* PR middle-end/44777 */
+/* { dg-options "-O0" } */
+/* A variant of gcc.c-torture/execute/comp-goto-2.c.  */
+
+extern void abort (void);
+extern void exit (int);
+
+#ifdef STACK_SIZE
+#define DEPTH ((STACK_SIZE) / 512 + 1)
+#else
+#define DEPTH 1000
+#endif
+
+#if ! defined (NO_LABEL_VALUES) && !defined (NO_TRAMPOLINES)
+int
+x (int a)
+{
+  __label__ xlab;
+  void y (int a)
+    {
+      void *x = &&llab;
+      if (a==-1)
+	goto *x;
+      if (a==0)
+	goto xlab;
+    llab:
+      y (a-1);
+    }
+  y (a);
+ xlab:;
+  return a;
+}
+#endif
+
+int
+main ()
+{
+#if ! defined (NO_LABEL_VALUES) && !defined (NO_TRAMPOLINES)
+  if (x (DEPTH) != DEPTH)
+    abort ();
+#endif
+  exit (0);
+}
diff mbox

Patch

--- libiberty/make-relative-prefix.c	(revision 182819)
+++ libiberty/make-relative-prefix.c	(revision 183561)
@@ -58,6 +58,9 @@ 
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
 
 #include <string.h>
 
@@ -245,10 +248,15 @@ 
 	{
 	  char *startp, *endp, *nstore;
 	  size_t prefixlen = strlen (temp) + 1;
+	  size_t len;
 	  if (prefixlen < 2)
 	    prefixlen = 2;
 
-	  nstore = (char *) alloca (prefixlen + strlen (progname) + 1);
+	  len = prefixlen + strlen (progname) + 1;
+#ifdef HAVE_HOST_EXECUTABLE_SUFFIX
+	  len += strlen (HOST_EXECUTABLE_SUFFIX);
+#endif
+	  nstore = (char *) alloca (len);
 
 	  startp = endp = temp;
 	  while (1)
@@ -263,7 +271,7 @@ 
 		    }
 		  else
 		    {
-		      strncpy (nstore, startp, endp - startp);
+		      memcpy (nstore, startp, endp - startp);
 		      if (! IS_DIR_SEPARATOR (endp[-1]))
 			{
 			  nstore[endp - startp] = DIR_SEPARATOR;
@@ -279,8 +287,14 @@ 
 #endif
 		      )
 		    {
-		      progname = nstore;
-		      break;
+#if defined (HAVE_SYS_STAT_H) && defined (S_ISREG)
+		      struct stat st;
+		      if (stat (nstore, &st) >= 0 && S_ISREG (st.st_mode))
+#endif
+			{
+			  progname = nstore;
+			  break;
+			}
 		    }
 
 		  if (*endp == 0)