This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

register tracking a-la memory tracking



Hi,
I am trying to add code to emit proper debug information after register renaming
or live range splitting passes.  I want to attach the DECL information with
corresponding register, track it and before final do simple dataflow pass
that will propagate the info and fiture out where the register is placed; genereate
notes that are then used by debugging output code.

I've found that our current tracking REGNO_DECL and ORIGINAL_PSEUDO is not enought,
as I need offsets for split multiple word registers. Additionally the information
is often thrown away.

This patch reorganizes the code to use same scheme as memory tracking does
and updates final.c to print the information collected and loop/gcse to
attach infromation for temporarily loaded globals.  In the debug dumps
the information already looks quite a more exact than previously.

bootstrapped/regtested i686

PS: Oops, forgot to kill the REGNO_DECL itself, would it be OK to do it
in separate patch? (as rename SET_DECL_RTL to set_decl_rtl) to keep the
noise in the patch low.

Sun Nov 11 18:05:41 CET 2001  Jan Hubicka  <jh@suse.cz>
	* emit-rtl.c (reg_attrs_htab): New static variable.
	(reg_attrs_htab_hash, reg_attrs_htab_eq, reg_attrs_mark,
	get_reg_attrs): New functions.
	(gen-rtx_REG_Offset, set_reg_attrs_from_mem,
	 set_mem_attrs_from_reg): New.
	(set_mem_decl): Kill.
	(init_once): Add new htab.
	* expr.h (set_mem_decl): Kill.
	(set_mem_attrs_from_reg, set_reg_attrs_from_mem): Declare.
	* final.c: Include expr.h
	(get_decl_from_op): Use REG_DECL.
	(output_asm_operand_names): Allways output separator;
	output original pseudo if available.
	* function.c (assign_params): Do not handle REGNO_DECL.
	* gcse.c (delete_store, build_store_vectors): Call
	set_reg_attrs_from_mem.
	* ggc-common.c (ggc_mark_rtx_children): Mark REG_ATTRS.
	* integrate.c: Kill REGNO_DECL handling.
	* loop.c (load_mems): Call set_reg_attrs_from_mem.
	* print-rtl.c (print_rtx): Output REG_ATTRTS.
	* regclass.c (reg_scan_mark_refs): Propagate attrs;
	do not handle REGNO_DECL.
	* reload1.c (alter_reg): Use set_mem_attrs_from_reg.
	* rtl.def (REG): Add third field.
	* rtl.h (struct reg_attrs): New.
	(rtunion_def): Add rtreg.
	(X0MEMATTR): CHeck that operand is MEM.
	(X0REGATTR): New.
	(REG_ATTRS, REG_DECL, REG_OFFSET): New macros.
	(gen_rtx_REG_offset): Declare.
	* simplify-rtx (simplify_subreg0: Use gen_rtx_REG_offset.

Index: emit-rtl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/emit-rtl.c,v
retrieving revision 1.222
diff -c -3 -p -r1.222 emit-rtl.c
*** emit-rtl.c	2001/11/09 22:48:29	1.222
--- emit-rtl.c	2001/11/11 17:01:35
*************** static htab_t const_int_htab;
*** 148,153 ****
--- 148,156 ----
  /* A hash table storing memory attribute structures.  */
  static htab_t mem_attrs_htab;
  
+ /* A hash table storing register attribute structures.  */
+ static htab_t reg_attrs_htab;
+ 
  /* start_sequence and gen_sequence can make a lot of rtx expressions which are
     shortly thrown away.  We use two mechanisms to prevent this waste:
  
*************** static void mem_attrs_mark		PARAMS ((con
*** 195,200 ****
--- 198,208 ----
  static mem_attrs *get_mem_attrs		PARAMS ((HOST_WIDE_INT, tree, rtx,
  						 rtx, unsigned int,
  						 enum machine_mode));
+ static hashval_t reg_attrs_htab_hash    PARAMS ((const void *));
+ static int reg_attrs_htab_eq            PARAMS ((const void *,
+ 						 const void *));
+ static void reg_attrs_mark		PARAMS ((const void *));
+ static reg_attrs *get_reg_attrs		PARAMS ((tree, int));
  
  /* Probability of the conditional branch currently proceeded by try_split.
     Set to -1 otherwise.  */
*************** get_mem_attrs (alias, decl, offset, size
*** 310,315 ****
--- 318,391 ----
    return *slot;
  }
  
+ /* Returns a hash code for X (which is a really a reg_attrs *).  */
+ 
+ static hashval_t
+ reg_attrs_htab_hash (x)
+      const void *x;
+ {
+   reg_attrs *p = (reg_attrs *) x;
+ 
+   return ((p->offset * 1000) ^ (long) p->decl);
+ }
+ 
+ /* Returns non-zero if the value represented by X (which is really a
+    reg_attrs *) is the same as that given by Y (which is also really a
+    reg_attrs *).  */
+ 
+ static int
+ reg_attrs_htab_eq (x, y)
+      const void *x;
+      const void *y;
+ {
+   reg_attrs *p = (reg_attrs *) x;
+   reg_attrs *q = (reg_attrs *) y;
+ 
+   return (p->decl == q->decl && p->offset == q->offset);
+ }
+ 
+ /* This routine is called when we determine that we need a reg_attrs entry.
+    It marks the associated decl and RTL as being used, if present.  */
+ 
+ static void
+ reg_attrs_mark (x)
+      const void *x;
+ {
+   reg_attrs *p = (reg_attrs *) x;
+ 
+   if (p->decl)
+     ggc_mark_tree (p->decl);
+ }
+ 
+ /* Allocate a new reg_attrs structure and insert it into the hash table if
+    one identical to it is not already in the table.  We are doing this for
+    MEM of mode MODE.  */
+ 
+ static reg_attrs *
+ get_reg_attrs (decl, offset)
+      tree decl;
+      int offset;
+ {
+   reg_attrs attrs;
+   void **slot;
+ 
+   /* If everything is the default, we can just return zero.  */
+   if (decl == 0 && offset == 0)
+     return 0;
+ 
+   attrs.decl = decl;
+   attrs.offset = offset;
+ 
+   slot = htab_find_slot (reg_attrs_htab, &attrs, INSERT);
+   if (*slot == 0)
+     {
+       *slot = ggc_alloc (sizeof (reg_attrs));
+       memcpy (*slot, &attrs, sizeof (reg_attrs));
+     }
+ 
+   return *slot;
+ }
+ 
  /* Generate a new REG rtx.  Make sure ORIGINAL_REGNO is set properly, and
     don't attempt to share with the various global pieces of rtl (such as
     frame_pointer_rtx).  */
*************** gen_reg_rtx (mode)
*** 701,706 ****
--- 777,844 ----
    return val;
  }
  
+ /* Generate an register with same attributes as REG,
+    but offsetted by OFFSET.  */
+ 
+ rtx
+ gen_rtx_REG_offset (reg, mode, regno, offset)
+      enum machine_mode mode;
+      unsigned int regno;
+      int offset;
+      rtx reg;
+ {
+   rtx new = gen_rtx_REG (mode, regno);
+   REG_ATTRS (new) = get_reg_attrs (REG_DECL (reg),
+ 		 		   REG_OFFSET (reg) + offset);
+   return new;
+ }
+ 
+ /* Set the decl for MEM to DECL.  */
+ 
+ void
+ set_reg_attrs_from_mem (reg, mem)
+      rtx reg;
+      rtx mem;
+ {
+   if (GET_CODE (MEM_OFFSET (mem)) == CONST_INT)
+     REG_ATTRS (reg)
+       = get_reg_attrs (MEM_DECL (mem), INTVAL (MEM_OFFSET (mem)));
+ }
+ 
+ /* Assign the RTX X to declaration T.  */
+ void
+ set_decl_rtl (t, x)
+      tree t;
+      rtx x;
+ {
+   DECL_CHECK (t)->decl.rtl = x;
+ 
+   if (!x)
+     return;
+   /* For register, we maitain the reverse information too.  */
+   if (GET_CODE (x) == REG)
+     REG_ATTRS (x) = get_reg_attrs (t, 0);
+   else if (GET_CODE (x) == SUBREG)
+     REG_ATTRS (SUBREG_REG (x))
+       = get_reg_attrs (t, -SUBREG_BYTE (x));
+   if (GET_CODE (x) == CONCAT)
+     {
+       REG_ATTRS (XEXP (x, 0)) = get_reg_attrs (t, 0);
+       REG_ATTRS (XEXP (x, 1))
+         = get_reg_attrs (t, GET_MODE_UNIT_SIZE (GET_MODE (XEXP (x, 0))));
+     }
+   if (GET_CODE (x) == PARALLEL)
+     {
+       int i;
+       for (i = 0; i < XVECLEN (x, 0); i++)
+ 	{
+ 	  rtx x = XVECEXP (x, 0, i);
+ 	  if (REG_P (XEXP (x, 0)))
+ 	    REG_ATTRS (XEXP (x, 0)) = get_reg_attrs (t, INTVAL (XEXP (x, 1)));
+ 	}
+     }
+ }
+ 
  /* Identify REG (which may be a CONCAT) as a user register.  */
  
  void
*************** set_mem_align (mem, align)
*** 1796,1807 ****
  /* Set the decl for MEM to DECL.  */
  
  void
! set_mem_decl (mem, decl)
       rtx mem;
!      tree decl;
  {
    MEM_ATTRS (mem)
!     = get_mem_attrs (MEM_ALIAS_SET (mem), decl, MEM_OFFSET (mem),
  		     MEM_SIZE (mem), MEM_ALIGN (mem), GET_MODE (mem));
  }
  
--- 1934,1946 ----
  /* Set the decl for MEM to DECL.  */
  
  void
! set_mem_attrs_from_reg (mem, reg)
       rtx mem;
!      rtx reg;
  {
    MEM_ATTRS (mem)
!     = get_mem_attrs (MEM_ALIAS_SET (mem), REG_DECL (reg),
! 		     GEN_INT (REG_OFFSET (reg)),
  		     MEM_SIZE (mem), MEM_ALIGN (mem), GET_MODE (mem));
  }
  
*************** init_emit_once (line_numbers)
*** 4586,4592 ****
--- 4725,4734 ----
  
    mem_attrs_htab = htab_create (37, mem_attrs_htab_hash,
  				mem_attrs_htab_eq, NULL);
+   reg_attrs_htab = htab_create (37, reg_attrs_htab_hash,
+ 				reg_attrs_htab_eq, NULL);
    ggc_add_deletable_htab (mem_attrs_htab, 0, mem_attrs_mark);
+   ggc_add_deletable_htab (reg_attrs_htab, 0, reg_attrs_mark);
  
    no_line_numbers = ! line_numbers;
  
Index: expr.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/expr.h,v
retrieving revision 1.102
diff -c -3 -p -r1.102 expr.h
*** expr.h	2001/11/11 11:02:25	1.102
--- expr.h	2001/11/11 17:01:35
*************** extern void set_mem_alias_set PARAMS ((r
*** 615,622 ****
  /* Set the alignment of MEM to ALIGN bits.  */
  extern void set_mem_align PARAMS ((rtx, unsigned int));
  
! /* Set the DECL for MEM to DECL.  */
! extern void set_mem_decl PARAMS ((rtx, tree));
  
  /* Return a memory reference like MEMREF, but with its mode changed
     to MODE and its address changed to ADDR.
--- 615,625 ----
  /* Set the alignment of MEM to ALIGN bits.  */
  extern void set_mem_align PARAMS ((rtx, unsigned int));
  
! /* Set the DECL for MEM to attributes of REG.  */
! extern void set_mem_attrs_from_reg PARAMS ((rtx, rtx));
! 
! /* Set the DECL for REG to attributes of MEM.  */
! extern void set_reg_attrs_from_mem PARAMS ((rtx, rtx));
  
  /* Return a memory reference like MEMREF, but with its mode changed
     to MODE and its address changed to ADDR.
Index: final.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/final.c,v
retrieving revision 1.219
diff -c -3 -p -r1.219 final.c
*** final.c	2001/11/11 11:25:18	1.219
--- final.c	2001/11/11 17:01:36
*************** Software Foundation, 59 Temple Place - S
*** 67,72 ****
--- 67,73 ----
  #include "basic-block.h"
  #include "target.h"
  #include "debug.h"
+ #include "expr.h"
  
  #ifdef XCOFF_DEBUGGING_INFO
  #include "xcoffout.h"		/* Needed for external data
*************** get_decl_from_op (op, paddressp)
*** 3306,3313 ****
  
    *paddressp = 0;
  
!   if (GET_CODE (op) == REG && ORIGINAL_REGNO (op) >= FIRST_PSEUDO_REGISTER)
!     return REGNO_DECL (ORIGINAL_REGNO (op));
    else if (GET_CODE (op) != MEM)
      return 0;
  
--- 3288,3295 ----
  
    *paddressp = 0;
  
!   if (GET_CODE (op) == REG)
!     return REG_DECL (op);
    else if (GET_CODE (op) != MEM)
      return 0;
  
*************** output_asm_operand_names (operands, opor
*** 3351,3365 ****
    for (i = 0; i < nops; i++)
      {
        int addressp;
!       tree decl = get_decl_from_op (operands[oporder[i]], &addressp);
  
        if (decl && DECL_NAME (decl))
  	{
! 	  fprintf (asm_out_file, "%c%s %s%s",
! 		   wrote ? ',' : '\t', wrote ? "" : ASM_COMMENT_START,
  		   addressp ? "*" : "", IDENTIFIER_POINTER (DECL_NAME (decl)));
- 	  wrote = 1;
  	}
      }
  }
  
--- 3333,3353 ----
    for (i = 0; i < nops; i++)
      {
        int addressp;
!       rtx op = operands[oporder[i]];
!       tree decl = get_decl_from_op (op, &addressp);
! 
!       fprintf (asm_out_file, "%c%s",
! 	       wrote ? ',' : '\t', wrote ? "" : ASM_COMMENT_START);
!       wrote = 1;
  
        if (decl && DECL_NAME (decl))
  	{
! 	  fprintf (asm_out_file, " %s%s",
  		   addressp ? "*" : "", IDENTIFIER_POINTER (DECL_NAME (decl)));
  	}
+       else if (REG_P (op) && ORIGINAL_REGNO (op)
+ 	       && ORIGINAL_REGNO (op) != REGNO (op))
+ 	fprintf (asm_out_file, " tmp%i", ORIGINAL_REGNO (op));
      }
  }
  
Index: function.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/function.c,v
retrieving revision 1.322
diff -c -3 -p -r1.322 function.c
*** function.c	2001/11/11 11:02:26	1.322
--- function.c	2001/11/11 17:01:37
*************** assign_parms (fndecl)
*** 5025,5039 ****
  	  set_mem_attributes (x, result, 1);
  	  SET_DECL_RTL (result, x);
  	}
- 
-       if (GET_CODE (DECL_RTL (parm)) == REG)
- 	REGNO_DECL (REGNO (DECL_RTL (parm))) = parm;
-       else if (GET_CODE (DECL_RTL (parm)) == CONCAT)
- 	{
- 	  REGNO_DECL (REGNO (XEXP (DECL_RTL (parm), 0))) = parm;
- 	  REGNO_DECL (REGNO (XEXP (DECL_RTL (parm), 1))) = parm;
- 	}
- 
      }
  
    /* Output all parameter conversion instructions (possibly including calls)
--- 5025,5030 ----
Index: gcse.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/gcse.c,v
retrieving revision 1.164
diff -c -3 -p -r1.164 gcse.c
*** gcse.c	2001/10/30 12:41:39	1.164
--- gcse.c	2001/11/11 17:01:38
*************** build_store_vectors () 
*** 6633,6638 ****
--- 6633,6639 ----
  		  if (st)
  		    {
  		      rtx r = gen_reg_rtx (GET_MODE (ptr->pattern));
+ 		      set_reg_attrs_from_mem (r, ptr->pattern);
  		      if (gcse_file)
  			fprintf(gcse_file, "Removing redundant store:\n");
  		      replace_store_insn (r, XEXP (st, 0), bb);
*************** delete_store (expr, bb)
*** 6844,6850 ****
    rtx reg, i, del;
  
    if (expr->reaching_reg == NULL_RTX)
!     expr->reaching_reg = gen_reg_rtx (GET_MODE (expr->pattern));
    
  
    /* If there is more than 1 store, the earlier ones will be dead, 
--- 6845,6854 ----
    rtx reg, i, del;
  
    if (expr->reaching_reg == NULL_RTX)
!     {
!       expr->reaching_reg = gen_reg_rtx (GET_MODE (expr->pattern));
!       set_reg_attrs_from_mem (expr->reaching_reg, expr->pattern);
!     }
    
  
    /* If there is more than 1 store, the earlier ones will be dead, 
Index: ggc-common.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/ggc-common.c,v
retrieving revision 1.45
diff -c -3 -p -r1.45 ggc-common.c
*** ggc-common.c	2001/10/05 02:49:16	1.45
--- ggc-common.c	2001/11/11 17:01:38
*************** ggc_mark_rtx_children (r)
*** 301,306 ****
--- 301,309 ----
  	case MEM:
  	  ggc_mark (MEM_ATTRS (r));
  	  break;
+ 	case REG:
+ 	  ggc_mark (REG_ATTRS (r));
+ 	  break;
  	case JUMP_INSN:
  	  ggc_mark_rtx (JUMP_LABEL (r));
  	  break;
Index: integrate.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/integrate.c,v
retrieving revision 1.174
diff -c -3 -p -r1.174 integrate.c
*** integrate.c	2001/10/24 19:36:36	1.174
--- integrate.c	2001/11/11 17:01:39
*************** integrate_decl_tree (let, map)
*** 1777,1790 ****
  	  subst_constants (&r, NULL_RTX, map, 1);
  	  SET_DECL_RTL (d, r);
  
- 	  if (GET_CODE (r) == REG)
- 	    REGNO_DECL (REGNO (r)) = d;
- 	  else if (GET_CODE (r) == CONCAT)
- 	    {
- 	      REGNO_DECL (REGNO (XEXP (r, 0))) = d;
- 	      REGNO_DECL (REGNO (XEXP (r, 1))) = d;
- 	    }
- 
  	  apply_change_group ();
  	}
  
--- 1777,1782 ----
Index: loop.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/loop.c,v
retrieving revision 1.366
diff -c -3 -p -r1.366 loop.c
*** loop.c	2001/11/07 06:24:46	1.366
--- loop.c	2001/11/11 17:01:41
*************** load_mems (loop)
*** 9026,9031 ****
--- 9026,9032 ----
  	 out of the loop just because this REG is neither a
  	 user-variable nor used in the loop test.  */
        reg = gen_reg_rtx (GET_MODE (mem));
+       set_reg_attrs_from_mem (reg, mem);
        REG_USERVAR_P (reg) = 1;
        loop_info->mems[i].reg = reg;
  
Index: print-rtl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/print-rtl.c,v
retrieving revision 1.71
diff -c -3 -p -r1.71 print-rtl.c
*** print-rtl.c	2001/10/24 16:38:51	1.71
--- print-rtl.c	2001/11/11 17:01:41
*************** print_rtx (in_rtx)
*** 371,376 ****
--- 371,399 ----
  	    else
  	      fprintf (outfile, " %d", value);
  
+ 	    if (GET_CODE (in_rtx) == REG && REG_ATTRS (in_rtx))
+ 	      {
+ 		tree decl;
+ 		fputs (" [", outfile);
+ 		if (ORIGINAL_REGNO (in_rtx) != REGNO (in_rtx))
+ 		  fprintf (outfile, "orig:%i ", ORIGINAL_REGNO (in_rtx));
+ 		decl = REG_DECL (in_rtx);
+ 		if (decl)
+ 		  fprintf (outfile, "%s",
+ 			   DECL_NAME (decl)
+ 			   ? IDENTIFIER_POINTER (DECL_NAME (decl))
+ 			   : TREE_CODE (decl) == RESULT_DECL ? "<result>"
+ 			   : "<anonymous>");
+ 
+ 		if (REG_OFFSET (in_rtx))
+ 		  {
+ 		    fputc ('+', outfile);
+ 		    fprintf (outfile, HOST_WIDE_INT_PRINT_DEC,
+ 			     REG_OFFSET (in_rtx));
+ 		  }
+ 		fputc (']', outfile);
+ 	      }
+ 
  	    if (is_insn && &INSN_CODE (in_rtx) == &XINT (in_rtx, i)
  		&& XINT (in_rtx, i) >= 0
  		&& (name = get_insn_name (XINT (in_rtx, i))) != NULL)
Index: regclass.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/regclass.c,v
retrieving revision 1.137
diff -c -3 -p -r1.137 regclass.c
*** regclass.c	2001/10/18 21:34:14	1.137
--- regclass.c	2001/11/11 17:01:41
*************** reg_scan_mark_refs (x, insn, note_flag, 
*** 2508,2517 ****
  		 || (GET_CODE (src) == SUBREG && subreg_lowpart_p (src)))
  	    src = XEXP (src, 0);
  
! 	  if (GET_CODE (src) == REG && REGNO_DECL (REGNO (src)) == 0)
! 	    REGNO_DECL (REGNO (src)) = REGNO_DECL (REGNO (dest));
! 	  else if (GET_CODE (src) == REG && REGNO_DECL (REGNO (dest)) == 0)
! 	    REGNO_DECL (REGNO (dest)) = REGNO_DECL (REGNO (src));
  	}
  
        /* ... fall through ...  */
--- 2508,2517 ----
  		 || (GET_CODE (src) == SUBREG && subreg_lowpart_p (src)))
  	    src = XEXP (src, 0);
  
! 	  if (!REG_ATTRS (dest) && REG_P (src))
! 	    REG_ATTRS (dest) = REG_ATTRS (src);
! 	  if (!REG_ATTRS (dest) && GET_CODE (src) == MEM)
! 	    set_reg_attrs_from_mem (dest, src);
  	}
  
        /* ... fall through ...  */
Index: reload1.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/reload1.c,v
retrieving revision 1.311
diff -c -3 -p -r1.311 reload1.c
*** reload1.c	2001/11/11 11:25:27	1.311
--- reload1.c	2001/11/11 17:01:43
*************** alter_reg (i, from_reg)
*** 2054,2065 ****
  
        /* If we have a decl for the original register, set it for the
  	 memory.  If this is a shared MEM, make a copy.  */
!       if (REGNO_DECL (i))
  	{
  	  if (from_reg != -1 && spill_stack_slot[from_reg] == x)
  	    x = copy_rtx (x);
  
! 	  set_mem_decl (x, REGNO_DECL (i));
  	}
  
        /* Save the stack slot for later.  */
--- 2054,2065 ----
  
        /* If we have a decl for the original register, set it for the
  	 memory.  If this is a shared MEM, make a copy.  */
!       if (REG_DECL (regno_reg_rtx[i]))
  	{
  	  if (from_reg != -1 && spill_stack_slot[from_reg] == x)
  	    x = copy_rtx (x);
  
! 	  set_mem_attrs_from_reg (x, regno_reg_rtx[i]);
  	}
  
        /* Save the stack slot for later.  */
Index: rtl.def
===================================================================
RCS file: /cvs/gcc/egcs/gcc/rtl.def,v
retrieving revision 1.50
diff -c -3 -p -r1.50 rtl.def
*** rtl.def	2001/11/03 16:28:33	1.50
--- rtl.def	2001/11/11 17:01:43
*************** DEF_RTL_EXPR(VALUE, "value", "0", 'o')
*** 589,595 ****
     pseudo register that got turned into a hard register.
     This rtx needs to have as many (or more) fields as a MEM, since we
     can change REG rtx's into MEMs during reload.  */
! DEF_RTL_EXPR(REG, "reg", "i0", 'o')
  
  /* A scratch register.  This represents a register used only within a
     single insn.  It will be turned into a REG during register allocation
--- 589,595 ----
     pseudo register that got turned into a hard register.
     This rtx needs to have as many (or more) fields as a MEM, since we
     can change REG rtx's into MEMs during reload.  */
! DEF_RTL_EXPR(REG, "reg", "i00", 'o')
  
  /* A scratch register.  This represents a register used only within a
     single insn.  It will be turned into a REG during register allocation
Index: rtl.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/rtl.h,v
retrieving revision 1.312
diff -c -3 -p -r1.312 rtl.h
*** rtl.h	2001/11/06 14:47:36	1.312
--- rtl.h	2001/11/11 17:01:44
*************** typedef struct
*** 98,103 ****
--- 98,112 ----
    unsigned int align;		/* Alignment of MEM in bits.  */
  } mem_attrs;
  
+ /* Structure used to describe the attributes of a REG in similar way as
+    mem_attrs does for MEM above.  */
+ 
+ typedef struct
+ {
+   tree decl;			/* decl corresponding to REG.  */
+   HOST_WIDE_INT offset;		/* Offset from start of DECL.  */
+ } reg_attrs;
+ 
  /* Common union for an element of an rtx.  */
  
  typedef union rtunion_def
*************** typedef union rtunion_def
*** 115,120 ****
--- 124,130 ----
    tree rttree;
    struct basic_block_def *bb;
    mem_attrs *rtmem;
+   reg_attrs *rtreg;
  } rtunion;
  
  /* RTL expression ("rtx").  */
*************** extern void rtvec_check_failed_bounds PA
*** 359,365 ****
  #define X0BBDEF(RTX, N)	   (RTL_CHECK1(RTX, N, '0').bb)
  #define X0ADVFLAGS(RTX, N) (RTL_CHECK1(RTX, N, '0').rt_addr_diff_vec_flags)
  #define X0CSELIB(RTX, N)   (RTL_CHECK1(RTX, N, '0').rt_cselib)
! #define X0MEMATTR(RTX, N)  (RTL_CHECK1(RTX, N, '0').rtmem)
  
  #define XCWINT(RTX, N, C)     (RTL_CHECKC1(RTX, N, C).rtwint)
  #define XCINT(RTX, N, C)      (RTL_CHECKC1(RTX, N, C).rtint)
--- 369,376 ----
  #define X0BBDEF(RTX, N)	   (RTL_CHECK1(RTX, N, '0').bb)
  #define X0ADVFLAGS(RTX, N) (RTL_CHECK1(RTX, N, '0').rt_addr_diff_vec_flags)
  #define X0CSELIB(RTX, N)   (RTL_CHECK1(RTX, N, '0').rt_cselib)
! #define X0MEMATTR(RTX, N)  (RTL_CHECKC1(RTX, N, MEM).rtmem)
! #define X0REGATTR(RTX, N)  (RTL_CHECKC1(RTX, N, REG).rtreg)
  
  #define XCWINT(RTX, N, C)     (RTL_CHECKC1(RTX, N, C).rtwint)
  #define XCINT(RTX, N, C)      (RTL_CHECKC1(RTX, N, C).rtint)
*************** extern unsigned int subreg_regno 	PARAMS
*** 891,896 ****
--- 902,911 ----
     in the block and provide defaults if none specified.  */
  #define MEM_ATTRS(RTX) X0MEMATTR (RTX, 1)
  
+ /* The register attribute block.  We provide access macros for each value
+    in the block and provide defaults if none specified.  */
+ #define REG_ATTRS(RTX) X0REGATTR (RTX, 2)
+ 
  /* For a MEM rtx, the alias set.  If 0, this MEM is not in any alias
     set, and may alias anything.  Otherwise, the MEM can only alias
     MEMs in the same alias set.  This value is set in a
*************** extern unsigned int subreg_regno 	PARAMS
*** 923,928 ****
--- 938,950 ----
   : GET_MODE (RTX) != BLKmode ? GET_MODE_ALIGNMENT (GET_MODE (RTX))	\
   : BITS_PER_UNIT)
  
+ /* For a REG rtx, the decl it is known to refer to, if it is known to
+    refer to part of a DECL.  */
+ #define REG_DECL(RTX) (REG_ATTRS (RTX) == 0 ? 0 : REG_ATTRS (RTX)->decl)
+ 
+ /* For a MEM rtx, the offset from the start of MEM_DECL, if known, as a
+    RTX that is always a CONST_INT.  */
+ #define REG_OFFSET(RTX) (REG_ATTRS (RTX) == 0 ? 0 : REG_ATTRS (RTX)->offset)
  
  /* Copy the attributes that apply to memory locations from RHS to LHS.  */
  #define MEM_COPY_ATTRIBUTES(LHS, RHS)				\
*************** extern int rtx_equal_p                  
*** 1231,1236 ****
--- 1253,1260 ----
  /* In emit-rtl.c */
  extern rtvec gen_rtvec_v		PARAMS ((int, rtx *));
  extern rtx gen_reg_rtx			PARAMS ((enum machine_mode));
+ extern rtx gen_rtx_REG_offset		PARAMS ((rtx, enum machine_mode,
+ 						 unsigned int, int));
  extern rtx gen_label_rtx		PARAMS ((void));
  extern int subreg_hard_regno		PARAMS ((rtx, int));
  extern rtx gen_lowpart_common		PARAMS ((enum machine_mode, rtx));
Index: simplify-rtx.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/simplify-rtx.c,v
retrieving revision 1.85
diff -c -3 -p -r1.85 simplify-rtx.c
*** simplify-rtx.c	2001/10/29 23:01:45	1.85
--- simplify-rtx.c	2001/11/11 17:01:44
*************** simplify_subreg (outermode, op, innermod
*** 2587,2593 ****
  	 arguments are passed on 32-bit Sparc and should be fixed.  */
        if (HARD_REGNO_MODE_OK (final_regno, outermode)
  	  || ! HARD_REGNO_MODE_OK (REGNO (op), innermode))
! 	return gen_rtx_REG (outermode, final_regno);
      }
  
    /* If we have a SUBREG of a register that we are replacing and we are
--- 2587,2604 ----
  	 arguments are passed on 32-bit Sparc and should be fixed.  */
        if (HARD_REGNO_MODE_OK (final_regno, outermode)
  	  || ! HARD_REGNO_MODE_OK (REGNO (op), innermode))
! 	{
! 	  rtx x = gen_rtx_REG_offset (op, outermode, final_regno, byte);
! 
! 	  /* Propagate original regno.  We don't have any way to specify
! 	     the offset inside orignal regno, so do so only for lowpart.
! 	     The information is used only by alias analysis that can not
! 	     grog partial register anyway.  */
! 
! 	  if (subreg_lowpart_offset (outermode, innermode) == byte)
! 	    ORIGINAL_REGNO (x) = ORIGINAL_REGNO (op);
! 	  return x;
! 	}
      }
  
    /* If we have a SUBREG of a register that we are replacing and we are
Index: stmt.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/stmt.c,v
retrieving revision 1.226
diff -c -3 -p -r1.226 stmt.c
*** stmt.c	2001/11/11 11:02:26	1.226
--- stmt.c	2001/11/11 17:01:46
*************** expand_decl (decl)
*** 4000,4013 ****
  
        SET_DECL_RTL (decl, gen_reg_rtx (reg_mode));
  
-       if (GET_CODE (DECL_RTL (decl)) == REG)
- 	REGNO_DECL (REGNO (DECL_RTL (decl))) = decl;
-       else if (GET_CODE (DECL_RTL (decl)) == CONCAT)
- 	{
- 	  REGNO_DECL (REGNO (XEXP (DECL_RTL (decl), 0))) = decl;
- 	  REGNO_DECL (REGNO (XEXP (DECL_RTL (decl), 1))) = decl;
- 	}
- 
        mark_user_reg (DECL_RTL (decl));
  
        if (POINTER_TYPE_P (type))
--- 4000,4005 ----
Index: tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/tree.h,v
retrieving revision 1.281
diff -c -3 -p -r1.281 tree.h
*** tree.h	2001/11/09 23:30:25	1.281
--- tree.h	2001/11/11 17:01:46
*************** struct tree_type
*** 1423,1429 ****
     : (make_decl_rtl (NODE, NULL), (NODE)->decl.rtl))
  /* Set the DECL_RTL for NODE to RTL.  */
  #define SET_DECL_RTL(NODE, RTL) \
!   (DECL_CHECK (NODE)->decl.rtl = (RTL))
  /* Returns non-zero if the DECL_RTL for NODE has already been set.  */
  #define DECL_RTL_SET_P(NODE) \
    (DECL_CHECK (NODE)->decl.rtl != NULL)
--- 1423,1429 ----
     : (make_decl_rtl (NODE, NULL), (NODE)->decl.rtl))
  /* Set the DECL_RTL for NODE to RTL.  */
  #define SET_DECL_RTL(NODE, RTL) \
!   set_decl_rtl (NODE, RTL)
  /* Returns non-zero if the DECL_RTL for NODE has already been set.  */
  #define DECL_RTL_SET_P(NODE) \
    (DECL_CHECK (NODE)->decl.rtl != NULL)
*************** extern void dwarf2out_return_reg	PARAMS 
*** 3053,3058 ****
--- 3057,3065 ----
  
  typedef tree (*walk_tree_fn)		PARAMS ((tree *, int *, void *));
  
+ /* Assign the RTX to declaration.  */
+ 
+ extern void set_decl_rtl		PARAMS ((tree, rtx));
  
  /* Redefine abort to report an internal error w/o coredump, and
     reporting the location of the error in the source file.  This logic


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]