summaryrefslogtreecommitdiff
path: root/gnu/usr.bin/gcc/f/gbe/2.7.2.2.diff
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/usr.bin/gcc/f/gbe/2.7.2.2.diff')
-rw-r--r--gnu/usr.bin/gcc/f/gbe/2.7.2.2.diff4100
1 files changed, 0 insertions, 4100 deletions
diff --git a/gnu/usr.bin/gcc/f/gbe/2.7.2.2.diff b/gnu/usr.bin/gcc/f/gbe/2.7.2.2.diff
deleted file mode 100644
index 80903bed46f..00000000000
--- a/gnu/usr.bin/gcc/f/gbe/2.7.2.2.diff
+++ /dev/null
@@ -1,4100 +0,0 @@
-IMPORTANT: After applying this patch, you must rebuild the
-Info documentation derived from the Texinfo files in the
-gcc distribution, as this patch does not include patches
-to any derived files (due to differences in the way gcc
-version 2.7.2.2 is obtained by users). Use the following
-command sequence after applying this patch:
-
- cd gcc-2.7.2.2; make -f Makefile.in gcc.info
-
-If that fails due to `makeinfo' not being installed, obtain
-texinfo-3.9.tar.gz from a GNU distribution site, unpack,
-build, and install it, and try the above command sequence
-again.
-
-
-diff -rcp2N gcc-2.7.2.2/ChangeLog gcc-2.7.2.2.f.2/ChangeLog
-*** gcc-2.7.2.2/ChangeLog Thu Feb 20 19:24:10 1997
---- gcc-2.7.2.2.f.2/ChangeLog Thu Feb 27 23:04:00 1997
-***************
-*** 1,2 ****
---- 1,69 ----
-+ Wed Feb 26 13:09:33 1997 Michael Meissner <meissner@cygnus.com>
-+
-+ * reload.c (debug_reload): Fix format string to print
-+ reload_nocombine[r].
-+
-+ Sun Feb 23 15:26:53 1997 Craig Burley <burley@gnu.ai.mit.edu>
-+
-+ * fold-const.c (multiple_of_p): Clean up and improve.
-+ (fold): Clean up invocation of multiple_of_p.
-+
-+ Sat Feb 8 04:53:27 1997 Craig Burley <burley@gnu.ai.mit.edu>
-+
-+ From <jfc@jfc.tiac.net> Fri, 07 Feb 1997 22:02:21 -0500:
-+ * alias.c (init_alias_analysis): Reduce amount of time
-+ needed to simplify the reg_base_value array in the
-+ typical case (especially involving function inlining).
-+
-+ Fri Jan 10 17:22:17 1997 Craig Burley <burley@gnu.ai.mit.edu>
-+
-+ Minor improvements/fixes to better alias handling:
-+ * Makefile.in (alias.o): Fix typo in rule (was RLT_H).
-+ * cse.c, sched.c: Fix up some indenting.
-+ * toplev.c: Add -fargument-alias flag, so Fortran users
-+ can turn C-style aliasing on once g77 defaults to
-+ -fargument-noalias-global.
-+
-+ Integrate patch for better alias handling from
-+ John Carr <jfc@mit.edu>:
-+ * Makefile.in (OBJS, alias.o): New module and rule.
-+ * alias.c: New source module.
-+ * calls.c (expand_call): Recognize alias status of calls
-+ to malloc().
-+ * combine.c (distribute_notes): New REG_NOALIAS note.
-+ * rtl.h (REG_NOALIAS): Ditto.
-+ Many other changes for new alias.c module.
-+ * cse.c: Many changes, and much code moved into alias.c.
-+ * flags.h (flag_alias_check, flag_argument_noalias):
-+ New flags.
-+ * toplev.c: New flags and related options.
-+ * local-alloc.c (validate_equiv_mem_from_store):
-+ Caller of true_dependence changed.
-+ * loop.c (NUM_STORES): Increase to 50 from 20.
-+ (prescan_loop): "const" functions don't alter unknown addresses.
-+ (invariant_p): Caller of true_dependence changed.
-+ (record_giv): Zero new unrolled and shared flags.
-+ (emit_iv_add_mult): Record base value for register.
-+ * sched.c: Many changes, mostly moving code to alias.c.
-+ (sched_note_set): SCHED_SORT macro def form, but not function,
-+ inexplicably changed.
-+ * unroll.c: Record base values for registers, etc.
-+
-+ Fri Jan 3 04:01:00 1997 Craig Burley <burley@gnu.ai.mit.edu>
-+
-+ * loop.c (check_final_value): Handle insns with no luid's
-+ appropriately, instead of crashing on INSN_LUID macro
-+ invocations.
-+
-+ Mon Dec 23 00:49:19 1996 Craig Burley <burley@gnu.ai.mit.edu>
-+
-+ * config/alpha/alpha.md: Fix pattern that matches if_then_else
-+ involving DF target, DF comparison, SF source.
-+
-+ Fri Dec 20 15:42:52 1996 Craig Burley <burley@gnu.ai.mit.edu>
-+
-+ * fold-const.c (multiple_of_p): New function.
-+ (fold): Use new function to turn *_DIV_EXPR into EXACT_DIV_EXPR.
-+
- Sat Jun 29 12:33:39 1996 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
-diff -rcp2N gcc-2.7.2.2/Makefile.in gcc-2.7.2.2.f.2/Makefile.in
-*** gcc-2.7.2.2/Makefile.in Sun Nov 26 14:44:25 1995
---- gcc-2.7.2.2.f.2/Makefile.in Sun Feb 23 16:36:34 1997
-*************** OBJS = toplev.o version.o tree.o print-t
-*** 519,523 ****
- integrate.o jump.o cse.o loop.o unroll.o flow.o stupid.o combine.o \
- regclass.o local-alloc.o global.o reload.o reload1.o caller-save.o \
-! insn-peep.o reorg.o sched.o final.o recog.o reg-stack.o \
- insn-opinit.o insn-recog.o insn-extract.o insn-output.o insn-emit.o \
- insn-attrtab.o $(out_object_file) getpwd.o convert.o $(EXTRA_OBJS)
---- 519,523 ----
- integrate.o jump.o cse.o loop.o unroll.o flow.o stupid.o combine.o \
- regclass.o local-alloc.o global.o reload.o reload1.o caller-save.o \
-! insn-peep.o reorg.o alias.o sched.o final.o recog.o reg-stack.o \
- insn-opinit.o insn-recog.o insn-extract.o insn-output.o insn-emit.o \
- insn-attrtab.o $(out_object_file) getpwd.o convert.o $(EXTRA_OBJS)
-*************** reorg.o : reorg.c $(CONFIG_H) $(RTL_H) c
-*** 1238,1241 ****
---- 1238,1242 ----
- basic-block.h regs.h insn-config.h insn-attr.h insn-flags.h recog.h \
- flags.h output.h
-+ alias.o : $(CONFIG_H) $(RTL_H) flags.h hard-reg-set.h regs.h
- sched.o : sched.c $(CONFIG_H) $(RTL_H) basic-block.h regs.h hard-reg-set.h \
- flags.h insn-config.h insn-attr.h
-diff -rcp2N gcc-2.7.2.2/alias.c gcc-2.7.2.2.f.2/alias.c
-*** gcc-2.7.2.2/alias.c Wed Dec 31 19:00:00 1969
---- gcc-2.7.2.2.f.2/alias.c Sat Feb 8 04:53:07 1997
-***************
-*** 0 ****
---- 1,989 ----
-+ /* Alias analysis for GNU C, by John Carr (jfc@mit.edu).
-+ Derived in part from sched.c */
-+ #include "config.h"
-+ #include "rtl.h"
-+ #include "expr.h"
-+ #include "regs.h"
-+ #include "hard-reg-set.h"
-+ #include "flags.h"
-+
-+ static rtx canon_rtx PROTO((rtx));
-+ static int rtx_equal_for_memref_p PROTO((rtx, rtx));
-+ static rtx find_symbolic_term PROTO((rtx));
-+ static int memrefs_conflict_p PROTO((int, rtx, int, rtx,
-+ HOST_WIDE_INT));
-+
-+ /* Set up all info needed to perform alias analysis on memory references. */
-+
-+ #define SIZE_FOR_MODE(X) (GET_MODE_SIZE (GET_MODE (X)))
-+
-+ /* reg_base_value[N] gives an address to which register N is related.
-+ If all sets after the first add or subtract to the current value
-+ or otherwise modify it so it does not point to a different top level
-+ object, reg_base_value[N] is equal to the address part of the source
-+ of the first set. The value will be a SYMBOL_REF, a LABEL_REF, or
-+ (address (reg)) to indicate that the address is derived from an
-+ argument or fixed register. */
-+ rtx *reg_base_value;
-+ unsigned int reg_base_value_size; /* size of reg_base_value array */
-+ #define REG_BASE_VALUE(X) \
-+ (REGNO (X) < reg_base_value_size ? reg_base_value[REGNO (X)] : 0)
-+
-+ /* Vector indexed by N giving the initial (unchanging) value known
-+ for pseudo-register N. */
-+ rtx *reg_known_value;
-+
-+ /* Indicates number of valid entries in reg_known_value. */
-+ static int reg_known_value_size;
-+
-+ /* Vector recording for each reg_known_value whether it is due to a
-+ REG_EQUIV note. Future passes (viz., reload) may replace the
-+ pseudo with the equivalent expression and so we account for the
-+ dependences that would be introduced if that happens. */
-+ /* ??? This is a problem only on the Convex. The REG_EQUIV notes created in
-+ assign_parms mention the arg pointer, and there are explicit insns in the
-+ RTL that modify the arg pointer. Thus we must ensure that such insns don't
-+ get scheduled across each other because that would invalidate the REG_EQUIV
-+ notes. One could argue that the REG_EQUIV notes are wrong, but solving
-+ the problem in the scheduler will likely give better code, so we do it
-+ here. */
-+ char *reg_known_equiv_p;
-+
-+ /* Inside SRC, the source of a SET, find a base address. */
-+
-+ /* When copying arguments into pseudo-registers, record the (ADDRESS)
-+ expression for the argument directly so that even if the argument
-+ register is changed later (e.g. for a function call) the original
-+ value is noted. */
-+ static int copying_arguments;
-+
-+ static rtx
-+ find_base_value (src)
-+ register rtx src;
-+ {
-+ switch (GET_CODE (src))
-+ {
-+ case SYMBOL_REF:
-+ case LABEL_REF:
-+ return src;
-+
-+ case REG:
-+ if (copying_arguments && REGNO (src) < FIRST_PSEUDO_REGISTER)
-+ return reg_base_value[REGNO (src)];
-+ return src;
-+
-+ case MEM:
-+ /* Check for an argument passed in memory. Only record in the
-+ copying-arguments block; it is too hard to track changes
-+ otherwise. */
-+ if (copying_arguments
-+ && (XEXP (src, 0) == arg_pointer_rtx
-+ || (GET_CODE (XEXP (src, 0)) == PLUS
-+ && XEXP (XEXP (src, 0), 0) == arg_pointer_rtx)))
-+ return gen_rtx (ADDRESS, VOIDmode, src);
-+ return 0;
-+
-+ case CONST:
-+ src = XEXP (src, 0);
-+ if (GET_CODE (src) != PLUS && GET_CODE (src) != MINUS)
-+ break;
-+ /* fall through */
-+ case PLUS:
-+ case MINUS:
-+ /* Guess which operand to set the register equivalent to. */
-+ /* If the first operand is a symbol or the second operand is
-+ an integer, the first operand is the base address. */
-+ if (GET_CODE (XEXP (src, 0)) == SYMBOL_REF
-+ || GET_CODE (XEXP (src, 0)) == LABEL_REF
-+ || GET_CODE (XEXP (src, 1)) == CONST_INT)
-+ return XEXP (src, 0);
-+ /* If an operand is a register marked as a pointer, it is the base. */
-+ if (GET_CODE (XEXP (src, 0)) == REG
-+ && REGNO_POINTER_FLAG (REGNO (XEXP (src, 0))))
-+ src = XEXP (src, 0);
-+ else if (GET_CODE (XEXP (src, 1)) == REG
-+ && REGNO_POINTER_FLAG (REGNO (XEXP (src, 1))))
-+ src = XEXP (src, 1);
-+ else
-+ return 0;
-+ if (copying_arguments && REGNO (src) < FIRST_PSEUDO_REGISTER)
-+ return reg_base_value[REGNO (src)];
-+ return src;
-+
-+ case AND:
-+ /* If the second operand is constant set the base
-+ address to the first operand. */
-+ if (GET_CODE (XEXP (src, 1)) == CONST_INT
-+ && GET_CODE (XEXP (src, 0)) == REG)
-+ {
-+ src = XEXP (src, 0);
-+ if (copying_arguments && REGNO (src) < FIRST_PSEUDO_REGISTER)
-+ return reg_base_value[REGNO (src)];
-+ return src;
-+ }
-+ return 0;
-+
-+ case HIGH:
-+ return XEXP (src, 0);
-+ }
-+
-+ return 0;
-+ }
-+
-+ /* Called from init_alias_analysis indirectly through note_stores. */
-+
-+ /* while scanning insns to find base values, reg_seen[N] is nonzero if
-+ register N has been set in this function. */
-+ static char *reg_seen;
-+
-+ static
-+ void record_set (dest, set)
-+ rtx dest, set;
-+ {
-+ register int regno;
-+ rtx src;
-+
-+ if (GET_CODE (dest) != REG)
-+ return;
-+
-+ regno = REGNO (dest);
-+
-+ if (set)
-+ {
-+ /* A CLOBBER wipes out any old value but does not prevent a previously
-+ unset register from acquiring a base address (i.e. reg_seen is not
-+ set). */
-+ if (GET_CODE (set) == CLOBBER)
-+ {
-+ reg_base_value[regno] = 0;
-+ return;
-+ }
-+ src = SET_SRC (set);
-+ }
-+ else
-+ {
-+ static int unique_id;
-+ if (reg_seen[regno])
-+ {
-+ reg_base_value[regno] = 0;
-+ return;
-+ }
-+ reg_seen[regno] = 1;
-+ reg_base_value[regno] = gen_rtx (ADDRESS, Pmode,
-+ GEN_INT (unique_id++));
-+ return;
-+ }
-+
-+ /* This is not the first set. If the new value is not related to the
-+ old value, forget the base value. Note that the following code is
-+ not detected:
-+ extern int x, y; int *p = &x; p += (&y-&x);
-+ ANSI C does not allow computing the difference of addresses
-+ of distinct top level objects. */
-+ if (reg_base_value[regno])
-+ switch (GET_CODE (src))
-+ {
-+ case PLUS:
-+ case MINUS:
-+ if (XEXP (src, 0) != dest && XEXP (src, 1) != dest)
-+ reg_base_value[regno] = 0;
-+ break;
-+ case AND:
-+ if (XEXP (src, 0) != dest || GET_CODE (XEXP (src, 1)) != CONST_INT)
-+ reg_base_value[regno] = 0;
-+ break;
-+ case LO_SUM:
-+ if (XEXP (src, 0) != dest)
-+ reg_base_value[regno] = 0;
-+ break;
-+ default:
-+ reg_base_value[regno] = 0;
-+ break;
-+ }
-+ /* If this is the first set of a register, record the value. */
-+ else if ((regno >= FIRST_PSEUDO_REGISTER || ! fixed_regs[regno])
-+ && ! reg_seen[regno] && reg_base_value[regno] == 0)
-+ reg_base_value[regno] = find_base_value (src);
-+
-+ reg_seen[regno] = 1;
-+ }
-+
-+ /* Called from loop optimization when a new pseudo-register is created. */
-+ void
-+ record_base_value (regno, val)
-+ int regno;
-+ rtx val;
-+ {
-+ if (!flag_alias_check || regno >= reg_base_value_size)
-+ return;
-+ if (GET_CODE (val) == REG)
-+ {
-+ if (REGNO (val) < reg_base_value_size)
-+ reg_base_value[regno] = reg_base_value[REGNO (val)];
-+ return;
-+ }
-+ reg_base_value[regno] = find_base_value (val);
-+ }
-+
-+ static rtx
-+ canon_rtx (x)
-+ rtx x;
-+ {
-+ /* Recursively look for equivalences. */
-+ if (GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER
-+ && REGNO (x) < reg_known_value_size)
-+ return reg_known_value[REGNO (x)] == x
-+ ? x : canon_rtx (reg_known_value[REGNO (x)]);
-+ else if (GET_CODE (x) == PLUS)
-+ {
-+ rtx x0 = canon_rtx (XEXP (x, 0));
-+ rtx x1 = canon_rtx (XEXP (x, 1));
-+
-+ if (x0 != XEXP (x, 0) || x1 != XEXP (x, 1))
-+ {
-+ /* We can tolerate LO_SUMs being offset here; these
-+ rtl are used for nothing other than comparisons. */
-+ if (GET_CODE (x0) == CONST_INT)
-+ return plus_constant_for_output (x1, INTVAL (x0));
-+ else if (GET_CODE (x1) == CONST_INT)
-+ return plus_constant_for_output (x0, INTVAL (x1));
-+ return gen_rtx (PLUS, GET_MODE (x), x0, x1);
-+ }
-+ }
-+ /* This gives us much better alias analysis when called from
-+ the loop optimizer. Note we want to leave the original
-+ MEM alone, but need to return the canonicalized MEM with
-+ all the flags with their original values. */
-+ else if (GET_CODE (x) == MEM)
-+ {
-+ rtx addr = canon_rtx (XEXP (x, 0));
-+ if (addr != XEXP (x, 0))
-+ {
-+ rtx new = gen_rtx (MEM, GET_MODE (x), addr);
-+ MEM_VOLATILE_P (new) = MEM_VOLATILE_P (x);
-+ RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (x);
-+ MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (x);
-+ x = new;
-+ }
-+ }
-+ return x;
-+ }
-+
-+ /* Return 1 if X and Y are identical-looking rtx's.
-+
-+ We use the data in reg_known_value above to see if two registers with
-+ different numbers are, in fact, equivalent. */
-+
-+ static int
-+ rtx_equal_for_memref_p (x, y)
-+ rtx x, y;
-+ {
-+ register int i;
-+ register int j;
-+ register enum rtx_code code;
-+ register char *fmt;
-+
-+ if (x == 0 && y == 0)
-+ return 1;
-+ if (x == 0 || y == 0)
-+ return 0;
-+ x = canon_rtx (x);
-+ y = canon_rtx (y);
-+
-+ if (x == y)
-+ return 1;
-+
-+ code = GET_CODE (x);
-+ /* Rtx's of different codes cannot be equal. */
-+ if (code != GET_CODE (y))
-+ return 0;
-+
-+ /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent.
-+ (REG:SI x) and (REG:HI x) are NOT equivalent. */
-+
-+ if (GET_MODE (x) != GET_MODE (y))
-+ return 0;
-+
-+ /* REG, LABEL_REF, and SYMBOL_REF can be compared nonrecursively. */
-+
-+ if (code == REG)
-+ return REGNO (x) == REGNO (y);
-+ if (code == LABEL_REF)
-+ return XEXP (x, 0) == XEXP (y, 0);
-+ if (code == SYMBOL_REF)
-+ return XSTR (x, 0) == XSTR (y, 0);
-+
-+ /* For commutative operations, the RTX match if the operand match in any
-+ order. Also handle the simple binary and unary cases without a loop. */
-+ if (code == EQ || code == NE || GET_RTX_CLASS (code) == 'c')
-+ return ((rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 0))
-+ && rtx_equal_for_memref_p (XEXP (x, 1), XEXP (y, 1)))
-+ || (rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 1))
-+ && rtx_equal_for_memref_p (XEXP (x, 1), XEXP (y, 0))));
-+ else if (GET_RTX_CLASS (code) == '<' || GET_RTX_CLASS (code) == '2')
-+ return (rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 0))
-+ && rtx_equal_for_memref_p (XEXP (x, 1), XEXP (y, 1)));
-+ else if (GET_RTX_CLASS (code) == '1')
-+ return rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 0));
-+
-+ /* Compare the elements. If any pair of corresponding elements
-+ fail to match, return 0 for the whole things. */
-+
-+ fmt = GET_RTX_FORMAT (code);
-+ for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
-+ {
-+ switch (fmt[i])
-+ {
-+ case 'w':
-+ if (XWINT (x, i) != XWINT (y, i))
-+ return 0;
-+ break;
-+
-+ case 'n':
-+ case 'i':
-+ if (XINT (x, i) != XINT (y, i))
-+ return 0;
-+ break;
-+
-+ case 'V':
-+ case 'E':
-+ /* Two vectors must have the same length. */
-+ if (XVECLEN (x, i) != XVECLEN (y, i))
-+ return 0;
-+
-+ /* And the corresponding elements must match. */
-+ for (j = 0; j < XVECLEN (x, i); j++)
-+ if (rtx_equal_for_memref_p (XVECEXP (x, i, j), XVECEXP (y, i, j)) == 0)
-+ return 0;
-+ break;
-+
-+ case 'e':
-+ if (rtx_equal_for_memref_p (XEXP (x, i), XEXP (y, i)) == 0)
-+ return 0;
-+ break;
-+
-+ case 'S':
-+ case 's':
-+ if (strcmp (XSTR (x, i), XSTR (y, i)))
-+ return 0;
-+ break;
-+
-+ case 'u':
-+ /* These are just backpointers, so they don't matter. */
-+ break;
-+
-+ case '0':
-+ break;
-+
-+ /* It is believed that rtx's at this level will never
-+ contain anything but integers and other rtx's,
-+ except for within LABEL_REFs and SYMBOL_REFs. */
-+ default:
-+ abort ();
-+ }
-+ }
-+ return 1;
-+ }
-+
-+ /* Given an rtx X, find a SYMBOL_REF or LABEL_REF within
-+ X and return it, or return 0 if none found. */
-+
-+ static rtx
-+ find_symbolic_term (x)
-+ rtx x;
-+ {
-+ register int i;
-+ register enum rtx_code code;
-+ register char *fmt;
-+
-+ code = GET_CODE (x);
-+ if (code == SYMBOL_REF || code == LABEL_REF)
-+ return x;
-+ if (GET_RTX_CLASS (code) == 'o')
-+ return 0;
-+
-+ fmt = GET_RTX_FORMAT (code);
-+ for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
-+ {
-+ rtx t;
-+
-+ if (fmt[i] == 'e')
-+ {
-+ t = find_symbolic_term (XEXP (x, i));
-+ if (t != 0)
-+ return t;
-+ }
-+ else if (fmt[i] == 'E')
-+ break;
-+ }
-+ return 0;
-+ }
-+
-+ static rtx
-+ find_base_term (x)
-+ rtx x;
-+ {
-+ switch (GET_CODE (x))
-+ {
-+ case REG:
-+ return REG_BASE_VALUE (x);
-+
-+ case HIGH:
-+ return find_base_value (XEXP (x, 0));
-+
-+ case CONST:
-+ x = XEXP (x, 0);
-+ if (GET_CODE (x) != PLUS && GET_CODE (x) != MINUS)
-+ return 0;
-+ /* fall through */
-+ case LO_SUM:
-+ case PLUS:
-+ case MINUS:
-+ {
-+ rtx tmp = find_base_term (XEXP (x, 0));
-+ if (tmp)
-+ return tmp;
-+ return find_base_term (XEXP (x, 1));
-+ }
-+
-+ case AND:
-+ if (GET_CODE (XEXP (x, 0)) == REG && GET_CODE (XEXP (x, 1)) == CONST_INT)
-+ return REG_BASE_VALUE (XEXP (x, 0));
-+ return 0;
-+
-+ case SYMBOL_REF:
-+ case LABEL_REF:
-+ return x;
-+
-+ default:
-+ return 0;
-+ }
-+ }
-+
-+ /* Return 0 if the addresses X and Y are known to point to different
-+ objects, 1 if they might be pointers to the same object. */
-+
-+ static int
-+ base_alias_check (x, y)
-+ rtx x, y;
-+ {
-+ rtx x_base = find_base_term (x);
-+ rtx y_base = find_base_term (y);
-+
-+ /* If either base address is unknown or the base addresses are equal,
-+ nothing is known about aliasing. */
-+ if (x_base == 0 || y_base == 0 || rtx_equal_p (x_base, y_base))
-+ return 1;
-+
-+ /* The base addresses of the read and write are different
-+ expressions. If they are both symbols there is no
-+ conflict. */
-+ if (GET_CODE (x_base) != ADDRESS && GET_CODE (y_base) != ADDRESS)
-+ return 0;
-+
-+ /* If one address is a stack reference there can be no alias:
-+ stack references using different base registers do not alias,
-+ a stack reference can not alias a parameter, and a stack reference
-+ can not alias a global. */
-+ if ((GET_CODE (x_base) == ADDRESS && GET_MODE (x_base) == Pmode)
-+ || (GET_CODE (y_base) == ADDRESS && GET_MODE (y_base) == Pmode))
-+ return 0;
-+
-+ if (! flag_argument_noalias)
-+ return 1;
-+
-+ if (flag_argument_noalias > 1)
-+ return 0;
-+
-+ /* Weak noalias assertion (arguments are distinct, but may match globals). */
-+ return ! (GET_MODE (x_base) == VOIDmode && GET_MODE (y_base) == VOIDmode);
-+ }
-+
-+ /* Return nonzero if X and Y (memory addresses) could reference the
-+ same location in memory. C is an offset accumulator. When
-+ C is nonzero, we are testing aliases between X and Y + C.
-+ XSIZE is the size in bytes of the X reference,
-+ similarly YSIZE is the size in bytes for Y.
-+
-+ If XSIZE or YSIZE is zero, we do not know the amount of memory being
-+ referenced (the reference was BLKmode), so make the most pessimistic
-+ assumptions.
-+
-+ We recognize the following cases of non-conflicting memory:
-+
-+ (1) addresses involving the frame pointer cannot conflict
-+ with addresses involving static variables.
-+ (2) static variables with different addresses cannot conflict.
-+
-+ Nice to notice that varying addresses cannot conflict with fp if no
-+ local variables had their addresses taken, but that's too hard now. */
-+
-+
-+ static int
-+ memrefs_conflict_p (xsize, x, ysize, y, c)
-+ register rtx x, y;
-+ int xsize, ysize;
-+ HOST_WIDE_INT c;
-+ {
-+ if (GET_CODE (x) == HIGH)
-+ x = XEXP (x, 0);
-+ else if (GET_CODE (x) == LO_SUM)
-+ x = XEXP (x, 1);
-+ else
-+ x = canon_rtx (x);
-+ if (GET_CODE (y) == HIGH)
-+ y = XEXP (y, 0);
-+ else if (GET_CODE (y) == LO_SUM)
-+ y = XEXP (y, 1);
-+ else
-+ y = canon_rtx (y);
-+
-+ if (rtx_equal_for_memref_p (x, y))
-+ {
-+ if (xsize == 0 || ysize == 0)
-+ return 1;
-+ if (c >= 0 && xsize > c)
-+ return 1;
-+ if (c < 0 && ysize+c > 0)
-+ return 1;
-+ return 0;
-+ }
-+
-+ if (y == frame_pointer_rtx || y == hard_frame_pointer_rtx
-+ || y == stack_pointer_rtx)
-+ {
-+ rtx t = y;
-+ int tsize = ysize;
-+ y = x; ysize = xsize;
-+ x = t; xsize = tsize;
-+ }
-+
-+ if (x == frame_pointer_rtx || x == hard_frame_pointer_rtx
-+ || x == stack_pointer_rtx)
-+ {
-+ rtx y1;
-+
-+ if (CONSTANT_P (y))
-+ return 0;
-+
-+ if (GET_CODE (y) == PLUS
-+ && canon_rtx (XEXP (y, 0)) == x
-+ && (y1 = canon_rtx (XEXP (y, 1)))
-+ && GET_CODE (y1) == CONST_INT)
-+ {
-+ c += INTVAL (y1);
-+ return (xsize == 0 || ysize == 0
-+ || (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0));
-+ }
-+
-+ if (GET_CODE (y) == PLUS
-+ && (y1 = canon_rtx (XEXP (y, 0)))
-+ && CONSTANT_P (y1))
-+ return 0;
-+
-+ return 1;
-+ }
-+
-+ if (GET_CODE (x) == PLUS)
-+ {
-+ /* The fact that X is canonicalized means that this
-+ PLUS rtx is canonicalized. */
-+ rtx x0 = XEXP (x, 0);
-+ rtx x1 = XEXP (x, 1);
-+
-+ if (GET_CODE (y) == PLUS)
-+ {
-+ /* The fact that Y is canonicalized means that this
-+ PLUS rtx is canonicalized. */
-+ rtx y0 = XEXP (y, 0);
-+ rtx y1 = XEXP (y, 1);
-+
-+ if (rtx_equal_for_memref_p (x1, y1))
-+ return memrefs_conflict_p (xsize, x0, ysize, y0, c);
-+ if (rtx_equal_for_memref_p (x0, y0))
-+ return memrefs_conflict_p (xsize, x1, ysize, y1, c);
-+ if (GET_CODE (x1) == CONST_INT)
-+ if (GET_CODE (y1) == CONST_INT)
-+ return memrefs_conflict_p (xsize, x0, ysize, y0,
-+ c - INTVAL (x1) + INTVAL (y1));
-+ else
-+ return memrefs_conflict_p (xsize, x0, ysize, y, c - INTVAL (x1));
-+ else if (GET_CODE (y1) == CONST_INT)
-+ return memrefs_conflict_p (xsize, x, ysize, y0, c + INTVAL (y1));
-+
-+ /* Handle case where we cannot understand iteration operators,
-+ but we notice that the base addresses are distinct objects. */
-+ /* ??? Is this still necessary? */
-+ x = find_symbolic_term (x);
-+ if (x == 0)
-+ return 1;
-+ y = find_symbolic_term (y);
-+ if (y == 0)
-+ return 1;
-+ return rtx_equal_for_memref_p (x, y);
-+ }
-+ else if (GET_CODE (x1) == CONST_INT)
-+ return memrefs_conflict_p (xsize, x0, ysize, y, c - INTVAL (x1));
-+ }
-+ else if (GET_CODE (y) == PLUS)
-+ {
-+ /* The fact that Y is canonicalized means that this
-+ PLUS rtx is canonicalized. */
-+ rtx y0 = XEXP (y, 0);
-+ rtx y1 = XEXP (y, 1);
-+
-+ if (GET_CODE (y1) == CONST_INT)
-+ return memrefs_conflict_p (xsize, x, ysize, y0, c + INTVAL (y1));
-+ else
-+ return 1;
-+ }
-+
-+ if (GET_CODE (x) == GET_CODE (y))
-+ switch (GET_CODE (x))
-+ {
-+ case MULT:
-+ {
-+ /* Handle cases where we expect the second operands to be the
-+ same, and check only whether the first operand would conflict
-+ or not. */
-+ rtx x0, y0;
-+ rtx x1 = canon_rtx (XEXP (x, 1));
-+ rtx y1 = canon_rtx (XEXP (y, 1));
-+ if (! rtx_equal_for_memref_p (x1, y1))
-+ return 1;
-+ x0 = canon_rtx (XEXP (x, 0));
-+ y0 = canon_rtx (XEXP (y, 0));
-+ if (rtx_equal_for_memref_p (x0, y0))
-+ return (xsize == 0 || ysize == 0
-+ || (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0));
-+
-+ /* Can't properly adjust our sizes. */
-+ if (GET_CODE (x1) != CONST_INT)
-+ return 1;
-+ xsize /= INTVAL (x1);
-+ ysize /= INTVAL (x1);
-+ c /= INTVAL (x1);
-+ return memrefs_conflict_p (xsize, x0, ysize, y0, c);
-+ }
-+ }
-+
-+ /* Treat an access through an AND (e.g. a subword access on an Alpha)
-+ as an access with indeterminate size. */
-+ if (GET_CODE (x) == AND && GET_CODE (XEXP (x, 1)) == CONST_INT)
-+ return memrefs_conflict_p (0, XEXP (x, 0), ysize, y, c);
-+ if (GET_CODE (y) == AND && GET_CODE (XEXP (y, 1)) == CONST_INT)
-+ return memrefs_conflict_p (xsize, x, 0, XEXP (y, 0), c);
-+
-+ if (CONSTANT_P (x))
-+ {
-+ if (GET_CODE (x) == CONST_INT && GET_CODE (y) == CONST_INT)
-+ {
-+ c += (INTVAL (y) - INTVAL (x));
-+ return (xsize == 0 || ysize == 0
-+ || (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0));
-+ }
-+
-+ if (GET_CODE (x) == CONST)
-+ {
-+ if (GET_CODE (y) == CONST)
-+ return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)),
-+ ysize, canon_rtx (XEXP (y, 0)), c);
-+ else
-+ return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)),
-+ ysize, y, c);
-+ }
-+ if (GET_CODE (y) == CONST)
-+ return memrefs_conflict_p (xsize, x, ysize,
-+ canon_rtx (XEXP (y, 0)), c);
-+
-+ if (CONSTANT_P (y))
-+ return (rtx_equal_for_memref_p (x, y)
-+ && (xsize == 0 || ysize == 0
-+ || (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0)));
-+
-+ return 1;
-+ }
-+ return 1;
-+ }
-+
-+ /* Functions to compute memory dependencies.
-+
-+ Since we process the insns in execution order, we can build tables
-+ to keep track of what registers are fixed (and not aliased), what registers
-+ are varying in known ways, and what registers are varying in unknown
-+ ways.
-+
-+ If both memory references are volatile, then there must always be a
-+ dependence between the two references, since their order can not be
-+ changed. A volatile and non-volatile reference can be interchanged
-+ though.
-+
-+ A MEM_IN_STRUCT reference at a non-QImode varying address can never
-+ conflict with a non-MEM_IN_STRUCT reference at a fixed address. We must
-+ allow QImode aliasing because the ANSI C standard allows character
-+ pointers to alias anything. We are assuming that characters are
-+ always QImode here. */
-+
-+ /* Read dependence: X is read after read in MEM takes place. There can
-+ only be a dependence here if both reads are volatile. */
-+
-+ int
-+ read_dependence (mem, x)
-+ rtx mem;
-+ rtx x;
-+ {
-+ return MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem);
-+ }
-+
-+ /* True dependence: X is read after store in MEM takes place. */
-+
-+ int
-+ true_dependence (mem, mem_mode, x, varies)
-+ rtx mem;
-+ enum machine_mode mem_mode;
-+ rtx x;
-+ int (*varies)();
-+ {
-+ rtx x_addr, mem_addr;
-+
-+ if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem))
-+ return 1;
-+
-+ x_addr = XEXP (x, 0);
-+ mem_addr = XEXP (mem, 0);
-+
-+ if (flag_alias_check && ! base_alias_check (x_addr, mem_addr))
-+ return 0;
-+
-+ /* If X is an unchanging read, then it can't possibly conflict with any
-+ non-unchanging store. It may conflict with an unchanging write though,
-+ because there may be a single store to this address to initialize it.
-+ Just fall through to the code below to resolve the case where we have
-+ both an unchanging read and an unchanging write. This won't handle all
-+ cases optimally, but the possible performance loss should be
-+ negligible. */
-+ if (RTX_UNCHANGING_P (x) && ! RTX_UNCHANGING_P (mem))
-+ return 0;
-+
-+ x_addr = canon_rtx (x_addr);
-+ mem_addr = canon_rtx (mem_addr);
-+ if (mem_mode == VOIDmode)
-+ mem_mode = GET_MODE (mem);
-+
-+ if (! memrefs_conflict_p (mem_mode, mem_addr, SIZE_FOR_MODE (x), x_addr, 0))
-+ return 0;
-+
-+ /* If both references are struct references, or both are not, nothing
-+ is known about aliasing.
-+
-+ If either reference is QImode or BLKmode, ANSI C permits aliasing.
-+
-+ If both addresses are constant, or both are not, nothing is known
-+ about aliasing. */
-+ if (MEM_IN_STRUCT_P (x) == MEM_IN_STRUCT_P (mem)
-+ || mem_mode == QImode || mem_mode == BLKmode
-+ || GET_MODE (x) == QImode || GET_MODE (mem) == BLKmode
-+ || varies (x_addr) == varies (mem_addr))
-+ return 1;
-+
-+ /* One memory reference is to a constant address, one is not.
-+ One is to a structure, the other is not.
-+
-+ If either memory reference is a variable structure the other is a
-+ fixed scalar and there is no aliasing. */
-+ if ((MEM_IN_STRUCT_P (mem) && varies (mem_addr))
-+ || (MEM_IN_STRUCT_P (x) && varies (x)))
-+ return 0;
-+
-+ return 1;
-+ }
-+
-+ /* Anti dependence: X is written after read in MEM takes place. */
-+
-+ int
-+ anti_dependence (mem, x)
-+ rtx mem;
-+ rtx x;
-+ {
-+ if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem))
-+ return 1;
-+
-+ if (flag_alias_check && ! base_alias_check (XEXP (x, 0), XEXP (mem, 0)))
-+ return 0;
-+
-+ /* If MEM is an unchanging read, then it can't possibly conflict with
-+ the store to X, because there is at most one store to MEM, and it must
-+ have occurred somewhere before MEM. */
-+ x = canon_rtx (x);
-+ mem = canon_rtx (mem);
-+ if (RTX_UNCHANGING_P (mem))
-+ return 0;
-+
-+ return (memrefs_conflict_p (SIZE_FOR_MODE (mem), XEXP (mem, 0),
-+ SIZE_FOR_MODE (x), XEXP (x, 0), 0)
-+ && ! (MEM_IN_STRUCT_P (mem) && rtx_addr_varies_p (mem)
-+ && GET_MODE (mem) != QImode
-+ && ! MEM_IN_STRUCT_P (x) && ! rtx_addr_varies_p (x))
-+ && ! (MEM_IN_STRUCT_P (x) && rtx_addr_varies_p (x)
-+ && GET_MODE (x) != QImode
-+ && ! MEM_IN_STRUCT_P (mem) && ! rtx_addr_varies_p (mem)));
-+ }
-+
-+ /* Output dependence: X is written after store in MEM takes place. */
-+
-+ int
-+ output_dependence (mem, x)
-+ register rtx mem;
-+ register rtx x;
-+ {
-+ if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem))
-+ return 1;
-+
-+ if (flag_alias_check && !base_alias_check (XEXP (x, 0), XEXP (mem, 0)))
-+ return 0;
-+
-+ x = canon_rtx (x);
-+ mem = canon_rtx (mem);
-+ return (memrefs_conflict_p (SIZE_FOR_MODE (mem), XEXP (mem, 0),
-+ SIZE_FOR_MODE (x), XEXP (x, 0), 0)
-+ && ! (MEM_IN_STRUCT_P (mem) && rtx_addr_varies_p (mem)
-+ && GET_MODE (mem) != QImode
-+ && ! MEM_IN_STRUCT_P (x) && ! rtx_addr_varies_p (x))
-+ && ! (MEM_IN_STRUCT_P (x) && rtx_addr_varies_p (x)
-+ && GET_MODE (x) != QImode
-+ && ! MEM_IN_STRUCT_P (mem) && ! rtx_addr_varies_p (mem)));
-+ }
-+
-+ void
-+ init_alias_analysis ()
-+ {
-+ int maxreg = max_reg_num ();
-+ register int i;
-+ register rtx insn;
-+ rtx note;
-+ rtx set;
-+ int changed;
-+
-+ reg_known_value_size = maxreg;
-+
-+ reg_known_value
-+ = (rtx *) oballoc ((maxreg - FIRST_PSEUDO_REGISTER) * sizeof (rtx))
-+ - FIRST_PSEUDO_REGISTER;
-+ reg_known_equiv_p =
-+ oballoc (maxreg - FIRST_PSEUDO_REGISTER) - FIRST_PSEUDO_REGISTER;
-+ bzero ((char *) (reg_known_value + FIRST_PSEUDO_REGISTER),
-+ (maxreg-FIRST_PSEUDO_REGISTER) * sizeof (rtx));
-+ bzero (reg_known_equiv_p + FIRST_PSEUDO_REGISTER,
-+ (maxreg - FIRST_PSEUDO_REGISTER) * sizeof (char));
-+
-+ if (flag_alias_check)
-+ {
-+ /* Overallocate reg_base_value to allow some growth during loop
-+ optimization. Loop unrolling can create a large number of
-+ registers. */
-+ reg_base_value_size = maxreg * 2;
-+ reg_base_value = (rtx *)oballoc (reg_base_value_size * sizeof (rtx));
-+ reg_seen = (char *)alloca (reg_base_value_size);
-+ bzero (reg_base_value, reg_base_value_size * sizeof (rtx));
-+ bzero (reg_seen, reg_base_value_size);
-+
-+ /* Mark all hard registers which may contain an address.
-+ The stack, frame and argument pointers may contain an address.
-+ An argument register which can hold a Pmode value may contain
-+ an address even if it is not in BASE_REGS.
-+
-+ The address expression is VOIDmode for an argument and
-+ Pmode for other registers. */
-+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-+ if (FUNCTION_ARG_REGNO_P (i) && HARD_REGNO_MODE_OK (i, Pmode))
-+ reg_base_value[i] = gen_rtx (ADDRESS, VOIDmode,
-+ gen_rtx (REG, Pmode, i));
-+
-+ reg_base_value[STACK_POINTER_REGNUM]
-+ = gen_rtx (ADDRESS, Pmode, stack_pointer_rtx);
-+ reg_base_value[ARG_POINTER_REGNUM]
-+ = gen_rtx (ADDRESS, Pmode, arg_pointer_rtx);
-+ reg_base_value[FRAME_POINTER_REGNUM]
-+ = gen_rtx (ADDRESS, Pmode, frame_pointer_rtx);
-+ reg_base_value[HARD_FRAME_POINTER_REGNUM]
-+ = gen_rtx (ADDRESS, Pmode, hard_frame_pointer_rtx);
-+ }
-+
-+ copying_arguments = 1;
-+ /* Fill in the entries with known constant values. */
-+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
-+ {
-+ if (flag_alias_check && GET_RTX_CLASS (GET_CODE (insn)) == 'i')
-+ {
-+ /* If this insn has a noalias note, process it, Otherwise,
-+ scan for sets. A simple set will have no side effects
-+ which could change the base value of any other register. */
-+ rtx noalias_note;
-+ if (GET_CODE (PATTERN (insn)) == SET
-+ && (noalias_note = find_reg_note (insn, REG_NOALIAS, NULL_RTX)))
-+ record_set(SET_DEST (PATTERN (insn)), 0);
-+ else
-+ note_stores (PATTERN (insn), record_set);
-+ }
-+ else if (GET_CODE (insn) == NOTE
-+ && NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_BEG)
-+ copying_arguments = 0;
-+
-+ if ((set = single_set (insn)) != 0
-+ && GET_CODE (SET_DEST (set)) == REG
-+ && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
-+ && (((note = find_reg_note (insn, REG_EQUAL, 0)) != 0
-+ && reg_n_sets[REGNO (SET_DEST (set))] == 1)
-+ || (note = find_reg_note (insn, REG_EQUIV, NULL_RTX)) != 0)
-+ && GET_CODE (XEXP (note, 0)) != EXPR_LIST)
-+ {
-+ int regno = REGNO (SET_DEST (set));
-+ reg_known_value[regno] = XEXP (note, 0);
-+ reg_known_equiv_p[regno] = REG_NOTE_KIND (note) == REG_EQUIV;
-+ }
-+ }
-+
-+ /* Fill in the remaining entries. */
-+ for (i = FIRST_PSEUDO_REGISTER; i < maxreg; i++)
-+ if (reg_known_value[i] == 0)
-+ reg_known_value[i] = regno_reg_rtx[i];
-+
-+ if (! flag_alias_check)
-+ return;
-+
-+ /* Simplify the reg_base_value array so that no register refers to
-+ another register, except to special registers indirectly through
-+ ADDRESS expressions.
-+
-+ In theory this loop can take as long as O(registers^2), but unless
-+ there are very long dependency chains it will run in close to linear
-+ time. */
-+ do
-+ {
-+ changed = 0;
-+ for (i = FIRST_PSEUDO_REGISTER; i < reg_base_value_size; i++)
-+ {
-+ rtx base = reg_base_value[i];
-+ if (base && GET_CODE (base) == REG)
-+ {
-+ int base_regno = REGNO (base);
-+ if (base_regno == i) /* register set from itself */
-+ reg_base_value[i] = 0;
-+ else
-+ reg_base_value[i] = reg_base_value[base_regno];
-+ changed = 1;
-+ }
-+ }
-+ }
-+ while (changed);
-+
-+ reg_seen = 0;
-+ }
-+
-+ void
-+ end_alias_analysis ()
-+ {
-+ reg_known_value = 0;
-+ reg_base_value = 0;
-+ reg_base_value_size = 0;
-+ }
-diff -rcp2N gcc-2.7.2.2/calls.c gcc-2.7.2.2.f.2/calls.c
-*** gcc-2.7.2.2/calls.c Thu Oct 26 21:53:43 1995
---- gcc-2.7.2.2.f.2/calls.c Fri Jan 10 23:18:21 1997
-*************** expand_call (exp, target, ignore)
-*** 564,567 ****
---- 564,569 ----
- /* Nonzero if it is plausible that this is a call to alloca. */
- int may_be_alloca;
-+ /* Nonzero if this is a call to malloc or a related function. */
-+ int is_malloc;
- /* Nonzero if this is a call to setjmp or a related function. */
- int returns_twice;
-*************** expand_call (exp, target, ignore)
-*** 852,855 ****
---- 854,858 ----
- returns_twice = 0;
- is_longjmp = 0;
-+ is_malloc = 0;
-
- if (name != 0 && IDENTIFIER_LENGTH (DECL_NAME (fndecl)) <= 15)
-*************** expand_call (exp, target, ignore)
-*** 891,894 ****
---- 894,901 ----
- && ! strcmp (tname, "longjmp"))
- is_longjmp = 1;
-+ /* Only recognize malloc when alias analysis is enabled. */
-+ else if (tname[0] == 'm' && flag_alias_check
-+ && ! strcmp(tname, "malloc"))
-+ is_malloc = 1;
- }
-
-*************** expand_call (exp, target, ignore)
-*** 1363,1367 ****
- /* Now we are about to start emitting insns that can be deleted
- if a libcall is deleted. */
-! if (is_const)
- start_sequence ();
-
---- 1370,1374 ----
- /* Now we are about to start emitting insns that can be deleted
- if a libcall is deleted. */
-! if (is_const || is_malloc)
- start_sequence ();
-
-*************** expand_call (exp, target, ignore)
-*** 1951,1954 ****
---- 1958,1975 ----
- end_sequence ();
- emit_insns (insns);
-+ }
-+ else if (is_malloc)
-+ {
-+ rtx temp = gen_reg_rtx (GET_MODE (valreg));
-+ rtx last, insns;
-+
-+ emit_move_insn (temp, valreg);
-+ last = get_last_insn ();
-+ REG_NOTES (last) =
-+ gen_rtx (EXPR_LIST, REG_NOALIAS, temp, REG_NOTES (last));
-+ insns = get_insns ();
-+ end_sequence ();
-+ emit_insns (insns);
-+ valreg = temp;
- }
-
-diff -rcp2N gcc-2.7.2.2/combine.c gcc-2.7.2.2.f.2/combine.c
-*** gcc-2.7.2.2/combine.c Sun Nov 26 14:32:07 1995
---- gcc-2.7.2.2.f.2/combine.c Fri Jan 10 23:18:21 1997
-*************** distribute_notes (notes, from_insn, i3,
-*** 10648,10651 ****
---- 10648,10652 ----
- case REG_EQUIV:
- case REG_NONNEG:
-+ case REG_NOALIAS:
- /* These notes say something about results of an insn. We can
- only support them if they used to be on I3 in which case they
-diff -rcp2N gcc-2.7.2.2/config/alpha/alpha.c gcc-2.7.2.2.f.2/config/alpha/alpha.c
-*** gcc-2.7.2.2/config/alpha/alpha.c Thu Feb 20 19:24:11 1997
---- gcc-2.7.2.2.f.2/config/alpha/alpha.c Sun Feb 23 15:35:33 1997
-*************** output_prolog (file, size)
-*** 1370,1373 ****
---- 1370,1378 ----
-
- alpha_function_needs_gp = 0;
-+ #ifdef __linux__
-+ if(profile_flag) {
-+ alpha_function_needs_gp = 1;
-+ }
-+ #endif
- for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
- if ((GET_CODE (insn) == CALL_INSN)
-diff -rcp2N gcc-2.7.2.2/config/alpha/alpha.h gcc-2.7.2.2.f.2/config/alpha/alpha.h
-*** gcc-2.7.2.2/config/alpha/alpha.h Thu Feb 20 19:24:12 1997
---- gcc-2.7.2.2.f.2/config/alpha/alpha.h Sun Feb 23 15:35:34 1997
-*************** extern int target_flags;
-*** 112,116 ****
---- 112,118 ----
- {"", TARGET_DEFAULT | TARGET_CPU_DEFAULT} }
-
-+ #ifndef TARGET_DEFAULT
- #define TARGET_DEFAULT 3
-+ #endif
-
- #ifndef TARGET_CPU_DEFAULT
-diff -rcp2N gcc-2.7.2.2/config/alpha/alpha.md gcc-2.7.2.2.f.2/config/alpha/alpha.md
-*** gcc-2.7.2.2/config/alpha/alpha.md Fri Oct 27 06:49:59 1995
---- gcc-2.7.2.2.f.2/config/alpha/alpha.md Mon Dec 23 00:43:55 1996
-***************
-*** 1746,1752 ****
- (if_then_else:DF
- (match_operator 3 "signed_comparison_operator"
-! [(match_operand:DF 1 "reg_or_fp0_operand" "fG,fG")
- (match_operand:DF 2 "fp0_operand" "G,G")])
-! (float_extend:DF (match_operand:SF 4 "reg_or_fp0_operand" "fG,0"))
- (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
- "TARGET_FP"
---- 1746,1752 ----
- (if_then_else:DF
- (match_operator 3 "signed_comparison_operator"
-! [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
- (match_operand:DF 2 "fp0_operand" "G,G")])
-! (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG,0"))
- (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
- "TARGET_FP"
-diff -rcp2N gcc-2.7.2.2/config/alpha/linux.h gcc-2.7.2.2.f.2/config/alpha/linux.h
-*** gcc-2.7.2.2/config/alpha/linux.h Wed Dec 31 19:00:00 1969
---- gcc-2.7.2.2.f.2/config/alpha/linux.h Thu Dec 19 12:31:08 1996
-***************
-*** 0 ****
---- 1,72 ----
-+ /* Definitions of target machine for GNU compiler, for Alpha Linux,
-+ using ECOFF.
-+ Copyright (C) 1995 Free Software Foundation, Inc.
-+ Contributed by Bob Manson.
-+ Derived from work contributed by Cygnus Support,
-+ (c) 1993 Free Software Foundation.
-+
-+ This file is part of GNU CC.
-+
-+ GNU CC is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License as published by
-+ the Free Software Foundation; either version 2, or (at your option)
-+ any later version.
-+
-+ GNU CC is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ GNU General Public License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with GNU CC; see the file COPYING. If not, write to
-+ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-+
-+ #define TARGET_DEFAULT (3 | MASK_GAS)
-+
-+ #include "alpha/alpha.h"
-+
-+ #undef TARGET_VERSION
-+ #define TARGET_VERSION fprintf (stderr, " (Linux/Alpha)");
-+
-+ #undef CPP_PREDEFINES
-+ #define CPP_PREDEFINES "\
-+ -D__alpha -D__alpha__ -D__linux__ -D__linux -D_LONGLONG -Dlinux -Dunix \
-+ -Asystem(linux) -Acpu(alpha) -Amachine(alpha)"
-+
-+ /* We don't actually need any of these; the MD_ vars are ignored
-+ anyway for cross-compilers, and the other specs won't get picked up
-+ 'coz the user is supposed to do ld -r (hmm, perhaps that should be
-+ the default). In any case, setting them thus will catch some
-+ common user errors. */
-+
-+ #undef MD_EXEC_PREFIX
-+ #undef MD_STARTFILE_PREFIX
-+
-+ #undef LIB_SPEC
-+ #define LIB_SPEC "%{pg:-lgmon} %{pg:-lc_p} %{!pg:-lc}"
-+
-+ #undef LINK_SPEC
-+ #define LINK_SPEC \
-+ "-G 8 %{O*:-O3} %{!O*:-O1}"
-+
-+ #undef ASM_SPEC
-+ #define ASM_SPEC "-nocpp"
-+
-+ /* Can't do stabs */
-+ #undef SDB_DEBUGGING_INFO
-+
-+ /* Prefer dbx. */
-+ #undef PREFERRED_DEBUGGING_TYPE
-+ #define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
-+
-+ #undef FUNCTION_PROFILER
-+
-+ #define FUNCTION_PROFILER(FILE, LABELNO) \
-+ do { \
-+ fputs ("\tlda $27,_mcount\n", (FILE)); \
-+ fputs ("\tjsr $26,($27),_mcount\n", (FILE)); \
-+ fputs ("\tldgp $29,0($26)\n", (FILE)); \
-+ } while (0);
-+
-+ /* Generate calls to memcpy, etc., not bcopy, etc. */
-+ #define TARGET_MEM_FUNCTIONS
-diff -rcp2N gcc-2.7.2.2/config/alpha/t-linux gcc-2.7.2.2.f.2/config/alpha/t-linux
-*** gcc-2.7.2.2/config/alpha/t-linux Wed Dec 31 19:00:00 1969
---- gcc-2.7.2.2.f.2/config/alpha/t-linux Thu Dec 19 12:31:08 1996
-***************
-*** 0 ****
---- 1,3 ----
-+ # Our header files are supposed to be correct, nein?
-+ FIXINCLUDES =
-+ STMP_FIXPROTO =
-diff -rcp2N gcc-2.7.2.2/config/alpha/x-linux gcc-2.7.2.2.f.2/config/alpha/x-linux
-*** gcc-2.7.2.2/config/alpha/x-linux Wed Dec 31 19:00:00 1969
---- gcc-2.7.2.2.f.2/config/alpha/x-linux Thu Dec 19 12:31:08 1996
-***************
-*** 0 ****
---- 1 ----
-+ CLIB=-lbfd -liberty
-diff -rcp2N gcc-2.7.2.2/config/alpha/xm-alpha.h gcc-2.7.2.2.f.2/config/alpha/xm-alpha.h
-*** gcc-2.7.2.2/config/alpha/xm-alpha.h Thu Aug 31 17:52:27 1995
---- gcc-2.7.2.2.f.2/config/alpha/xm-alpha.h Thu Dec 19 12:31:08 1996
-*************** Boston, MA 02111-1307, USA. */
-*** 46,51 ****
---- 46,53 ----
- #include <alloca.h>
- #else
-+ #ifndef __alpha__
- extern void *alloca ();
- #endif
-+ #endif
-
- /* The host compiler has problems with enum bitfields since it makes
-*************** extern void *malloc (), *realloc (), *ca
-*** 68,72 ****
---- 70,76 ----
- /* OSF/1 has vprintf. */
-
-+ #ifndef linux /* 1996/02/22 mauro@craftwork.com -- unreliable with Linux */
- #define HAVE_VPRINTF
-+ #endif
-
- /* OSF/1 has putenv. */
-diff -rcp2N gcc-2.7.2.2/config/alpha/xm-linux.h gcc-2.7.2.2.f.2/config/alpha/xm-linux.h
-*** gcc-2.7.2.2/config/alpha/xm-linux.h Wed Dec 31 19:00:00 1969
---- gcc-2.7.2.2.f.2/config/alpha/xm-linux.h Thu Dec 19 12:31:08 1996
-***************
-*** 0 ****
---- 1,8 ----
-+ #ifndef _XM_LINUX_H
-+ #define _XM_LINUX_H
-+
-+ #include "xm-alpha.h"
-+
-+ #define DONT_DECLARE_SYS_SIGLIST
-+ #define USE_BFD
-+ #endif
-diff -rcp2N gcc-2.7.2.2/config/x-linux gcc-2.7.2.2.f.2/config/x-linux
-*** gcc-2.7.2.2/config/x-linux Tue Mar 28 07:43:37 1995
---- gcc-2.7.2.2.f.2/config/x-linux Thu Dec 19 12:31:08 1996
-*************** BOOT_CFLAGS = -O $(CFLAGS) -Iinclude
-*** 13,14 ****
---- 13,17 ----
- # Don't run fixproto
- STMP_FIXPROTO =
-+
-+ # Don't install "assert.h" in gcc. We use the one in glibc.
-+ INSTALL_ASSERT_H =
-diff -rcp2N gcc-2.7.2.2/config/x-linux-aout gcc-2.7.2.2.f.2/config/x-linux-aout
-*** gcc-2.7.2.2/config/x-linux-aout Wed Dec 31 19:00:00 1969
---- gcc-2.7.2.2.f.2/config/x-linux-aout Thu Dec 19 12:31:08 1996
-***************
-*** 0 ****
---- 1,14 ----
-+ # It is defined in config/xm-linux.h.
-+ # X_CFLAGS = -DPOSIX
-+
-+ # The following is needed when compiling stages 2 and 3 because gcc's
-+ # limits.h must be picked up before /usr/include/limits.h. This is because
-+ # each does an #include_next of the other if the other hasn't been included.
-+ # /usr/include/limits.h loses if it gets found first because /usr/include is
-+ # at the end of the search order. When a new version of gcc is released,
-+ # gcc's limits.h hasn't been installed yet and hence isn't found.
-+
-+ BOOT_CFLAGS = -O $(CFLAGS) -Iinclude
-+
-+ # Don't run fixproto
-+ STMP_FIXPROTO =
-diff -rcp2N gcc-2.7.2.2/configure gcc-2.7.2.2.f.2/configure
-*** gcc-2.7.2.2/configure Thu Feb 20 19:24:33 1997
---- gcc-2.7.2.2.f.2/configure Sun Feb 23 16:15:12 1997
-*************** exec_prefix='$(prefix)'
-*** 82,85 ****
---- 82,86 ----
- # The default g++ include directory is $(libdir)/g++-include.
- gxx_include_dir='$(libdir)/g++-include'
-+ #gxx_include_dir='$(exec_prefix)/include/g++'
-
- # Default --program-transform-name to nothing.
-*************** for machine in $canon_build $canon_host
-*** 548,551 ****
---- 549,559 ----
- use_collect2=yes
- ;;
-+ alpha-*-linux*)
-+ tm_file=alpha/linux.h
-+ tmake_file=alpha/t-linux
-+ xmake_file=alpha/x-linux
-+ fixincludes=Makefile.in
-+ xm_file=alpha/xm-linux.h
-+ ;;
- alpha-dec-osf[23456789]*)
- tm_file=alpha/osf2.h
-*************** for machine in $canon_build $canon_host
-*** 985,989 ****
- cpu_type=i386 # with a.out format using pre BFD linkers
- xm_file=i386/xm-linux.h
-! xmake_file=x-linux
- tm_file=i386/linux-oldld.h
- fixincludes=Makefile.in # The headers are ok already.
---- 993,997 ----
- cpu_type=i386 # with a.out format using pre BFD linkers
- xm_file=i386/xm-linux.h
-! xmake_file=x-linux-aout
- tm_file=i386/linux-oldld.h
- fixincludes=Makefile.in # The headers are ok already.
-*************** for machine in $canon_build $canon_host
-*** 994,998 ****
- cpu_type=i386 # with a.out format
- xm_file=i386/xm-linux.h
-! xmake_file=x-linux
- tm_file=i386/linux-aout.h
- fixincludes=Makefile.in # The headers are ok already.
---- 1002,1006 ----
- cpu_type=i386 # with a.out format
- xm_file=i386/xm-linux.h
-! xmake_file=x-linux-aout
- tm_file=i386/linux-aout.h
- fixincludes=Makefile.in # The headers are ok already.
-*************** for machine in $canon_build $canon_host
-*** 1003,1007 ****
- cpu_type=i386 # with ELF format, using GNU libc v1.
- xm_file=i386/xm-linux.h
-! xmake_file=x-linux
- tmake_file=t-linux-libc1
- tm_file=i386/linux.h
---- 1011,1015 ----
- cpu_type=i386 # with ELF format, using GNU libc v1.
- xm_file=i386/xm-linux.h
-! xmake_file=x-linux-aout
- tmake_file=t-linux-libc1
- tm_file=i386/linux.h
-diff -rcp2N gcc-2.7.2.2/cse.c gcc-2.7.2.2.f.2/cse.c
-*** gcc-2.7.2.2/cse.c Sun Nov 26 14:47:05 1995
---- gcc-2.7.2.2.f.2/cse.c Fri Jan 10 23:18:22 1997
-*************** static struct table_elt *last_jump_equiv
-*** 520,544 ****
- static int constant_pool_entries_cost;
-
-- /* Bits describing what kind of values in memory must be invalidated
-- for a particular instruction. If all three bits are zero,
-- no memory refs need to be invalidated. Each bit is more powerful
-- than the preceding ones, and if a bit is set then the preceding
-- bits are also set.
--
-- Here is how the bits are set:
-- Pushing onto the stack invalidates only the stack pointer,
-- writing at a fixed address invalidates only variable addresses,
-- writing in a structure element at variable address
-- invalidates all but scalar variables,
-- and writing in anything else at variable address invalidates everything. */
--
-- struct write_data
-- {
-- int sp : 1; /* Invalidate stack pointer. */
-- int var : 1; /* Invalidate variable addresses. */
-- int nonscalar : 1; /* Invalidate all but scalar variables. */
-- int all : 1; /* Invalidate all memory refs. */
-- };
--
- /* Define maximum length of a branch path. */
-
---- 520,523 ----
-*************** static void merge_equiv_classes PROTO((s
-*** 626,632 ****
- struct table_elt *));
- static void invalidate PROTO((rtx, enum machine_mode));
- static void remove_invalid_refs PROTO((int));
- static void rehash_using_reg PROTO((rtx));
-! static void invalidate_memory PROTO((struct write_data *));
- static void invalidate_for_call PROTO((void));
- static rtx use_related_value PROTO((rtx, struct table_elt *));
---- 605,612 ----
- struct table_elt *));
- static void invalidate PROTO((rtx, enum machine_mode));
-+ static int cse_rtx_varies_p PROTO((rtx));
- static void remove_invalid_refs PROTO((int));
- static void rehash_using_reg PROTO((rtx));
-! static void invalidate_memory PROTO((void));
- static void invalidate_for_call PROTO((void));
- static rtx use_related_value PROTO((rtx, struct table_elt *));
-*************** static void set_nonvarying_address_compo
-*** 638,644 ****
- HOST_WIDE_INT *));
- static int refers_to_p PROTO((rtx, rtx));
-- static int refers_to_mem_p PROTO((rtx, rtx, HOST_WIDE_INT,
-- HOST_WIDE_INT));
-- static int cse_rtx_addr_varies_p PROTO((rtx));
- static rtx canon_reg PROTO((rtx, rtx));
- static void find_best_addr PROTO((rtx, rtx *));
---- 618,621 ----
-*************** static void record_jump_cond PROTO((enum
-*** 656,661 ****
- rtx, rtx, int));
- static void cse_insn PROTO((rtx, int));
-! static void note_mem_written PROTO((rtx, struct write_data *));
-! static void invalidate_from_clobbers PROTO((struct write_data *, rtx));
- static rtx cse_process_notes PROTO((rtx, rtx));
- static void cse_around_loop PROTO((rtx));
---- 633,638 ----
- rtx, rtx, int));
- static void cse_insn PROTO((rtx, int));
-! static int note_mem_written PROTO((rtx));
-! static void invalidate_from_clobbers PROTO((rtx));
- static rtx cse_process_notes PROTO((rtx, rtx));
- static void cse_around_loop PROTO((rtx));
-*************** invalidate (x, full_mode)
-*** 1512,1517 ****
- register int i;
- register struct table_elt *p;
-- rtx base;
-- HOST_WIDE_INT start, end;
-
- /* If X is a register, dependencies on its contents
---- 1489,1492 ----
-*************** invalidate (x, full_mode)
-*** 1605,1611 ****
- full_mode = GET_MODE (x);
-
-- set_nonvarying_address_components (XEXP (x, 0), GET_MODE_SIZE (full_mode),
-- &base, &start, &end);
--
- for (i = 0; i < NBUCKETS; i++)
- {
---- 1580,1583 ----
-*************** invalidate (x, full_mode)
-*** 1614,1618 ****
- {
- next = p->next_same_hash;
-! if (refers_to_mem_p (p->exp, base, start, end))
- remove_from_table (p, i);
- }
---- 1586,1594 ----
- {
- next = p->next_same_hash;
-! /* Invalidate ASM_OPERANDS which reference memory (this is easier
-! than checking all the aliases). */
-! if (p->in_memory
-! && (GET_CODE (p->exp) != MEM
-! || true_dependence (x, full_mode, p->exp, cse_rtx_varies_p)))
- remove_from_table (p, i);
- }
-*************** rehash_using_reg (x)
-*** 1695,1722 ****
- }
-
-- /* Remove from the hash table all expressions that reference memory,
-- or some of them as specified by *WRITES. */
--
-- static void
-- invalidate_memory (writes)
-- struct write_data *writes;
-- {
-- register int i;
-- register struct table_elt *p, *next;
-- int all = writes->all;
-- int nonscalar = writes->nonscalar;
--
-- for (i = 0; i < NBUCKETS; i++)
-- for (p = table[i]; p; p = next)
-- {
-- next = p->next_same_hash;
-- if (p->in_memory
-- && (all
-- || (nonscalar && p->in_struct)
-- || cse_rtx_addr_varies_p (p->exp)))
-- remove_from_table (p, i);
-- }
-- }
--
- /* Remove from the hash table any expression that is a call-clobbered
- register. Also update their TICK values. */
---- 1671,1674 ----
-*************** invalidate_for_call ()
-*** 1756,1759 ****
---- 1708,1717 ----
- next = p->next_same_hash;
-
-+ if (p->in_memory)
-+ {
-+ remove_from_table (p, hash);
-+ continue;
-+ }
-+
- if (GET_CODE (p->exp) != REG
- || REGNO (p->exp) >= FIRST_PSEUDO_REGISTER)
-*************** set_nonvarying_address_components (addr,
-*** 2395,2477 ****
- }
-
-! /* Return 1 iff any subexpression of X refers to memory
-! at an address of BASE plus some offset
-! such that any of the bytes' offsets fall between START (inclusive)
-! and END (exclusive).
-!
-! The value is undefined if X is a varying address (as determined by
-! cse_rtx_addr_varies_p). This function is not used in such cases.
-!
-! When used in the cse pass, `qty_const' is nonzero, and it is used
-! to treat an address that is a register with a known constant value
-! as if it were that constant value.
-! In the loop pass, `qty_const' is zero, so this is not done. */
-!
-! static int
-! refers_to_mem_p (x, base, start, end)
-! rtx x, base;
-! HOST_WIDE_INT start, end;
-! {
-! register HOST_WIDE_INT i;
-! register enum rtx_code code;
-! register char *fmt;
-!
-! repeat:
-! if (x == 0)
-! return 0;
-!
-! code = GET_CODE (x);
-! if (code == MEM)
-! {
-! register rtx addr = XEXP (x, 0); /* Get the address. */
-! rtx mybase;
-! HOST_WIDE_INT mystart, myend;
-!
-! set_nonvarying_address_components (addr, GET_MODE_SIZE (GET_MODE (x)),
-! &mybase, &mystart, &myend);
-!
-!
-! /* refers_to_mem_p is never called with varying addresses.
-! If the base addresses are not equal, there is no chance
-! of the memory addresses conflicting. */
-! if (! rtx_equal_p (mybase, base))
-! return 0;
-!
-! return myend > start && mystart < end;
-! }
-!
-! /* X does not match, so try its subexpressions. */
-!
-! fmt = GET_RTX_FORMAT (code);
-! for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
-! if (fmt[i] == 'e')
-! {
-! if (i == 0)
-! {
-! x = XEXP (x, 0);
-! goto repeat;
-! }
-! else
-! if (refers_to_mem_p (XEXP (x, i), base, start, end))
-! return 1;
-! }
-! else if (fmt[i] == 'E')
-! {
-! int j;
-! for (j = 0; j < XVECLEN (x, i); j++)
-! if (refers_to_mem_p (XVECEXP (x, i, j), base, start, end))
-! return 1;
-! }
-!
-! return 0;
-! }
-!
-! /* Nonzero if X refers to memory at a varying address;
- except that a register which has at the moment a known constant value
- isn't considered variable. */
-
- static int
-! cse_rtx_addr_varies_p (x)
-! rtx x;
- {
- /* We need not check for X and the equivalence class being of the same
---- 2353,2363 ----
- }
-
-! /* Nonzero if X, a memory address, refers to a varying address;
- except that a register which has at the moment a known constant value
- isn't considered variable. */
-
- static int
-! cse_rtx_varies_p (x)
-! register rtx x;
- {
- /* We need not check for X and the equivalence class being of the same
-*************** cse_rtx_addr_varies_p (x)
-*** 2479,2497 ****
- doesn't vary in any mode. */
-
-! if (GET_CODE (x) == MEM
-! && GET_CODE (XEXP (x, 0)) == REG
-! && REGNO_QTY_VALID_P (REGNO (XEXP (x, 0)))
-! && GET_MODE (XEXP (x, 0)) == qty_mode[reg_qty[REGNO (XEXP (x, 0))]]
-! && qty_const[reg_qty[REGNO (XEXP (x, 0))]] != 0)
- return 0;
-
-! if (GET_CODE (x) == MEM
-! && GET_CODE (XEXP (x, 0)) == PLUS
-! && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
-! && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
-! && REGNO_QTY_VALID_P (REGNO (XEXP (XEXP (x, 0), 0)))
-! && (GET_MODE (XEXP (XEXP (x, 0), 0))
-! == qty_mode[reg_qty[REGNO (XEXP (XEXP (x, 0), 0))]])
-! && qty_const[reg_qty[REGNO (XEXP (XEXP (x, 0), 0))]])
- return 0;
-
---- 2365,2381 ----
- doesn't vary in any mode. */
-
-! if (GET_CODE (x) == REG
-! && REGNO_QTY_VALID_P (REGNO (x))
-! && GET_MODE (x) == qty_mode[reg_qty[REGNO (x)]]
-! && qty_const[reg_qty[REGNO (x)]] != 0)
- return 0;
-
-! if (GET_CODE (x) == PLUS
-! && GET_CODE (XEXP (x, 1)) == CONST_INT
-! && GET_CODE (XEXP (x, 0)) == REG
-! && REGNO_QTY_VALID_P (REGNO (XEXP (x, 0)))
-! && (GET_MODE (XEXP (x, 0))
-! == qty_mode[reg_qty[REGNO (XEXP (x, 0))]])
-! && qty_const[reg_qty[REGNO (XEXP (x, 0))]])
- return 0;
-
-*************** cse_rtx_addr_varies_p (x)
-*** 2501,2519 ****
- load fp minus a constant into a register, then a MEM which is the
- sum of the two `constant' registers. */
-! if (GET_CODE (x) == MEM
-! && GET_CODE (XEXP (x, 0)) == PLUS
-! && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
-! && GET_CODE (XEXP (XEXP (x, 0), 1)) == REG
-! && REGNO_QTY_VALID_P (REGNO (XEXP (XEXP (x, 0), 0)))
-! && (GET_MODE (XEXP (XEXP (x, 0), 0))
-! == qty_mode[reg_qty[REGNO (XEXP (XEXP (x, 0), 0))]])
-! && qty_const[reg_qty[REGNO (XEXP (XEXP (x, 0), 0))]]
-! && REGNO_QTY_VALID_P (REGNO (XEXP (XEXP (x, 0), 1)))
-! && (GET_MODE (XEXP (XEXP (x, 0), 1))
-! == qty_mode[reg_qty[REGNO (XEXP (XEXP (x, 0), 1))]])
-! && qty_const[reg_qty[REGNO (XEXP (XEXP (x, 0), 1))]])
- return 0;
-
-! return rtx_addr_varies_p (x);
- }
-
---- 2385,2402 ----
- load fp minus a constant into a register, then a MEM which is the
- sum of the two `constant' registers. */
-! if (GET_CODE (x) == PLUS
-! && GET_CODE (XEXP (x, 0)) == REG
-! && GET_CODE (XEXP (x, 1)) == REG
-! && REGNO_QTY_VALID_P (REGNO (XEXP (x, 0)))
-! && (GET_MODE (XEXP (x, 0))
-! == qty_mode[reg_qty[REGNO (XEXP (x, 0))]])
-! && qty_const[reg_qty[REGNO (XEXP (x, 0))]]
-! && REGNO_QTY_VALID_P (REGNO (XEXP (x, 1)))
-! && (GET_MODE (XEXP (x, 1))
-! == qty_mode[reg_qty[REGNO (XEXP (x, 1))]])
-! && qty_const[reg_qty[REGNO (XEXP (x, 1))]])
- return 0;
-
-! return rtx_varies_p (x);
- }
-
-*************** cse_insn (insn, in_libcall_block)
-*** 6105,6110 ****
- rtx this_insn_cc0 = 0;
- enum machine_mode this_insn_cc0_mode;
-- struct write_data writes_memory;
-- static struct write_data init = {0, 0, 0, 0};
-
- rtx src_eqv = 0;
---- 5988,5991 ----
-*************** cse_insn (insn, in_libcall_block)
-*** 6118,6122 ****
-
- this_insn = insn;
-- writes_memory = init;
-
- /* Find all the SETs and CLOBBERs in this instruction.
---- 5999,6002 ----
-*************** cse_insn (insn, in_libcall_block)
-*** 6220,6225 ****
- else if (GET_CODE (y) == CLOBBER)
- {
-! /* If we clobber memory, take note of that,
-! and canon the address.
- This does nothing when a register is clobbered
- because we have already invalidated the reg. */
---- 6100,6104 ----
- else if (GET_CODE (y) == CLOBBER)
- {
-! /* If we clobber memory, canon the address.
- This does nothing when a register is clobbered
- because we have already invalidated the reg. */
-*************** cse_insn (insn, in_libcall_block)
-*** 6227,6231 ****
- {
- canon_reg (XEXP (y, 0), NULL_RTX);
-! note_mem_written (XEXP (y, 0), &writes_memory);
- }
- }
---- 6106,6110 ----
- {
- canon_reg (XEXP (y, 0), NULL_RTX);
-! note_mem_written (XEXP (y, 0));
- }
- }
-*************** cse_insn (insn, in_libcall_block)
-*** 6249,6253 ****
- {
- canon_reg (XEXP (x, 0), NULL_RTX);
-! note_mem_written (XEXP (x, 0), &writes_memory);
- }
- }
---- 6128,6132 ----
- {
- canon_reg (XEXP (x, 0), NULL_RTX);
-! note_mem_written (XEXP (x, 0));
- }
- }
-*************** cse_insn (insn, in_libcall_block)
-*** 6674,6678 ****
- }
- #endif /* LOAD_EXTEND_OP */
-!
- if (src == src_folded)
- src_folded = 0;
---- 6553,6557 ----
- }
- #endif /* LOAD_EXTEND_OP */
-!
- if (src == src_folded)
- src_folded = 0;
-*************** cse_insn (insn, in_libcall_block)
-*** 6860,6864 ****
- || (GET_CODE (src_folded) != MEM
- && ! src_folded_force_flag))
-! && GET_MODE_CLASS (mode) != MODE_CC)
- {
- src_folded_force_flag = 1;
---- 6739,6744 ----
- || (GET_CODE (src_folded) != MEM
- && ! src_folded_force_flag))
-! && GET_MODE_CLASS (mode) != MODE_CC
-! && mode != VOIDmode)
- {
- src_folded_force_flag = 1;
-*************** cse_insn (insn, in_libcall_block)
-*** 6984,6993 ****
- {
- dest = fold_rtx (dest, insn);
-!
-! /* Decide whether we invalidate everything in memory,
-! or just things at non-fixed places.
-! Writing a large aggregate must invalidate everything
-! because we don't know how long it is. */
-! note_mem_written (dest, &writes_memory);
- }
-
---- 6864,6868 ----
- {
- dest = fold_rtx (dest, insn);
-! note_mem_written (dest);
- }
-
-*************** cse_insn (insn, in_libcall_block)
-*** 7234,7238 ****
- sets[i].src_elt = src_eqv_elt;
-
-! invalidate_from_clobbers (&writes_memory, x);
-
- /* Some registers are invalidated by subroutine calls. Memory is
---- 7109,7113 ----
- sets[i].src_elt = src_eqv_elt;
-
-! invalidate_from_clobbers (x);
-
- /* Some registers are invalidated by subroutine calls. Memory is
-*************** cse_insn (insn, in_libcall_block)
-*** 7241,7248 ****
- if (GET_CODE (insn) == CALL_INSN)
- {
-- static struct write_data everything = {0, 1, 1, 1};
--
- if (! CONST_CALL_P (insn))
-! invalidate_memory (&everything);
- invalidate_for_call ();
- }
---- 7116,7121 ----
- if (GET_CODE (insn) == CALL_INSN)
- {
- if (! CONST_CALL_P (insn))
-! invalidate_memory ();
- invalidate_for_call ();
- }
-*************** cse_insn (insn, in_libcall_block)
-*** 7265,7270 ****
- we have just done an invalidate_memory that covers even those. */
- if (GET_CODE (dest) == REG || GET_CODE (dest) == SUBREG
-! || (GET_CODE (dest) == MEM && ! writes_memory.all
-! && ! cse_rtx_addr_varies_p (dest)))
- invalidate (dest, VOIDmode);
- else if (GET_CODE (dest) == STRICT_LOW_PART
---- 7138,7142 ----
- we have just done an invalidate_memory that covers even those. */
- if (GET_CODE (dest) == REG || GET_CODE (dest) == SUBREG
-! || GET_CODE (dest) == MEM)
- invalidate (dest, VOIDmode);
- else if (GET_CODE (dest) == STRICT_LOW_PART
-*************** cse_insn (insn, in_libcall_block)
-*** 7532,7580 ****
- }
-
-- /* Store 1 in *WRITES_PTR for those categories of memory ref
-- that must be invalidated when the expression WRITTEN is stored in.
-- If WRITTEN is null, say everything must be invalidated. */
--
- static void
-! note_mem_written (written, writes_ptr)
-! rtx written;
-! struct write_data *writes_ptr;
-! {
-! static struct write_data everything = {0, 1, 1, 1};
-!
-! if (written == 0)
-! *writes_ptr = everything;
-! else if (GET_CODE (written) == MEM)
-! {
-! /* Pushing or popping the stack invalidates just the stack pointer. */
-! rtx addr = XEXP (written, 0);
-! if ((GET_CODE (addr) == PRE_DEC || GET_CODE (addr) == PRE_INC
-! || GET_CODE (addr) == POST_DEC || GET_CODE (addr) == POST_INC)
-! && GET_CODE (XEXP (addr, 0)) == REG
-! && REGNO (XEXP (addr, 0)) == STACK_POINTER_REGNUM)
-! {
-! writes_ptr->sp = 1;
-! return;
-! }
-! else if (GET_MODE (written) == BLKmode)
-! *writes_ptr = everything;
-! /* (mem (scratch)) means clobber everything. */
-! else if (GET_CODE (addr) == SCRATCH)
-! *writes_ptr = everything;
-! else if (cse_rtx_addr_varies_p (written))
-! {
-! /* A varying address that is a sum indicates an array element,
-! and that's just as good as a structure element
-! in implying that we need not invalidate scalar variables.
-! However, we must allow QImode aliasing of scalars, because the
-! ANSI C standard allows character pointers to alias anything. */
-! if (! ((MEM_IN_STRUCT_P (written)
-! || GET_CODE (XEXP (written, 0)) == PLUS)
-! && GET_MODE (written) != QImode))
-! writes_ptr->all = 1;
-! writes_ptr->nonscalar = 1;
-! }
-! writes_ptr->var = 1;
- }
- }
-
---- 7404,7447 ----
- }
-
- static void
-! invalidate_memory ()
-! {
-! register int i;
-! register struct table_elt *p, *next;
-!
-! for (i = 0; i < NBUCKETS; i++)
-! for (p = table[i]; p; p = next)
-! {
-! next = p->next_same_hash;
-! if (p->in_memory)
-! remove_from_table (p, i);
-! }
-! }
-!
-! static int
-! note_mem_written (mem)
-! register rtx mem;
-! {
-! if (mem == 0 || GET_CODE(mem) != MEM )
-! return 0;
-! else
-! {
-! register rtx addr = XEXP (mem, 0);
-! /* Pushing or popping the stack invalidates just the stack pointer. */
-! if ((GET_CODE (addr) == PRE_DEC || GET_CODE (addr) == PRE_INC
-! || GET_CODE (addr) == POST_DEC || GET_CODE (addr) == POST_INC)
-! && GET_CODE (XEXP (addr, 0)) == REG
-! && REGNO (XEXP (addr, 0)) == STACK_POINTER_REGNUM)
-! {
-! if (reg_tick[STACK_POINTER_REGNUM] >= 0)
-! reg_tick[STACK_POINTER_REGNUM]++;
-!
-! /* This should be *very* rare. */
-! if (TEST_HARD_REG_BIT (hard_regs_in_table, STACK_POINTER_REGNUM))
-! invalidate (stack_pointer_rtx, VOIDmode);
-! return 1;
- }
-+ return 0;
-+ }
- }
-
-*************** note_mem_written (written, writes_ptr)
-*** 7584,7612 ****
- alias with something that is SET or CLOBBERed.
-
-- W points to the writes_memory for this insn, a struct write_data
-- saying which kinds of memory references must be invalidated.
- X is the pattern of the insn. */
-
- static void
-! invalidate_from_clobbers (w, x)
-! struct write_data *w;
- rtx x;
- {
-- /* If W->var is not set, W specifies no action.
-- If W->all is set, this step gets all memory refs
-- so they can be ignored in the rest of this function. */
-- if (w->var)
-- invalidate_memory (w);
--
-- if (w->sp)
-- {
-- if (reg_tick[STACK_POINTER_REGNUM] >= 0)
-- reg_tick[STACK_POINTER_REGNUM]++;
--
-- /* This should be *very* rare. */
-- if (TEST_HARD_REG_BIT (hard_regs_in_table, STACK_POINTER_REGNUM))
-- invalidate (stack_pointer_rtx, VOIDmode);
-- }
--
- if (GET_CODE (x) == CLOBBER)
- {
---- 7451,7460 ----
- alias with something that is SET or CLOBBERed.
-
- X is the pattern of the insn. */
-
- static void
-! invalidate_from_clobbers (x)
- rtx x;
- {
- if (GET_CODE (x) == CLOBBER)
- {
-*************** invalidate_from_clobbers (w, x)
-*** 7615,7619 ****
- {
- if (GET_CODE (ref) == REG || GET_CODE (ref) == SUBREG
-! || (GET_CODE (ref) == MEM && ! w->all))
- invalidate (ref, VOIDmode);
- else if (GET_CODE (ref) == STRICT_LOW_PART
---- 7463,7467 ----
- {
- if (GET_CODE (ref) == REG || GET_CODE (ref) == SUBREG
-! || GET_CODE (ref) == MEM)
- invalidate (ref, VOIDmode);
- else if (GET_CODE (ref) == STRICT_LOW_PART
-*************** invalidate_from_clobbers (w, x)
-*** 7634,7638 ****
- {
- if (GET_CODE (ref) == REG || GET_CODE (ref) == SUBREG
-! || (GET_CODE (ref) == MEM && !w->all))
- invalidate (ref, VOIDmode);
- else if (GET_CODE (ref) == STRICT_LOW_PART
---- 7482,7486 ----
- {
- if (GET_CODE (ref) == REG || GET_CODE (ref) == SUBREG
-! || GET_CODE (ref) == MEM)
- invalidate (ref, VOIDmode);
- else if (GET_CODE (ref) == STRICT_LOW_PART
-*************** cse_around_loop (loop_start)
-*** 7800,7807 ****
- }
-
-- /* Variable used for communications between the next two routines. */
--
-- static struct write_data skipped_writes_memory;
--
- /* Process one SET of an insn that was skipped. We ignore CLOBBERs
- since they are done elsewhere. This function is called via note_stores. */
---- 7648,7651 ----
-*************** invalidate_skipped_set (dest, set)
-*** 7812,7815 ****
---- 7656,7675 ----
- rtx dest;
- {
-+ enum rtx_code code = GET_CODE (dest);
-+
-+ if (code == MEM
-+ && ! note_mem_written (dest) /* If this is not a stack push ... */
-+ /* There are times when an address can appear varying and be a PLUS
-+ during this scan when it would be a fixed address were we to know
-+ the proper equivalences. So invalidate all memory if there is
-+ a BLKmode or nonscalar memory reference or a reference to a
-+ variable address. */
-+ && (MEM_IN_STRUCT_P (dest) || GET_MODE (dest) == BLKmode
-+ || cse_rtx_varies_p (XEXP (dest, 0))))
-+ {
-+ invalidate_memory ();
-+ return;
-+ }
-+
- if (GET_CODE (set) == CLOBBER
- #ifdef HAVE_cc0
-*************** invalidate_skipped_set (dest, set)
-*** 7819,7837 ****
- return;
-
-! if (GET_CODE (dest) == MEM)
-! note_mem_written (dest, &skipped_writes_memory);
-!
-! /* There are times when an address can appear varying and be a PLUS
-! during this scan when it would be a fixed address were we to know
-! the proper equivalences. So promote "nonscalar" to be "all". */
-! if (skipped_writes_memory.nonscalar)
-! skipped_writes_memory.all = 1;
-!
-! if (GET_CODE (dest) == REG || GET_CODE (dest) == SUBREG
-! || (! skipped_writes_memory.all && ! cse_rtx_addr_varies_p (dest)))
-! invalidate (dest, VOIDmode);
-! else if (GET_CODE (dest) == STRICT_LOW_PART
-! || GET_CODE (dest) == ZERO_EXTRACT)
- invalidate (XEXP (dest, 0), GET_MODE (dest));
- }
-
---- 7679,7686 ----
- return;
-
-! if (code == STRICT_LOW_PART || code == ZERO_EXTRACT)
- invalidate (XEXP (dest, 0), GET_MODE (dest));
-+ else if (code == REG || code == SUBREG || code == MEM)
-+ invalidate (dest, VOIDmode);
- }
-
-*************** invalidate_skipped_block (start)
-*** 7845,7850 ****
- {
- rtx insn;
-- static struct write_data init = {0, 0, 0, 0};
-- static struct write_data everything = {0, 1, 1, 1};
-
- for (insn = start; insn && GET_CODE (insn) != CODE_LABEL;
---- 7694,7697 ----
-*************** invalidate_skipped_block (start)
-*** 7854,7867 ****
- continue;
-
-- skipped_writes_memory = init;
--
- if (GET_CODE (insn) == CALL_INSN)
- {
- invalidate_for_call ();
-- skipped_writes_memory = everything;
- }
-
- note_stores (PATTERN (insn), invalidate_skipped_set);
-- invalidate_from_clobbers (&skipped_writes_memory, PATTERN (insn));
- }
- }
---- 7701,7712 ----
- continue;
-
- if (GET_CODE (insn) == CALL_INSN)
- {
-+ if (! CONST_CALL_P (insn))
-+ invalidate_memory ();
- invalidate_for_call ();
- }
-
- note_stores (PATTERN (insn), invalidate_skipped_set);
- }
- }
-*************** cse_set_around_loop (x, insn, loop_start
-*** 7913,7920 ****
- {
- struct table_elt *src_elt;
-- static struct write_data init = {0, 0, 0, 0};
-- struct write_data writes_memory;
--
-- writes_memory = init;
-
- /* If this is a SET, see if we can replace SET_SRC, but ignore SETs that
---- 7758,7761 ----
-*************** cse_set_around_loop (x, insn, loop_start
-*** 7976,7991 ****
-
- /* Now invalidate anything modified by X. */
-! note_mem_written (SET_DEST (x), &writes_memory);
-!
-! if (writes_memory.var)
-! invalidate_memory (&writes_memory);
-!
-! /* See comment on similar code in cse_insn for explanation of these tests. */
-! if (GET_CODE (SET_DEST (x)) == REG || GET_CODE (SET_DEST (x)) == SUBREG
-! || (GET_CODE (SET_DEST (x)) == MEM && ! writes_memory.all
-! && ! cse_rtx_addr_varies_p (SET_DEST (x))))
-! invalidate (SET_DEST (x), VOIDmode);
-! else if (GET_CODE (SET_DEST (x)) == STRICT_LOW_PART
-! || GET_CODE (SET_DEST (x)) == ZERO_EXTRACT)
- invalidate (XEXP (SET_DEST (x), 0), GET_MODE (SET_DEST (x)));
- }
---- 7817,7828 ----
-
- /* Now invalidate anything modified by X. */
-! note_mem_written (SET_DEST (x));
-!
-! /* See comment on similar code in cse_insn for explanation of these tests. */
-! if (GET_CODE (SET_DEST (x)) == REG || GET_CODE (SET_DEST (x)) == SUBREG
-! || GET_CODE (SET_DEST (x)) == MEM)
-! invalidate (SET_DEST (x), VOIDmode);
-! else if (GET_CODE (SET_DEST (x)) == STRICT_LOW_PART
-! || GET_CODE (SET_DEST (x)) == ZERO_EXTRACT)
- invalidate (XEXP (SET_DEST (x), 0), GET_MODE (SET_DEST (x)));
- }
-*************** cse_main (f, nregs, after_loop, file)
-*** 8234,8237 ****
---- 8071,8075 ----
-
- init_recog ();
-+ init_alias_analysis ();
-
- max_reg = nregs;
-diff -rcp2N gcc-2.7.2.2/flags.h gcc-2.7.2.2.f.2/flags.h
-*** gcc-2.7.2.2/flags.h Thu Jun 15 07:34:11 1995
---- gcc-2.7.2.2.f.2/flags.h Fri Jan 10 23:18:22 1997
-*************** extern int flag_unroll_loops;
-*** 204,207 ****
---- 204,221 ----
- extern int flag_unroll_all_loops;
-
-+ /* Nonzero forces all invariant computations in loops to be moved
-+ outside the loop. */
-+
-+ extern int flag_move_all_movables;
-+
-+ /* Nonzero forces all general induction variables in loops to be
-+ strength reduced. */
-+
-+ extern int flag_reduce_all_givs;
-+
-+ /* Nonzero gets another run of loop_optimize performed. */
-+
-+ extern int flag_rerun_loop_opt;
-+
- /* Nonzero for -fcse-follow-jumps:
- have cse follow jumps to do a more extensive job. */
-*************** extern int flag_gnu_linker;
-*** 339,342 ****
---- 353,369 ----
- /* Tag all structures with __attribute__(packed) */
- extern int flag_pack_struct;
-+
-+ /* 1 if alias checking is enabled: symbols do not alias each other
-+ and parameters do not alias the current stack frame. */
-+ extern int flag_alias_check;
-+
-+ /* This flag is only tested if alias checking is enabled.
-+ 0 if pointer arguments may alias each other. True in C.
-+ 1 if pointer arguments may not alias each other but may alias
-+ global variables.
-+ 2 if pointer arguments may not alias each other and may not
-+ alias global variables. True in Fortran.
-+ The value is ignored if flag_alias_check is 0. */
-+ extern int flag_argument_noalias;
-
- /* Other basic status info about current function. */
-diff -rcp2N gcc-2.7.2.2/fold-const.c gcc-2.7.2.2.f.2/fold-const.c
-*** gcc-2.7.2.2/fold-const.c Fri Sep 15 18:26:12 1995
---- gcc-2.7.2.2.f.2/fold-const.c Sun Feb 23 15:25:58 1997
-*************** static tree unextend PROTO((tree, int, i
-*** 80,83 ****
---- 80,84 ----
- static tree fold_truthop PROTO((enum tree_code, tree, tree, tree));
- static tree strip_compound_expr PROTO((tree, tree));
-+ static int multiple_of_p PROTO((tree, tree, tree));
-
- #ifndef BRANCH_COST
-*************** strip_compound_expr (t, s)
-*** 3065,3068 ****
---- 3066,3169 ----
- }
-
-+ /* Determine if first argument is a multiple of second argument.
-+ Return 0 if it is not, or is not easily determined to so be.
-+
-+ An example of the sort of thing we care about (at this point --
-+ this routine could surely be made more general, and expanded
-+ to do what the *_DIV_EXPR's fold() cases do now) is discovering
-+ that
-+
-+ SAVE_EXPR (I) * SAVE_EXPR (J * 8)
-+
-+ is a multiple of
-+
-+ SAVE_EXPR (J * 8)
-+
-+ when we know that the two `SAVE_EXPR (J * 8)' nodes are the
-+ same node (which means they will have the same value at run
-+ time, even though we don't know when they'll be assigned).
-+
-+ This code also handles discovering that
-+
-+ SAVE_EXPR (I) * SAVE_EXPR (J * 8)
-+
-+ is a multiple of
-+
-+ 8
-+
-+ (of course) so we don't have to worry about dealing with a
-+ possible remainder.
-+
-+ Note that we _look_ inside a SAVE_EXPR only to determine
-+ how it was calculated; it is not safe for fold() to do much
-+ of anything else with the internals of a SAVE_EXPR, since
-+ fold() cannot know when it will be evaluated at run time.
-+ For example, the latter example above _cannot_ be implemented
-+ as
-+
-+ SAVE_EXPR (I) * J
-+
-+ or any variant thereof, since the value of J at evaluation time
-+ of the original SAVE_EXPR is not necessarily the same at the time
-+ the new expression is evaluated. The only optimization of this
-+ sort that would be valid is changing
-+
-+ SAVE_EXPR (I) * SAVE_EXPR (SAVE_EXPR (J) * 8)
-+ divided by
-+ 8
-+
-+ to
-+
-+ SAVE_EXPR (I) * SAVE_EXPR (J)
-+
-+ (where the same SAVE_EXPR (J) is used in the original and the
-+ transformed version). */
-+
-+ static int
-+ multiple_of_p (type, top, bottom)
-+ tree type;
-+ tree top;
-+ tree bottom;
-+ {
-+ if (operand_equal_p (top, bottom, 0))
-+ return 1;
-+
-+ if (TREE_CODE (type) != INTEGER_TYPE)
-+ return 0;
-+
-+ switch (TREE_CODE (top))
-+ {
-+ case MULT_EXPR:
-+ return (multiple_of_p (type, TREE_OPERAND (top, 0), bottom)
-+ || multiple_of_p (type, TREE_OPERAND (top, 1), bottom));
-+
-+ case PLUS_EXPR:
-+ case MINUS_EXPR:
-+ return (multiple_of_p (type, TREE_OPERAND (top, 0), bottom)
-+ && multiple_of_p (type, TREE_OPERAND (top, 1), bottom));
-+
-+ case NOP_EXPR:
-+ /* Punt if conversion from non-integral or wider integral type. */
-+ if ((TREE_CODE (TREE_TYPE (TREE_OPERAND (top, 0))) != INTEGER_TYPE)
-+ || (TYPE_PRECISION (type)
-+ < TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (top, 0)))))
-+ return 0;
-+ /* Fall through. */
-+ case SAVE_EXPR:
-+ return multiple_of_p (type, TREE_OPERAND (top, 0), bottom);
-+
-+ case INTEGER_CST:
-+ if ((TREE_CODE (bottom) != INTEGER_CST)
-+ || (tree_int_cst_sgn (top) < 0)
-+ || (tree_int_cst_sgn (bottom) < 0))
-+ return 0;
-+ return integer_zerop (const_binop (TRUNC_MOD_EXPR,
-+ top, bottom, 0));
-+
-+ default:
-+ return 0;
-+ }
-+ }
-+
- /* Perform constant folding and related simplification of EXPR.
- The related simplifications include x*1 => x, x*0 => 0, etc.,
-*************** fold (expr)
-*** 4010,4013 ****
---- 4111,4121 ----
- case FLOOR_DIV_EXPR:
- case CEIL_DIV_EXPR:
-+ if (integer_onep (arg1))
-+ return non_lvalue (convert (type, arg0));
-+ /* If arg0 is a multiple of arg1, then rewrite to the fastest div
-+ operation, EXACT_DIV_EXPR. Otherwise, handle folding of
-+ general divide. */
-+ if (multiple_of_p (type, arg0, arg1))
-+ return fold (build (EXACT_DIV_EXPR, type, arg0, arg1));
- case EXACT_DIV_EXPR:
- if (integer_onep (arg1))
-diff -rcp2N gcc-2.7.2.2/gcc.texi gcc-2.7.2.2.f.2/gcc.texi
-*** gcc-2.7.2.2/gcc.texi Thu Feb 20 19:24:19 1997
---- gcc-2.7.2.2.f.2/gcc.texi Sun Feb 23 16:16:49 1997
-*************** original English.
-*** 149,152 ****
---- 149,153 ----
- @sp 3
- @center Last updated 29 June 1996
-+ @center (Revised for GNU Fortran 1997-01-10)
- @sp 1
- @c The version number appears twice more in this file.
-diff -rcp2N gcc-2.7.2.2/glimits.h gcc-2.7.2.2.f.2/glimits.h
-*** gcc-2.7.2.2/glimits.h Wed Sep 29 17:30:54 1993
---- gcc-2.7.2.2.f.2/glimits.h Thu Dec 19 12:31:08 1996
-***************
-*** 64,68 ****
- (Same as `int'). */
- #ifndef __LONG_MAX__
-! #define __LONG_MAX__ 2147483647L
- #endif
- #undef LONG_MIN
---- 64,72 ----
- (Same as `int'). */
- #ifndef __LONG_MAX__
-! # ifndef __alpha__
-! # define __LONG_MAX__ 2147483647L
-! # else
-! # define __LONG_MAX__ 9223372036854775807LL
-! # endif /* __alpha__ */
- #endif
- #undef LONG_MIN
-diff -rcp2N gcc-2.7.2.2/invoke.texi gcc-2.7.2.2.f.2/invoke.texi
-*** gcc-2.7.2.2/invoke.texi Tue Oct 3 11:40:43 1995
---- gcc-2.7.2.2.f.2/invoke.texi Sun Feb 23 16:18:06 1997
-***************
-*** 1,3 ****
-! @c Copyright (C) 1988, 89, 92, 93, 94, 1995 Free Software Foundation, Inc.
- @c This is part of the GCC manual.
- @c For copying conditions, see the file gcc.texi.
---- 1,3 ----
-! @c Copyright (C) 1988, 89, 92-95, 1997 Free Software Foundation, Inc.
- @c This is part of the GCC manual.
- @c For copying conditions, see the file gcc.texi.
-*************** in the following sections.
-*** 149,152 ****
---- 149,153 ----
- -fschedule-insns2 -fstrength-reduce -fthread-jumps
- -funroll-all-loops -funroll-loops
-+ -fmove-all-movables -freduce-all-givs -frerun-loop-opt
- -O -O0 -O1 -O2 -O3
- @end smallexample
-*************** in addition to the above:
-*** 331,334 ****
---- 332,337 ----
- -fshort-double -fvolatile -fvolatile-global
- -fverbose-asm -fpack-struct +e0 +e1
-+ -fargument-alias -fargument-noalias
-+ -fargument-noalias-global
- @end smallexample
- @end table
-*************** and usually makes programs run more slow
-*** 1941,1944 ****
---- 1944,1992 ----
- implies @samp{-fstrength-reduce} as well as @samp{-frerun-cse-after-loop}.
-
-+ @item -fmove-all-movables
-+ Forces all invariant computations in loops to be moved
-+ outside the loop.
-+ This option is provided primarily to improve performance
-+ for some Fortran code, though it might improve code written
-+ in other languages.
-+
-+ @emph{Note:} When compiling programs written in Fortran,
-+ this option is enabled by default.
-+
-+ Analysis of Fortran code optimization and the resulting
-+ optimizations triggered by this option, and the
-+ @samp{-freduce-all-givs} and @samp{-frerun-loop-opt}
-+ options as well, were
-+ contributed by Toon Moene (@code{toon@@moene.indiv.nluug.nl}).
-+
-+ These three options are intended to be removed someday, once
-+ they have helped determine the efficacy of various
-+ approaches to improving the performance of Fortran code.
-+
-+ Please let us (@code{fortran@@gnu.ai.mit.edu})
-+ know how use of these options affects
-+ the performance of your production code.
-+ We're very interested in code that runs @emph{slower}
-+ when these options are @emph{enabled}.
-+
-+ @item -freduce-all-givs
-+ Forces all general-induction variables in loops to be
-+ strength-reduced.
-+ This option is provided primarily to improve performance
-+ for some Fortran code, though it might improve code written
-+ in other languages.
-+
-+ @emph{Note:} When compiling programs written in Fortran,
-+ this option is enabled by default.
-+
-+ @item -frerun-loop-opt
-+ Runs loop optimizations a second time.
-+ This option is provided primarily to improve performance
-+ for some Fortran code, though it might improve code written
-+ in other languages.
-+
-+ @emph{Note:} When compiling programs written in Fortran,
-+ this option is enabled by default.
-+
- @item -fno-peephole
- Disable any machine-specific peephole optimizations.
-*************** compilation).
-*** 4229,4232 ****
---- 4277,4352 ----
- With @samp{+e1}, G++ actually generates the code implementing virtual
- functions defined in the code, and makes them publicly visible.
-+
-+ @cindex aliasing of parameters
-+ @cindex parameters, aliased
-+ @item -fargument-alias
-+ @item -fargument-noalias
-+ @item -fargument-noalias-global
-+ Specify the possible relationships among parameters and between
-+ parameters and global data.
-+
-+ @samp{-fargument-alias} specifies that arguments (parameters) may
-+ alias each other and may alias global storage.
-+ @samp{-fargument-noalias} specifies that arguments do not alias
-+ each other, but may alias global storage.
-+ @samp{-fargument-noalias-global} specifies that arguments do not
-+ alias each other and do not alias global storage.
-+
-+ For code written in C, C++, and Objective-C, @samp{-fargument-alias}
-+ is the default.
-+ For code written in Fortran, @samp{-fargument-noalias-global} is
-+ the default, though this is pertinent only on systems where
-+ @code{g77} is installed.
-+ (See the documentation for other compilers for information on the
-+ defaults for their respective languages.)
-+
-+ Normally, @code{gcc} assumes that a write through a pointer
-+ passed as a parameter to the current function might modify a
-+ value pointed to by another pointer passed as a parameter, or
-+ in global storage.
-+
-+ For example, consider this code:
-+
-+ @example
-+ void x(int *i, int *j)
-+ @{
-+ extern int k;
-+
-+ ++*i;
-+ ++*j;
-+ ++k;
-+ @}
-+ @end example
-+
-+ When compiling the above function, @code{gcc} assumes that @samp{i} might
-+ be a pointer to the same variable as @samp{j}, and that either @samp{i},
-+ @samp{j}, or both might be a pointer to @samp{k}.
-+
-+ Therefore, @code{gcc} does not assume it can generate code to read
-+ @samp{*i}, @samp{*j}, and @samp{k} into separate registers, increment
-+ each register, then write the incremented values back out.
-+
-+ Instead, @code{gcc} must generate code that reads @samp{*i},
-+ increments it, and writes it back before reading @samp{*j},
-+ in case @samp{i} and @samp{j} are aliased, and, similarly,
-+ that writes @samp{*j} before reading @samp{k}.
-+ The result is code that, on many systems, takes longer to execute,
-+ due to the way many processors schedule instruction execution.
-+
-+ Compiling the above code with the @samp{-fargument-noalias} option
-+ allows @code{gcc} to assume that @samp{i} and @samp{j} do not alias
-+ each other, but either might alias @samp{k}.
-+
-+ Compiling the above code with the @samp{-fargument-noalias-global}
-+ option allows @code{gcc} to assume that no combination of @samp{i},
-+ @samp{j}, and @samp{k} are aliases for each other.
-+
-+ @emph{Note:} Use the @samp{-fargument-noalias} and
-+ @samp{-fargument-noalias-global} options with care.
-+ While they can result in faster executables, they can
-+ also result in executables with subtle bugs, bugs that
-+ show up only when compiled for specific target systems,
-+ or bugs that show up only when compiled by specific versions
-+ of @code{g77}.
- @end table
-
-diff -rcp2N gcc-2.7.2.2/local-alloc.c gcc-2.7.2.2.f.2/local-alloc.c
-*** gcc-2.7.2.2/local-alloc.c Mon Aug 21 13:15:44 1995
---- gcc-2.7.2.2.f.2/local-alloc.c Fri Jan 10 23:18:22 1997
-*************** validate_equiv_mem_from_store (dest, set
-*** 545,549 ****
- && reg_overlap_mentioned_p (dest, equiv_mem))
- || (GET_CODE (dest) == MEM
-! && true_dependence (dest, equiv_mem)))
- equiv_mem_modified = 1;
- }
---- 545,549 ----
- && reg_overlap_mentioned_p (dest, equiv_mem))
- || (GET_CODE (dest) == MEM
-! && true_dependence (dest, VOIDmode, equiv_mem, rtx_varies_p)))
- equiv_mem_modified = 1;
- }
-*************** memref_referenced_p (memref, x)
-*** 630,634 ****
-
- case MEM:
-! if (true_dependence (memref, x))
- return 1;
- break;
---- 630,634 ----
-
- case MEM:
-! if (true_dependence (memref, VOIDmode, x, rtx_varies_p))
- return 1;
- break;
-diff -rcp2N gcc-2.7.2.2/loop.c gcc-2.7.2.2.f.2/loop.c
-*** gcc-2.7.2.2/loop.c Thu Feb 20 19:24:20 1997
---- gcc-2.7.2.2.f.2/loop.c Sun Feb 23 15:35:42 1997
-*************** int *loop_number_exit_count;
-*** 111,116 ****
- unsigned HOST_WIDE_INT loop_n_iterations;
-
-! /* Nonzero if there is a subroutine call in the current loop.
-! (unknown_address_altered is also nonzero in this case.) */
-
- static int loop_has_call;
---- 111,115 ----
- unsigned HOST_WIDE_INT loop_n_iterations;
-
-! /* Nonzero if there is a subroutine call in the current loop. */
-
- static int loop_has_call;
-*************** static char *moved_once;
-*** 160,164 ****
- here, we just turn on unknown_address_altered. */
-
-! #define NUM_STORES 20
- static rtx loop_store_mems[NUM_STORES];
-
---- 159,163 ----
- here, we just turn on unknown_address_altered. */
-
-! #define NUM_STORES 50
- static rtx loop_store_mems[NUM_STORES];
-
-*************** move_movables (movables, threshold, insn
-*** 1629,1632 ****
---- 1628,1632 ----
-
- if (already_moved[regno]
-+ || flag_move_all_movables
- || (threshold * savings * m->lifetime) >= insn_count
- || (m->forces && m->forces->done
-*************** prescan_loop (start, end)
-*** 2199,2203 ****
- else if (GET_CODE (insn) == CALL_INSN)
- {
-! unknown_address_altered = 1;
- loop_has_call = 1;
- }
---- 2199,2204 ----
- else if (GET_CODE (insn) == CALL_INSN)
- {
-! if (! CONST_CALL_P (insn))
-! unknown_address_altered = 1;
- loop_has_call = 1;
- }
-*************** invariant_p (x)
-*** 2777,2781 ****
- /* See if there is any dependence between a store and this load. */
- for (i = loop_store_mems_idx - 1; i >= 0; i--)
-! if (true_dependence (loop_store_mems[i], x))
- return 0;
-
---- 2778,2782 ----
- /* See if there is any dependence between a store and this load. */
- for (i = loop_store_mems_idx - 1; i >= 0; i--)
-! if (true_dependence (loop_store_mems[i], VOIDmode, x, rtx_varies_p))
- return 0;
-
-*************** strength_reduce (scan_start, end, loop_t
-*** 3821,3826 ****
- exit. */
-
-! if (v->lifetime * threshold * benefit < insn_count
-! && ! bl->reversed)
- {
- if (loop_dump_stream)
---- 3822,3827 ----
- exit. */
-
-! if ( ! flag_reduce_all_givs && v->lifetime * threshold * benefit < insn_count
-! && ! bl->reversed )
- {
- if (loop_dump_stream)
-*************** record_giv (v, insn, src_reg, dest_reg,
-*** 4375,4378 ****
---- 4376,4381 ----
- v->final_value = 0;
- v->same_insn = 0;
-+ v->unrolled = 0;
-+ v->shared = 0;
-
- /* The v->always_computable field is used in update_giv_derive, to
-*************** check_final_value (v, loop_start, loop_e
-*** 4652,4657 ****
- if (GET_CODE (p) == JUMP_INSN && JUMP_LABEL (p)
- && LABEL_NAME (JUMP_LABEL (p))
-! && ((INSN_LUID (JUMP_LABEL (p)) < INSN_LUID (v->insn)
-! && INSN_LUID (JUMP_LABEL (p)) > INSN_LUID (loop_start))
- || (INSN_LUID (JUMP_LABEL (p)) > INSN_LUID (last_giv_use)
- && INSN_LUID (JUMP_LABEL (p)) < INSN_LUID (loop_end))))
---- 4655,4663 ----
- if (GET_CODE (p) == JUMP_INSN && JUMP_LABEL (p)
- && LABEL_NAME (JUMP_LABEL (p))
-! && ((INSN_UID (JUMP_LABEL (p)) >= max_uid_for_loop)
-! || (INSN_UID (v->insn) >= max_uid_for_loop)
-! || (INSN_UID (last_giv_use) >= max_uid_for_loop)
-! || (INSN_LUID (JUMP_LABEL (p)) < INSN_LUID (v->insn)
-! && INSN_LUID (JUMP_LABEL (p)) > INSN_LUID (loop_start))
- || (INSN_LUID (JUMP_LABEL (p)) > INSN_LUID (last_giv_use)
- && INSN_LUID (JUMP_LABEL (p)) < INSN_LUID (loop_end))))
-*************** emit_iv_add_mult (b, m, a, reg, insert_b
-*** 5560,5563 ****
---- 5566,5571 ----
-
- emit_insn_before (seq, insert_before);
-+
-+ record_base_value (REGNO (reg), b);
- }
-
-diff -rcp2N gcc-2.7.2.2/loop.h gcc-2.7.2.2.f.2/loop.h
-*** gcc-2.7.2.2/loop.h Fri Jul 14 08:23:28 1995
---- gcc-2.7.2.2.f.2/loop.h Fri Jan 10 23:18:23 1997
-*************** struct induction
-*** 89,92 ****
---- 89,95 ----
- we won't use it to eliminate a biv, it
- would probably lose. */
-+ unsigned unrolled : 1; /* 1 if new register has been allocated in
-+ unrolled loop. */
-+ unsigned shared : 1;
- int lifetime; /* Length of life of this giv */
- int times_used; /* # times this giv is used. */
-diff -rcp2N gcc-2.7.2.2/real.c gcc-2.7.2.2.f.2/real.c
-*** gcc-2.7.2.2/real.c Tue Aug 15 17:57:18 1995
---- gcc-2.7.2.2.f.2/real.c Thu Dec 19 12:31:09 1996
-*************** make_nan (nan, sign, mode)
-*** 5625,5633 ****
- }
-
-! /* Convert an SFmode target `float' value to a REAL_VALUE_TYPE.
-! This is the inverse of the function `etarsingle' invoked by
- REAL_VALUE_TO_TARGET_SINGLE. */
-
- REAL_VALUE_TYPE
- ereal_from_float (f)
- HOST_WIDE_INT f;
---- 5625,5699 ----
- }
-
-! /* This is the inverse of the function `etarsingle' invoked by
- REAL_VALUE_TO_TARGET_SINGLE. */
-
- REAL_VALUE_TYPE
-+ ereal_unto_float (f)
-+ long f;
-+ {
-+ REAL_VALUE_TYPE r;
-+ unsigned EMUSHORT s[2];
-+ unsigned EMUSHORT e[NE];
-+
-+ /* Convert 32 bit integer to array of 16 bit pieces in target machine order.
-+ This is the inverse operation to what the function `endian' does. */
-+ if (REAL_WORDS_BIG_ENDIAN)
-+ {
-+ s[0] = (unsigned EMUSHORT) (f >> 16);
-+ s[1] = (unsigned EMUSHORT) f;
-+ }
-+ else
-+ {
-+ s[0] = (unsigned EMUSHORT) f;
-+ s[1] = (unsigned EMUSHORT) (f >> 16);
-+ }
-+ /* Convert and promote the target float to E-type. */
-+ e24toe (s, e);
-+ /* Output E-type to REAL_VALUE_TYPE. */
-+ PUT_REAL (e, &r);
-+ return r;
-+ }
-+
-+
-+ /* This is the inverse of the function `etardouble' invoked by
-+ REAL_VALUE_TO_TARGET_DOUBLE. */
-+
-+ REAL_VALUE_TYPE
-+ ereal_unto_double (d)
-+ long d[];
-+ {
-+ REAL_VALUE_TYPE r;
-+ unsigned EMUSHORT s[4];
-+ unsigned EMUSHORT e[NE];
-+
-+ /* Convert array of HOST_WIDE_INT to equivalent array of 16-bit pieces. */
-+ if (REAL_WORDS_BIG_ENDIAN)
-+ {
-+ s[0] = (unsigned EMUSHORT) (d[0] >> 16);
-+ s[1] = (unsigned EMUSHORT) d[0];
-+ s[2] = (unsigned EMUSHORT) (d[1] >> 16);
-+ s[3] = (unsigned EMUSHORT) d[1];
-+ }
-+ else
-+ {
-+ /* Target float words are little-endian. */
-+ s[0] = (unsigned EMUSHORT) d[0];
-+ s[1] = (unsigned EMUSHORT) (d[0] >> 16);
-+ s[2] = (unsigned EMUSHORT) d[1];
-+ s[3] = (unsigned EMUSHORT) (d[1] >> 16);
-+ }
-+ /* Convert target double to E-type. */
-+ e53toe (s, e);
-+ /* Output E-type to REAL_VALUE_TYPE. */
-+ PUT_REAL (e, &r);
-+ return r;
-+ }
-+
-+
-+ /* Convert an SFmode target `float' value to a REAL_VALUE_TYPE.
-+ This is somewhat like ereal_unto_float, but the input types
-+ for these are different. */
-+
-+ REAL_VALUE_TYPE
- ereal_from_float (f)
- HOST_WIDE_INT f;
-*************** ereal_from_float (f)
-*** 5658,5663 ****
-
- /* Convert a DFmode target `double' value to a REAL_VALUE_TYPE.
-! This is the inverse of the function `etardouble' invoked by
-! REAL_VALUE_TO_TARGET_DOUBLE.
-
- The DFmode is stored as an array of HOST_WIDE_INT in the target's
---- 5724,5729 ----
-
- /* Convert a DFmode target `double' value to a REAL_VALUE_TYPE.
-! This is somewhat like ereal_unto_double, but the input types
-! for these are different.
-
- The DFmode is stored as an array of HOST_WIDE_INT in the target's
-diff -rcp2N gcc-2.7.2.2/real.h gcc-2.7.2.2.f.2/real.h
-*** gcc-2.7.2.2/real.h Thu Jun 15 07:57:56 1995
---- gcc-2.7.2.2.f.2/real.h Thu Dec 19 12:31:09 1996
-*************** extern void ereal_to_decimal PROTO((REAL
-*** 152,155 ****
---- 152,157 ----
- extern int ereal_cmp PROTO((REAL_VALUE_TYPE, REAL_VALUE_TYPE));
- extern int ereal_isneg PROTO((REAL_VALUE_TYPE));
-+ extern REAL_VALUE_TYPE ereal_unto_float PROTO((long));
-+ extern REAL_VALUE_TYPE ereal_unto_double PROTO((long *));
- extern REAL_VALUE_TYPE ereal_from_float PROTO((HOST_WIDE_INT));
- extern REAL_VALUE_TYPE ereal_from_double PROTO((HOST_WIDE_INT *));
-*************** extern REAL_VALUE_TYPE real_value_trunca
-*** 197,200 ****
---- 199,208 ----
- /* IN is a REAL_VALUE_TYPE. OUT is a long. */
- #define REAL_VALUE_TO_TARGET_SINGLE(IN, OUT) ((OUT) = etarsingle ((IN)))
-+
-+ /* Inverse of REAL_VALUE_TO_TARGET_DOUBLE. */
-+ #define REAL_VALUE_UNTO_TARGET_DOUBLE(d) (ereal_unto_double (d))
-+
-+ /* Inverse of REAL_VALUE_TO_TARGET_SINGLE. */
-+ #define REAL_VALUE_UNTO_TARGET_SINGLE(f) (ereal_unto_float (f))
-
- /* d is an array of HOST_WIDE_INT that holds a double precision
-diff -rcp2N gcc-2.7.2.2/reload.c gcc-2.7.2.2.f.2/reload.c
-*** gcc-2.7.2.2/reload.c Sat Nov 11 08:23:54 1995
---- gcc-2.7.2.2.f.2/reload.c Thu Feb 27 23:03:05 1997
-***************
-*** 1,4 ****
- /* Search an insn for pseudo regs that must be in hard regs and are not.
-! Copyright (C) 1987, 88, 89, 92, 93, 94, 1995 Free Software Foundation, Inc.
-
- This file is part of GNU CC.
---- 1,4 ----
- /* Search an insn for pseudo regs that must be in hard regs and are not.
-! Copyright (C) 1987, 88, 89, 92-5, 1996 Free Software Foundation, Inc.
-
- This file is part of GNU CC.
-*************** static int push_secondary_reload PROTO((
-*** 292,295 ****
---- 292,296 ----
- enum machine_mode, enum reload_type,
- enum insn_code *));
-+ static enum reg_class find_valid_class PROTO((enum machine_mode, int));
- static int push_reload PROTO((rtx, rtx, rtx *, rtx *, enum reg_class,
- enum machine_mode, enum machine_mode,
-*************** push_secondary_reload (in_p, x, opnum, o
-*** 361,364 ****
---- 362,368 ----
- mode and object being reloaded. */
- if (GET_CODE (x) == SUBREG
-+ #ifdef CLASS_CANNOT_CHANGE_SIZE
-+ && reload_class != CLASS_CANNOT_CHANGE_SIZE
-+ #endif
- && (GET_MODE_SIZE (GET_MODE (x))
- > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
-*************** clear_secondary_mem ()
-*** 689,692 ****
---- 693,728 ----
- #endif /* SECONDARY_MEMORY_NEEDED */
-
-+ /* Find the largest class for which every register number plus N is valid in
-+ M1 (if in range). Abort if no such class exists. */
-+
-+ static enum reg_class
-+ find_valid_class (m1, n)
-+ enum machine_mode m1;
-+ int n;
-+ {
-+ int class;
-+ int regno;
-+ enum reg_class best_class;
-+ int best_size = 0;
-+
-+ for (class = 1; class < N_REG_CLASSES; class++)
-+ {
-+ int bad = 0;
-+ for (regno = 0; regno < FIRST_PSEUDO_REGISTER && ! bad; regno++)
-+ if (TEST_HARD_REG_BIT (reg_class_contents[class], regno)
-+ && TEST_HARD_REG_BIT (reg_class_contents[class], regno + n)
-+ && ! HARD_REGNO_MODE_OK (regno + n, m1))
-+ bad = 1;
-+
-+ if (! bad && reg_class_size[class] > best_size)
-+ best_class = class, best_size = reg_class_size[class];
-+ }
-+
-+ if (best_size == 0)
-+ abort ();
-+
-+ return best_class;
-+ }
-+
- /* Record one reload that needs to be performed.
- IN is an rtx saying where the data are to be found before this instruction.
-*************** push_reload (in, out, inloc, outloc, cla
-*** 894,898 ****
- && GET_CODE (SUBREG_REG (in)) == REG
- && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
-! && (! HARD_REGNO_MODE_OK (REGNO (SUBREG_REG (in)), inmode)
- || (GET_MODE_SIZE (inmode) <= UNITS_PER_WORD
- && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
---- 930,935 ----
- && GET_CODE (SUBREG_REG (in)) == REG
- && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
-! && (! HARD_REGNO_MODE_OK (REGNO (SUBREG_REG (in)) + SUBREG_WORD (in),
-! inmode)
- || (GET_MODE_SIZE (inmode) <= UNITS_PER_WORD
- && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
-*************** push_reload (in, out, inloc, outloc, cla
-*** 909,913 ****
- output before the outer reload. */
- push_reload (SUBREG_REG (in), NULL_RTX, &SUBREG_REG (in), NULL_PTR,
-! GENERAL_REGS, VOIDmode, VOIDmode, 0, 0, opnum, type);
- dont_remove_subreg = 1;
- }
---- 946,951 ----
- output before the outer reload. */
- push_reload (SUBREG_REG (in), NULL_RTX, &SUBREG_REG (in), NULL_PTR,
-! find_valid_class (inmode, SUBREG_WORD (in)),
-! VOIDmode, VOIDmode, 0, 0, opnum, type);
- dont_remove_subreg = 1;
- }
-*************** push_reload (in, out, inloc, outloc, cla
-*** 982,986 ****
- && GET_CODE (SUBREG_REG (out)) == REG
- && REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
-! && (! HARD_REGNO_MODE_OK (REGNO (SUBREG_REG (out)), outmode)
- || (GET_MODE_SIZE (outmode) <= UNITS_PER_WORD
- && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (out)))
---- 1020,1025 ----
- && GET_CODE (SUBREG_REG (out)) == REG
- && REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
-! && (! HARD_REGNO_MODE_OK (REGNO (SUBREG_REG (out)) + SUBREG_WORD (out),
-! outmode)
- || (GET_MODE_SIZE (outmode) <= UNITS_PER_WORD
- && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (out)))
-*************** push_reload (in, out, inloc, outloc, cla
-*** 998,1002 ****
- dont_remove_subreg = 1;
- push_reload (SUBREG_REG (out), SUBREG_REG (out), &SUBREG_REG (out),
-! &SUBREG_REG (out), ALL_REGS, VOIDmode, VOIDmode, 0, 0,
- opnum, RELOAD_OTHER);
- }
---- 1037,1043 ----
- dont_remove_subreg = 1;
- push_reload (SUBREG_REG (out), SUBREG_REG (out), &SUBREG_REG (out),
-! &SUBREG_REG (out),
-! find_valid_class (outmode, SUBREG_WORD (out)),
-! VOIDmode, VOIDmode, 0, 0,
- opnum, RELOAD_OTHER);
- }
-*************** find_equiv_reg (goal, insn, class, other
-*** 5518,5522 ****
- and is also a register that appears in the address of GOAL. */
-
-! if (goal_mem && value == SET_DEST (PATTERN (where))
- && refers_to_regno_for_reload_p (valueno,
- (valueno
---- 5559,5563 ----
- and is also a register that appears in the address of GOAL. */
-
-! if (goal_mem && value == SET_DEST (single_set (where))
- && refers_to_regno_for_reload_p (valueno,
- (valueno
-*************** debug_reload()
-*** 5900,5904 ****
-
- if (reload_nocombine[r])
-! fprintf (stderr, ", can combine", reload_nocombine[r]);
-
- if (reload_secondary_p[r])
---- 5941,5945 ----
-
- if (reload_nocombine[r])
-! fprintf (stderr, ", can't combine %d", reload_nocombine[r]);
-
- if (reload_secondary_p[r])
-diff -rcp2N gcc-2.7.2.2/rtl.h gcc-2.7.2.2.f.2/rtl.h
-*** gcc-2.7.2.2/rtl.h Thu Jun 15 08:03:16 1995
---- gcc-2.7.2.2.f.2/rtl.h Fri Jan 10 23:18:23 1997
-*************** enum reg_note { REG_DEAD = 1, REG_INC =
-*** 349,353 ****
- REG_NONNEG = 8, REG_NO_CONFLICT = 9, REG_UNUSED = 10,
- REG_CC_SETTER = 11, REG_CC_USER = 12, REG_LABEL = 13,
-! REG_DEP_ANTI = 14, REG_DEP_OUTPUT = 15 };
-
- /* Define macros to extract and insert the reg-note kind in an EXPR_LIST. */
---- 349,353 ----
- REG_NONNEG = 8, REG_NO_CONFLICT = 9, REG_UNUSED = 10,
- REG_CC_SETTER = 11, REG_CC_USER = 12, REG_LABEL = 13,
-! REG_DEP_ANTI = 14, REG_DEP_OUTPUT = 15, REG_NOALIAS = 16 };
-
- /* Define macros to extract and insert the reg-note kind in an EXPR_LIST. */
-*************** extern char *reg_note_name[];
-*** 432,436 ****
- #define NOTE_INSN_FUNCTION_BEG -13
-
--
- #if 0 /* These are not used, and I don't know what they were for. --rms. */
- #define NOTE_DECL_NAME(INSN) ((INSN)->fld[3].rtstr)
---- 432,435 ----
-*************** extern char *note_insn_name[];
-*** 576,579 ****
---- 575,579 ----
- /* For a TRAP_IF rtx, TRAP_CONDITION is an expression. */
- #define TRAP_CONDITION(RTX) ((RTX)->fld[0].rtx)
-+ #define TRAP_CODE(RTX) ((RTX)->fld[1].rtint)
-
- /* 1 in a SYMBOL_REF if it addresses this function's constants pool. */
-*************** extern rtx eliminate_constant_term PROTO
-*** 817,820 ****
---- 817,830 ----
- extern rtx expand_complex_abs PROTO((enum machine_mode, rtx, rtx, int));
- extern enum machine_mode choose_hard_reg_mode PROTO((int, int));
-+ extern int rtx_varies_p PROTO((rtx));
-+ extern int may_trap_p PROTO((rtx));
-+ extern int side_effects_p PROTO((rtx));
-+ extern int volatile_refs_p PROTO((rtx));
-+ extern int volatile_insn_p PROTO((rtx));
-+ extern void remove_note PROTO((rtx, rtx));
-+ extern void note_stores PROTO((rtx, void (*)()));
-+ extern int refers_to_regno_p PROTO((int, int, rtx, rtx *));
-+ extern int reg_overlap_mentioned_p PROTO((rtx, rtx));
-+
-
- /* Maximum number of parallel sets and clobbers in any insn in this fn.
-*************** extern rtx *regno_reg_rtx;
-*** 967,968 ****
---- 977,985 ----
-
- extern int rtx_to_tree_code PROTO((enum rtx_code));
-+
-+ extern int true_dependence PROTO((rtx, enum machine_mode, rtx, int (*)()));
-+ extern int read_dependence PROTO((rtx, rtx));
-+ extern int anti_dependence PROTO((rtx, rtx));
-+ extern int output_dependence PROTO((rtx, rtx));
-+ extern void init_alias_analysis PROTO((void));
-+ extern void end_alias_analysis PROTO((void));
-diff -rcp2N gcc-2.7.2.2/sched.c gcc-2.7.2.2.f.2/sched.c
-*** gcc-2.7.2.2/sched.c Thu Jun 15 08:06:39 1995
---- gcc-2.7.2.2.f.2/sched.c Fri Jan 10 23:18:24 1997
-*************** Boston, MA 02111-1307, USA. */
-*** 126,129 ****
---- 126,132 ----
- #include "insn-attr.h"
-
-+ extern char *reg_known_equiv_p;
-+ extern rtx *reg_known_value;
-+
- #ifdef INSN_SCHEDULING
- /* Arrays set up by scheduling for the same respective purposes as
-*************** static int *sched_reg_live_length;
-*** 143,146 ****
---- 146,150 ----
- by splitting insns. */
- static rtx *reg_last_uses;
-+ static int reg_last_uses_size;
- static rtx *reg_last_sets;
- static regset reg_pending_sets;
-*************** struct sometimes
-*** 294,302 ****
-
- /* Forward declarations. */
-- static rtx canon_rtx PROTO((rtx));
-- static int rtx_equal_for_memref_p PROTO((rtx, rtx));
-- static rtx find_symbolic_term PROTO((rtx));
-- static int memrefs_conflict_p PROTO((int, rtx, int, rtx,
-- HOST_WIDE_INT));
- static void add_dependence PROTO((rtx, rtx, enum reg_note));
- static void remove_dependence PROTO((rtx, rtx));
---- 298,301 ----
-*************** void schedule_insns PROTO((FILE *));
-*** 346,885 ****
- #endif /* INSN_SCHEDULING */
-
-- #define SIZE_FOR_MODE(X) (GET_MODE_SIZE (GET_MODE (X)))
--
-- /* Vector indexed by N giving the initial (unchanging) value known
-- for pseudo-register N. */
-- static rtx *reg_known_value;
--
-- /* Vector recording for each reg_known_value whether it is due to a
-- REG_EQUIV note. Future passes (viz., reload) may replace the
-- pseudo with the equivalent expression and so we account for the
-- dependences that would be introduced if that happens. */
-- /* ??? This is a problem only on the Convex. The REG_EQUIV notes created in
-- assign_parms mention the arg pointer, and there are explicit insns in the
-- RTL that modify the arg pointer. Thus we must ensure that such insns don't
-- get scheduled across each other because that would invalidate the REG_EQUIV
-- notes. One could argue that the REG_EQUIV notes are wrong, but solving
-- the problem in the scheduler will likely give better code, so we do it
-- here. */
-- static char *reg_known_equiv_p;
--
-- /* Indicates number of valid entries in reg_known_value. */
-- static int reg_known_value_size;
--
-- static rtx
-- canon_rtx (x)
-- rtx x;
-- {
-- if (GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER
-- && REGNO (x) <= reg_known_value_size)
-- return reg_known_value[REGNO (x)];
-- else if (GET_CODE (x) == PLUS)
-- {
-- rtx x0 = canon_rtx (XEXP (x, 0));
-- rtx x1 = canon_rtx (XEXP (x, 1));
--
-- if (x0 != XEXP (x, 0) || x1 != XEXP (x, 1))
-- {
-- /* We can tolerate LO_SUMs being offset here; these
-- rtl are used for nothing other than comparisons. */
-- if (GET_CODE (x0) == CONST_INT)
-- return plus_constant_for_output (x1, INTVAL (x0));
-- else if (GET_CODE (x1) == CONST_INT)
-- return plus_constant_for_output (x0, INTVAL (x1));
-- return gen_rtx (PLUS, GET_MODE (x), x0, x1);
-- }
-- }
-- return x;
-- }
--
-- /* Set up all info needed to perform alias analysis on memory references. */
--
-- void
-- init_alias_analysis ()
-- {
-- int maxreg = max_reg_num ();
-- rtx insn;
-- rtx note;
-- rtx set;
--
-- reg_known_value_size = maxreg;
--
-- reg_known_value
-- = (rtx *) oballoc ((maxreg-FIRST_PSEUDO_REGISTER) * sizeof (rtx))
-- - FIRST_PSEUDO_REGISTER;
-- bzero ((char *) (reg_known_value + FIRST_PSEUDO_REGISTER),
-- (maxreg-FIRST_PSEUDO_REGISTER) * sizeof (rtx));
--
-- reg_known_equiv_p
-- = (char *) oballoc ((maxreg -FIRST_PSEUDO_REGISTER) * sizeof (char))
-- - FIRST_PSEUDO_REGISTER;
-- bzero (reg_known_equiv_p + FIRST_PSEUDO_REGISTER,
-- (maxreg - FIRST_PSEUDO_REGISTER) * sizeof (char));
--
-- /* Fill in the entries with known constant values. */
-- for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
-- if ((set = single_set (insn)) != 0
-- && GET_CODE (SET_DEST (set)) == REG
-- && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
-- && (((note = find_reg_note (insn, REG_EQUAL, 0)) != 0
-- && reg_n_sets[REGNO (SET_DEST (set))] == 1)
-- || (note = find_reg_note (insn, REG_EQUIV, NULL_RTX)) != 0)
-- && GET_CODE (XEXP (note, 0)) != EXPR_LIST)
-- {
-- int regno = REGNO (SET_DEST (set));
-- reg_known_value[regno] = XEXP (note, 0);
-- reg_known_equiv_p[regno] = REG_NOTE_KIND (note) == REG_EQUIV;
-- }
--
-- /* Fill in the remaining entries. */
-- while (--maxreg >= FIRST_PSEUDO_REGISTER)
-- if (reg_known_value[maxreg] == 0)
-- reg_known_value[maxreg] = regno_reg_rtx[maxreg];
-- }
--
-- /* Return 1 if X and Y are identical-looking rtx's.
--
-- We use the data in reg_known_value above to see if two registers with
-- different numbers are, in fact, equivalent. */
--
-- static int
-- rtx_equal_for_memref_p (x, y)
-- rtx x, y;
-- {
-- register int i;
-- register int j;
-- register enum rtx_code code;
-- register char *fmt;
--
-- if (x == 0 && y == 0)
-- return 1;
-- if (x == 0 || y == 0)
-- return 0;
-- x = canon_rtx (x);
-- y = canon_rtx (y);
--
-- if (x == y)
-- return 1;
--
-- code = GET_CODE (x);
-- /* Rtx's of different codes cannot be equal. */
-- if (code != GET_CODE (y))
-- return 0;
--
-- /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent.
-- (REG:SI x) and (REG:HI x) are NOT equivalent. */
--
-- if (GET_MODE (x) != GET_MODE (y))
-- return 0;
--
-- /* REG, LABEL_REF, and SYMBOL_REF can be compared nonrecursively. */
--
-- if (code == REG)
-- return REGNO (x) == REGNO (y);
-- if (code == LABEL_REF)
-- return XEXP (x, 0) == XEXP (y, 0);
-- if (code == SYMBOL_REF)
-- return XSTR (x, 0) == XSTR (y, 0);
--
-- /* For commutative operations, the RTX match if the operand match in any
-- order. Also handle the simple binary and unary cases without a loop. */
-- if (code == EQ || code == NE || GET_RTX_CLASS (code) == 'c')
-- return ((rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 0))
-- && rtx_equal_for_memref_p (XEXP (x, 1), XEXP (y, 1)))
-- || (rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 1))
-- && rtx_equal_for_memref_p (XEXP (x, 1), XEXP (y, 0))));
-- else if (GET_RTX_CLASS (code) == '<' || GET_RTX_CLASS (code) == '2')
-- return (rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 0))
-- && rtx_equal_for_memref_p (XEXP (x, 1), XEXP (y, 1)));
-- else if (GET_RTX_CLASS (code) == '1')
-- return rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 0));
--
-- /* Compare the elements. If any pair of corresponding elements
-- fail to match, return 0 for the whole things. */
--
-- fmt = GET_RTX_FORMAT (code);
-- for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
-- {
-- switch (fmt[i])
-- {
-- case 'w':
-- if (XWINT (x, i) != XWINT (y, i))
-- return 0;
-- break;
--
-- case 'n':
-- case 'i':
-- if (XINT (x, i) != XINT (y, i))
-- return 0;
-- break;
--
-- case 'V':
-- case 'E':
-- /* Two vectors must have the same length. */
-- if (XVECLEN (x, i) != XVECLEN (y, i))
-- return 0;
--
-- /* And the corresponding elements must match. */
-- for (j = 0; j < XVECLEN (x, i); j++)
-- if (rtx_equal_for_memref_p (XVECEXP (x, i, j), XVECEXP (y, i, j)) == 0)
-- return 0;
-- break;
--
-- case 'e':
-- if (rtx_equal_for_memref_p (XEXP (x, i), XEXP (y, i)) == 0)
-- return 0;
-- break;
--
-- case 'S':
-- case 's':
-- if (strcmp (XSTR (x, i), XSTR (y, i)))
-- return 0;
-- break;
--
-- case 'u':
-- /* These are just backpointers, so they don't matter. */
-- break;
--
-- case '0':
-- break;
--
-- /* It is believed that rtx's at this level will never
-- contain anything but integers and other rtx's,
-- except for within LABEL_REFs and SYMBOL_REFs. */
-- default:
-- abort ();
-- }
-- }
-- return 1;
-- }
--
-- /* Given an rtx X, find a SYMBOL_REF or LABEL_REF within
-- X and return it, or return 0 if none found. */
--
-- static rtx
-- find_symbolic_term (x)
-- rtx x;
-- {
-- register int i;
-- register enum rtx_code code;
-- register char *fmt;
--
-- code = GET_CODE (x);
-- if (code == SYMBOL_REF || code == LABEL_REF)
-- return x;
-- if (GET_RTX_CLASS (code) == 'o')
-- return 0;
--
-- fmt = GET_RTX_FORMAT (code);
-- for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
-- {
-- rtx t;
--
-- if (fmt[i] == 'e')
-- {
-- t = find_symbolic_term (XEXP (x, i));
-- if (t != 0)
-- return t;
-- }
-- else if (fmt[i] == 'E')
-- break;
-- }
-- return 0;
-- }
--
-- /* Return nonzero if X and Y (memory addresses) could reference the
-- same location in memory. C is an offset accumulator. When
-- C is nonzero, we are testing aliases between X and Y + C.
-- XSIZE is the size in bytes of the X reference,
-- similarly YSIZE is the size in bytes for Y.
--
-- If XSIZE or YSIZE is zero, we do not know the amount of memory being
-- referenced (the reference was BLKmode), so make the most pessimistic
-- assumptions.
--
-- We recognize the following cases of non-conflicting memory:
--
-- (1) addresses involving the frame pointer cannot conflict
-- with addresses involving static variables.
-- (2) static variables with different addresses cannot conflict.
--
-- Nice to notice that varying addresses cannot conflict with fp if no
-- local variables had their addresses taken, but that's too hard now. */
--
-- /* ??? In Fortran, references to a array parameter can never conflict with
-- another array parameter. */
--
-- static int
-- memrefs_conflict_p (xsize, x, ysize, y, c)
-- rtx x, y;
-- int xsize, ysize;
-- HOST_WIDE_INT c;
-- {
-- if (GET_CODE (x) == HIGH)
-- x = XEXP (x, 0);
-- else if (GET_CODE (x) == LO_SUM)
-- x = XEXP (x, 1);
-- else
-- x = canon_rtx (x);
-- if (GET_CODE (y) == HIGH)
-- y = XEXP (y, 0);
-- else if (GET_CODE (y) == LO_SUM)
-- y = XEXP (y, 1);
-- else
-- y = canon_rtx (y);
--
-- if (rtx_equal_for_memref_p (x, y))
-- return (xsize == 0 || ysize == 0 ||
-- (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0));
--
-- if (y == frame_pointer_rtx || y == hard_frame_pointer_rtx
-- || y == stack_pointer_rtx)
-- {
-- rtx t = y;
-- int tsize = ysize;
-- y = x; ysize = xsize;
-- x = t; xsize = tsize;
-- }
--
-- if (x == frame_pointer_rtx || x == hard_frame_pointer_rtx
-- || x == stack_pointer_rtx)
-- {
-- rtx y1;
--
-- if (CONSTANT_P (y))
-- return 0;
--
-- if (GET_CODE (y) == PLUS
-- && canon_rtx (XEXP (y, 0)) == x
-- && (y1 = canon_rtx (XEXP (y, 1)))
-- && GET_CODE (y1) == CONST_INT)
-- {
-- c += INTVAL (y1);
-- return (xsize == 0 || ysize == 0
-- || (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0));
-- }
--
-- if (GET_CODE (y) == PLUS
-- && (y1 = canon_rtx (XEXP (y, 0)))
-- && CONSTANT_P (y1))
-- return 0;
--
-- return 1;
-- }
--
-- if (GET_CODE (x) == PLUS)
-- {
-- /* The fact that X is canonicalized means that this
-- PLUS rtx is canonicalized. */
-- rtx x0 = XEXP (x, 0);
-- rtx x1 = XEXP (x, 1);
--
-- if (GET_CODE (y) == PLUS)
-- {
-- /* The fact that Y is canonicalized means that this
-- PLUS rtx is canonicalized. */
-- rtx y0 = XEXP (y, 0);
-- rtx y1 = XEXP (y, 1);
--
-- if (rtx_equal_for_memref_p (x1, y1))
-- return memrefs_conflict_p (xsize, x0, ysize, y0, c);
-- if (rtx_equal_for_memref_p (x0, y0))
-- return memrefs_conflict_p (xsize, x1, ysize, y1, c);
-- if (GET_CODE (x1) == CONST_INT)
-- if (GET_CODE (y1) == CONST_INT)
-- return memrefs_conflict_p (xsize, x0, ysize, y0,
-- c - INTVAL (x1) + INTVAL (y1));
-- else
-- return memrefs_conflict_p (xsize, x0, ysize, y, c - INTVAL (x1));
-- else if (GET_CODE (y1) == CONST_INT)
-- return memrefs_conflict_p (xsize, x, ysize, y0, c + INTVAL (y1));
--
-- /* Handle case where we cannot understand iteration operators,
-- but we notice that the base addresses are distinct objects. */
-- x = find_symbolic_term (x);
-- if (x == 0)
-- return 1;
-- y = find_symbolic_term (y);
-- if (y == 0)
-- return 1;
-- return rtx_equal_for_memref_p (x, y);
-- }
-- else if (GET_CODE (x1) == CONST_INT)
-- return memrefs_conflict_p (xsize, x0, ysize, y, c - INTVAL (x1));
-- }
-- else if (GET_CODE (y) == PLUS)
-- {
-- /* The fact that Y is canonicalized means that this
-- PLUS rtx is canonicalized. */
-- rtx y0 = XEXP (y, 0);
-- rtx y1 = XEXP (y, 1);
--
-- if (GET_CODE (y1) == CONST_INT)
-- return memrefs_conflict_p (xsize, x, ysize, y0, c + INTVAL (y1));
-- else
-- return 1;
-- }
--
-- if (GET_CODE (x) == GET_CODE (y))
-- switch (GET_CODE (x))
-- {
-- case MULT:
-- {
-- /* Handle cases where we expect the second operands to be the
-- same, and check only whether the first operand would conflict
-- or not. */
-- rtx x0, y0;
-- rtx x1 = canon_rtx (XEXP (x, 1));
-- rtx y1 = canon_rtx (XEXP (y, 1));
-- if (! rtx_equal_for_memref_p (x1, y1))
-- return 1;
-- x0 = canon_rtx (XEXP (x, 0));
-- y0 = canon_rtx (XEXP (y, 0));
-- if (rtx_equal_for_memref_p (x0, y0))
-- return (xsize == 0 || ysize == 0
-- || (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0));
--
-- /* Can't properly adjust our sizes. */
-- if (GET_CODE (x1) != CONST_INT)
-- return 1;
-- xsize /= INTVAL (x1);
-- ysize /= INTVAL (x1);
-- c /= INTVAL (x1);
-- return memrefs_conflict_p (xsize, x0, ysize, y0, c);
-- }
-- }
--
-- if (CONSTANT_P (x))
-- {
-- if (GET_CODE (x) == CONST_INT && GET_CODE (y) == CONST_INT)
-- {
-- c += (INTVAL (y) - INTVAL (x));
-- return (xsize == 0 || ysize == 0
-- || (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0));
-- }
--
-- if (GET_CODE (x) == CONST)
-- {
-- if (GET_CODE (y) == CONST)
-- return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)),
-- ysize, canon_rtx (XEXP (y, 0)), c);
-- else
-- return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)),
-- ysize, y, c);
-- }
-- if (GET_CODE (y) == CONST)
-- return memrefs_conflict_p (xsize, x, ysize,
-- canon_rtx (XEXP (y, 0)), c);
--
-- if (CONSTANT_P (y))
-- return (rtx_equal_for_memref_p (x, y)
-- && (xsize == 0 || ysize == 0
-- || (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0)));
--
-- return 1;
-- }
-- return 1;
-- }
--
-- /* Functions to compute memory dependencies.
--
-- Since we process the insns in execution order, we can build tables
-- to keep track of what registers are fixed (and not aliased), what registers
-- are varying in known ways, and what registers are varying in unknown
-- ways.
--
-- If both memory references are volatile, then there must always be a
-- dependence between the two references, since their order can not be
-- changed. A volatile and non-volatile reference can be interchanged
-- though.
--
-- A MEM_IN_STRUCT reference at a non-QImode varying address can never
-- conflict with a non-MEM_IN_STRUCT reference at a fixed address. We must
-- allow QImode aliasing because the ANSI C standard allows character
-- pointers to alias anything. We are assuming that characters are
-- always QImode here. */
--
-- /* Read dependence: X is read after read in MEM takes place. There can
-- only be a dependence here if both reads are volatile. */
--
-- int
-- read_dependence (mem, x)
-- rtx mem;
-- rtx x;
-- {
-- return MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem);
-- }
--
-- /* True dependence: X is read after store in MEM takes place. */
--
-- int
-- true_dependence (mem, x)
-- rtx mem;
-- rtx x;
-- {
-- /* If X is an unchanging read, then it can't possibly conflict with any
-- non-unchanging store. It may conflict with an unchanging write though,
-- because there may be a single store to this address to initialize it.
-- Just fall through to the code below to resolve the case where we have
-- both an unchanging read and an unchanging write. This won't handle all
-- cases optimally, but the possible performance loss should be
-- negligible. */
-- if (RTX_UNCHANGING_P (x) && ! RTX_UNCHANGING_P (mem))
-- return 0;
--
-- return ((MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem))
-- || (memrefs_conflict_p (SIZE_FOR_MODE (mem), XEXP (mem, 0),
-- SIZE_FOR_MODE (x), XEXP (x, 0), 0)
-- && ! (MEM_IN_STRUCT_P (mem) && rtx_addr_varies_p (mem)
-- && GET_MODE (mem) != QImode
-- && ! MEM_IN_STRUCT_P (x) && ! rtx_addr_varies_p (x))
-- && ! (MEM_IN_STRUCT_P (x) && rtx_addr_varies_p (x)
-- && GET_MODE (x) != QImode
-- && ! MEM_IN_STRUCT_P (mem) && ! rtx_addr_varies_p (mem))));
-- }
--
-- /* Anti dependence: X is written after read in MEM takes place. */
--
-- int
-- anti_dependence (mem, x)
-- rtx mem;
-- rtx x;
-- {
-- /* If MEM is an unchanging read, then it can't possibly conflict with
-- the store to X, because there is at most one store to MEM, and it must
-- have occurred somewhere before MEM. */
-- if (RTX_UNCHANGING_P (mem))
-- return 0;
--
-- return ((MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem))
-- || (memrefs_conflict_p (SIZE_FOR_MODE (mem), XEXP (mem, 0),
-- SIZE_FOR_MODE (x), XEXP (x, 0), 0)
-- && ! (MEM_IN_STRUCT_P (mem) && rtx_addr_varies_p (mem)
-- && GET_MODE (mem) != QImode
-- && ! MEM_IN_STRUCT_P (x) && ! rtx_addr_varies_p (x))
-- && ! (MEM_IN_STRUCT_P (x) && rtx_addr_varies_p (x)
-- && GET_MODE (x) != QImode
-- && ! MEM_IN_STRUCT_P (mem) && ! rtx_addr_varies_p (mem))));
-- }
--
-- /* Output dependence: X is written after store in MEM takes place. */
--
-- int
-- output_dependence (mem, x)
-- rtx mem;
-- rtx x;
-- {
-- return ((MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem))
-- || (memrefs_conflict_p (SIZE_FOR_MODE (mem), XEXP (mem, 0),
-- SIZE_FOR_MODE (x), XEXP (x, 0), 0)
-- && ! (MEM_IN_STRUCT_P (mem) && rtx_addr_varies_p (mem)
-- && GET_MODE (mem) != QImode
-- && ! MEM_IN_STRUCT_P (x) && ! rtx_addr_varies_p (x))
-- && ! (MEM_IN_STRUCT_P (x) && rtx_addr_varies_p (x)
-- && GET_MODE (x) != QImode
-- && ! MEM_IN_STRUCT_P (mem) && ! rtx_addr_varies_p (mem))));
-- }
--
- /* Helper functions for instruction scheduling. */
-
---- 345,348 ----
-*************** sched_analyze_2 (x, insn)
-*** 1922,1926 ****
- /* If a dependency already exists, don't create a new one. */
- if (! find_insn_list (XEXP (pending, 0), LOG_LINKS (insn)))
-! if (true_dependence (XEXP (pending_mem, 0), x))
- add_dependence (insn, XEXP (pending, 0), 0);
-
---- 1385,1390 ----
- /* If a dependency already exists, don't create a new one. */
- if (! find_insn_list (XEXP (pending, 0), LOG_LINKS (insn)))
-! if (true_dependence (XEXP (pending_mem, 0), VOIDmode,
-! x, rtx_varies_p))
- add_dependence (insn, XEXP (pending, 0), 0);
-
-*************** sched_analyze_insn (x, insn, loop_notes)
-*** 2021,2025 ****
- register RTX_CODE code = GET_CODE (x);
- rtx link;
-! int maxreg = max_reg_num ();
- int i;
-
---- 1485,1489 ----
- register RTX_CODE code = GET_CODE (x);
- rtx link;
-! int maxreg = reg_last_uses_size;
- int i;
-
-*************** sched_analyze_insn (x, insn, loop_notes)
-*** 2058,2062 ****
- if (loop_notes)
- {
-! int max_reg = max_reg_num ();
- rtx link;
-
---- 1522,1526 ----
- if (loop_notes)
- {
-! int max_reg = reg_last_uses_size;
- rtx link;
-
-*************** sched_analyze (head, tail)
-*** 2202,2207 ****
- && NOTE_LINE_NUMBER (NEXT_INSN (insn)) == NOTE_INSN_SETJMP)
- {
-! int max_reg = max_reg_num ();
-! for (i = 0; i < max_reg; i++)
- {
- for (u = reg_last_uses[i]; u; u = XEXP (u, 1))
---- 1666,1670 ----
- && NOTE_LINE_NUMBER (NEXT_INSN (insn)) == NOTE_INSN_SETJMP)
- {
-! for (i = 0; i < reg_last_uses_size; i++)
- {
- for (u = reg_last_uses[i]; u; u = XEXP (u, 1))
-*************** sched_note_set (b, x, death)
-*** 2372,2380 ****
-
- #define SCHED_SORT(READY, NEW_READY, OLD_READY) \
-! do { if ((NEW_READY) - (OLD_READY) == 1) \
-! swap_sort (READY, NEW_READY); \
-! else if ((NEW_READY) - (OLD_READY) > 1) \
-! qsort (READY, NEW_READY, sizeof (rtx), rank_for_schedule); } \
-! while (0)
-
- /* Returns a positive value if y is preferred; returns a negative value if
---- 1835,1842 ----
-
- #define SCHED_SORT(READY, NEW_READY, OLD_READY) \
-! if ((NEW_READY) - (OLD_READY) == 1) \
-! swap_sort (READY, NEW_READY); \
-! else if ((NEW_READY) - (OLD_READY) > 1) \
-! qsort (READY, NEW_READY, sizeof (rtx), rank_for_schedule); else \
-
- /* Returns a positive value if y is preferred; returns a negative value if
-*************** schedule_block (b, file)
-*** 3174,3178 ****
- b, INSN_UID (basic_block_head[b]), INSN_UID (basic_block_end[b]));
-
-! i = max_reg_num ();
- reg_last_uses = (rtx *) alloca (i * sizeof (rtx));
- bzero ((char *) reg_last_uses, i * sizeof (rtx));
---- 2636,2640 ----
- b, INSN_UID (basic_block_head[b]), INSN_UID (basic_block_end[b]));
-
-! reg_last_uses_size = i = max_reg_num ();
- reg_last_uses = (rtx *) alloca (i * sizeof (rtx));
- bzero ((char *) reg_last_uses, i * sizeof (rtx));
-*************** schedule_insns (dump_file)
-*** 4718,4721 ****
---- 4180,4198 ----
- max_regno * sizeof (short));
- init_alias_analysis ();
-+ #if 0
-+ if (dump_file)
-+ {
-+ extern rtx *reg_base_value;
-+ extern int reg_base_value_size;
-+ int i;
-+ for (i = 0; i < reg_base_value_size; i++)
-+ if (reg_base_value[i])
-+ {
-+ fprintf (dump_file, ";; reg_base_value[%d] = ", i);
-+ print_rtl (dump_file, reg_base_value[i]);
-+ fputc ('\n', dump_file);
-+ }
-+ }
-+ #endif
- }
- else
-*************** schedule_insns (dump_file)
-*** 4726,4731 ****
- bb_dead_regs = 0;
- bb_live_regs = 0;
-! if (! flag_schedule_insns)
-! init_alias_analysis ();
- }
-
---- 4203,4207 ----
- bb_dead_regs = 0;
- bb_live_regs = 0;
-! init_alias_analysis ();
- }
-
-diff -rcp2N gcc-2.7.2.2/toplev.c gcc-2.7.2.2.f.2/toplev.c
-*** gcc-2.7.2.2/toplev.c Fri Oct 20 17:56:35 1995
---- gcc-2.7.2.2.f.2/toplev.c Fri Jan 10 23:18:24 1997
-*************** int flag_unroll_loops;
-*** 388,391 ****
---- 388,405 ----
- int flag_unroll_all_loops;
-
-+ /* Nonzero forces all invariant computations in loops to be moved
-+ outside the loop. */
-+
-+ int flag_move_all_movables = 0;
-+
-+ /* Nonzero forces all general induction variables in loops to be
-+ strength reduced. */
-+
-+ int flag_reduce_all_givs = 0;
-+
-+ /* Nonzero gets another run of loop_optimize performed. */
-+
-+ int flag_rerun_loop_opt = 0;
-+
- /* Nonzero for -fwritable-strings:
- store string constants in data segment and don't uniquize them. */
-*************** int flag_gnu_linker = 1;
-*** 522,525 ****
---- 536,550 ----
- int flag_pack_struct = 0;
-
-+ /* 1 if alias checking is on (by default, when -O). */
-+ int flag_alias_check = 0;
-+
-+ /* 0 if pointer arguments may alias each other. True in C.
-+ 1 if pointer arguments may not alias each other but may alias
-+ global variables.
-+ 2 if pointer arguments may not alias each other and may not
-+ alias global variables. True in Fortran.
-+ This defaults to 0 for C. */
-+ int flag_argument_noalias = 0;
-+
- /* Table of language-independent -f options.
- STRING is the option name. VARIABLE is the address of the variable.
-*************** struct { char *string; int *variable; in
-*** 542,545 ****
---- 567,573 ----
- {"unroll-loops", &flag_unroll_loops, 1},
- {"unroll-all-loops", &flag_unroll_all_loops, 1},
-+ {"move-all-movables", &flag_move_all_movables, 1},
-+ {"reduce-all-givs", &flag_reduce_all_givs, 1},
-+ {"rerun-loop-opt", &flag_rerun_loop_opt, 1},
- {"writable-strings", &flag_writable_strings, 1},
- {"peephole", &flag_no_peephole, 0},
-*************** struct { char *string; int *variable; in
-*** 568,572 ****
- {"gnu-linker", &flag_gnu_linker, 1},
- {"pack-struct", &flag_pack_struct, 1},
-! {"bytecode", &output_bytecode, 1}
- };
-
---- 596,604 ----
- {"gnu-linker", &flag_gnu_linker, 1},
- {"pack-struct", &flag_pack_struct, 1},
-! {"bytecode", &output_bytecode, 1},
-! {"alias-check", &flag_alias_check, 1},
-! {"argument-alias", &flag_argument_noalias, 0},
-! {"argument-noalias", &flag_argument_noalias, 1},
-! {"argument-noalias-global", &flag_argument_noalias, 2}
- };
-
-*************** rest_of_compilation (decl)
-*** 2894,2897 ****
---- 2926,2931 ----
- {
- loop_optimize (insns, loop_dump_file);
-+ if (flag_rerun_loop_opt)
-+ loop_optimize (insns, loop_dump_file);
- });
- }
-*************** main (argc, argv, envp)
-*** 3383,3386 ****
---- 3417,3421 ----
- flag_omit_frame_pointer = 1;
- #endif
-+ flag_alias_check = 1;
- }
-
-diff -rcp2N gcc-2.7.2.2/unroll.c gcc-2.7.2.2.f.2/unroll.c
-*** gcc-2.7.2.2/unroll.c Sat Aug 19 17:33:26 1995
---- gcc-2.7.2.2.f.2/unroll.c Fri Jan 10 23:18:24 1997
-*************** unroll_loop (loop_end, insn_count, loop_
-*** 995,1000 ****
- for (j = FIRST_PSEUDO_REGISTER; j < max_reg_before_loop; j++)
- if (local_regno[j])
-! map->reg_map[j] = gen_reg_rtx (GET_MODE (regno_reg_rtx[j]));
-!
- /* The last copy needs the compare/branch insns at the end,
- so reset copy_end here if the loop ends with a conditional
---- 995,1003 ----
- for (j = FIRST_PSEUDO_REGISTER; j < max_reg_before_loop; j++)
- if (local_regno[j])
-! {
-! map->reg_map[j] = gen_reg_rtx (GET_MODE (regno_reg_rtx[j]));
-! record_base_value (REGNO (map->reg_map[j]),
-! regno_reg_rtx[j]);
-! }
- /* The last copy needs the compare/branch insns at the end,
- so reset copy_end here if the loop ends with a conditional
-*************** unroll_loop (loop_end, insn_count, loop_
-*** 1136,1140 ****
- for (j = FIRST_PSEUDO_REGISTER; j < max_reg_before_loop; j++)
- if (local_regno[j])
-! map->reg_map[j] = gen_reg_rtx (GET_MODE (regno_reg_rtx[j]));
-
- /* If loop starts with a branch to the test, then fix it so that
---- 1139,1147 ----
- for (j = FIRST_PSEUDO_REGISTER; j < max_reg_before_loop; j++)
- if (local_regno[j])
-! {
-! map->reg_map[j] = gen_reg_rtx (GET_MODE (regno_reg_rtx[j]));
-! record_base_value (REGNO (map->reg_map[j]),
-! regno_reg_rtx[j]);
-! }
-
- /* If loop starts with a branch to the test, then fix it so that
-*************** copy_loop_body (copy_start, copy_end, ma
-*** 1631,1635 ****
- incrementing the shared pseudo reg more than
- once. */
-! if (! tv->same_insn)
- {
- /* tv->dest_reg may actually be a (PLUS (REG)
---- 1638,1642 ----
- incrementing the shared pseudo reg more than
- once. */
-! if (! tv->same_insn && ! tv->shared)
- {
- /* tv->dest_reg may actually be a (PLUS (REG)
-*************** copy_loop_body (copy_start, copy_end, ma
-*** 1757,1760 ****
---- 1764,1768 ----
- giv_dest_reg = tem;
- map->reg_map[regno] = tem;
-+ record_base_value (REGNO (tem), giv_src_reg);
- }
- else
-*************** find_splittable_regs (unroll_type, loop_
-*** 2443,2447 ****
- {
- rtx tem = gen_reg_rtx (bl->biv->mode);
-!
- emit_insn_before (gen_move_insn (tem, bl->biv->src_reg),
- loop_start);
---- 2451,2456 ----
- {
- rtx tem = gen_reg_rtx (bl->biv->mode);
-!
-! record_base_value (REGNO (tem), bl->biv->add_val);
- emit_insn_before (gen_move_insn (tem, bl->biv->src_reg),
- loop_start);
-*************** find_splittable_regs (unroll_type, loop_
-*** 2500,2503 ****
---- 2509,2514 ----
- exits. */
- rtx tem = gen_reg_rtx (bl->biv->mode);
-+ record_base_value (REGNO (tem), bl->biv->add_val);
-+
- emit_insn_before (gen_move_insn (tem, bl->biv->src_reg),
- loop_start);
-*************** find_splittable_givs (bl, unroll_type, l
-*** 2675,2678 ****
---- 2686,2690 ----
- rtx tem = gen_reg_rtx (bl->biv->mode);
-
-+ record_base_value (REGNO (tem), bl->biv->add_val);
- emit_insn_before (gen_move_insn (tem, bl->biv->src_reg),
- loop_start);
-*************** find_splittable_givs (bl, unroll_type, l
-*** 2716,2719 ****
---- 2728,2732 ----
- {
- rtx tem = gen_reg_rtx (v->mode);
-+ record_base_value (REGNO (tem), v->add_val);
- emit_iv_add_mult (bl->initial_value, v->mult_val,
- v->add_val, tem, loop_start);
-*************** find_splittable_givs (bl, unroll_type, l
-*** 2734,2747 ****
- register for the split addr giv, just to be safe. */
-
-! /* ??? If there are multiple address givs which have been
-! combined with the same dest_reg giv, then we may only need
-! one new register for them. Pulling out constants below will
-! catch some of the common cases of this. Currently, I leave
-! the work of simplifying multiple address givs to the
-! following cse pass. */
-!
-! /* As a special case, if we have multiple identical address givs
-! within a single instruction, then we do use a single pseudo
-! reg for both. This is necessary in case one is a match_dup
- of the other. */
-
---- 2747,2753 ----
- register for the split addr giv, just to be safe. */
-
-! /* If we have multiple identical address givs within a
-! single instruction, then use a single pseudo reg for
-! both. This is necessary in case one is a match_dup
- of the other. */
-
-*************** find_splittable_givs (bl, unroll_type, l
-*** 2756,2759 ****
---- 2762,2776 ----
- INSN_UID (v->insn));
- }
-+ /* If multiple address GIVs have been combined with the
-+ same dest_reg GIV, do not create a new register for
-+ each. */
-+ else if (unroll_type != UNROLL_COMPLETELY
-+ && v->giv_type == DEST_ADDR
-+ && v->same && v->same->giv_type == DEST_ADDR
-+ && v->same->unrolled)
-+ {
-+ v->dest_reg = v->same->dest_reg;
-+ v->shared = 1;
-+ }
- else if (unroll_type != UNROLL_COMPLETELY)
- {
-*************** find_splittable_givs (bl, unroll_type, l
-*** 2761,2765 ****
- register to hold the split value of the DEST_ADDR giv.
- Emit insn to initialize its value before loop start. */
-! tem = gen_reg_rtx (v->mode);
-
- /* If the address giv has a constant in its new_reg value,
---- 2778,2785 ----
- register to hold the split value of the DEST_ADDR giv.
- Emit insn to initialize its value before loop start. */
-!
-! rtx tem = gen_reg_rtx (v->mode);
-! record_base_value (REGNO (tem), v->add_val);
-! v->unrolled = 1;
-
- /* If the address giv has a constant in its new_reg value,
-*************** find_splittable_givs (bl, unroll_type, l
-*** 2772,2776 ****
- v->dest_reg
- = plus_constant (tem, INTVAL (XEXP (v->new_reg,1)));
-!
- /* Only succeed if this will give valid addresses.
- Try to validate both the first and the last
---- 2792,2796 ----
- v->dest_reg
- = plus_constant (tem, INTVAL (XEXP (v->new_reg,1)));
-!
- /* Only succeed if this will give valid addresses.
- Try to validate both the first and the last
-*************** final_biv_value (bl, loop_start, loop_en
-*** 3061,3064 ****
---- 3081,3085 ----
-
- tem = gen_reg_rtx (bl->biv->mode);
-+ record_base_value (REGNO (tem), bl->biv->add_val);
- /* Make sure loop_end is not the last insn. */
- if (NEXT_INSN (loop_end) == 0)
-*************** final_giv_value (v, loop_start, loop_end
-*** 3154,3157 ****
---- 3175,3179 ----
- /* Put the final biv value in tem. */
- tem = gen_reg_rtx (bl->biv->mode);
-+ record_base_value (REGNO (tem), bl->biv->add_val);
- emit_iv_add_mult (increment, GEN_INT (loop_n_iterations),
- bl->initial_value, tem, insert_before);
-diff -rcp2N gcc-2.7.2.2/version.c gcc-2.7.2.2.f.2/version.c
-*** gcc-2.7.2.2/version.c Thu Feb 20 19:24:33 1997
---- gcc-2.7.2.2.f.2/version.c Sun Feb 23 16:30:36 1997
-***************
-*** 1 ****
-! char *version_string = "2.7.2.2";
---- 1 ----
-! char *version_string = "2.7.2.2.f.2";