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]

Re: A patch to constify gcc.c (Really, summarizing remaining warnings)


 > From: Richard Henderson <rth@cygnus.com>
 > 
 > On Thu, Mar 11, 1999 at 11:08:45AM -0500, Kaveh R. Ghazi wrote:
 > > I guess you could create a new function out of the code in between the
 > > two calls to set_float_handler() and pass that function pointer to
 > > do_float_handler().  Then if do_float_handler() returned 0, you'd
 > > return 0?
 > 
 > Yes.
 > 
 > > How would you pass all the necessary data in a void *?
 > > Would you create a customized struct with all the info passed in and
 > > out and then call do_float_handler() with the struct as the second
 > > argument?
 > 
 > Yes.
 > 
 > > 	Also, let's assume what I describe above is accurate and we did
 > > it.  Out of curiosity, if I happened to bootstrap with -O3, and then
 > > do_float_handler() is inlined, would the errors come back?
 > 
 > Given that I'd expect do_float_handler to live next to set_float_handler
 > in toplev.c, I would not expect it to be inlined.

	CLICK!  Okay I get it. :-)


 > But answering the question you actually asked, yes, if it were inlined
 > the errors would come back.
 > r~


	Here's my first attempt to do this.  I wrapped two of the places
where the setjmp caused the "might be clobbered" warnings to appear. 

	However, gotos and jmp stuff make my head hurt, so please
examine this with a careful eye to make sure I got everything right. :-) 
(I did a successful bootstrap on Irix6.)

	Note, I made one change to the original do_float_handler you
posted which was to call set_float_handler(NULL) in the case where
setjmp returned a value > 0.  This makes sure all exit points of
do_float_handler reset the handler back to zero. 

	Is this okay to install?

		Thanks,
		--Kaveh


Sun Mar 14 07:11:15 1999  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>

	* cse.c (check_fold_consts): New static function.
	(cfc_args): New struct.
	(simplify_relational_operation): Use them in call to
	`do_float_handler'.
	
	* toplev.c (do_float_handler): New function to wrap calls to
	setjmp/set_float_handler.

	* toplev.h (do_float_handler): Add extern prototype.

	* tree.c (build_real_from_int_cst_1): New static function.
	(brfic_args): New struct.
	(build_real_from_int_cst): Use them in call to
	`do_float_handler'.

diff -rp orig/egcs-CVS19990313/gcc/cse.c egcs-CVS19990313/gcc/cse.c
*** orig/egcs-CVS19990313/gcc/cse.c	Sun Mar  7 08:02:35 1999
--- egcs-CVS19990313/gcc/cse.c	Sat Mar 13 22:37:16 1999
*************** static void cse_set_around_loop	PROTO((r
*** 664,669 ****
--- 664,670 ----
  static rtx cse_basic_block	PROTO((rtx, rtx, struct branch_path *, int));
  static void count_reg_usage	PROTO((rtx, int *, rtx, int));
  extern void dump_class          PROTO((struct table_elt*));
+ static void check_fold_consts	PROTO((PTR));
  
  extern int rtx_equal_function_value_matters;
  
*************** cse_gen_binary (code, mode, op0, op1)
*** 4594,4599 ****
--- 4595,4620 ----
      return gen_rtx_fmt_ee (code, mode, op0, op1);
  }
  
+ struct cfc_args
+ {
+   rtx op0, op1;
+   int equal, op0lt, op1lt;
+ };
+ 
+ static void
+ check_fold_consts (data)
+   PTR data;
+ {
+   struct cfc_args * args = (struct cfc_args *) data;
+   REAL_VALUE_TYPE d0, d1;
+ 
+   REAL_VALUE_FROM_CONST_DOUBLE (d0, args->op0);
+   REAL_VALUE_FROM_CONST_DOUBLE (d1, args->op1);
+   args->equal = REAL_VALUES_EQUAL (d0, d1);
+   args->op0lt = REAL_VALUES_LESS (d0, d1);
+   args->op1lt = REAL_VALUES_LESS (d1, d0);
+ }
+ 
  /* Like simplify_binary_operation except used for relational operators.
     MODE is the mode of the operands, not that of the result.  If MODE
     is VOIDmode, both operands must also be VOIDmode and we compare the
*************** simplify_relational_operation (code, mod
*** 4655,4673 ****
    else if (GET_CODE (op0) == CONST_DOUBLE && GET_CODE (op1) == CONST_DOUBLE
  	   && GET_MODE_CLASS (GET_MODE (op0)) == MODE_FLOAT)
      {
!       REAL_VALUE_TYPE d0, d1;
!       jmp_buf handler;
        
!       if (setjmp (handler))
  	return 0;
  
!       set_float_handler (handler);
!       REAL_VALUE_FROM_CONST_DOUBLE (d0, op0);
!       REAL_VALUE_FROM_CONST_DOUBLE (d1, op1);
!       equal = REAL_VALUES_EQUAL (d0, d1);
!       op0lt = op0ltu = REAL_VALUES_LESS (d0, d1);
!       op1lt = op1ltu = REAL_VALUES_LESS (d1, d0);
!       set_float_handler (NULL_PTR);
      }
  #endif  /* not REAL_IS_NOT_DOUBLE, or REAL_ARITHMETIC */
  
--- 4676,4692 ----
    else if (GET_CODE (op0) == CONST_DOUBLE && GET_CODE (op1) == CONST_DOUBLE
  	   && GET_MODE_CLASS (GET_MODE (op0)) == MODE_FLOAT)
      {
!       struct cfc_args args;
! 
!       args.op0 = op0;
!       args.op1 = op1;
        
!       if (do_float_handler(check_fold_consts, (PTR) &args) == 0)
  	return 0;
  
!       equal = args.equal;
!       op0lt = op0ltu = args.op0lt;
!       op1lt = op1ltu = args.op1lt;
      }
  #endif  /* not REAL_IS_NOT_DOUBLE, or REAL_ARITHMETIC */
  
diff -rp orig/egcs-CVS19990313/gcc/toplev.c egcs-CVS19990313/gcc/toplev.c
*** orig/egcs-CVS19990313/gcc/toplev.c	Sat Mar 13 22:29:30 1999
--- egcs-CVS19990313/gcc/toplev.c	Sat Mar 13 22:32:07 1999
*************** set_float_handler (handler)
*** 2389,2394 ****
--- 2389,2421 ----
      }
  }
  
+ /* This is a wrapper function for code which might elicit an
+    arithmetic exception.  That code should be passed in as a function
+    pointer FN, and one argument DATA.  DATA is usually a struct which
+    contains the real input and output for function FN.  This function
+    returns 0 (failure) if longjmp was called (i.e. an exception
+    occured.)  It returns 1 (success) otherwise. */
+ 
+ int
+ do_float_handler (fn, data)
+   void (*fn) PROTO ((PTR));
+   PTR data;
+ {
+   jmp_buf buf;
+ 
+   if (setjmp (buf))
+     {
+       /* We got here via longjmp() caused by an exception in function fn() */
+       set_float_handler (NULL);
+       return 0;
+     }
+ 
+   set_float_handler (buf);
+   (*fn)(data);
+   set_float_handler (NULL);
+   return 1;
+ }
+ 
  /* Specify, in HANDLER, where to longjmp to when a floating arithmetic
     error happens, pushing the previous specification into OLD_HANDLER.
     Return an indication of whether there was a previous handler in effect.  */
diff -rp orig/egcs-CVS19990313/gcc/toplev.h egcs-CVS19990313/gcc/toplev.h
*** orig/egcs-CVS19990313/gcc/toplev.h	Tue Feb  2 16:43:19 1999
--- egcs-CVS19990313/gcc/toplev.h	Sat Mar 13 21:28:26 1999
*************** extern void set_float_handler PROTO((jmp
*** 92,97 ****
--- 92,98 ----
  extern int push_float_handler PROTO((jmp_buf, jmp_buf));
  extern void pop_float_handler PROTO((int, jmp_buf));
  #endif
+ extern int do_float_handler PROTO((void (*) (PTR), PTR));
  
  #ifdef BUFSIZ
  extern void output_quoted_string	PROTO ((FILE *, const char *));
diff -rp orig/egcs-CVS19990313/gcc/tree.c egcs-CVS19990313/gcc/tree.c
*** orig/egcs-CVS19990313/gcc/tree.c	Tue Mar  2 16:30:04 1999
--- egcs-CVS19990313/gcc/tree.c	Sat Mar 13 22:38:42 1999
*************** int (*lang_get_alias_set) PROTO((tree));
*** 266,271 ****
--- 266,272 ----
  
  static void set_type_quals PROTO((tree, int));
  static void append_random_chars PROTO((char *));
+ static void build_real_from_int_cst_1 PROTO((PTR));
  
  extern char *mode_name[];
  
*************** real_value_from_int_cst (type, i)
*** 1450,1455 ****
--- 1451,1477 ----
    return d;
  }
  
+ struct brfic_args
+ {
+   tree type, i;
+   REAL_VALUE_TYPE d;
+ };
+ 
+ static void
+ build_real_from_int_cst_1 (data)
+   PTR data;
+ {
+   struct brfic_args * args = (struct brfic_args *) data;
+   
+ #ifdef REAL_ARITHMETIC
+   args->d = real_value_from_int_cst (args->type, args->i);
+ #else
+   args->d =
+     REAL_VALUE_TRUNCATE (TYPE_MODE (args->type),
+ 			 real_value_from_int_cst (args->type, args->i));
+ #endif
+ }
+ 
  /* This function can't be implemented if we can't do arithmetic
     on the float representation.  */
  
*************** build_real_from_int_cst (type, i)
*** 1461,1491 ****
    tree v;
    int overflow = TREE_OVERFLOW (i);
    REAL_VALUE_TYPE d;
!   jmp_buf float_error;
  
    v = make_node (REAL_CST);
    TREE_TYPE (v) = type;
  
!   if (setjmp (float_error))
      {
        d = dconst0;
        overflow = 1;
-       goto got_it;
      }
! 
!   set_float_handler (float_error);
! 
! #ifdef REAL_ARITHMETIC
!   d = real_value_from_int_cst (type, i);
! #else
!   d = REAL_VALUE_TRUNCATE (TYPE_MODE (type),
! 			   real_value_from_int_cst (type, i));
! #endif
! 
    /* Check for valid float value for this type on this target machine.  */
- 
-  got_it:
-   set_float_handler (NULL_PTR);
  
  #ifdef CHECK_FLOAT_VALUE
    CHECK_FLOAT_VALUE (TYPE_MODE (type), d, overflow);
--- 1483,1506 ----
    tree v;
    int overflow = TREE_OVERFLOW (i);
    REAL_VALUE_TYPE d;
!   struct brfic_args args;
  
    v = make_node (REAL_CST);
    TREE_TYPE (v) = type;
  
!   args.type = type;
!   args.i = i;
!   if (do_float_handler (build_real_from_int_cst_1, (PTR) &args))
!     {
!       d = args.d;
!     }
!   else
      {
        d = dconst0;
        overflow = 1;
      }
!   
    /* Check for valid float value for this type on this target machine.  */
  
  #ifdef CHECK_FLOAT_VALUE
    CHECK_FLOAT_VALUE (TYPE_MODE (type), d, overflow);



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