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]

Fix latent bug in optabs


Hi,

when emiting a libcall whose parameter is large
(for example "struct { unsigned char b[128]; } bitvec;" )
the loop is created to copy the parameter.

When compiling my testcase, the REG_LIBCALL note was tried to attach to
NOTE_INSN_LOOP_BEG  which of course did not success and the missing
REG_LIBCALL note caused a segfault in gcse.
However if the REG_LIBCALL note was attached to some "normal" instruction
it would be wrong because the block between REG_LIBCALL and REG_RETVAL
must be in a single basic block
but the loop copying the parameters  was inside too.

This patch checks whether the insns between REG_LIBCALL and REG_RETVAL
will be contained in a single basic block (by checking whether all
instructions are not control_flow_insn_p) and
if the insns will not be in a single basic block
the REG_LIBCALL and REG_RETVAL notes will not be emitted.
This fixes the problem with a source which made gcse to segfault.

Bootstrapped/regtested mainline i386 (athlon).
OK for mainline and 3_3-branch?

Josef


Sun Jan  5 15:47:06 CET 2003  Josef Zlomek <zlomj9am@artax.karlin.mff.cuni.cz>

	* Makefile.in (optabs.o): Add dependencies on basic-block.h and
	hard-reg-set.h.
	* basic-block.h (control_flow_insn_p): Fuction was exported.
	* cfgbuild.c (control_flow_insn_p): Fuction was made non-static.
	* optabs.c (emit_libcall_block): Emit REG_LIBCALL and REG_RETVAL
	notes only when the region is contained in a single basic block.

Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v
retrieving revision 1.961
diff -u -c -3 -p -r1.961 Makefile.in
*** Makefile.in	19 Dec 2002 15:53:46 -0000	1.961
--- Makefile.in	5 Jan 2003 15:08:15 -0000
*************** explow.o : explow.c $(CONFIG_H) $(SYSTEM
*** 1460,1466 ****
     toplev.h function.h ggc.h $(TM_P_H) gt-explow.h
  optabs.o : optabs.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
     flags.h insn-config.h $(EXPR_H) $(OPTABS_H) libfuncs.h $(RECOG_H) reload.h \
!    toplev.h $(GGC_H) real.h $(TM_P_H) except.h gt-optabs.h
  dbxout.o : dbxout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(RTL_H) \
     flags.h $(REGS_H) debug.h $(TM_P_H) $(TARGET_H) function.h langhooks.h \
     insn-config.h reload.h gstab.h xcoffout.h output.h dbxout.h toplev.h
--- 1460,1467 ----
     toplev.h function.h ggc.h $(TM_P_H) gt-explow.h
  optabs.o : optabs.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
     flags.h insn-config.h $(EXPR_H) $(OPTABS_H) libfuncs.h $(RECOG_H) reload.h \
!    toplev.h $(GGC_H) real.h $(TM_P_H) except.h gt-optabs.h hard-reg-set.h \
!    $(BASIC_BLOCK_H)
  dbxout.o : dbxout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(RTL_H) \
     flags.h $(REGS_H) debug.h $(TM_P_H) $(TARGET_H) function.h langhooks.h \
     insn-config.h reload.h gstab.h xcoffout.h output.h dbxout.h toplev.h
Index: basic-block.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/basic-block.h,v
retrieving revision 1.163
diff -u -c -3 -p -r1.163 basic-block.h
*** basic-block.h	19 Dec 2002 02:59:15 -0000	1.163
--- basic-block.h	5 Jan 2003 15:08:16 -0000
*************** extern void fixup_abnormal_edges	PARAMS 
*** 805,810 ****
--- 805,811 ----
  extern bool can_hoist_insn_p		PARAMS ((rtx, rtx, regset));
  extern rtx hoist_insn_after		PARAMS ((rtx, rtx, rtx, rtx));
  extern rtx hoist_insn_to_edge		PARAMS ((rtx, edge, rtx, rtx));
+ extern bool control_flow_insn_p		PARAMS ((rtx));
  
  /* In dominance.c */
  
Index: cfgbuild.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfgbuild.c,v
retrieving revision 1.29
diff -u -c -3 -p -r1.29 cfgbuild.c
*** cfgbuild.c	16 Dec 2002 18:19:06 -0000	1.29
--- cfgbuild.c	5 Jan 2003 15:08:16 -0000
*************** static void make_eh_edge		PARAMS ((sbitm
*** 59,65 ****
  static void find_bb_boundaries		PARAMS ((basic_block));
  static void compute_outgoing_frequencies PARAMS ((basic_block));
  static bool inside_basic_block_p	PARAMS ((rtx));
- static bool control_flow_insn_p		PARAMS ((rtx));
  
  /* Return true if insn is something that should be contained inside basic
     block.  */
--- 59,64 ----
*************** inside_basic_block_p (insn)
*** 97,103 ****
  /* Return true if INSN may cause control flow transfer, so it should be last in
     the basic block.  */
  
! static bool
  control_flow_insn_p (insn)
       rtx insn;
  {
--- 96,102 ----
  /* Return true if INSN may cause control flow transfer, so it should be last in
     the basic block.  */
  
! bool
  control_flow_insn_p (insn)
       rtx insn;
  {
Index: optabs.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/optabs.c,v
retrieving revision 1.154
diff -u -c -3 -p -r1.154 optabs.c
*** optabs.c	16 Dec 2002 18:19:44 -0000	1.154
--- optabs.c	5 Jan 2003 15:08:16 -0000
*************** Software Foundation, 59 Temple Place - S
*** 42,47 ****
--- 42,49 ----
  #include "reload.h"
  #include "ggc.h"
  #include "real.h"
+ #include "hard-reg-set.h"
+ #include "basic-block.h"
  
  /* Each optab contains info on how this target machine
     can perform a particular operation
*************** emit_libcall_block (insns, target, resul
*** 3309,3318 ****
    /* Encapsulate the block so it gets manipulated as a unit.  */
    if (!flag_non_call_exceptions || !may_trap_p (equiv))
      {
!       REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
! 		      			     REG_NOTES (first));
!       REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first,
! 		      			    REG_NOTES (last));
      }
  }
  
--- 3311,3336 ----
    /* Encapsulate the block so it gets manipulated as a unit.  */
    if (!flag_non_call_exceptions || !may_trap_p (equiv))
      {
!       /* We can't attach the REG_LIBCALL and REG_RETVAL notes
! 	 when the encapsulated region would not be in one basic block,
! 	 i.e. when there is a control_flow_insn_p insn between FIRST and LAST.
!        */
!       bool attach_libcall_retval_notes = true;
!       next = NEXT_INSN (last);
!       for (insn = first; insn != next; insn = NEXT_INSN (insn))
! 	if (control_flow_insn_p (insn))
! 	  {
! 	    attach_libcall_retval_notes = false;
! 	    break;
! 	  }
! 
!       if (attach_libcall_retval_notes)
! 	{
! 	  REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
! 						 REG_NOTES (first));
! 	  REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first,
! 						REG_NOTES (last));
! 	}
      }
  }
  


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