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]
Other format: [Raw text]

[PATCH] Split log links creation from flow.c


Hello,

this is first part of an attempt to clean up flow.c a bit. It splits
log links creation out of it.

Zdenek

	* flow-df.c: New.
	* Makefile.in (flow-df.o): New.
	* basic-block.h (PROP_LOG_LINKS): Removed.
	(create_log_links): Declare.
	* cfgcleanup.c (cleanup_cfg): Do not use PROP_LOG_LINKS.
	* ra.c (reg_alloc): Ditto.
	* df.c (df_def_record_1, df_uses_record): Add more information to
	DF_REF_READ_WRITE flag.
	(df_insn_refs_record): Set DF_REF_CALL_STACK_USAGE flag.
	(df_dump): Modified.
	* df.h (DF_REF_READ_WRITE): Split into ...
	(DF_REF_READ_WRITE_PPID, DF_REF_READ_WRITE_SUBREG): ... new flags.
	(DF_REF_CALL_STACK_USAGE): New flag.
	* flow.c (clear_log_links): Moved to flow-df.c.
	(life_analysis, update_life_info, init_propagate_block_info,
	mark_set_1, mark_used_reg): Do not compute log links.
	* toplev.c (rest_of_compilation): Call create_log_links.

Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v
retrieving revision 1.994
diff -c -3 -p -r1.994 Makefile.in
*** Makefile.in	13 Feb 2003 17:23:48 -0000	1.994
--- Makefile.in	15 Feb 2003 20:16:51 -0000
*************** OBJS = alias.o bb-reorder.o bitmap.o bui
*** 772,778 ****
   cfgrtl.o combine.o conflict.o convert.o cse.o cselib.o dbxout.o	   \
   debug.o df.o diagnostic.o doloop.o dominance.o		                   \
   dwarf2asm.o dwarf2out.o dwarfout.o emit-rtl.o except.o explow.o	   \
!  expmed.o expr.o final.o flow.o fold-const.o function.o gcse.o		   \
   genrtl.o ggc-common.o global.o graph.o gtype-desc.o			   \
   haifa-sched.o hashtable.o hooks.o ifcvt.o insn-attrtab.o insn-emit.o	   \
   insn-extract.o insn-opinit.o insn-output.o insn-peep.o insn-recog.o	   \
--- 772,778 ----
   cfgrtl.o combine.o conflict.o convert.o cse.o cselib.o dbxout.o	   \
   debug.o df.o diagnostic.o doloop.o dominance.o		                   \
   dwarf2asm.o dwarf2out.o dwarfout.o emit-rtl.o except.o explow.o	   \
!  expmed.o expr.o final.o flow.o flow-df.o fold-const.o function.o gcse.o   \
   genrtl.o ggc-common.o global.o graph.o gtype-desc.o			   \
   haifa-sched.o hashtable.o hooks.o ifcvt.o insn-attrtab.o insn-emit.o	   \
   insn-extract.o insn-opinit.o insn-output.o insn-peep.o insn-recog.o	   \
*************** alloc-pool.o : alloc-pool.c $(CONFIG_H) 
*** 1582,1587 ****
--- 1582,1589 ----
  flow.o : flow.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
     flags.h insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h \
     $(RECOG_H) function.h except.h $(EXPR_H) ssa.h $(GGC_H) $(TM_P_H)
+ flow-df.o : flow-df.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(BASIC_BLOCK_H) \
+    $(RTL_H) df.h flags.h
  cfg.o : cfg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) flags.h insn-config.h \
     $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h $(RECOG_H) \
     function.h except.h $(GGC_H) $(TM_P_H) alloc-pool.h
Index: basic-block.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/basic-block.h,v
retrieving revision 1.169
diff -c -3 -p -r1.169 basic-block.h
*** basic-block.h	6 Feb 2003 10:02:31 -0000	1.169
--- basic-block.h	15 Feb 2003 20:16:52 -0000
*************** enum update_life_extent
*** 466,481 ****
  /* Flags for life_analysis and update_life_info.  */
  
  #define PROP_DEATH_NOTES	1	/* Create DEAD and UNUSED notes.  */
! #define PROP_LOG_LINKS		2	/* Create LOG_LINKS.  */
! #define PROP_REG_INFO		4	/* Update regs_ever_live et al.  */
! #define PROP_KILL_DEAD_CODE	8	/* Remove dead code.  */
! #define PROP_SCAN_DEAD_CODE	16	/* Scan for dead code.  */
! #define PROP_ALLOW_CFG_CHANGES	32	/* Allow the CFG to be changed
  					   by dead code removal.  */
! #define PROP_AUTOINC		64	/* Create autoinc mem references.  */
! #define PROP_EQUAL_NOTES	128	/* Take into account REG_EQUAL notes.  */
! #define PROP_SCAN_DEAD_STORES	256	/* Scan for dead code.  */
! #define PROP_FINAL		(PROP_DEATH_NOTES | PROP_LOG_LINKS  \
  				 | PROP_REG_INFO | PROP_KILL_DEAD_CODE  \
  				 | PROP_SCAN_DEAD_CODE | PROP_AUTOINC \
  				 | PROP_ALLOW_CFG_CHANGES \
--- 466,480 ----
  /* Flags for life_analysis and update_life_info.  */
  
  #define PROP_DEATH_NOTES	1	/* Create DEAD and UNUSED notes.  */
! #define PROP_REG_INFO		2	/* Update regs_ever_live et al.  */
! #define PROP_KILL_DEAD_CODE	4	/* Remove dead code.  */
! #define PROP_SCAN_DEAD_CODE	8	/* Scan for dead code.  */
! #define PROP_ALLOW_CFG_CHANGES	16	/* Allow the CFG to be changed
  					   by dead code removal.  */
! #define PROP_AUTOINC		32	/* Create autoinc mem references.  */
! #define PROP_EQUAL_NOTES	64	/* Take into account REG_EQUAL notes.  */
! #define PROP_SCAN_DEAD_STORES	128	/* Scan for dead code.  */
! #define PROP_FINAL		(PROP_DEATH_NOTES \
  				 | PROP_REG_INFO | PROP_KILL_DEAD_CODE  \
  				 | PROP_SCAN_DEAD_CODE | PROP_AUTOINC \
  				 | PROP_ALLOW_CFG_CHANGES \
*************** extern void life_analysis	PARAMS ((rtx, 
*** 498,504 ****
  extern int update_life_info	PARAMS ((sbitmap, enum update_life_extent,
  					 int));
  extern int update_life_info_in_dirty_blocks PARAMS ((enum update_life_extent,
! 						      int));
  extern int count_or_remove_death_notes	PARAMS ((sbitmap, int));
  extern int propagate_block	PARAMS ((basic_block, regset, regset, regset,
  					 int));
--- 497,504 ----
  extern int update_life_info	PARAMS ((sbitmap, enum update_life_extent,
  					 int));
  extern int update_life_info_in_dirty_blocks PARAMS ((enum update_life_extent,
!        						     int));
! extern void create_log_links	PARAMS ((sbitmap));
  extern int count_or_remove_death_notes	PARAMS ((sbitmap, int));
  extern int propagate_block	PARAMS ((basic_block, regset, regset, regset,
  					 int));
Index: cfgcleanup.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfgcleanup.c,v
retrieving revision 1.72
diff -c -3 -p -r1.72 cfgcleanup.c
*** cfgcleanup.c	13 Feb 2003 18:31:40 -0000	1.72
--- cfgcleanup.c	15 Feb 2003 20:16:55 -0000
*************** cleanup_cfg (mode)
*** 1787,1794 ****
  	  if (!update_life_info_in_dirty_blocks (UPDATE_LIFE_GLOBAL_RM_NOTES,
  						 PROP_DEATH_NOTES
  						 | PROP_SCAN_DEAD_CODE
! 						 | PROP_KILL_DEAD_CODE
! 						 | PROP_LOG_LINKS))
  	    break;
  	}
        else if (!(mode & (CLEANUP_NO_INSN_DEL | CLEANUP_PRE_SIBCALL))
--- 1787,1793 ----
  	  if (!update_life_info_in_dirty_blocks (UPDATE_LIFE_GLOBAL_RM_NOTES,
  						 PROP_DEATH_NOTES
  						 | PROP_SCAN_DEAD_CODE
! 						 | PROP_KILL_DEAD_CODE))
  	    break;
  	}
        else if (!(mode & (CLEANUP_NO_INSN_DEL | CLEANUP_PRE_SIBCALL))
Index: df.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/df.c,v
retrieving revision 1.46
diff -c -3 -p -r1.46 df.c
*** df.c	31 Jan 2003 23:34:12 -0000	1.46
--- df.c	15 Feb 2003 20:16:57 -0000
*************** df_def_record_1 (df, x, bb, insn)
*** 955,961 ****
  #endif
        loc = &XEXP (dst, 0);
        dst = *loc;
!       flags |= DF_REF_READ_WRITE;
      }
  
    if (GET_CODE (dst) == REG
--- 955,961 ----
  #endif
        loc = &XEXP (dst, 0);
        dst = *loc;
!       flags |= DF_REF_READ_WRITE_SUBREG;
      }
  
    if (GET_CODE (dst) == REG
*************** df_uses_record (df, loc, ref_type, bb, i
*** 1074,1080 ****
  	    case SUBREG:
  	      if (read_modify_subreg_p (dst))
  		{
! 		  use_flags = DF_REF_READ_WRITE;
  #ifdef CLASS_CANNOT_CHANGE_MODE
  		  if (CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (dst),
  						  GET_MODE (SUBREG_REG (dst))))
--- 1074,1080 ----
  	    case SUBREG:
  	      if (read_modify_subreg_p (dst))
  		{
! 		  use_flags = DF_REF_READ_WRITE_SUBREG;
  #ifdef CLASS_CANNOT_CHANGE_MODE
  		  if (CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (dst),
  						  GET_MODE (SUBREG_REG (dst))))
*************** df_uses_record (df, loc, ref_type, bb, i
*** 1100,1106 ****
  	      dst = XEXP (dst, 0);
  	      if (GET_CODE (dst) != SUBREG)
  		abort ();
! 	      use_flags = DF_REF_READ_WRITE;
  #ifdef CLASS_CANNOT_CHANGE_MODE
  	      if (CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (dst),
  					      GET_MODE (SUBREG_REG (dst))))
--- 1100,1106 ----
  	      dst = XEXP (dst, 0);
  	      if (GET_CODE (dst) != SUBREG)
  		abort ();
! 	      use_flags = DF_REF_READ_WRITE_SUBREG;
  #ifdef CLASS_CANNOT_CHANGE_MODE
  	      if (CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (dst),
  					      GET_MODE (SUBREG_REG (dst))))
*************** df_uses_record (df, loc, ref_type, bb, i
*** 1112,1118 ****
  	    case ZERO_EXTRACT:
  	    case SIGN_EXTRACT:
  	      df_uses_record (df, &XEXP (dst, 0), DF_REF_REG_USE, bb, insn,
! 			      DF_REF_READ_WRITE);
  	      df_uses_record (df, &XEXP (dst, 1), DF_REF_REG_USE, bb, insn, 0);
  	      df_uses_record (df, &XEXP (dst, 2), DF_REF_REG_USE, bb, insn, 0);
  	      dst = XEXP (dst, 0);
--- 1112,1118 ----
  	    case ZERO_EXTRACT:
  	    case SIGN_EXTRACT:
  	      df_uses_record (df, &XEXP (dst, 0), DF_REF_REG_USE, bb, insn,
! 			      DF_REF_READ_WRITE_SUBREG);
  	      df_uses_record (df, &XEXP (dst, 1), DF_REF_REG_USE, bb, insn, 0);
  	      df_uses_record (df, &XEXP (dst, 2), DF_REF_REG_USE, bb, insn, 0);
  	      dst = XEXP (dst, 0);
*************** df_uses_record (df, loc, ref_type, bb, i
*** 1165,1171 ****
      case PRE_MODIFY:
      case POST_MODIFY:
        /* Catch the def of the register being modified.  */
!       df_ref_record (df, XEXP (x, 0), &XEXP (x, 0), insn, DF_REF_REG_DEF, DF_REF_READ_WRITE);
  
        /* ... Fall through to handle uses ...  */
  
--- 1165,1172 ----
      case PRE_MODIFY:
      case POST_MODIFY:
        /* Catch the def of the register being modified.  */
!       df_ref_record (df, XEXP (x, 0), &XEXP (x, 0), insn, DF_REF_REG_DEF, DF_REF_READ_WRITE_PPID);
!       flags |= DF_REF_READ_WRITE_PPID;
  
        /* ... Fall through to handle uses ...  */
  
*************** df_insn_refs_record (df, bb, insn)
*** 1249,1255 ****
  
  	  /* The stack ptr is used (honorarily) by a CALL insn.  */
  	  x = df_reg_use_gen (STACK_POINTER_REGNUM);
! 	  df_uses_record (df, &XEXP (x, 0), DF_REF_REG_USE, bb, insn, 0);
  
  	  if (df->flags & DF_HARD_REGS)
  	    {
--- 1250,1256 ----
  
  	  /* The stack ptr is used (honorarily) by a CALL insn.  */
  	  x = df_reg_use_gen (STACK_POINTER_REGNUM);
! 	  df_uses_record (df, &XEXP (x, 0), DF_REF_REG_USE, bb, insn, DF_REF_CALL_STACK_USAGE);
  
  	  if (df->flags & DF_HARD_REGS)
  	    {
*************** df_dump (df, flags, file)
*** 3344,3351 ****
  		       DF_INSN_LUID (df, DF_REF_INSN (df->defs[j])),
  		       DF_REF_INSN_UID (df->defs[j]),
  		       DF_REF_REGNO (df->defs[j]));
! 	      if (df->defs[j]->flags & DF_REF_READ_WRITE)
! 		fprintf (file, "read/write ");
  	      df_chain_dump (DF_REF_CHAIN (df->defs[j]), file);
  	      fprintf (file, "\n");
  	    }
--- 3345,3354 ----
  		       DF_INSN_LUID (df, DF_REF_INSN (df->defs[j])),
  		       DF_REF_INSN_UID (df->defs[j]),
  		       DF_REF_REGNO (df->defs[j]));
! 	      if (df->defs[j]->flags & DF_REF_READ_WRITE_PPID)
! 		fprintf (file, "read/write (pre/post inc)");
! 	      if (df->defs[j]->flags & DF_REF_READ_WRITE_SUBREG)
! 		fprintf (file, "read/write (subreg)");
  	      df_chain_dump (DF_REF_CHAIN (df->defs[j]), file);
  	      fprintf (file, "\n");
  	    }
*************** df_dump (df, flags, file)
*** 3385,3392 ****
  		       DF_INSN_LUID (df, DF_REF_INSN (df->uses[j])),
  		       DF_REF_INSN_UID (df->uses[j]),
  		       DF_REF_REGNO (df->uses[j]));
! 	      if (df->uses[j]->flags & DF_REF_READ_WRITE)
! 		fprintf (file, "read/write ");
  	      df_chain_dump (DF_REF_CHAIN (df->uses[j]), file);
  	      fprintf (file, "\n");
  	    }
--- 3388,3397 ----
  		       DF_INSN_LUID (df, DF_REF_INSN (df->uses[j])),
  		       DF_REF_INSN_UID (df->uses[j]),
  		       DF_REF_REGNO (df->uses[j]));
! 	      if (df->defs[j]->flags & DF_REF_READ_WRITE_PPID)
! 		fprintf (file, "read/write (pre/post inc)");
! 	      if (df->defs[j]->flags & DF_REF_READ_WRITE_SUBREG)
! 		fprintf (file, "read/write (subreg)");
  	      df_chain_dump (DF_REF_CHAIN (df->uses[j]), file);
  	      fprintf (file, "\n");
  	    }
Index: df.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/df.h,v
retrieving revision 1.15
diff -c -3 -p -r1.15 df.h
*** df.h	26 Jan 2003 06:10:37 -0000	1.15
--- df.h	15 Feb 2003 20:16:58 -0000
*************** enum df_ref_flags
*** 48,55 ****
    {
      /* Read-modify-write refs generate both a use and a def and
         these are marked with this flag to show that they are not
!        independent.  */
!     DF_REF_READ_WRITE = 1,
      
      /* This flag is set on register references inside a subreg on
         machines which have CLASS_CANNOT_CHANGE_MODE and where the mode
--- 48,58 ----
    {
      /* Read-modify-write refs generate both a use and a def and
         these are marked with this flag to show that they are not
!        independent; DF_REF_READ_WRITE_PPID is for pre/post
!        increment/decrement, whereas DF_REF_READ_WRITE_SUBREG
!        stands for STRICT_LOW_PART/ZERO_EXTRACT/...  */
!     DF_REF_READ_WRITE_PPID = 1,
!     DF_REF_READ_WRITE_SUBREG = 2,
      
      /* This flag is set on register references inside a subreg on
         machines which have CLASS_CANNOT_CHANGE_MODE and where the mode
*************** enum df_ref_flags
*** 58,64 ****
         the REG itself (i.e., one might not see the subreg anyore).
         Also note, that this flag is set also for hardreg refs, i.e.,
         you must check yourself if it's a pseudo.  */
!     DF_REF_MODE_CHANGE = 2
    };
  
  
--- 61,70 ----
         the REG itself (i.e., one might not see the subreg anyore).
         Also note, that this flag is set also for hardreg refs, i.e.,
         you must check yourself if it's a pseudo.  */
!     DF_REF_MODE_CHANGE = 4,
! 
!     /* This flag is set on usage of stack pointer due to function call.  */
!     DF_REF_CALL_STACK_USAGE = 8
    };
  
  
Index: flow.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/flow.c,v
retrieving revision 1.548
diff -c -3 -p -r1.548 flow.c
*** flow.c	31 Jan 2003 06:52:48 -0000	1.548
--- flow.c	15 Feb 2003 20:17:02 -0000
*************** Software Foundation, 59 Temple Place - S
*** 87,95 ****
  
     ** Other actions of life_analysis **
  
-    life_analysis sets up the LOG_LINKS fields of insns because the
-    information needed to do so is readily available.
- 
     life_analysis deletes insns whose only effect is to store a value
     that is never used.
  
--- 87,92 ----
*************** Software Foundation, 59 Temple Place - S
*** 114,120 ****
     Split out from life_analysis:
  	- local property discovery (bb->local_live, bb->local_set)
  	- global property computation
- 	- log links creation
  	- pre/post modify transformation
  */
  
--- 111,116 ----
*************** static void add_to_mem_set_list		PARAMS 
*** 340,346 ****
  static int invalidate_mems_from_autoinc PARAMS ((rtx *, void *));
  static void invalidate_mems_from_set	PARAMS ((struct propagate_block_info *,
  						 rtx));
- static void clear_log_links		PARAMS ((sbitmap));
  
  
  void
--- 336,341 ----
*************** life_analysis (f, file, flags)
*** 444,450 ****
  #endif
  
    if (! optimize)
!     flags &= ~(PROP_LOG_LINKS | PROP_AUTOINC | PROP_ALLOW_CFG_CHANGES);
  
    /* The post-reload life analysis have (on a global basis) the same
       registers live as was computed by reload itself.  elimination
--- 439,445 ----
  #endif
  
    if (! optimize)
!     flags &= ~(PROP_AUTOINC | PROP_ALLOW_CFG_CHANGES);
  
    /* The post-reload life analysis have (on a global basis) the same
       registers live as was computed by reload itself.  elimination
*************** update_life_info (blocks, extent, prop_f
*** 710,719 ****
  	count_or_remove_death_notes (blocks, 1);
      }
  
-   /* Clear log links in case we are asked to (re)compute them.  */
-   if (prop_flags & PROP_LOG_LINKS)
-     clear_log_links (blocks);
- 
    if (blocks)
      {
        EXECUTE_IF_SET_IN_SBITMAP (blocks, 0, i,
--- 705,710 ----
*************** init_propagate_block_info (bb, live, loc
*** 1885,1891 ****
    pbi->cc0_live = 0;
    pbi->flags = flags;
  
!   if (flags & (PROP_LOG_LINKS | PROP_AUTOINC))
      pbi->reg_next_use = (rtx *) xcalloc (max_reg_num (), sizeof (rtx));
    else
      pbi->reg_next_use = NULL;
--- 1876,1882 ----
    pbi->cc0_live = 0;
    pbi->flags = flags;
  
!   if (flags & PROP_AUTOINC)
      pbi->reg_next_use = (rtx *) xcalloc (max_reg_num (), sizeof (rtx));
    else
      pbi->reg_next_use = NULL;
*************** mark_set_1 (pbi, code, reg, cond, insn, 
*** 2755,2768 ****
  #endif
  
        /* Additional data to record if this is the final pass.  */
!       if (flags & (PROP_LOG_LINKS | PROP_REG_INFO
! 		   | PROP_DEATH_NOTES | PROP_AUTOINC))
  	{
  	  rtx y;
  	  int blocknum = pbi->bb->index;
  
  	  y = NULL_RTX;
! 	  if (flags & (PROP_LOG_LINKS | PROP_AUTOINC))
  	    {
  	      y = pbi->reg_next_use[regno_first];
  
--- 2746,2758 ----
  #endif
  
        /* Additional data to record if this is the final pass.  */
!       if (flags & (PROP_REG_INFO | PROP_DEATH_NOTES | PROP_AUTOINC))
  	{
  	  rtx y;
  	  int blocknum = pbi->bb->index;
  
  	  y = NULL_RTX;
! 	  if (flags & PROP_AUTOINC)
  	    {
  	      y = pbi->reg_next_use[regno_first];
  
*************** mark_set_1 (pbi, code, reg, cond, insn, 
*** 2804,2829 ****
  		}
  	    }
  
! 	  if (! some_was_dead)
! 	    {
! 	      if (flags & PROP_LOG_LINKS)
! 		{
! 		  /* Make a logical link from the next following insn
! 		     that uses this register, back to this insn.
! 		     The following insns have already been processed.
! 
! 		     We don't build a LOG_LINK for hard registers containing
! 		     in ASM_OPERANDs.  If these registers get replaced,
! 		     we might wind up changing the semantics of the insn,
! 		     even if reload can make what appear to be valid
! 		     assignments later.  */
! 		  if (y && (BLOCK_NUM (y) == blocknum)
! 		      && (regno_first >= FIRST_PSEUDO_REGISTER
! 			  || asm_noperands (PATTERN (y)) < 0))
! 		    LOG_LINKS (y) = alloc_INSN_LIST (insn, LOG_LINKS (y));
! 		}
! 	    }
! 	  else if (not_dead)
  	    ;
  	  else if (! some_was_live)
  	    {
--- 2794,2800 ----
  		}
  	    }
  
! 	  if (! some_was_dead || not_dead)
  	    ;
  	  else if (! some_was_live)
  	    {
*************** mark_set_1 (pbi, code, reg, cond, insn, 
*** 2876,2882 ****
      }
    else if (GET_CODE (reg) == REG)
      {
!       if (flags & (PROP_LOG_LINKS | PROP_AUTOINC))
  	pbi->reg_next_use[regno_first] = 0;
      }
  
--- 2847,2853 ----
      }
    else if (GET_CODE (reg) == REG)
      {
!       if (flags & PROP_AUTOINC)
  	pbi->reg_next_use[regno_first] = 0;
      }
  
*************** mark_used_reg (pbi, reg, cond, insn)
*** 3589,3595 ****
    for (i = regno_first; i <= regno_last; ++i)
      some_not_set |= ! REGNO_REG_SET_P (pbi->new_set, i);
  
!   if (pbi->flags & (PROP_LOG_LINKS | PROP_AUTOINC))
      {
        /* Record where each reg is used, so when the reg is set we know
  	 the next insn that uses it.  */
--- 3560,3566 ----
    for (i = regno_first; i <= regno_last; ++i)
      some_not_set |= ! REGNO_REG_SET_P (pbi->new_set, i);
  
!   if (pbi->flags & PROP_AUTOINC)
      {
        /* Record where each reg is used, so when the reg is set we know
  	 the next insn that uses it.  */
*************** count_or_remove_death_notes (blocks, kil
*** 4349,4381 ****
      }
  
    return count;
- }
- /* Clear LOG_LINKS fields of insns in a selected blocks or whole chain
-    if blocks is NULL.  */
- 
- static void
- clear_log_links (blocks)
-      sbitmap blocks;
- {
-   rtx insn;
-   int i;
- 
-   if (!blocks)
-     {
-       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
- 	if (INSN_P (insn))
- 	  free_INSN_LIST_list (&LOG_LINKS (insn));
-     }
-   else
-     EXECUTE_IF_SET_IN_SBITMAP (blocks, 0, i,
-       {
- 	basic_block bb = BASIC_BLOCK (i);
- 
- 	for (insn = bb->head; insn != NEXT_INSN (bb->end);
- 	     insn = NEXT_INSN (insn))
- 	  if (INSN_P (insn))
- 	    free_INSN_LIST_list (&LOG_LINKS (insn));
-       });
  }
  
  /* Given a register bitmap, turn on the bits in a HARD_REG_SET that
--- 4320,4325 ----
Index: ra.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ra.c,v
retrieving revision 1.7
diff -c -3 -p -r1.7 ra.c
*** ra.c	17 Jan 2003 03:28:09 -0000	1.7
--- ra.c	15 Feb 2003 20:17:04 -0000
*************** reg_alloc ()
*** 859,865 ****
    if ((debug_new_regalloc & DUMP_LAST_FLOW) == 0)
      rtl_dump_file = NULL;
    life_analysis (get_insns (), rtl_dump_file,
! 		 PROP_DEATH_NOTES | PROP_LOG_LINKS  | PROP_REG_INFO);
    cleanup_cfg (CLEANUP_EXPENSIVE);
    recompute_reg_usage (get_insns (), TRUE);
    if (rtl_dump_file)
--- 859,865 ----
    if ((debug_new_regalloc & DUMP_LAST_FLOW) == 0)
      rtl_dump_file = NULL;
    life_analysis (get_insns (), rtl_dump_file,
! 		 PROP_DEATH_NOTES | PROP_REG_INFO);
    cleanup_cfg (CLEANUP_EXPENSIVE);
    recompute_reg_usage (get_insns (), TRUE);
    if (rtl_dump_file)
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/toplev.c,v
retrieving revision 1.709
diff -c -3 -p -r1.709 toplev.c
*** toplev.c	12 Feb 2003 21:48:57 -0000	1.709
--- toplev.c	15 Feb 2003 20:17:10 -0000
*************** rest_of_compilation (decl)
*** 3182,3189 ****
  	  /* Insns were inserted, so things might look a bit different.  */
  	  insns = get_insns ();
  	  update_life_info_in_dirty_blocks (UPDATE_LIFE_GLOBAL_RM_NOTES,
! 					    PROP_LOG_LINKS | PROP_REG_INFO
! 					    | PROP_DEATH_NOTES);
  	}
      }
  
--- 3182,3188 ----
  	  /* Insns were inserted, so things might look a bit different.  */
  	  insns = get_insns ();
  	  update_life_info_in_dirty_blocks (UPDATE_LIFE_GLOBAL_RM_NOTES,
! 					    PROP_REG_INFO | PROP_DEATH_NOTES);
  	}
      }
  
*************** rest_of_compilation (decl)
*** 3200,3206 ****
--- 3199,3206 ----
        timevar_push (TV_COMBINE);
        open_dump_file (DFI_combine, decl);
  
+       create_log_links (NULL);
        close_dump_file (DFI_combine, print_rtl_with_bb, insns);
        rebuild_jump_labels_after_combine
  	= combine_instructions (insns, max_reg_num ());
  
/* Data flow analysis for GNU compiler.
   Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
   1999, 2000, 2001, 2002 Free Software Foundation, Inc.

This file is part of GCC.

GCC 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.

GCC 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 GCC; see the file COPYING.  If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.  */

/* This file contains a few pieces that were split of flow.c; some of
   them are related to dataflow analysis, the other are just unrelated
   tasks that were embedded into liveness analysis during the time.

   Currently we perform the following tasks:

   1) LOG_LINKS computation.  Log links are basically a local version of ud
      chains (they link the use to def only if it is in the same basic block,
      and they are created only for first use of the register).

   Other parts of flow.c should eventually end up here, namely
      -- register usage computation -- most of the information needed is
	 already computed in df.c
      -- pre/post modify transformation -- does not really fit into dataflow,
	 so we might want to instead place it somewhere else
      -- dead store elimination (or we could just improve the redundant store
	 elimination that store_motion does instead?)
      -- ? dead code elimination based on du chains ?
   */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "rtl.h"
#include "basic-block.h"
#include "df.h"
#include "flags.h"

static void clear_log_links		PARAMS ((sbitmap));

/* Fill in log links field for all insns.  If BLOCKS is not null, do so
   just for basic blocks in this bitmap.  */
void
create_log_links (blocks)
     sbitmap blocks;
{
  struct df *df;
  basic_block bb;
  rtx *next_use, insn;
  struct df_link *ref;
  bitmap bblocks;
  int i;

  clear_log_links (blocks);

  df = df_init ();

  if (blocks)
    {
      bblocks = BITMAP_XMALLOC();
      for (i = 0; i < last_basic_block; i++)
	if (TEST_BIT (blocks, i))
	  bitmap_set_bit (bblocks, i);
    }
  else
    bblocks = NULL;
    
  /* We just want defs & uses for insns.  We could base the work on real
     ud (or du) chains, but it would be slower and it would not make the
     code significantly simpler.  */
  df_analyse (df, bblocks, DF_HARD_REGS);

  next_use = xcalloc (max_reg_num (), sizeof (rtx));

  /* Pass through each block from the end, recording the uses of each
     register and establishing log links when def is encountered.
     Note that we do not clear last_def array in order to save time,
     so we have to test whether the use is in the same basic block as def.
	      
     There are a few cases below when we do not consider the definition or
     usage -- these are taken from original flow.c did. Don't ask me why it is
     done this way; I don't know and if it works, I don't want to know.  */

  FOR_EACH_BB (bb)
    {
      if (blocks && !TEST_BIT (blocks, bb->index))
	continue;

      for (insn = bb->end; insn != PREV_INSN (bb->head);
	   insn = PREV_INSN (insn))
	{
	  if (!INSN_P (insn))
	    continue;

	  for (ref = DF_INSN_DEFS (df, insn); ref; ref = ref->next)
	    {
	      int regno = DF_REF_REGNO (ref->ref);
	      rtx use_insn;

	      if (!next_use[regno])
		continue;

	      /* Do not consider if it is pre/post modification in MEM.  */
	      if (DF_REF_FLAGS (ref->ref) & DF_REF_READ_WRITE_PPID)
		continue;

	      /* Do not make the log link for frame pointer.  */
	      if ((regno == FRAME_POINTER_REGNUM
		   && (! reload_completed || frame_pointer_needed))
#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
		  || (regno == HARD_FRAME_POINTER_REGNUM
	      	      && (! reload_completed || frame_pointer_needed))
#endif
#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
		  || (regno == ARG_POINTER_REGNUM && fixed_regs[regno])
#endif
		  )
		continue;

	      use_insn = next_use[regno];
	      if (BLOCK_FOR_INSN (use_insn) == bb)
		{
		  /* flow.c claimed:

		     We don't build a LOG_LINK for hard registers contained
		     in ASM_OPERANDs.  If these registers get replaced,
		     we might wind up changing the semantics of the insn,
		     even if reload can make what appear to be valid
		     assignments later.  */
		  if (regno >= FIRST_PSEUDO_REGISTER
		      || asm_noperands (PATTERN (use_insn)) < 0)
		    LOG_LINKS (use_insn) =
		      alloc_INSN_LIST (insn, LOG_LINKS (use_insn));
		}
	      next_use[regno] = NULL_RTX;
	    }

	  for (ref = DF_INSN_USES (df, insn); ref; ref = ref->next)
	    {
	      int regno = DF_REF_REGNO (ref->ref);

	      /* Do not consider usage of stack pointer by function call.  */
	      if (DF_REF_FLAGS (ref->ref) & DF_REF_CALL_STACK_USAGE)
		continue;

	      next_use[regno] = insn;
	    }
	}
    }

  if (bblocks)
    BITMAP_XFREE (bblocks);

  free (next_use);
  df_finish (df);
}

/* Clear LOG_LINKS fields of insns in a selected blocks or whole chain
   if blocks is NULL.  */

static void
clear_log_links (blocks)
     sbitmap blocks;
{
  rtx insn;
  int i;

  if (!blocks)
    {
      for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
	if (INSN_P (insn))
	  free_INSN_LIST_list (&LOG_LINKS (insn));
    }
  else
    EXECUTE_IF_SET_IN_SBITMAP (blocks, 0, i,
      {
	basic_block bb = BASIC_BLOCK (i);

	for (insn = bb->head; insn != NEXT_INSN (bb->end);
	     insn = NEXT_INSN (insn))
	  if (INSN_P (insn))
	    free_INSN_LIST_list (&LOG_LINKS (insn));
      });
}

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