aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Kenner <kenner@gcc.gnu.org>1994-02-05 08:05:42 -0500
committerRichard Kenner <kenner@gcc.gnu.org>1994-02-05 08:05:42 -0500
commit7bac1be089a8a64dbbaeba20856e5441b5f1794d (patch)
treefaf69af25525c459c820b307b367688fbeeff6d9
parent17a08984d38e8bc6cf581651a8dcc02ee2a11f26 (diff)
downloadgcc-7bac1be089a8a64dbbaeba20856e5441b5f1794d.zip
gcc-7bac1be089a8a64dbbaeba20856e5441b5f1794d.tar.gz
gcc-7bac1be089a8a64dbbaeba20856e5441b5f1794d.tar.bz2
(memory_extend_rtx): New variable.
(cse_main): Initialize it. (cse_insn): See if we have already loaded a MEM in a wider mode. From-SVN: r6484
-rw-r--r--gcc/cse.c61
1 files changed, 60 insertions, 1 deletions
diff --git a/gcc/cse.c b/gcc/cse.c
index 45e7d44..e2a49ef 100644
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -348,6 +348,12 @@ static int cse_jumps_altered;
static int do_not_record;
+#ifdef LOAD_EXTEND_OP
+
+/* Scratch rtl used when looking for load-extended copy of a MEM. */
+static rtx memory_extend_rtx;
+#endif
+
/* canon_hash stores 1 in hash_arg_in_memory
if it notices a reference to memory within the expression being hashed. */
@@ -6378,7 +6384,53 @@ cse_insn (insn, in_libcall_block)
}
}
}
-
+
+#ifdef LOAD_EXTEND_OP
+ /* See if a MEM has already been loaded with a widening operation;
+ if it has, we can use a subreg of that. Many CISC machines
+ also have such operations, but this is only likely to be
+ beneficial these machines. */
+
+ if (flag_expensive_optimizations && src_related == 0
+ && (GET_MODE_SIZE (mode) < UNITS_PER_WORD)
+ && GET_MODE_CLASS (mode) == MODE_INT
+ && GET_CODE (src) == MEM && ! do_not_record
+ && LOAD_EXTEND_OP (mode) != NIL)
+ {
+ enum machine_mode tmode;
+
+ /* Set what we are trying to extend and the operation it might
+ have been extended with. */
+ PUT_CODE (memory_extend_rtx, LOAD_EXTEND_OP (mode));
+ XEXP (memory_extend_rtx, 0) = src;
+
+ for (tmode = GET_MODE_WIDER_MODE (mode);
+ GET_MODE_SIZE (tmode) <= UNITS_PER_WORD;
+ tmode = GET_MODE_WIDER_MODE (tmode))
+ {
+ struct table_elt *larger_elt;
+
+ PUT_MODE (memory_extend_rtx, tmode);
+ larger_elt = lookup (memory_extend_rtx,
+ HASH (memory_extend_rtx, tmode), tmode);
+ if (larger_elt == 0)
+ continue;
+
+ for (larger_elt = larger_elt->first_same_value;
+ larger_elt; larger_elt = larger_elt->next_same_value)
+ if (GET_CODE (larger_elt->exp) == REG)
+ {
+ src_related = gen_lowpart_if_possible (mode,
+ larger_elt->exp);
+ break;
+ }
+
+ if (src_related)
+ break;
+ }
+ }
+#endif /* LOAD_EXTEND_OP */
+
if (src == src_folded)
src_folded = 0;
@@ -7916,6 +7968,13 @@ cse_main (f, nregs, after_loop, file)
reg_in_table = (int *) alloca (nregs * sizeof (int));
reg_tick = (int *) alloca (nregs * sizeof (int));
+#ifdef LOAD_EXTEND_OP
+
+ /* Allocate scratch rtl here. cse_insn will fill in the memory reference
+ and change the code and mode as appropriate. */
+ memory_extend_rtx = gen_rtx (ZERO_EXTEND, VOIDmode, 0);
+#endif
+
/* Discard all the free elements of the previous function
since they are allocated in the temporarily obstack. */
bzero (table, sizeof table);