summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authoraoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4>2012-02-25 12:09:27 +0000
committeraoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4>2012-02-25 12:09:27 +0000
commit0be329eff8728d984adb170591e01cd499de7a36 (patch)
tree6ab41affb99d878e95476613024ed2c4536fa5c6 /gcc
parenta617841ca2bb5f4abc8d14884193dce35df87ceb (diff)
downloadgcc-0be329eff8728d984adb170591e01cd499de7a36.tar.gz
PR debug/52001
* cselib.c (preserve_only_constants): Rename to... (preserve_constants_and_equivs): ... this. Split out... (invariant_or_equiv_p): ... this. Preserve plus expressions of other preserved expressions too. (cselib_reset_table): Adjust. * var-tracking.c (reverse_op): Use canonical value to build reverse operation. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@184571 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/cselib.c56
-rw-r--r--gcc/var-tracking.c4
3 files changed, 49 insertions, 22 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 121d74a6406..4a2c9fb6c2f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+2012-02-25 Alexandre Oliva <aoliva@redhat.com>
+
+ PR debug/52001
+ * cselib.c (preserve_only_constants): Rename to...
+ (preserve_constants_and_equivs): ... this. Split out...
+ (invariant_or_equiv_p): ... this. Preserve plus expressions
+ of other preserved expressions too.
+ (cselib_reset_table): Adjust.
+ * var-tracking.c (reverse_op): Use canonical value to build
+ reverse operation.
+
2012-02-23 Kai Tietz <ktietz@redhat.com>
* config/i386/i386.c (ix86_delegitimize_address): Handle
diff --git a/gcc/cselib.c b/gcc/cselib.c
index d7cb355fc33..4985357c83a 100644
--- a/gcc/cselib.c
+++ b/gcc/cselib.c
@@ -383,22 +383,29 @@ cselib_clear_table (void)
cselib_reset_table (1);
}
-/* Remove from hash table all VALUEs except constants
- and function invariants. */
+/* Return TRUE if V is a constant, a function invariant or a VALUE
+ equivalence; FALSE otherwise. */
-static int
-preserve_only_constants (void **x, void *info ATTRIBUTE_UNUSED)
+static bool
+invariant_or_equiv_p (cselib_val *v)
{
- cselib_val *v = (cselib_val *)*x;
struct elt_loc_list *l;
+ if (v == cfa_base_preserved_val)
+ return true;
+
+ /* Keep VALUE equivalences around. */
+ for (l = v->locs; l; l = l->next)
+ if (GET_CODE (l->loc) == VALUE)
+ return true;
+
if (v->locs != NULL
&& v->locs->next == NULL)
{
if (CONSTANT_P (v->locs->loc)
&& (GET_CODE (v->locs->loc) != CONST
|| !references_value_p (v->locs->loc, 0)))
- return 1;
+ return true;
/* Although a debug expr may be bound to different expressions,
we can preserve it as if it was constant, to get unification
and proper merging within var-tracking. */
@@ -406,24 +413,29 @@ preserve_only_constants (void **x, void *info ATTRIBUTE_UNUSED)
|| GET_CODE (v->locs->loc) == DEBUG_IMPLICIT_PTR
|| GET_CODE (v->locs->loc) == ENTRY_VALUE
|| GET_CODE (v->locs->loc) == DEBUG_PARAMETER_REF)
- return 1;
- if (cfa_base_preserved_val)
- {
- if (v == cfa_base_preserved_val)
- return 1;
- if (GET_CODE (v->locs->loc) == PLUS
- && CONST_INT_P (XEXP (v->locs->loc, 1))
- && XEXP (v->locs->loc, 0) == cfa_base_preserved_val->val_rtx)
- return 1;
- }
+ return true;
+
+ /* (plus (value V) (const_int C)) is invariant iff V is invariant. */
+ if (GET_CODE (v->locs->loc) == PLUS
+ && CONST_INT_P (XEXP (v->locs->loc, 1))
+ && GET_CODE (XEXP (v->locs->loc, 0)) == VALUE
+ && invariant_or_equiv_p (CSELIB_VAL_PTR (XEXP (v->locs->loc, 0))))
+ return true;
}
- /* Keep VALUE equivalences around. */
- for (l = v->locs; l; l = l->next)
- if (GET_CODE (l->loc) == VALUE)
- return 1;
+ return false;
+}
+
+/* Remove from hash table all VALUEs except constants, function
+ invariants and VALUE equivalences. */
+
+static int
+preserve_constants_and_equivs (void **x, void *info ATTRIBUTE_UNUSED)
+{
+ cselib_val *v = (cselib_val *)*x;
- htab_clear_slot (cselib_hash_table, x);
+ if (!invariant_or_equiv_p (v))
+ htab_clear_slot (cselib_hash_table, x);
return 1;
}
@@ -463,7 +475,7 @@ cselib_reset_table (unsigned int num)
}
if (cselib_preserve_constants)
- htab_traverse (cselib_hash_table, preserve_only_constants, NULL);
+ htab_traverse (cselib_hash_table, preserve_constants_and_equivs, NULL);
else
htab_empty (cselib_hash_table);
diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c
index e9b5ca886ae..c6280e2c1f1 100644
--- a/gcc/var-tracking.c
+++ b/gcc/var-tracking.c
@@ -5334,6 +5334,10 @@ reverse_op (rtx val, const_rtx expr, rtx insn)
if (!v || !cselib_preserved_value_p (v))
return;
+ /* Use canonical V to avoid creating multiple redundant expressions
+ for different VALUES equivalent to V. */
+ v = canonical_cselib_val (v);
+
/* Adding a reverse op isn't useful if V already has an always valid
location. Ignore ENTRY_VALUE, while it is always constant, we should
prefer non-ENTRY_VALUE locations whenever possible. */