ldmud-3.2.9/doc/
ldmud-3.2.9/doc/efun/
ldmud-3.2.9/mud/
ldmud-3.2.9/mud/heaven7/
ldmud-3.2.9/mud/heaven7/lib/
ldmud-3.2.9/mud/lp-245/
ldmud-3.2.9/mud/lp-245/banish/
ldmud-3.2.9/mud/lp-245/doc/
ldmud-3.2.9/mud/lp-245/doc/examples/
ldmud-3.2.9/mud/lp-245/doc/sefun/
ldmud-3.2.9/mud/lp-245/log/
ldmud-3.2.9/mud/lp-245/obj/Go/
ldmud-3.2.9/mud/lp-245/players/lars/
ldmud-3.2.9/mud/lp-245/room/death/
ldmud-3.2.9/mud/lp-245/room/maze1/
ldmud-3.2.9/mud/lp-245/room/sub/
ldmud-3.2.9/mud/lp-245/secure/
ldmud-3.2.9/mud/morgengrauen/
ldmud-3.2.9/mud/morgengrauen/lib/
ldmud-3.2.9/mud/sticklib/
ldmud-3.2.9/mud/sticklib/src/
ldmud-3.2.9/mudlib/uni-crasher/
ldmud-3.2.9/pkg/
ldmud-3.2.9/pkg/debugger/
ldmud-3.2.9/pkg/diff/
ldmud-3.2.9/pkg/misc/
ldmud-3.2.9/src/autoconf/
ldmud-3.2.9/src/bugs/
ldmud-3.2.9/src/bugs/MudCompress/
ldmud-3.2.9/src/bugs/b-020916-files/
ldmud-3.2.9/src/bugs/doomdark/
ldmud-3.2.9/src/bugs/ferrycode/ferry/
ldmud-3.2.9/src/bugs/ferrycode/obj/
ldmud-3.2.9/src/bugs/psql/
ldmud-3.2.9/src/done/
ldmud-3.2.9/src/done/order_alist/
ldmud-3.2.9/src/done/order_alist/obj/
ldmud-3.2.9/src/done/order_alist/room/
ldmud-3.2.9/src/gcc/
ldmud-3.2.9/src/gcc/2.7.0/
ldmud-3.2.9/src/gcc/2.7.1/
ldmud-3.2.9/src/hosts/
ldmud-3.2.9/src/hosts/GnuWin32/
ldmud-3.2.9/src/hosts/amiga/NetIncl/
ldmud-3.2.9/src/hosts/amiga/NetIncl/netinet/
ldmud-3.2.9/src/hosts/amiga/NetIncl/sys/
ldmud-3.2.9/src/hosts/i386/
ldmud-3.2.9/src/hosts/msdos/byacc/
ldmud-3.2.9/src/hosts/msdos/doc/
ldmud-3.2.9/src/hosts/os2/
ldmud-3.2.9/src/hosts/win32/
ldmud-3.2.9/src/util/
ldmud-3.2.9/src/util/erq/
ldmud-3.2.9/src/util/indent/hosts/next/
ldmud-3.2.9/src/util/xerq/
ldmud-3.2.9/src/util/xerq/lpc/
ldmud-3.2.9/src/util/xerq/lpc/www/
===================================================================
RCS file: /user/src/master/gcc/ChangeLog,v
retrieving revision 1.1.1.4
retrieving revision 1.9
diff -c -r1.1.1.4 -r1.9
*** 1.1.1.4	1995/10/11 22:07:04
--- 1.9	1995/10/12 20:31:32
***************
*** 1,3 ****
--- 1,49 ----
+ Thu Oct 12 20:55:22 1995  J"orn Rennecke (amylaar@meolyon.hanse.de)
+ 	* loop.c (strength_reduce, maybe_eliminate_biv) fixed two
+ 	cases where rtl fields could be used that are not valid.
+ 	* expr.c (extract_index): new function.
+ 	(expand_expr): use it.
+ Wed Oct 11 06:04:09 1995  J"orn Rennecke (amylaar@meolyon.hanse.de)
+ 	* loop.c (record_giv): do comparison to MAX_RECORDED_MULTVAL
+ 	unsigned to avoid -MIN_INT == MIN_INT causing trouble.
+ 	(maybe_eliminate_biv_1): actually use arg_offset, and
+ 	various sign bug fixes.
+ Tue Oct 10 17:38:20 1995  J"orn Rennecke (amylaar@meolyon.hanse.de)
+ 	* c-typeck.c (pointer_int_sum): add TREE_ADDRESSABLE to
+ 	the MULT_EXPR.
+ 	* tree.h: added to the comment on TREE_ADDRESSABLE
+ 	* rtl.def (NOTE): change format letter for fld[3] to 'N'.
+ 	* rtl.c (note_insn_name) added string for NOTE_INSN_INDEX
+ 	(read_rtx, copy_most_rtx): handle rtx format letter 'N'.
+ 	rtl.h: (NOTE_INDEX, NOTE_INDEX_REG, NOTE_INDEX_SCALE, NOTE_INSN_INDEX):
+ 	added.
+ 	* expr.c (expand_expr): add NOTE_INSN_INDEX for most frequent
+ 	cases of indexing.
+ 	* integrate.c (expand_inline_function): handle NOTE_INSN_INDEX
+ 	* (do_jump_for_compare): #ifndef HAVE_cc0, ADD a early REG_DEAD note
+ 	for the condition code register used.
+ 	* final.c (leaf_renumber_regs_insn), genattrtab.c (attr_copy_rtx),
+ 	jump.c (reg_equal_for_thread_p), print-rtl.c (print_rtx),
+ 	rtlanal.c (rtx_equal_p), sched.c (rtx_equal_for_memref_p): handle
+ 	rtx format letter 'N'
+ 	loop.h: definitions for MULTVAL_SET.
+ 	(iv_class): new members max_mult_val, index_multvals.
+ 	* loop.c: new variables loop_has_return, loop_has_extra_exit.
+ 	(prescan_loop): set loop_has_return.
+ 	(strength_reduce): use NOTE_INSN_INDEX notes to set bl->max_mult_val.
+ 	Set loop_has_extra_exit.
+ 	(record_biv): initialize max_mult_val and index_multvals.
+ 	(record_giv): record multvals from DEST_ADDR givs.
+ 	(maybe_eliminate_biv_1): new argument loop_test.  Changed all callers.
+ 	case COMPARE restricted to avoid incorrect code.  Case SET
+ 	should find most COMPARES now and handle them together with the
+ 	following branch.
+ 	(remove_early_reg_dead_notes): new function.
+ 	* flags.h: new flag flag_no_unmapped_memory
+ 	* toplev.c: new flag flag_no_unmapped_memory
+ 	(rest_of_compilation): call remove_early_reg_dead_notes after loop
+ 	optimization.
+
  Mon Oct  9 12:38:06 1995  Michael Meissner  <meissner@cygnus.com>

  	* protoize.c (reverse_def_dec_list): Silence compiler warnings.
===================================================================
RCS file: /user/src/master/gcc/c-typeck.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -c -r1.1.1.2 -r1.2
*** 1.1.1.2	1995/10/05 07:19:33
--- 1.2	1995/10/10 20:25:48
***************
*** 2678,2686 ****
       Do this multiplication as signed, then convert to the appropriate
       pointer type (actually unsigned integral).  */

!   intop = convert (result_type,
! 		   build_binary_op (MULT_EXPR, intop,
! 				    convert (TREE_TYPE (intop), size_exp), 1));

    /* Create the sum or difference.  */

--- 2678,2688 ----
       Do this multiplication as signed, then convert to the appropriate
       pointer type (actually unsigned integral).  */

!   intop = build_binary_op (MULT_EXPR, intop,
! 				    convert (TREE_TYPE (intop), size_exp), 1);
!   /* Record that this multiplication is from address calculation.  */
!   TREE_ADDRESSABLE (intop) = 1;
!   intop = convert (result_type, intop);

    /* Create the sum or difference.  */

===================================================================
RCS file: /user/src/master/gcc/expr.c,v
retrieving revision 1.1.1.4
retrieving revision 1.8
diff -c -r1.1.1.4 -r1.8
*** 1.1.1.4	1995/10/11 22:07:00
--- 1.8	1995/10/13 20:37:10
***************
*** 190,195 ****
--- 190,196 ----
  static rtx compare		PROTO((tree, enum rtx_code, enum rtx_code));
  static rtx do_store_flag	PROTO((tree, rtx, enum machine_mode, int));
  static tree defer_cleanups_to	PROTO((tree));
+ static tree extract_index	PROTO((tree));
  extern void (*interim_eh_hook)	PROTO((tree));

  /* Record for each mode whether we can move a register directly to or
***************
*** 4533,4538 ****
--- 4534,4540 ----
        {
  	tree exp1 = TREE_OPERAND (exp, 0);
  	tree exp2;
+ 	tree size;

  	/* A SAVE_EXPR as the address in an INDIRECT_EXPR is generated
  	   for  *PTR += ANYTHING  where PTR is put inside the SAVE_EXPR.
***************
*** 4557,4562 ****
--- 4559,4582 ----
  	  }

  	temp = gen_rtx (MEM, mode, op0);
+ 	/* If there is a multiply from address arithmetic, emit an
+ 	   appropriate note if optimizing.  */
+ 	if (optimize
+ 	    && TREE_CODE (exp1) == PLUS_EXPR
+ 	    && (TREE_CODE (exp2 = TREE_OPERAND (exp1, 1)) == MULT_EXPR
+ 	        || TREE_CODE (exp2) == CONVERT_EXPR
+ 		   && TREE_CODE (exp2 = TREE_OPERAND (exp2, 0)) == MULT_EXPR)
+ 	    && TREE_ADDRESSABLE (exp2)
+ 	    && TREE_CODE (size = TREE_OPERAND (exp2, 1)) == INTEGER_CST)
+ 	  {
+ 	    tree index = extract_index (TREE_OPERAND (exp2, 0));
+ 	    if (index)
+ 	      emit_note ((char *)gen_rtx (
+ 				EXPR_LIST, VOIDmode,
+ 				expand_expr (index, VOIDmode, 0, EXPAND_SUM),
+ 				expand_expr (size, VOIDmode, 0, 0)),
+ 		       NOTE_INSN_INDEX);
+ 	  }
  	/* If address was computed by addition,
  	   mark this as an element of an aggregate.  */
  	if (TREE_CODE (TREE_OPERAND (exp, 0)) == PLUS_EXPR
***************
*** 4661,4667 ****
  	    TREE_THIS_VOLATILE (elt) = TREE_THIS_VOLATILE (exp);
  	    TREE_READONLY (elt) = TREE_READONLY (exp);

! 	    return expand_expr (elt, target, tmode, modifier);
  	  }

  	/* Fold an expression like: "foo"[2].
--- 4681,4695 ----
  	    TREE_THIS_VOLATILE (elt) = TREE_THIS_VOLATILE (exp);
  	    TREE_READONLY (elt) = TREE_READONLY (exp);

! 	    temp = expand_expr (elt, target, tmode, modifier);
! 	    if (optimize && TREE_CODE (size) == INTEGER_CST
! 		&& (index = extract_index (index)))
! 	      emit_note ((char *)gen_rtx (
! 				EXPR_LIST, VOIDmode,
! 				expand_expr (index, VOIDmode, 0, EXPAND_SUM),
! 				expand_expr (size, VOIDmode, 0, 0)),
! 			 NOTE_INSN_INDEX);
! 	    return temp;
  	  }

  	/* Fold an expression like: "foo"[2].
***************
*** 6958,6963 ****
--- 6986,7023 ----
    bc_expand_increment (incroptab, type);
    return;
  }
+
+ /* Find something that will be turned into a REG RTL in INDEX, if there are
+    essentially only added constants.  Return 0 if no safe match was found.  */
+
+ static tree
+ extract_index (index)
+   tree index;
+ {
+   switch (TREE_CODE (index))
+     {
+     case VAR_DECL:
+     case PARM_DECL:
+       return index;
+     case PLUS_EXPR:
+     case MINUS_EXPR:
+       if (TREE_CONSTANT (TREE_OPERAND (index, 0)))
+ 	return extract_index (TREE_OPERAND (index, 1));
+     case POSTINCREMENT_EXPR:
+     case PREDECREMENT_EXPR:
+       if (TREE_CONSTANT (TREE_OPERAND (index, 1)))
+     case SAVE_EXPR:
+ 	return extract_index (TREE_OPERAND (index, 0));
+       return NULL;
+     case NOP_EXPR:
+     case CONVERT_EXPR:
+       if (TYPE_SIZE (TREE_TYPE (index))
+ 	  == TYPE_SIZE (TREE_TYPE (TREE_OPERAND (index, 0))))
+ 	return extract_index (TREE_OPERAND (index, 0));
+     default:
+       return NULL;
+     }
+ }
  
  /* Return the alignment in bits of EXP, a pointer valued expression.
     But don't return more than MAX_ALIGN no matter what.
***************
*** 9506,9512 ****
    if (if_true_label)
      {
        if (bcc_gen_fctn[(int) GET_CODE (comparison)] != 0)
! 	emit_jump_insn ((*bcc_gen_fctn[(int) GET_CODE (comparison)]) (if_true_label));
        else
  	abort ();

--- 9566,9607 ----
    if (if_true_label)
      {
        if (bcc_gen_fctn[(int) GET_CODE (comparison)] != 0)
! 	{
! 	  rtx bcc;
!
! 	  bcc = (*bcc_gen_fctn[(int) GET_CODE (comparison)]) (if_true_label);
! #ifndef HAVE_cc0
! 	  /* If this compare/jump is done in two RTL instructions, add a
!              READ_DEAD note for the condition code register so that
! 	     loop optimization can safely modify the jump without
!              worrying about possible later uses of the data in the
! 	     register.  */
!
! 	  switch (0)
! 	    {
! 		rtx cmp_pattern, jmp_insn, set_target;
! 	      default:
! 		if (! optimize)
! 		  break;
! 		if (GET_CODE (bcc) != SEQUENCE || XVECLEN (bcc, 0) != 2)
! 		  break;
! 		cmp_pattern = PATTERN (XVECEXP (bcc, 0, 0));
! 		if (GET_CODE (cmp_pattern) != SET
! 		    || GET_CODE (XEXP (cmp_pattern, 1)) != COMPARE)
! 		  break;
! 		set_target = XEXP (cmp_pattern, 0);
! 		if (GET_CODE (set_target) != REG)
! 		  break;
! 		jmp_insn = XVECEXP (bcc, 0, 1);
! 		if (GET_CODE (jmp_insn) != JUMP_INSN)
! 		  break;
! 		REG_NOTES (jmp_insn) =
! 		  gen_rtx (EXPR_LIST, REG_DEAD, set_target,
!                            REG_NOTES (jmp_insn));
! 	    }
! #endif /* not HAVE_cc0 */
! 	  emit_jump_insn (bcc);
! 	}
        else
  	abort ();

===================================================================
RCS file: /user/src/master/gcc/final.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -c -r1.1.1.2 -r1.2
*** 1.1.1.2	1995/10/05 07:19:59
--- 1.2	1995/10/10 20:25:53
***************
*** 3107,3112 ****
--- 3107,3115 ----
    for (i = 0; i < GET_RTX_LENGTH (GET_CODE (in_rtx)); i++)
      switch (*format_ptr++)
        {
+       case 'N':
+ 	if (NOTE_LINE_NUMBER (in_rtx) != NOTE_INSN_INDEX)
+ 	  break;
        case 'e':
  	leaf_renumber_regs_insn (XEXP (in_rtx, i));
  	break;
===================================================================
RCS file: /user/src/master/gcc/flags.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -c -r1.1.1.1 -r1.2
*** 1.1.1.1	1995/10/05 06:55:32
--- 1.2	1995/10/10 20:25:54
***************
*** 338,343 ****
--- 338,351 ----

  /* Tag all structures with __attribute__(packed) */
  extern int flag_pack_struct;
+
+ /* When producing code for some special targets, it might be OK to address
+    through the entire address range in a loop. As a result, we can't infer
+    from the use of a giv as an index that the assiciated biv may be replaced
+    by a giv with the same mult_val as the MEM the index generates.
+    -fno-unmapped-memory is used to indicate this. */
+
+ extern flag_no_unmapped_memory;
  
  /* Other basic status info about current function.  */

===================================================================
RCS file: /user/src/master/gcc/genattrtab.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -c -r1.1.1.1 -r1.2
*** 1.1.1.1	1995/10/05 06:55:48
--- 1.2	1995/10/10 20:25:55
***************
*** 905,910 ****
--- 905,911 ----

  	case 's':
  	case 'S':
+ 	case 'N':
  	  XSTR (copy, i) = XSTR (orig, i);
  	  break;

===================================================================
RCS file: /user/src/master/gcc/integrate.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -c -r1.1.1.2 -r1.2
*** 1.1.1.2	1995/10/05 07:20:23
--- 1.2	1995/10/10 20:25:56
***************
*** 1839,1845 ****
  	     Also, NOTE_INSN_DELETED notes aren't useful (save_for_inline
  	     deleted these in the copy used for continuing compilation,
  	     not the copy used for inlining).  */
! 	  if (NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_END
  	      && NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_BEG
  	      && NOTE_LINE_NUMBER (insn) != NOTE_INSN_DELETED)
  	    copy = emit_note (NOTE_SOURCE_FILE (insn), NOTE_LINE_NUMBER (insn));
--- 1839,1850 ----
  	     Also, NOTE_INSN_DELETED notes aren't useful (save_for_inline
  	     deleted these in the copy used for continuing compilation,
  	     not the copy used for inlining).  */
! 	  if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_INDEX)
! 	    copy =
! 	      emit_note ((char *)copy_rtx_and_substitute (NOTE_INDEX (insn),
! 							  map),
! 			 NOTE_INSN_INDEX);
! 	  else if (NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_END
  	      && NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_BEG
  	      && NOTE_LINE_NUMBER (insn) != NOTE_INSN_DELETED)
  	    copy = emit_note (NOTE_SOURCE_FILE (insn), NOTE_LINE_NUMBER (insn));
===================================================================
RCS file: /user/src/master/gcc/jump.c,v
retrieving revision 1.1.1.3
diff -c -r1.1.1.3 jump.c
*** 1.1.1.3	1995/11/01 20:12:57
--- jump.c	1995/11/01 20:52:45
***************
*** 4491,4496 ****
--- 4491,4497 ----

  	case 'S':
  	case 's':
+ 	case 'N':
  	  if (strcmp (XSTR (x, i), XSTR (y, i)))
  	    return 0;
  	  break;
===================================================================
RCS file: /user/src/master/gcc/loop.c,v
retrieving revision 1.1.1.3
retrieving revision 1.4
diff -c -r1.1.1.3 -r1.4
*** 1.1.1.3	1995/10/05 07:39:56
--- 1.4	1995/10/12 14:50:13
***************
*** 120,125 ****
--- 120,134 ----

  static int loop_has_volatile;

+ /* Nonzero if there is a return instruction in the current loop.  */
+
+ static int loop_has_return;
+
+ /* Nonzero if either of loop_number_exit_count, loop_has_call or
+    loop_has_return is.  */
+
+ static int loop_has_extra_exit;
+
  /* Added loop_continue which is the NOTE_INSN_LOOP_CONT of the
     current loop.  A continue statement will generate a branch to
     NEXT_INSN (loop_continue).  */
***************
*** 2164,2169 ****
--- 2173,2179 ----
    unknown_address_altered = 0;
    loop_has_call = 0;
    loop_has_volatile = 0;
+   loop_has_return = 0;
    loop_store_mems_idx = 0;

    num_mem_sets = 0;
***************
*** 2209,2214 ****
--- 2219,2226 ----
  		loop_has_volatile = 1;

  	      note_stores (PATTERN (insn), note_addr_stored);
+ 	      if (GET_CODE (PATTERN (insn)) == RETURN)
+ 		loop_has_return = 1;
  	    }
  	}
      }
***************
*** 3665,3670 ****
--- 3677,3692 ----
  	    loop_depth++;
  	  else if (NOTE_LINE_NUMBER (p) == NOTE_INSN_LOOP_END)
  	    loop_depth--;
+ 	  else if (NOTE_LINE_NUMBER (p) == NOTE_INSN_INDEX
+ 		   && GET_CODE (NOTE_INDEX_REG (p)) == REG)
+ 	    {
+ 	      struct iv_class *bl;
+
+ 	      bl = reg_biv_class[REGNO (NOTE_INDEX_REG (p))];
+ 	      if (bl && !not_every_iteration && !flag_no_unmapped_memory
+ 		  && INTVAL (NOTE_INDEX_SCALE (p)) > bl->max_mult_val)
+ 		bl->max_mult_val = INTVAL (NOTE_INDEX_SCALE (p));
+ 	    }
  	}

        /* Unlike in the code motion pass where MAYBE_NEVER indicates that
***************
*** 3714,3719 ****
--- 3736,3743 ----
    /* Examine each iv class for feasibility of strength reduction/induction
       variable elimination.  */

+   loop_has_extra_exit = loop_has_return | loop_has_call
+     | loop_number_exit_count[uid_loop_num[INSN_UID (loop_start)]];
    for (bl = loop_iv_list; bl; bl = bl->next)
      {
        struct induction *v;
***************
*** 4291,4296 ****
--- 4315,4322 ----
        bl->nonneg = 0;
        bl->reversed = 0;
        bl->total_benefit = 0;
+       bl->max_mult_val = 1;
+       CLEAR_MULTVAL_SET(bl->index_multvals);

        /* Add this class to loop_iv_list.  */
        bl->next = loop_iv_list;
***************
*** 4425,4430 ****
--- 4451,4469 ----
        if (type == DEST_REG)
  	bl->giv_count++;
        bl->total_benefit += benefit;
+       if (!flag_no_unmapped_memory && !not_every_iteration
+ 	  && CONSTANT_P (mult_val)
+ 	  && (unsigned)abs (INTVAL (v->mult_val))
+ 	     <= (unsigned)MAX_RECORDED_MULTVAL
+ 	  && !TEST_MULTVAL (bl->index_multvals, abs (INTVAL (v->mult_val)))
+ 	  && (type == DEST_ADDR
+ #if 0
+ 	      || type == DEST_REG && used_in_mem (dest_reg, insn)
+ #endif
+ 	      ))
+ 	{
+ 	  RECORD_MULTVAL(bl->index_multvals, abs (INTVAL (v->mult_val)));
+ 	}
      }
    else
      /* Fatal error, biv missing for this giv?  */
***************
*** 5958,5963 ****
--- 5997,6003 ----
  {
    rtx reg = bl->biv->dest_reg;
    rtx p;
+   int loop_test = 0;

    /* Scan all insns in the loop, stopping if we find one that uses the
       biv in a way that we cannot eliminate.  */
***************
*** 5969,5975 ****

        if ((code == INSN || code == JUMP_INSN || code == CALL_INSN)
  	  && reg_mentioned_p (reg, PATTERN (p))
! 	  && ! maybe_eliminate_biv_1 (PATTERN (p), p, bl, eliminate_p, where))
  	{
  	  if (loop_dump_stream)
  	    fprintf (loop_dump_stream,
--- 6009,6016 ----

        if ((code == INSN || code == JUMP_INSN || code == CALL_INSN)
  	  && reg_mentioned_p (reg, PATTERN (p))
! 	  && ! maybe_eliminate_biv_1 (PATTERN (p), p, bl, eliminate_p, where,
! 				      loop_test))
  	{
  	  if (loop_dump_stream)
  	    fprintf (loop_dump_stream,
***************
*** 5977,5982 ****
--- 6018,6045 ----
  		     bl->regno, INSN_UID (p));
  	  break;
  	}
+       else if (code == NOTE
+ 	       && (NOTE_LINE_NUMBER (p) == NOTE_INSN_LOOP_CONT
+ 		   || NOTE_LINE_NUMBER (p) == NOTE_INSN_LOOP_VTOP))
+
+ 	/* we rely here on NOTE_INSN_CONT coming before NOTE_INSN_LOOP_VTOP,
+ 	   so that the latter overrides the former.  */
+ 	loop_test = NOTE_LINE_NUMBER (p);
+
+       /* If there is a jump within the loop, subsequent instructions might
+          not be executed, and thus be no necessary part of the loop
+ 	 predicate.
+ 	 Here and in maybe_eliminate_biv_1 we rely on the previous jump
+          optimization to have made loop exit and loop continue jumps
+ 	 easier to recognize.  */
+       if (code == JUMP_INSN
+ 	  && (! JUMP_LABEL (p)
+ 	      || uid_loop_num[INSN_UID (JUMP_LABEL (p))]
+ 		 == uid_loop_num[INSN_UID (p)]))
+
+ 	/* This could be refined by pushing the old loop_test on a stack,
+ 	   and getting it back when flow of control merges again.  */
+ 	loop_test = 0;
      }

    if (p == end)
***************
*** 5990,5995 ****
--- 6053,6169 ----
    return 0;
  }
  
+ /*
+    Existence of MEM expressions that use givs with particular mult_vals
+    invokes undefined behaviour if the value added to the pointer,
+    when multiplied by the size of the pointed to object, exceeds
+    the range of prtdiff_t.  Thus we can use the existance of such MEMs
+    as an indication that such a range overflow does not occur, or if it
+    does, the behaviour of the program does not matter.
+
+    With 'scalable' in the following I mean a number that remains the same
+    when multiplied with the mult_val of the considered giv.
+
+    column 1: mult_val of giv
+     +1 / -1:                             s
+     1:                                   1
+     positive:                            p
+     negative:                            n
+     constant != 0:                       c
+     loop invariant != 0                  ,
+     don't care: (loop invariant)         .
+    column 2: add_val of giv
+     0:                                   0
+     label + constant:                    L
+     don't care: (loop invariant)         .
+    column 3: biv direction
+     increment by scaleable constant:     i
+     increment by 1:                      I
+     decrement by scaleable constant:     d
+     decrement by 1:                      D
+     don't care: (i or d)                 .
+    column 4: biv index use;
+     existence of an every iteration executed MEM that uses a giv of a
+     mode at least as wide as a pointer with a mult_val, either directly
+     or as originally as input to a pointer addition,
+     - equal to the mult_val of the
+       considered giv's mult_val:         m
+     - equal to 1,                        1
+     - don't care:                        .
+    column 5: start value: . < p < P  &&  . < n < N && . < s < S
+     const scalable as positive signed:   P
+     const scalable as positive unsigned: p
+     const scalable as negative signed    N
+     const scalable as negative unsigned: n
+     P or N:                              S
+     p or n:                              s
+     don't care:                          .
+    column 6: loop style:
+     for() S / while() S                  w
+     for() S / while() S, with VTOP       W
+     do S while()                         d
+     don't care:                          .
+    column 7: comparison, normalized to be required true in exit tests:
+     equality                             e
+     inequality                           i
+     GT or GTU                            gt
+     LT or LTU                            lt
+     GT or GE                             gs
+     GTU or GEU                           gu
+     gs or gu                             g
+     LT or LE                             ls
+     LTU or LEU                           lu
+     ls or lu                             l
+     don't care:                          .
+    column 8: compared to:
+     0:                                   0
+     const scalable as positive signed:   P
+     const scalable as positive unsigned: p
+     const scalable as negative signed    N
+     const scalable as negative unsigned: n
+     P or N:                              S
+     p or n:                              s
+     loop invariant                       i
+     don't care:
+      (eliminable giv of other biv,
+       or loop invariant)                 .
+    column 9: comparison role:
+     required true in continue test:      p
+     required true in continue test,
+      no other loop exits:                P
+     don't care:                          .
+
+
+   a m d i s s c   t r
+   d u i n t t o   o o
+   d l r d a y m     l
+     t   e r l p     e
+         x t e
+
+   . . D . . W gt  i p     comp := NE, rescan
+   . . I . . W lt  i p     comp := NE, rescan
+   . s . . . . e   . .     just eliminate
+   . , . m . . NE  i P     just eliminate
+   . , . 1 . . NE  i .     just eliminate
+   . c . . S . e   S .     just eliminate
+   0 c . 1 . . .   . .     just eliminate
+   0 c d . S . g   S .     adjust comp to sign of mult_val, eliminate
+   0 c i . S . l   S .     adjust comp to sign of mult_val, eliminate
+   L c D m . W ge  i P     if (abs(mult_val) != 1 || to != 0) # else no gain
+                             biv := (biv + 1 - to) * mult_val, comp := NE,
+                             to := 0
+   L c I m . W le  i P     if (abs(mult_val) != 1 || to != 0)
+                             biv := (biv - 1 + to) * mult_val, comp := NE,
+                             to := 0
+   . , D m . W ge  i P     to := to - 1, comp := NE, eliminate
+   . , D 1 . W ge  i p     to := to - 1, comp := NE, eliminate
+   . s D . . W ge  i p     to := to - 1, comp := NE, eliminate
+   . , I m . W le  i P     to := to + 1, comp := NE, eliminate
+   . , I 1 . W le  i p     to := to + 1, comp := NE, eliminate
+   . s I . . W le  i p     to := to + 1, comp := NE, eliminate
+
+   Only a small part of this table is currently implemented.  */
+
  /* If BL appears in X (part of the pattern of INSN), see if we can
     eliminate its use.  If so, return 1.  If not, return 0.

***************
*** 5998,6011 ****
     If ELIMINATE_P is non-zero, actually do the elimination.  WHERE indicates
     where extra insns should be added.  Depending on how many items have been
     moved out of the loop, it will either be before INSN or at the start of
!    the loop.  */

  static int
! maybe_eliminate_biv_1 (x, insn, bl, eliminate_p, where)
       rtx x, insn;
       struct iv_class *bl;
       int eliminate_p;
       rtx where;
  {
    enum rtx_code code = GET_CODE (x);
    rtx reg = bl->biv->dest_reg;
--- 6172,6189 ----
     If ELIMINATE_P is non-zero, actually do the elimination.  WHERE indicates
     where extra insns should be added.  Depending on how many items have been
     moved out of the loop, it will either be before INSN or at the start of
!    the loop.

+    LOOP_TEST is non-zero if X is evaluated in every loop test.  It
+    is NOTE_INSN_LOOP_VTOP if it is evaluated in a copied loop test.  */
+
  static int
! maybe_eliminate_biv_1 (x, insn, bl, eliminate_p, where, loop_test)
       rtx x, insn;
       struct iv_class *bl;
       int eliminate_p;
       rtx where;
+      int loop_test;
  {
    enum rtx_code code = GET_CODE (x);
    rtx reg = bl->biv->dest_reg;
***************
*** 6036,6110 ****
  	if (v->giv_type == DEST_REG && SET_DEST (x) == v->dest_reg)
  	  return 1;

- #ifdef HAVE_cc0
-       if (SET_DEST (x) == cc0_rtx && SET_SRC (x) == reg)
  	{
! 	  /* Can replace with any giv that was reduced and
! 	     that has (MULT_VAL != 0) and (ADD_VAL == 0).
! 	     Require a constant for MULT_VAL, so we know it's nonzero.  */
!
! 	  for (v = bl->giv; v; v = v->next_iv)
! 	    if (CONSTANT_P (v->mult_val) && v->mult_val != const0_rtx
! 		&& v->add_val == const0_rtx
! 		&& ! v->ignore && ! v->maybe_dead && v->always_computable
! 		&& v->mode == mode)
! 	      {
! 		if (! eliminate_p)
! 		  return 1;

! 		/* If the giv has the opposite direction of change,
! 		   then reverse the comparison.  */
! 		if (INTVAL (v->mult_val) < 0)
! 		  new = gen_rtx (COMPARE, GET_MODE (v->new_reg),
! 				 const0_rtx, v->new_reg);
! 		else
! 		  new = v->new_reg;

! 		/* We can probably test that giv's reduced reg.  */
! 		if (validate_change (insn, &SET_SRC (x), new, 0))
! 		  return 1;
! 	      }

! 	  /* Look for a giv with (MULT_VAL != 0) and (ADD_VAL != 0);
! 	     replace test insn with a compare insn (cmp REDUCED_GIV ADD_VAL).
! 	     Require a constant for MULT_VAL, so we know it's nonzero.  */

! 	  for (v = bl->giv; v; v = v->next_iv)
! 	    if (CONSTANT_P (v->mult_val) && v->mult_val != const0_rtx
! 		&& ! v->ignore && ! v->maybe_dead && v->always_computable
! 		&& v->mode == mode)
! 	      {
! 		if (! eliminate_p)
! 		  return 1;

! 		/* If the giv has the opposite direction of change,
! 		   then reverse the comparison.  */
! 		if (INTVAL (v->mult_val) < 0)
! 		  new = gen_rtx (COMPARE, VOIDmode, copy_rtx (v->add_val),
! 				 v->new_reg);
! 		else
! 		  new = gen_rtx (COMPARE, VOIDmode, v->new_reg,
! 				 copy_rtx (v->add_val));
!
! 		/* Replace biv with the giv's reduced register.  */
! 		update_reg_last_use (v->add_val, insn);
! 		if (validate_change (insn, &SET_SRC (PATTERN (insn)), new, 0))
! 		  return 1;

! 		/* Insn doesn't support that constant or invariant.  Copy it
! 		   into a register (it will be a loop invariant.)  */
! 		tem = gen_reg_rtx (GET_MODE (v->new_reg));
!
! 		emit_insn_before (gen_move_insn (tem, copy_rtx (v->add_val)),
! 				  where);
!
! 		if (validate_change (insn, &SET_SRC (PATTERN (insn)),
! 				     gen_rtx (COMPARE, VOIDmode,
! 					      v->new_reg, tem), 0))
! 		  return 1;
  	      }
  	}
- #endif
        break;

      case COMPARE:
--- 6214,6480 ----
  	if (v->giv_type == DEST_REG && SET_DEST (x) == v->dest_reg)
  	  return 1;

  	{
! 	  rtx jmp, src, dest, comp_rtx;
! 	  enum rtx_code comp;
! 	  int biv_dir;
! 	  int pass, pass_step;

! 	  dest = SET_DEST (x);
! #ifdef HAVE_cc0
! 	  if (dest == cc0_rtx && (jmp = next_cc0_user (insn))
! 	      && GET_CODE (jmp) == JUMP_INSN)
! #else
! 	  jmp = NEXT_INSN (insn);
! 	  if (GET_CODE (jmp) == JUMP_INSN && GET_CODE (dest) == REG
! 	      && find_regno_note (jmp, REG_DEAD, REGNO (dest)))
! #endif
! 	    {
! 	      int precond = 0; /* > 0 for true precondition, < 0 for false */

! 	      src = SET_SRC (x);
! 	      if (src == reg)
! 		arg = const0_rtx, arg_operand = -1;
! 	      else if (GET_CODE(src) == COMPARE)
! 		{
! 		  /* See if either argument is the biv.  */
! 		  if (XEXP (src, 0) == reg)
! 		    arg = XEXP (src, 1), arg_operand = 1;
! 		  else if (XEXP (src, 1) == reg)
! 		    arg = XEXP (src, 0), arg_operand = 0;
! 		  else
! 		    break;
! 		  if (!CONSTANT_P (arg)
! 		      && ((GET_CODE (arg) != REG && GET_CODE (arg) != MEM)
! 			  || invariant_p (arg) != 1))
! 		    break;
! 		}
! 	      else
! 		break;
! 	      tem = PATTERN (jmp);
! 	      if (GET_CODE (tem) != SET)
! 		break;
! 	      tem = SET_SRC(tem);
! 	      if (GET_CODE (tem) != IF_THEN_ELSE)
! 		break;
! 	      comp_rtx = XEXP (tem, 0);
! 	      comp = GET_CODE (comp_rtx);
! 	      if (GET_RTX_CLASS (comp) != '<')
! 		break;
! 	      if (XEXP (comp_rtx, 0) != dest)
! 		break;
! 	      if (invariant_p (arg) != 1)
! 		break;
! 	      if (loop_test)
! 		{
! 		  if (uid_luid[INSN_UID (JUMP_LABEL (jmp))]
! 		      > uid_luid[INSN_UID (jmp)])
! 		    {
! 		      if (uid_loop_num[INSN_UID (JUMP_LABEL (jmp))]
! 			  != uid_loop_num[INSN_UID (jmp)])
! 			precond = -1;
! 		    }
! 		  else
! 		    {
! 		      if (! next_nonnote_insn (jmp)
! 			  || uid_loop_num[INSN_UID (next_nonnote_insn (jmp))]
! 			     != uid_loop_num[INSN_UID (jmp)])
! 			precond = 1;
! 		    }
! 		}
! 	      biv_dir = INTVAL (bl->biv->add_val);
! 	      if (! arg_operand)
! 		biv_dir = -biv_dir;
!
! 	      if (comp == GTU && arg == const0_rtx)
! 		comp = NE;
! 	      else if (comp == LEU && arg == const0_rtx)
! 		comp = EQ;
! 	      else if (loop_test == NOTE_INSN_LOOP_VTOP)
! 		{
! 		  if (precond > 0)
! 		    {
! 		      if (((comp == GT || comp == GTU) && biv_dir == -1)
! 			  || ((comp == LT || comp == LTU) && biv_dir == 1))
! 			comp = NE;
! 		    }
! 		  else if (precond < 0)
! 		    {
! 		      if (((comp == LE || comp == LEU) && biv_dir == -1)
! 			  || ((comp == GE || comp == GEU) && biv_dir == 1))
! 			comp = EQ;
! 		    }
! 		}
! 	      /* Changing the comparison into an equality test can hardly
! 		 produce worse code, but it can enable a number of
! 		 subsequent optimizations.
! 		 We assume here that the existence of an inequality test
! 		 implies the existance of an equality test.  If this
! 		 should fail for any target, additional checks need to
! 		 be inserted.  */
! 	      GET_CODE (comp_rtx) = comp;
!
! 	      /* There are three passes in trying to find a matching giv:
! 		 2: try to find a giv with ADD_VAL == 0 .  Optional.
! 		 1: try to find a giv with constant ADD_VAL.  Optional.
! 		 0: try any giv. */
! 	      if (CONSTANT_P (arg))
! 		{
! 		  pass_step = 1;
! 		  pass = arg == const0_rtx ? 2 : 1;
! 		}
! 	      else
! 		{
! 		  pass_step = 2;
! 		  pass = 2;
! 		}
! 	      for (v = bl->giv;
! 		   v || (pass -= pass_step) >= 0 && (v = bl->giv);
! 		   v = v->next_iv)
! 		{
! 		  int check_precond;
! 		  int arg_offset;
! 		  int abs_mult_val;
! 		  enum rtx_code new_comp = comp;
!
! 		  if (v->ignore || v->maybe_dead || ! v->always_computable
! 		      || v->mode != mode)
! 		    continue;
! 		  if (pass == 2)
! 		    {
! 		      if (v->add_val != const0_rtx)
! 			continue;
! 		    }
! 		  else if (pass == 1)
! 		    {
! 		      if (! CONSTANT_P (v->add_val))
! 			continue;
! 		    }
! 		  /* Require a constant for MULT_VAL, so we know it's
! 		     nonzero.  */
! 		  if (! CONSTANT_P (v->mult_val) || v->mult_val == const0_rtx)
! 		    continue;
! 		  abs_mult_val = abs (INTVAL (v->mult_val));
! 		  check_precond = 0;
! 		  if (abs_mult_val > bl->max_mult_val
! 		      && (abs_mult_val > MAX_RECORDED_MULTVAL
! 			  || ! TEST_MULTVAL (bl->index_multvals, abs_mult_val)
! 			  || ! (check_precond = precond)
! 			  || loop_has_extra_exit))
! 		    continue;
! 		  arg_offset = 0;
! 		  if (loop_test == NOTE_INSN_LOOP_VTOP
! 		      && (v->add_val != const0_rtx || check_precond)
! 		      && pass != 2)
! 		    {
! 		      if (precond > 0)
! 			{
! 			  if ((comp == GE || comp == GEU) && biv_dir == -1
! 			      || (comp == LE || comp == LEU) && biv_dir == 1)
! 			    {
! 			      new_comp = NE;
! 			      arg_offset = INTVAL (bl->biv->add_val);
! 			    }
! 			}
! 		      else if (precond < 0)
! 			{
! 			  if ((comp == LT || comp == LTU) && biv_dir == -1
! 			      || (comp == GT || comp == GTU) && biv_dir == 1)
! 			    {
! 			      new_comp = EQ;
! 			      arg_offset = INTVAL (bl->biv->add_val);
! 			    }
! 			}
! 		    }
! 		  if (v->add_val == const0_rtx && ! check_precond
! 		      || new_comp == NE && check_precond >= 0
! 		      || new_comp == EQ && check_precond <= 0)
! 		    {
! 		      if (! eliminate_p)
! 			return 1;

! 		      switch (0)
! 			{ default:
! 			  if (arg_operand < 0)
! 			    {
! 			      if (v->add_val == const0_rtx && !arg_offset)
! 				if (validate_change (insn, &SET_SRC (x),
! 						     v->new_reg, 0))
! 				  break;
! 			      /* Create an ordinary compare so that the other
! 			         code can operate on it.  */
! 			      if (! validate_change (insn, &SET_SRC (x),
! 						     gen_rtx (COMPARE, mode,
! 							      reg, const0_rtx),
! 						     0))
! 				continue;
! 			      src = SET_SRC (x);
! 			      arg_operand = 1;
! 			    }

! 			  /* Replace biv with the giv's reduced reg.  */
! 			  XEXP (src, 1-arg_operand) = v->new_reg;

! 			  /* If all values used to compute the new ARG are
! 			     actually constant integers and the derived
! 			     constant can be directly placed in the COMPARE,
! 			     do so.  */
! 			  if (GET_CODE (arg) == CONST_INT
! 			      && GET_CODE (v->mult_val) == CONST_INT
! 			      && GET_CODE (v->add_val) == CONST_INT
! 			      && validate_change (
! 					insn, &XEXP (src, arg_operand),
! 					GEN_INT ((INTVAL (arg) + arg_offset)
! 						 * INTVAL (v->mult_val)
! 						 + INTVAL (v->add_val)), 0))
! 			    break;
! 			  /* If that failed, put back the change we made
! 			     above.  */
! 			  XEXP (src, 1-arg_operand) = reg;
!
! 			  /* Load it into a register.  */
! 			  tem = gen_reg_rtx (mode);
!
! 			  /* Replace biv with giv's reduced register.  */
! 			  validate_change (insn,
! 					   &XEXP (src, 1 - arg_operand),
! 					   v->new_reg, 1);
!
! 			  /* Compute value to compare against.  We rely on
! 			     emit_iv_add_mult to fix up the expression
! 			     generated with gen_rtx.  */
! 			  emit_iv_add_mult (
! 			    gen_rtx (PLUS, mode, arg, GEN_INT (arg_offset)),
! 			    v->mult_val, v->add_val, tem, where);
! 			  /* Use it in this insn.  */
! 			  validate_change (insn, &XEXP (src, arg_operand),
! 					   tem, 1);
! 			  if (apply_change_group ())
! 			    break;

! 			  /* This giv failed due to operand constraints.  */
! 			  continue;
! 			}
! 		      if (INTVAL (v->mult_val) < 0)
! 			switch (new_comp)
! 			  {
! 			  default: abort();
! 			  case GE:  new_comp = LE;  break;
! 			  case LE:  new_comp = GE;  break;
! 			  case GT:  new_comp = LT;  break;
! 			  case LT:  new_comp = GT;  break;
! 			  case GEU: new_comp = LEU; break;
! 			  case LEU: new_comp = GEU; break;
! 			  case GTU: new_comp = LTU; break;
! 			  case LTU: new_comp = GTU; break;
! 			  case NE: case EQ: break;
! 			  }
! 		      GET_CODE (comp_rtx) = new_comp;
! 		      return 1;
! 		    }
  	      }
+ 	    }
  	}
        break;

      case COMPARE:
***************
*** 6121,6133 ****

        if (CONSTANT_P (arg))
  	{
! 	  /* First try to replace with any giv that has constant positive
! 	     mult_val and constant add_val.  We might be able to support
! 	     negative mult_val, but it seems complex to do it in general.  */

  	  for (v = bl->giv; v; v = v->next_iv)
! 	    if (CONSTANT_P (v->mult_val) && INTVAL (v->mult_val) > 0
  		&& CONSTANT_P (v->add_val)
  		&& ! v->ignore && ! v->maybe_dead && v->always_computable
  		&& v->mode == mode)
  	      {
--- 6491,6505 ----

        if (CONSTANT_P (arg))
  	{
! 	  /* First try to replace with any giv that has constant
! 	     mult_val and constant add_val. */

  	  for (v = bl->giv; v; v = v->next_iv)
! 	    if (CONSTANT_P (v->mult_val) && INTVAL (v->mult_val)
! 		&& abs (INTVAL (v->mult_val)) <= bl->max_mult_val
  		&& CONSTANT_P (v->add_val)
+ 		&& ((v->add_val == const0_rtx && INTVAL (v->mult_val) > 0)
+ 		    || code == EQ || code == NE)
  		&& ! v->ignore && ! v->maybe_dead && v->always_computable
  		&& v->mode == mode)
  	      {
***************
*** 6159,6164 ****
--- 6531,6539 ----
  		XEXP (x, 1-arg_operand) = reg;
  	      }
  	
+ 	  if (code != NE && code != EQ)
+ 	    break;
+
  	  /* Look for giv with positive constant mult_val and nonconst add_val.
  	     Insert insns to calculate new compare value.  */

***************
*** 6194,6200 ****
  		 add_val. Insert insns to compute new compare value.  */

  	      for (v = bl->giv; v; v = v->next_iv)
! 		if (CONSTANT_P (v->mult_val) && INTVAL (v->mult_val) > 0
  		    && ! v->ignore && ! v->maybe_dead && v->always_computable
  		    && v->mode == mode)
  		  {
--- 6569,6578 ----
  		 add_val. Insert insns to compute new compare value.  */

  	      for (v = bl->giv; v; v = v->next_iv)
! 		if (CONSTANT_P (v->mult_val) && INTVAL (v->mult_val)
! 		    && abs (INTVAL (v->mult_val)) <= bl->max_mult_val
! 		    && ((v->add_val == const0_rtx && INTVAL (v->mult_val) > 0)
! 			|| code == EQ || code == NE)
  		    && ! v->ignore && ! v->maybe_dead && v->always_computable
  		    && v->mode == mode)
  		  {
***************
*** 6285,6298 ****
  	{
  	case 'e':
  	  if (! maybe_eliminate_biv_1 (XEXP (x, i), insn, bl,
! 				       eliminate_p, where))
  	    return 0;
  	  break;

  	case 'E':
  	  for (j = XVECLEN (x, i) - 1; j >= 0; j--)
  	    if (! maybe_eliminate_biv_1 (XVECEXP (x, i, j), insn, bl,
! 					 eliminate_p, where))
  	      return 0;
  	  break;
  	}
--- 6663,6676 ----
  	{
  	case 'e':
  	  if (! maybe_eliminate_biv_1 (XEXP (x, i), insn, bl,
! 				       eliminate_p, where, loop_test))
  	    return 0;
  	  break;

  	case 'E':
  	  for (j = XVECLEN (x, i) - 1; j >= 0; j--)
  	    if (! maybe_eliminate_biv_1 (XVECEXP (x, i, j), insn, bl,
! 					 eliminate_p, where, loop_test))
  	      return 0;
  	  break;
  	}
***************
*** 6628,6631 ****
--- 7006,7023 ----

    return gen_rtx (swap_condition (GET_CODE (comparison)), VOIDmode,
  		  XEXP (comparison, 1), XEXP (comparison, 0));
+ }
+
+ void
+ remove_early_reg_dead_notes ()
+ {
+   rtx insn, note;
+   for (insn = get_insns(); insn; insn = NEXT_INSN (insn))
+     {
+       if (GET_CODE (insn) != JUMP_INSN)
+ 	continue;
+       note = find_reg_note (insn, REG_DEAD, 0);
+       if (note)
+ 	remove_note (insn, note);
+     }
  }
===================================================================
RCS file: /user/src/master/gcc/loop.h,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -c -r1.1.1.2 -r1.2
*** 1.1.1.2	1995/10/05 07:19:24
--- 1.2	1995/10/10 20:26:00
***************
*** 37,42 ****
--- 37,66 ----
     as memory addresses and those that are calculated into registers.  */
  enum g_types { DEST_ADDR, DEST_REG };

+ /* Using a strength reduced giv to eliminate a biv is not correct in general.
+    However, on most hosted systems it invokes undefined behavouir to
+    index so that the offset has its highest bit set.  Thus, we can
+    assume that a sign overflow/underflow does not happen for a mult_val that
+    is used in a mult_val used for memory addressing (unless the mult_val is
+    smallest value representable by ptrdiff_t).
+    We remember the set of small mult_vals used in such givs, so that we
+    can use even a different giv with the same mult_val */
+
+ #define MAX_RECORDED_MULTVAL 255
+ #define MULTVAL_RECORD_LONGS \
+   ((MAX_RECORDED_MULTVAL - 1) / HOST_BITS_PER_WIDE_INT + 1)
+ typedef HOST_WIDE_INT MULTVAL_SET[MULTVAL_RECORD_LONGS];
+
+ #define CLEAR_MULTVAL_SET(SET) bzero((SET), sizeof (SET))
+
+ #define RECORD_MULTVAL(SET, N) \
+   ((SET)[(N) / (unsigned)HOST_BITS_PER_WIDE_INT]       \
+    |= HARD_CONST (1) << ((N) % (unsigned)HOST_BITS_PER_WIDE_INT))
+
+ #define TEST_MULTVAL(SET, N) \
+   ((SET)[(N) / (unsigned)HOST_BITS_PER_WIDE_INT]       \
+    & (HARD_CONST (1) << ((N) % (unsigned)HOST_BITS_PER_WIDE_INT)))
+
  /* A `struct induction' is created for every instruction that sets
     an induction variable (either a biv or a giv).  */

***************
*** 123,128 ****
--- 147,155 ----
    struct induction *giv;	/* List of all insns that compute a giv
  				   from this reg.  */
    int total_benefit;		/* Sum of BENEFITs of all those givs */
+   int max_mult_val;		/* maximum mult_val that might be used in an
+ 				   inequality comparison instruction.
+ 				   Generated from givs used in a MEM. */
    rtx initial_value;		/* Value of reg at loop start */
    rtx initial_test;		/* Test performed on BIV before loop */
    struct iv_class *next;	/* Links all class structures together */
***************
*** 133,138 ****
--- 160,166 ----
    unsigned nonneg : 1;		/* 1 if we added a REG_NONNEG note for this. */
    unsigned reversed : 1;	/* 1 if we reversed the loop that this
  				   biv controls. */
+   MULTVAL_SET index_multvals;
  };

  /* Definitions used by the basic induction variable discovery code.  */
===================================================================
RCS file: /user/src/master/gcc/print-rtl.c,v
retrieving revision 1.1.1.1
retrieving revision 1.4
diff -c -r1.1.1.1 -r1.4
*** 1.1.1.1	1995/10/05 06:55:54
--- 1.4	1995/10/10 20:26:01
***************
*** 106,111 ****
--- 106,114 ----
    for (i = 0; i < GET_RTX_LENGTH (GET_CODE (in_rtx)); i++)
      switch (*format_ptr++)
        {
+       case 'N':
+         if (NOTE_LINE_NUMBER (in_rtx) == NOTE_INSN_INDEX)
+ 	  goto print_expression;
        case 'S':
        case 's':
  	if (XSTR (in_rtx, i) == 0)
***************
*** 120,125 ****
--- 123,129 ----
  	break;

        case 'e':
+       print_expression:
  	indent += 2;
  	if (!sawclose)
  	  fprintf (outfile, " ");
===================================================================
RCS file: /user/src/master/gcc/rtl.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -c -r1.1.1.1 -r1.2
*** 1.1.1.1	1995/10/05 06:55:37
--- 1.2	1995/10/10 20:26:02
***************
*** 172,178 ****
  			   "NOTE_INSN_FUNCTION_END", "NOTE_INSN_SETJMP",
  			   "NOTE_INSN_LOOP_CONT", "NOTE_INSN_LOOP_VTOP",
  			   "NOTE_INSN_PROLOGUE_END", "NOTE_INSN_EPILOGUE_BEG",
! 			   "NOTE_INSN_DELETED_LABEL", "NOTE_INSN_FUNCTION_BEG"};

  char *reg_note_name[] = { "", "REG_DEAD", "REG_INC", "REG_EQUIV", "REG_WAS_0",
  			  "REG_EQUAL", "REG_RETVAL", "REG_LIBCALL",
--- 172,179 ----
  			   "NOTE_INSN_FUNCTION_END", "NOTE_INSN_SETJMP",
  			   "NOTE_INSN_LOOP_CONT", "NOTE_INSN_LOOP_VTOP",
  			   "NOTE_INSN_PROLOGUE_END", "NOTE_INSN_EPILOGUE_BEG",
! 			   "NOTE_INSN_DELETED_LABEL", "NOTE_INSN_FUNCTION_BEG",
! 			   "NOTE_INSN_INDEX"};

  char *reg_note_name[] = { "", "REG_DEAD", "REG_INC", "REG_EQUIV", "REG_WAS_0",
  			  "REG_EQUAL", "REG_RETVAL", "REG_LIBCALL",
***************
*** 429,434 ****
--- 430,436 ----

  	case 's':
  	case 'S':
+         case 'N':
  	  XSTR (copy, i) = XSTR (orig, i);
  	  break;

***************
*** 697,702 ****
--- 699,705 ----
  	  }

        case 's':
+       case 'N':
  	{
  	  int saw_paren = 0;
  	  register char *stringbuf;
===================================================================
RCS file: /user/src/master/gcc/rtl.def,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -c -r1.1.1.1 -r1.2
*** 1.1.1.1	1995/10/05 06:55:38
--- 1.2	1995/10/10 20:26:02
***************
*** 379,385 ****
        are really changed to NOTEs with a number of -1.
     -2 means beginning of a name binding contour; output N_LBRAC.
     -3 means end of a contour; output N_RBRAC.  */
! DEF_RTL_EXPR(NOTE, "note", "iuusn", 'x')

  /* INLINE_HEADER is use by inline function machinery.  The information
     it contains helps to build the mapping function between the rtx's of
--- 379,385 ----
        are really changed to NOTEs with a number of -1.
     -2 means beginning of a name binding contour; output N_LBRAC.
     -3 means end of a contour; output N_RBRAC.  */
! DEF_RTL_EXPR(NOTE, "note", "iuuNn", 'x')

  /* INLINE_HEADER is use by inline function machinery.  The information
     it contains helps to build the mapping function between the rtx's of
===================================================================
RCS file: /user/src/master/gcc/rtl.h,v
retrieving revision 1.1.1.1
retrieving revision 1.4
diff -c -r1.1.1.1 -r1.4
*** 1.1.1.1	1995/10/05 06:55:39
--- 1.4	1995/10/10 20:26:03
***************
*** 383,388 ****
--- 383,391 ----

  #define NOTE_SOURCE_FILE(INSN)  ((INSN)->fld[3].rtstr)
  #define NOTE_BLOCK_NUMBER(INSN) ((INSN)->fld[3].rtint)
+ #define NOTE_INDEX(INSN)        ((INSN)->fld[3].rtx)
+ #define NOTE_INDEX_REG(INSN)    (NOTE_INDEX(INSN)->fld[0].rtx)
+ #define NOTE_INDEX_SCALE(INSN)  (NOTE_INDEX(INSN)->fld[1].rtx)

  /* In a NOTE that is a line number, this is the line number.
     Other kinds of NOTEs are identified by negative numbers here.  */
***************
*** 430,435 ****
--- 433,439 ----
     i.e. the point just after all of the parms have been moved into
     their homes, etc.  */
  #define NOTE_INSN_FUNCTION_BEG -13
+ #define NOTE_INSN_INDEX -14


  #if 0 /* These are not used, and I don't know what they were for. --rms.  */
===================================================================
RCS file: /user/src/master/gcc/rtlanal.c,v
retrieving revision 1.1.1.3
retrieving revision 1.3
diff -c -r1.1.1.3 -r1.3
*** 1.1.1.3	1995/10/11 22:08:53
--- 1.3	1995/10/12 00:51:23
***************
*** 1001,1006 ****
--- 1001,1007 ----

  	case 'S':
  	case 's':
+         case 'N':
  	  if (strcmp (XSTR (x, i), XSTR (y, i)))
  	    return 0;
  	  break;
===================================================================
RCS file: /user/src/master/gcc/sched.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -c -r1.1.1.1 -r1.2
*** 1.1.1.1	1995/10/05 06:55:39
--- 1.2	1995/10/10 20:26:07
***************
*** 533,538 ****
--- 533,539 ----

  	case 'S':
  	case 's':
+         case 'N':
  	  if (strcmp (XSTR (x, i), XSTR (y, i)))
  	    return 0;
  	  break;
===================================================================
RCS file: /user/src/master/gcc/stmt.c,v
retrieving revision 1.1.1.2
retrieving revision 1.3
diff -c -r1.1.1.2 -r1.3
===================================================================
RCS file: /user/src/master/gcc/toplev.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -c -r1.1.1.2 -r1.2
*** 1.1.1.2	1995/10/05 07:19:44
--- 1.2	1995/10/10 20:26:08
***************
*** 518,523 ****
--- 518,530 ----
  int flag_gnu_linker = 1;
  #endif

+ /* When producing code for some special targets, it might be OK to address
+    through the entire address range in a loop. As a result, we can't infer
+    from the use of a giv as an index that the assiciated biv may be replaced
+    by a giv with the same mult_val as the MEM the index generates.  */
+
+ int flag_no_unmapped_memory = 0;
+
  /* Tag all structures with __attribute__(packed) */
  int flag_pack_struct = 0;

***************
*** 567,572 ****
--- 574,580 ----
    {"verbose-asm", &flag_verbose_asm, 1},
    {"gnu-linker", &flag_gnu_linker, 1},
    {"pack-struct", &flag_pack_struct, 1},
+   {"unmapped-memory", &flag_no_unmapped_memory, 0},
    {"bytecode", &output_bytecode, 1}
  };

***************
*** 2893,2898 ****
--- 2901,2907 ----
        TIMEVAR (loop_time,
  	       {
  		 loop_optimize (insns, loop_dump_file);
+ 		 remove_early_reg_dead_notes ();
  	       });
      }

===================================================================
RCS file: /user/src/master/gcc/tree.h,v
retrieving revision 1.1.1.3
retrieving revision 1.2
diff -c -r1.1.1.3 -r1.2
*** 1.1.1.3	1995/10/05 07:40:57
--- 1.2	1995/10/10 20:26:09
***************
*** 254,260 ****
     be fully addressable.  This means that pieces of this
     object cannot go into register parameters, for example.
     In IDENTIFIER_NODEs, this means that some extern decl for this name
!    had its address taken.  That matters for inline functions.  */
  #define TREE_ADDRESSABLE(NODE) ((NODE)->common.addressable_flag)

  /* In a VAR_DECL, nonzero means allocate static storage.
--- 254,262 ----
     be fully addressable.  This means that pieces of this
     object cannot go into register parameters, for example.
     In IDENTIFIER_NODEs, this means that some extern decl for this name
!    had its address taken.  That matters for inline functions.
!    In MULT_EXPR, it means that the multiply is the result of
!    an address calculation.  */
  #define TREE_ADDRESSABLE(NODE) ((NODE)->common.addressable_flag)

  /* In a VAR_DECL, nonzero means allocate static storage.