summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog15
-rw-r--r--gcc/alias.c3
-rw-r--r--gcc/cselib.c21
-rw-r--r--gcc/cselib.h2
-rw-r--r--gcc/rtl.h3
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/gcc.dg/guality/pr54796.c25
-rw-r--r--gcc/var-tracking.c18
8 files changed, 89 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index dfbc6118622..73c415632e6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,20 @@
2012-10-16 Jakub Jelinek <jakub@redhat.com>
+ PR debug/54796
+ * rtl.h: Document jump flag on VALUE.
+ * cselib.h (cselib_set_value_sp_based,
+ cselib_sp_based_value_p): New prototypes.
+ * alias.c (find_base_term): For cselib_sp_based_value_p
+ return static_reg_base_value[STACK_POINTER_REGNUM].
+ * cselib.c (SP_BASED_VALUE_P): Define.
+ (cselib_set_value_sp_based, cselib_sp_based_value_p): New functions.
+ * var-tracking.c (add_stores): Call cselib_set_value_sp_based
+ for not yet preserved VALUEs of sp on sp assignments if
+ hard_frame_pointer_adjustment != -1.
+ (vt_initialize): When setting hard_frame_pointer_adjustment,
+ disassociate sp from its previous value and call
+ cselib_set_value_sp_based on a new VALUE created for sp.
+
PR tree-optimization/54889
* tree-vect-stmts.c (vectorizable_load): Add VIEW_CONVERT_EXPR if
ARRAY_REF newref doesn't have compatible type with vectype element
diff --git a/gcc/alias.c b/gcc/alias.c
index 09aef1137ef..244ca520c92 100644
--- a/gcc/alias.c
+++ b/gcc/alias.c
@@ -1640,6 +1640,9 @@ find_base_term (rtx x)
if (!val)
return ret;
+ if (cselib_sp_based_value_p (val))
+ return static_reg_base_value[STACK_POINTER_REGNUM];
+
f = val->locs;
/* Temporarily reset val->locs to avoid infinite recursion. */
val->locs = NULL;
diff --git a/gcc/cselib.c b/gcc/cselib.c
index e7c4221df3e..1f9f97efc5d 100644
--- a/gcc/cselib.c
+++ b/gcc/cselib.c
@@ -210,6 +210,9 @@ void (*cselib_record_sets_hook) (rtx insn, struct cselib_set *sets,
#define PRESERVED_VALUE_P(RTX) \
(RTL_FLAG_CHECK1("PRESERVED_VALUE_P", (RTX), VALUE)->unchanging)
+#define SP_BASED_VALUE_P(RTX) \
+ (RTL_FLAG_CHECK1("SP_BASED_VALUE_P", (RTX), VALUE)->jump)
+
/* Allocate a struct elt_list and fill in its two elements with the
@@ -739,6 +742,24 @@ cselib_preserve_only_values (void)
gcc_assert (first_containing_mem == &dummy_val);
}
+/* Arrange for a value to be marked as based on stack pointer
+ for find_base_term purposes. */
+
+void
+cselib_set_value_sp_based (cselib_val *v)
+{
+ SP_BASED_VALUE_P (v->val_rtx) = 1;
+}
+
+/* Test whether a value is based on stack pointer for
+ find_base_term purposes. */
+
+bool
+cselib_sp_based_value_p (cselib_val *v)
+{
+ return SP_BASED_VALUE_P (v->val_rtx);
+}
+
/* Return the mode in which a register was last set. If X is not a
register, return its mode. If the mode in which the register was
set is not known, or the value was already clobbered, return
diff --git a/gcc/cselib.h b/gcc/cselib.h
index 96575f985e0..95fdbf7a5d5 100644
--- a/gcc/cselib.h
+++ b/gcc/cselib.h
@@ -99,6 +99,8 @@ extern void cselib_preserve_only_values (void);
extern void cselib_preserve_cfa_base_value (cselib_val *, unsigned int);
extern void cselib_add_permanent_equiv (cselib_val *, rtx, rtx);
extern bool cselib_have_permanent_equivalences (void);
+extern void cselib_set_value_sp_based (cselib_val *);
+extern bool cselib_sp_based_value_p (cselib_val *);
extern void dump_cselib_table (FILE *);
diff --git a/gcc/rtl.h b/gcc/rtl.h
index cd5d4352b86..a38924d2537 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -267,7 +267,8 @@ struct GTY((chain_next ("RTX_NEXT (&%h)"),
1 in a CALL_INSN if it is a sibling call.
1 in a SET that is for a return.
In a CODE_LABEL, part of the two-bit alternate entry field.
- 1 in a CONCAT is VAL_EXPR_IS_COPIED in var-tracking.c. */
+ 1 in a CONCAT is VAL_EXPR_IS_COPIED in var-tracking.c.
+ 1 in a VALUE is SP_BASED_VALUE_P in cselib.c. */
unsigned int jump : 1;
/* In a CODE_LABEL, part of the two-bit alternate entry field.
1 in a MEM if it cannot trap.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index babeba69d48..ea1e5ca1969 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
2012-10-16 Jakub Jelinek <jakub@redhat.com>
+ PR debug/54796
+ * gcc.dg/guality/pr54796.c: New test.
+
PR tree-optimization/54889
* gfortran.dg/pr54889.f90: New test.
diff --git a/gcc/testsuite/gcc.dg/guality/pr54796.c b/gcc/testsuite/gcc.dg/guality/pr54796.c
new file mode 100644
index 00000000000..f58e5a02cc6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/guality/pr54796.c
@@ -0,0 +1,25 @@
+/* PR debug/54796 */
+/* { dg-do run } */
+/* { dg-options "-g" } */
+
+__attribute__((noinline, noclone)) void
+bar (char *a, int b)
+{
+ __asm volatile ("" : "+r" (a), "+r" (b) : : "memory");
+}
+
+__attribute__((noinline, noclone)) void
+foo (int a, int b)
+{
+ int c = a;
+ char d[b]; /* { dg-final { gdb-test 17 "a" "5" } } */
+ bar (d, 2); /* { dg-final { gdb-test 17 "b" "6" } } */
+ bar (d, 4); /* { dg-final { gdb-test 17 "c" "5" } } */
+}
+
+int
+main ()
+{
+ foo (5, 6);
+ return 0;
+}
diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c
index 7e6bee3e130..65116c287e9 100644
--- a/gcc/var-tracking.c
+++ b/gcc/var-tracking.c
@@ -5769,6 +5769,11 @@ add_stores (rtx loc, const_rtx expr, void *cuip)
resolve = preserve = !cselib_preserved_value_p (v);
+ if (loc == stack_pointer_rtx
+ && hard_frame_pointer_adjustment != -1
+ && preserve)
+ cselib_set_value_sp_based (v);
+
nloc = replace_expr_with_values (oloc);
if (nloc)
oloc = nloc;
@@ -9867,6 +9872,19 @@ vt_initialize (void)
{
vt_init_cfa_base ();
hard_frame_pointer_adjustment = fp_cfa_offset;
+ /* Disassociate sp from fp now. */
+ if (MAY_HAVE_DEBUG_INSNS)
+ {
+ cselib_val *v;
+ cselib_invalidate_rtx (stack_pointer_rtx);
+ v = cselib_lookup (stack_pointer_rtx, Pmode, 1,
+ VOIDmode);
+ if (v && !cselib_preserved_value_p (v))
+ {
+ cselib_set_value_sp_based (v);
+ preserve_value (v);
+ }
+ }
}
}
}