aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2001-01-23 19:36:06 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2001-01-23 19:36:06 +0100
commit96e60f0c1a31d4a76905e01d583f4c62b19fd6d1 (patch)
treef1ed9d3a3aa4c282e6afcb7e636e652eec822c8f
parent909b968ecb78bdc07303dffc5fcd26d9c7a8f722 (diff)
downloadgcc-96e60f0c1a31d4a76905e01d583f4c62b19fd6d1.zip
gcc-96e60f0c1a31d4a76905e01d583f4c62b19fd6d1.tar.gz
gcc-96e60f0c1a31d4a76905e01d583f4c62b19fd6d1.tar.bz2
integrate.h (struct inline_remap): Add compare_src, compare_mode.
* integrate.h (struct inline_remap): Add compare_src, compare_mode. * integrate.c (expand_inline_function): Initialize them. (subst_constants): If changing COMPARE so that both its arguments will be VOIDmode and the comparison mode will be lost, note compare_mode. Use the recorded compare_mode to optimize IF_THEN_ELSE. From-SVN: r39203
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/integrate.c68
-rw-r--r--gcc/integrate.h4
3 files changed, 77 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 59047cb..d227b85 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2001-01-23 Jakub Jelinek <jakub@redhat.com>
+
+ * integrate.h (struct inline_remap): Add compare_src, compare_mode.
+ * integrate.c (expand_inline_function): Initialize them.
+ (subst_constants): If changing COMPARE so that both its arguments
+ will be VOIDmode and the comparison mode will be lost, note
+ compare_mode. Use the recorded compare_mode to optimize
+ IF_THEN_ELSE.
+
2001-01-23 Jason Merrill <jason@redhat.com>
* dwarf2out.c (new_die): Use xcalloc.
diff --git a/gcc/integrate.c b/gcc/integrate.c
index 9859a02..bfcd85b 100644
--- a/gcc/integrate.c
+++ b/gcc/integrate.c
@@ -788,6 +788,8 @@ expand_inline_function (fndecl, parms, target, ignore, type,
map->max_insnno = inl_max_uid;
map->integrating = 1;
+ map->compare_src = NULL_RTX;
+ map->compare_mode = VOIDmode;
/* const_equiv_varray maps pseudos in our routine to constants, so
it needs to be large enough for all our pseudos. This is the
@@ -2440,6 +2442,25 @@ subst_constants (loc, insn, map, memonly)
rtx *dest_loc = &SET_DEST (x);
rtx dest = *dest_loc;
rtx src, tem;
+ enum machine_mode compare_mode = VOIDmode;
+
+ /* If SET_SRC is a COMPARE which subst_constants would turn into
+ COMPARE of 2 VOIDmode constants, note the mode in which comparison
+ is to be done. */
+ if (GET_CODE (SET_SRC (x)) == COMPARE)
+ {
+ src = SET_SRC (x);
+ if (GET_MODE_CLASS (GET_MODE (src)) == MODE_CC
+#ifdef HAVE_cc0
+ || dest == cc0_rtx
+#endif
+ )
+ {
+ compare_mode = GET_MODE (XEXP (src, 0));
+ if (compare_mode == VOIDmode)
+ compare_mode = GET_MODE (XEXP (src, 1));
+ }
+ }
subst_constants (&SET_SRC (x), insn, map, memonly);
src = SET_SRC (x);
@@ -2495,8 +2516,22 @@ subst_constants (loc, insn, map, memonly)
/* Normally, this copy won't do anything. But, if SRC is a COMPARE
it will cause us to save the COMPARE with any constants
substituted, which is what we want for later. */
- map->equiv_sets[map->num_sets].equiv = copy_rtx (src);
+ rtx src_copy = copy_rtx (src);
+ map->equiv_sets[map->num_sets].equiv = src_copy;
map->equiv_sets[map->num_sets++].dest = dest;
+ if (compare_mode != VOIDmode
+ && GET_CODE (src) == COMPARE
+ && (GET_MODE_CLASS (GET_MODE (src)) == MODE_CC
+#ifdef HAVE_cc0
+ || dest == cc0_rtx
+#endif
+ )
+ && GET_MODE (XEXP (src, 0)) == VOIDmode
+ && GET_MODE (XEXP (src, 1)) == VOIDmode)
+ {
+ map->compare_src = src_copy;
+ map->compare_mode = compare_mode;
+ }
}
}
return;
@@ -2600,9 +2635,34 @@ subst_constants (loc, insn, map, memonly)
if (op0_mode == MAX_MACHINE_MODE)
abort ();
- new = simplify_ternary_operation (code, GET_MODE (x), op0_mode,
- XEXP (x, 0), XEXP (x, 1),
- XEXP (x, 2));
+ if (code == IF_THEN_ELSE)
+ {
+ rtx op0 = XEXP (x, 0);
+
+ if (GET_RTX_CLASS (GET_CODE (op0)) == '<'
+ && GET_MODE (op0) == VOIDmode
+ && ! side_effects_p (op0)
+ && XEXP (op0, 0) == map->compare_src
+ && GET_MODE (XEXP (op0, 1)) == VOIDmode)
+ {
+ /* We have compare of two VOIDmode constants for which
+ we recorded the comparison mode. */
+ rtx temp =
+ simplify_relational_operation (GET_CODE (op0),
+ map->compare_mode,
+ XEXP (op0, 0),
+ XEXP (op0, 1));
+
+ if (temp == const0_rtx)
+ new = XEXP (x, 2);
+ else if (temp == const1_rtx)
+ new = XEXP (x, 1);
+ }
+ }
+ if (!new)
+ new = simplify_ternary_operation (code, GET_MODE (x), op0_mode,
+ XEXP (x, 0), XEXP (x, 1),
+ XEXP (x, 2));
break;
}
diff --git a/gcc/integrate.h b/gcc/integrate.h
index 794276b..51fced4 100644
--- a/gcc/integrate.h
+++ b/gcc/integrate.h
@@ -112,6 +112,10 @@ struct inline_remap
/* Record the last thing assigned to cc0. */
rtx last_cc0_value;
#endif
+ /* Note mode of COMPARE if the mode would be otherwise lost (comparing of
+ two VOIDmode constants. */
+ rtx compare_src;
+ enum machine_mode compare_mode;
};
/* Return a copy of an rtx (as needed), substituting pseudo-register,