public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Faster streaming of enums
@ 2011-05-25 10:32 Jan Hubicka
  2011-05-25 12:15 ` Richard Guenther
  0 siblings, 1 reply; 6+ messages in thread
From: Jan Hubicka @ 2011-05-25 10:32 UTC (permalink / raw)
  To: gcc-patches, rguenther

Hi,
after fixing 1 byte i/o function call and most of hash table overhead,
functions to handle ulebs and slebs shows top in profile.  We use them in
many cases where we know value range of the operand will fit in 1 byte. In
particular to handle enums.
This is also dangerous since we generally assume enums to be in their value
range.

This patch adds i/o bits for enums and integers in range that should inline
well and add some sanity checking.

I converted only tree streamer tags, but if accepted, I will convert more.

Bootstrapped/regtested x86_64-linux, OK?

	* lto-streamer-out.c (output_record_start): Use lto_output_enum
	(lto_output_tree): Use output_record_start.
	* lto-streamer-in.c (input_record_start): Use lto_input_enum
	(lto_get_pickled_tree): Use input_record_start.
	* lto-section-in.c (lto_section_overrun): Turn into fatal error.
	(lto_value_range_error): New function.
	* lto-streamer.h (lto_value_range_error): Declare.
	(lto_output_int_in_range, lto_input_int_in_range): New functions.
	(lto_output_enum, lto_input_enum): New macros.
Index: lto-streamer-out.c
===================================================================
*** lto-streamer-out.c	(revision 174175)
--- lto-streamer-out.c	(working copy)
*************** output_sleb128 (struct output_block *ob,
*** 270,281 ****
  
  /* Output the start of a record with TAG to output block OB.  */
  
! static void
  output_record_start (struct output_block *ob, enum LTO_tags tag)
  {
!   /* Make sure TAG fits inside an unsigned int.  */
!   gcc_assert (tag == (enum LTO_tags) (unsigned) tag);
!   output_uleb128 (ob, tag);
  }
  
  
--- 270,279 ----
  
  /* Output the start of a record with TAG to output block OB.  */
  
! static inline void
  output_record_start (struct output_block *ob, enum LTO_tags tag)
  {
!   lto_output_enum (ob->main_stream, LTO_tags, LTO_NUM_TAGS, tag);
  }
  
  
*************** lto_output_tree (struct output_block *ob
*** 1401,1407 ****
  	 will instantiate two different nodes for the same object.  */
        output_record_start (ob, LTO_tree_pickle_reference);
        output_uleb128 (ob, ix);
!       output_uleb128 (ob, lto_tree_code_to_tag (TREE_CODE (expr)));
      }
    else if (lto_stream_as_builtin_p (expr))
      {
--- 1399,1405 ----
  	 will instantiate two different nodes for the same object.  */
        output_record_start (ob, LTO_tree_pickle_reference);
        output_uleb128 (ob, ix);
!       output_record_start (ob, lto_tree_code_to_tag (TREE_CODE (expr)));
      }
    else if (lto_stream_as_builtin_p (expr))
      {
Index: lto-streamer-in.c
===================================================================
*** lto-streamer-in.c	(revision 174175)
--- lto-streamer-in.c	(working copy)
*************** lto_input_string (struct data_in *data_i
*** 231,241 ****
  
  /* Return the next tag in the input block IB.  */
  
! static enum LTO_tags
  input_record_start (struct lto_input_block *ib)
  {
!   enum LTO_tags tag = (enum LTO_tags) lto_input_uleb128 (ib);
!   return tag;
  }
  
  
--- 231,240 ----
  
  /* Return the next tag in the input block IB.  */
  
! static inline enum LTO_tags
  input_record_start (struct lto_input_block *ib)
  {
!   return lto_input_enum (ib, LTO_tags, LTO_NUM_TAGS);
  }
  
  
*************** lto_get_pickled_tree (struct lto_input_b
*** 2558,2564 ****
    enum LTO_tags expected_tag;
  
    ix = lto_input_uleb128 (ib);
!   expected_tag = (enum LTO_tags) lto_input_uleb128 (ib);
  
    result = lto_streamer_cache_get (data_in->reader_cache, ix);
    gcc_assert (result
--- 2557,2563 ----
    enum LTO_tags expected_tag;
  
    ix = lto_input_uleb128 (ib);
!   expected_tag = input_record_start (ib);
  
    result = lto_streamer_cache_get (data_in->reader_cache, ix);
    gcc_assert (result
Index: lto-section-in.c
===================================================================
*** lto-section-in.c	(revision 174175)
--- lto-section-in.c	(working copy)
*************** lto_get_function_in_decl_state (struct l
*** 483,488 ****
  void
  lto_section_overrun (struct lto_input_block *ib)
  {
!   internal_error ("bytecode stream: trying to read %d bytes "
! 	          "after the end of the input buffer", ib->p - ib->len);
  }
--- 483,498 ----
  void
  lto_section_overrun (struct lto_input_block *ib)
  {
!   fatal_error ("bytecode stream: trying to read %d bytes "
! 	       "after the end of the input buffer", ib->p - ib->len);
! }
! 
! /* Report out of range value.  */
! 
! void
! lto_value_range_error (const char *purpose, HOST_WIDE_INT val,
! 		       HOST_WIDE_INT min, HOST_WIDE_INT max)
! {
!   fatal_error ("%s out of range: Range is %i to %i, value is %i",
! 	       purpose, (int)min, (int)max, (int)val);
  }
Index: lto-streamer.h
===================================================================
*** lto-streamer.h	(revision 174175)
--- lto-streamer.h	(working copy)
*************** extern int lto_eq_in_decl_state (const v
*** 771,776 ****
--- 771,779 ----
  extern struct lto_in_decl_state *lto_get_function_in_decl_state (
  				      struct lto_file_decl_data *, tree);
  extern void lto_section_overrun (struct lto_input_block *) ATTRIBUTE_NORETURN;
+ extern void lto_value_range_error (const char *,
+ 				   HOST_WIDE_INT, HOST_WIDE_INT,
+ 				   HOST_WIDE_INT) ATTRIBUTE_NORETURN;
  
  /* In lto-section-out.c  */
  extern hashval_t lto_hash_decl_slot_node (const void *);
*************** lto_input_1_unsigned (struct lto_input_b
*** 1199,1202 ****
--- 1202,1267 ----
    return (ib->data[ib->p++]);
  }
  
+ /* Output VAL into OBS and verify it is in range MIN...MAX that is supposed
+    to be compile time constant.
+    Be host independent, limit range to 31bits.  */
+ 
+ static inline void
+ lto_output_int_in_range (struct lto_output_stream *obs,
+ 			 HOST_WIDE_INT min,
+ 			 HOST_WIDE_INT max,
+ 			 HOST_WIDE_INT val)
+ {
+   HOST_WIDE_INT range = max - min;
+ 
+   gcc_checking_assert (val >= min && val <= max && range > 0
+ 		       && range < 0x7fffffff);
+ 
+   val -= min;
+   lto_output_1_stream (obs, val & 255);
+   if (range >= 0xff)
+     lto_output_1_stream (obs, (val << 8) & 255);
+   if (range >= 0xffff)
+     lto_output_1_stream (obs, (val << 16) & 255);
+   if (range >= 0xffffff)
+     lto_output_1_stream (obs, (val << 24) & 255);
+ }
+ 
+ /* Input VAL into OBS and verify it is in range MIN...MAX that is supposed
+    to be compile time constant.  PURPOSE is used for error reporting.  */
+ 
+ static inline HOST_WIDE_INT
+ lto_input_int_in_range (struct lto_input_block *ib,
+ 			const char *purpose,
+ 			HOST_WIDE_INT min,
+ 			HOST_WIDE_INT max)
+ {
+   HOST_WIDE_INT range = max - min;
+   HOST_WIDE_INT val = lto_input_1_unsigned (ib);
+ 
+   gcc_checking_assert (range > 0);
+ 
+   if (range >= 0xff)
+     val |= ((HOST_WIDE_INT)lto_input_1_unsigned (ib)) << 8;
+   if (range >= 0xffff)
+     val |= ((HOST_WIDE_INT)lto_input_1_unsigned (ib)) << 16;
+   if (range >= 0xffffff)
+     val |= ((HOST_WIDE_INT)lto_input_1_unsigned (ib)) << 24;
+   val += min;
+   if (val < min || val > max)
+     lto_value_range_error (purpose, val, min, max);
+   return val;
+ }
+ 
+ /* Output VAL of type "enum enum_name" into OBS.
+    Assume range 0...ENUM_LAST - 1.  */
+ #define lto_output_enum(obs,enum_name,enum_last,val) \
+   lto_output_int_in_range ((obs), 0, (int)(enum_last) - 1, (int)(val))
+ 
+ /* Input enum of type "enum enum_name" from IB.
+    Assume range 0...ENUM_LAST - 1.  */
+ #define lto_input_enum(ib,enum_name,enum_last) \
+   (enum enum_name)lto_input_int_in_range ((ib), #enum_name, 0, \
+ 					  (int)(enum_last) - 1)
+ 
  #endif /* GCC_LTO_STREAMER_H  */

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2011-05-26 17:45 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-05-25 10:32 Faster streaming of enums Jan Hubicka
2011-05-25 12:15 ` Richard Guenther
2011-05-25 12:18   ` Jan Hubicka
2011-05-25 12:58     ` Richard Guenther
2011-05-26 16:56       ` Jan Hubicka
2011-05-26 18:33         ` Tom Tromey

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).