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] pack structures better on 64-bit hosts


The patch below is the result of spending quality time with pahole on an
x86-64 host.  The changes suggested by pahole range from the
almost-useless (diagnostic-context.h) to the possibly-useful (df.h,
c-tree.h, cp-tree.h).  I've attached the output from pahole (in emacs
org format) showing before/after formats for each affected structure so
the effects of the patch are somewhat more understandable.

No, I haven't measured the effect of these changes.

Bootstrapped on x86-64-linux-gnu.  OK to commit?

-Nathan

gcc/
	* basic-block.h (struct control_flow_graph): Move last_label_uid field up.
	* c-parser.c (struct c_token): Move location field up.
	* c-tree.h (struct c_typespec): Move expr_const_operands field up.
	(struct c_declspecs): Convert typespec_word, storage_class, and
	default_int_p into bitfields.
	(struct c_declarator): Move loc field up.
	* cfgloop.h (struct loop): Move can_be_parallel field up.
	* df.h (struct df_base_ref): Move regno field up.
	* diagnostic.h (struct diagnostic_context): Move classify_diagnostic
	field down.
	* dwarf2out.c (struct dw_fde_struct): Move funcdef_number field down.
	* expr.h (struct separate_ops): Move location field up.
	* ipa-prop.h (struct ipa_node_params): Move bitfields up.
	* optabs.h (struct optab_d): Move libcall_basename field down.
	* tree-ssa-loop-ivopts.c (struct version_info): Move inv_id field down.
	(struct iv_cand): Convert pos field into a bitfield.
	* tree-vectorizer.h (struct _loop_vec_info): Move loop_line_number field up.
	(struct _stmt_vec_info): Shuffle fields for better packing.
	* config/i386/i386.c (struct ix86_frame): Move red_zone_size up.
	* config/i386/i386.h (struct machine_function): Convert call_abi field
	into a bitfield.  Move cfa field to the end of the structure.

gcc/cp/
	* cp-tree.h (struct cp_decl_specifier_seq): Move type_location field up.
	(struct cp_declarator): Move id_loc field up.

diff --git a/gcc/basic-block.h b/gcc/basic-block.h
index 34b18bd..836c23e 100644
--- a/gcc/basic-block.h
+++ b/gcc/basic-block.h
@@ -389,6 +389,9 @@ struct GTY(()) control_flow_graph {
   /* The first free basic block number.  */
   int x_last_basic_block;
 
+  /* UIDs for LABEL_DECLs.  */
+  int last_label_uid;
+
   /* Mapping of labels to their associated blocks.  At present
      only used for the gimple CFG.  */
   VEC(basic_block,gc) *x_label_to_block_map;
@@ -404,9 +407,6 @@ struct GTY(()) control_flow_graph {
   /* Maximal number of entities in the single jumptable.  Used to estimate
      final flowgraph size.  */
   int max_jumptable_ents;
-
-  /* UIDs for LABEL_DECLs.  */
-  int last_label_uid;
 };
 
 /* Defines for accessing the fields of the CFG structure for function FN.  */
diff --git a/gcc/c-parser.c b/gcc/c-parser.c
index 27f0b81..62f1ea3 100644
--- a/gcc/c-parser.c
+++ b/gcc/c-parser.c
@@ -156,10 +156,10 @@ typedef struct GTY (()) c_token {
   /* If this token is a CPP_PRAGMA, this indicates the pragma that
      was seen.  Otherwise it is PRAGMA_NONE.  */
   ENUM_BITFIELD (pragma_kind) pragma_kind : 8;
-  /* The value associated with this token, if any.  */
-  tree value;
   /* The location at which this token was found.  */
   location_t location;
+  /* The value associated with this token, if any.  */
+  tree value;
 } c_token;
 
 /* A parser structure recording information about the state and
diff --git a/gcc/c-tree.h b/gcc/c-tree.h
index 3681ed7..882f545 100644
--- a/gcc/c-tree.h
+++ b/gcc/c-tree.h
@@ -160,6 +160,9 @@ enum c_typespec_kind {
 struct c_typespec {
   /* What kind of type specifier this is.  */
   enum c_typespec_kind kind;
+  /* Whether the expression has operands suitable for use in constant
+     expressions.  */
+  bool expr_const_operands;
   /* The specifier itself.  */
   tree spec;
   /* An expression to be evaluated before the type specifier, in the
@@ -171,9 +174,6 @@ struct c_typespec {
      expression itself (as opposed to the array sizes) forms no part
      of the type and so needs to be recorded separately.  */
   tree expr;
-  /* Whether the expression has operands suitable for use in constant
-     expressions.  */
-  bool expr_const_operands;
 };
 
 /* A storage class specifier.  */
@@ -220,11 +220,11 @@ struct c_declspecs {
      NULL; attributes (possibly from multiple lists) will be passed
      separately.  */
   tree attrs;
-  /* Any type specifier keyword used such as "int", not reflecting
-     modifiers such as "short", or cts_none if none.  */
-  enum c_typespec_keyword typespec_word;
   /* The storage class specifier, or csc_none if none.  */
   enum c_storage_class storage_class;
+  /* Any type specifier keyword used such as "int", not reflecting
+     modifiers such as "short", or cts_none if none.  */
+  ENUM_BITFIELD (c_typespec_keyword) typespec_word : 8;
   /* Whether any expressions in typeof specifiers may appear in
      constant expressions.  */
   BOOL_BITFIELD expr_const_operands : 1;
@@ -252,7 +252,7 @@ struct c_declspecs {
   BOOL_BITFIELD deprecated_p : 1;
   /* Whether the type defaulted to "int" because there were no type
      specifiers.  */
-  BOOL_BITFIELD default_int_p;
+  BOOL_BITFIELD default_int_p : 1;
   /* Whether "long" was specified.  */
   BOOL_BITFIELD long_p : 1;
   /* Whether "long" was specified more than once.  */
@@ -319,9 +319,9 @@ struct c_arg_info {
 struct c_declarator {
   /* The kind of declarator.  */
   enum c_declarator_kind kind;
+  location_t id_loc; /* Currently only set for cdk_id, cdk_array. */
   /* Except for cdk_id, the contained declarator.  For cdk_id, NULL.  */
   struct c_declarator *declarator;
-  location_t id_loc; /* Currently only set for cdk_id, cdk_array. */
   union {
     /* For identifiers, an IDENTIFIER_NODE or NULL_TREE if an abstract
        declarator.  */
diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h
index 26f9050..4135ed7 100644
--- a/gcc/cfgloop.h
+++ b/gcc/cfgloop.h
@@ -148,6 +148,9 @@ struct GTY ((chain_next ("%h.next"))) loop {
   bool any_upper_bound;
   bool any_estimate;
 
+  /* True if the loop can be parallel.  */
+  bool can_be_parallel;
+
   /* An integer estimation of the number of iterations.  Estimate_state
      describes what is the state of the estimation.  */
   enum loop_estimation estimate_state;
@@ -158,9 +161,6 @@ struct GTY ((chain_next ("%h.next"))) loop {
   /* Head of the cyclic list of the exits of the loop.  */
   struct loop_exit *exits;
 
-  /* True if the loop can be parallel.  */
-  bool can_be_parallel;
-
   /* The single induction variable of the loop when the loop is in
      normal form.  */
   tree single_iv;
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index f91410a..7b094dc 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -1759,10 +1759,10 @@ struct ix86_frame
   int nregs;
   int padding1;
   int va_arg_size;
+  int red_zone_size;
   HOST_WIDE_INT frame;
   int padding2;
   int outgoing_arguments_size;
-  int red_zone_size;
 
   HOST_WIDE_INT to_allocate;
   /* The offsets relative to ARG_POINTER.  */
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 4b83370..4f564a1 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -2364,12 +2364,9 @@ struct GTY(()) machine_function {
      has been computed for.  */
   int use_fast_prologue_epilogue_nregs;
 
-  /* The CFA state at the end of the prologue.  */
-  struct machine_cfa_state cfa;
-
   /* This value is used for amd64 targets and specifies the current abi
      to be used. MS_ABI means ms abi. Otherwise SYSV_ABI means sysv abi.  */
-  enum calling_abi call_abi;
+  ENUM_BITFIELD(calling_abi) call_abi : 8;
 
   /* Nonzero if the function accesses a previous frame.  */
   BOOL_BITFIELD accesses_prev_frame : 1;
@@ -2395,6 +2392,9 @@ struct GTY(()) machine_function {
   /* If true, the current function has a STATIC_CHAIN is placed on the
      stack below the return address.  */
   BOOL_BITFIELD static_chain_on_stack : 1;
+
+  /* The CFA state at the end of the prologue.  */
+  struct machine_cfa_state cfa;
 };
 #endif
 
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 22ee2d7..5981f2c 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -4363,14 +4363,14 @@ typedef enum cp_decl_spec {
 typedef struct cp_decl_specifier_seq {
   /* The number of times each of the keywords has been seen.  */
   unsigned specs[(int) ds_last];
+  /* The location of the primary type. Mainly used for error
+     reporting.  */
+  location_t type_location;
   /* The primary type, if any, given by the decl-specifier-seq.
      Modifiers, like "short", "const", and "unsigned" are not
      reflected here.  This field will be a TYPE, unless a typedef-name
      was used, in which case it will be a TYPE_DECL.  */
   tree type;
-  /* The location of the primary type. Mainly used for error
-     reporting.  */
-  location_t type_location;
   /* The attributes, if any, provided with the specifier sequence.  */
   tree attributes;
   /* If non-NULL, a built-in type that the user attempted to redefine
@@ -4438,12 +4438,12 @@ struct cp_declarator {
   /* Whether we parsed an ellipsis (`...') just before the declarator,
      to indicate this is a parameter pack.  */
   BOOL_BITFIELD parameter_pack_p : 1;
+  location_t id_loc; /* Currently only set for cdk_id and cdk_function. */
   /* Attributes that apply to this declarator.  */
   tree attributes;
   /* For all but cdk_id and cdk_error, the contained declarator.  For
      cdk_id and cdk_error, guaranteed to be NULL.  */
   cp_declarator *declarator;
-  location_t id_loc; /* Currently only set for cdk_id and cdk_function. */
   union {
     /* For identifiers.  */
     struct {
diff --git a/gcc/df.h b/gcc/df.h
index 194cbcf..2e9f19f 100644
--- a/gcc/df.h
+++ b/gcc/df.h
@@ -362,6 +362,7 @@ struct df_base_ref
   ENUM_BITFIELD(df_ref_type) type : 8;
 				/* Type of ref.  */
   int flags : 16;		/* Various df_ref_flags.  */
+  unsigned int regno;		/* The register number referenced.  */
   rtx reg;			/* The register referenced.  */
   struct df_link *chain;	/* Head of def-use, use-def.  */
   /* Pointer to the insn info of the containing instruction.  FIXME!
@@ -373,7 +374,6 @@ struct df_base_ref
      themselves rather than using an external structure.  */
   union df_ref_d *next_reg;     /* Next ref with same regno and type.  */
   union df_ref_d *prev_reg;     /* Prev ref with same regno and type.  */
-  unsigned int regno;		/* The register number referenced.  */
   /* Location in the ref table.  This is only valid after a call to
      df_maybe_reorganize_[use,def]_refs which is an expensive operation.  */
   int id;
diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h
index 65e8c7f..3e0a032 100644
--- a/gcc/diagnostic.h
+++ b/gcc/diagnostic.h
@@ -74,13 +74,6 @@ struct diagnostic_context
   /* True if it has been requested that warnings be treated as errors.  */
   bool warning_as_error_requested;
 
-  /* For each option index that can be passed to warning() et all
-     (OPT_* from options.h), this array may contain a new kind that
-     the diagnostic should be changed to before reporting, or
-     DK_UNSPECIFIED to leave it as the reported kind, or DK_IGNORED to
-     not report it at all.  N_OPTS is from <options.h>.  */
-  diagnostic_t classify_diagnostic[N_OPTS];
-
   /* True if we should print the command line option which controls
      each diagnostic, if known.  */
   bool show_option_requested;
@@ -88,6 +81,13 @@ struct diagnostic_context
   /* True if we should raise a SIGABRT on errors.  */
   bool abort_on_error;
 
+  /* For each option index that can be passed to warning() et all
+     (OPT_* from options.h), this array may contain a new kind that
+     the diagnostic should be changed to before reporting, or
+     DK_UNSPECIFIED to leave it as the reported kind, or DK_IGNORED to
+     not report it at all.  N_OPTS is from <options.h>.  */
+  diagnostic_t classify_diagnostic[N_OPTS];
+
   /* This function is called before any message is printed out.  It is
      responsible for preparing message prefix and such.  For example, it
      might say:
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 6e76998..58be89b 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -305,8 +305,8 @@ typedef struct GTY(()) dw_fde_struct {
   const char *dw_fde_unlikely_section_end_label;
   dw_cfi_ref dw_fde_cfi;
   dw_cfi_ref dw_fde_switch_cfi; /* Last CFI before switching sections.  */
-  unsigned funcdef_number;
   HOST_WIDE_INT stack_realignment;
+  unsigned funcdef_number;
   /* Dynamic realign argument pointer register.  */
   unsigned int drap_reg;
   /* Virtual dynamic realign argument pointer register.  */
diff --git a/gcc/expr.h b/gcc/expr.h
index 4fddde6..af230a6 100644
--- a/gcc/expr.h
+++ b/gcc/expr.h
@@ -273,9 +273,9 @@ do {								\
 typedef struct separate_ops
 {
   enum tree_code code;
+  location_t location;
   tree type;
   tree op0, op1, op2;
-  location_t location;
 } *sepops;
 
 /* Functions from optabs.c, commonly used, and without need for the optabs
diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
index 4cb2469..1df3abd 100644
--- a/gcc/ipa-prop.h
+++ b/gcc/ipa-prop.h
@@ -181,6 +181,15 @@ struct ipa_node_params
      this function's parameters would not be analyzed by the different
      stages of IPA CP.  */
   int param_count;
+  /* Whether this function is called with variable number of actual
+     arguments.  */
+  unsigned called_with_var_arguments : 1;
+  /* Whether the modification analysis has already been performed. */
+  unsigned modification_analysis_done : 1;
+  /* Whether the param uses analysis has already been performed.  */
+  unsigned uses_analysis_done : 1;
+  /* Whether the function is enqueued in an ipa_func_list.  */
+  unsigned node_enqueued : 1;
   /* Pointer to an array of structures describing individual formal
      parameters.  */
   struct ipa_param_descriptor *params;
@@ -195,16 +204,6 @@ struct ipa_node_params
      the profiling information of the original function and the versioned
      one.  */
   gcov_type count_scale;
-
-  /* Whether this function is called with variable number of actual
-     arguments.  */
-  unsigned called_with_var_arguments : 1;
-  /* Whether the modification analysis has already been performed. */
-  unsigned modification_analysis_done : 1;
-  /* Whether the param uses analysis has already been performed.  */
-  unsigned uses_analysis_done : 1;
-  /* Whether the function is enqueued in an ipa_func_list.  */
-  unsigned node_enqueued : 1;
 };
 
 /* ipa_node_params access functions.  Please use these to access fields that
diff --git a/gcc/optabs.h b/gcc/optabs.h
index 0161d3e..038ef2f 100644
--- a/gcc/optabs.h
+++ b/gcc/optabs.h
@@ -46,8 +46,8 @@ struct optab_handlers
 struct optab_d
 {
   enum rtx_code code;
-  const char *libcall_basename;
   char libcall_suffix;
+  const char *libcall_basename;
   void (*libcall_gen)(struct optab_d *, const char *name, char suffix,
 		      enum machine_mode);
   struct optab_handlers handlers[NUM_MACHINE_MODES];
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index f6db241..bb63be2 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -120,8 +120,8 @@ struct version_info
   struct iv *iv;	/* Induction variable description.  */
   bool has_nonlin_use;	/* For a loop-level invariant, whether it is used in
 			   an expression that is not an induction variable.  */
-  unsigned inv_id;	/* Id of an invariant.  */
   bool preserve_biv;	/* For the original biv, whether to preserve it.  */
+  unsigned inv_id;	/* Id of an invariant.  */
 };
 
 /* Types of uses.  */
@@ -192,7 +192,7 @@ struct iv_cand
   unsigned id;		/* The number of the candidate.  */
   bool important;	/* Whether this is an "important" candidate, i.e. such
 			   that it should be considered by all uses.  */
-  enum iv_position pos;	/* Where it is computed.  */
+  ENUM_BITFIELD(iv_position) pos : 8;	/* Where it is computed.  */
   gimple incremented_at;/* For original biv, the statement where it is
 			   incremented.  */
   tree var_before;	/* The variable used for it before increment.  */
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index bd43a4b..2c38c7f 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -198,6 +198,9 @@ typedef struct _loop_vec_info {
   /* Unrolling factor  */
   int vectorization_factor;
 
+  /* The loop location in the source.  */
+  LOC loop_line_number;
+
   /* Unknown DRs according to which loop was peeled.  */
   struct data_reference *unaligned_dr;
 
@@ -228,9 +231,6 @@ typedef struct _loop_vec_info {
      runtime (loop versioning) misalignment check.  */
   VEC(gimple,heap) *may_misalign_stmts;
 
-  /* The loop location in the source.  */
-  LOC loop_line_number;
-
   /* All interleaving chains of stores in the loop, represented by the first
      stmt in the chain.  */
   VEC(gimple, heap) *strided_stores;
@@ -398,21 +398,23 @@ typedef struct _stmt_vec_info {
 
   enum stmt_vec_info_type type;
 
+  /* Indicates whether this stmts is part of a computation whose result is
+     used outside the loop.  */
+  bool live;
+
+  /* Stmt is part of some pattern (computation idiom)  */
+  bool in_pattern_p;
+
+  /* For loads only, if there is a store with the same location, this field is
+     TRUE.  */
+  bool read_write_dep;
+
   /* The stmt to which this info struct refers to.  */
   gimple stmt;
 
   /* The loop_vec_info with respect to which STMT is vectorized.  */
   loop_vec_info loop_vinfo;
 
-  /* Not all stmts in the loop need to be vectorized. e.g, the increment
-     of the loop induction variable and computation of array indexes. relevant
-     indicates whether the stmt needs to be vectorized.  */
-  enum vect_relevant relevant;
-
-  /* Indicates whether this stmts is part of a computation whose result is
-     used outside the loop.  */
-  bool live;
-
   /* The vector type to be used for the LHS of this statement.  */
   tree vectype;
 
@@ -436,9 +438,6 @@ typedef struct _stmt_vec_info {
   tree dr_step;
   tree dr_aligned_to;
 
-  /* Stmt is part of some pattern (computation idiom)  */
-  bool in_pattern_p;
-
   /* Used for various bookkeeping purposes, generally holding a pointer to
      some other stmt S that is in some way "related" to this stmt.
      Current use of this field is:
@@ -457,11 +456,17 @@ typedef struct _stmt_vec_info {
   /* Classify the def of this stmt.  */
   enum vect_def_type def_type;
 
+  /*  Whether the stmt is SLPed, loop-based vectorized, or both.  */
+  enum slp_vect_type slp_type;
+
   /* Interleaving info.  */
   /* First data-ref in the interleaving group.  */
   gimple first_dr;
   /* Pointer to the next data-ref in the group.  */
   gimple next_dr;
+  /* In case that two or more stmts share data-ref, this is the pointer to the
+     previously detected stmt with the same dr.  */
+  gimple same_dr_stmt;
   /* The size of the interleaving group.  */
   unsigned int size;
   /* For stores, number of stores from this group seen. We vectorize the last
@@ -470,12 +475,11 @@ typedef struct _stmt_vec_info {
   /* For loads only, the gap from the previous load. For consecutive loads, GAP
      is 1.  */
   unsigned int gap;
-  /* In case that two or more stmts share data-ref, this is the pointer to the
-     previously detected stmt with the same dr.  */
-  gimple same_dr_stmt;
-  /* For loads only, if there is a store with the same location, this field is
-     TRUE.  */
-  bool read_write_dep;
+
+  /* Not all stmts in the loop need to be vectorized. e.g, the increment
+     of the loop induction variable and computation of array indexes. relevant
+     indicates whether the stmt needs to be vectorized.  */
+  enum vect_relevant relevant;
 
   /* Vectorization costs associated with statement.  */
   struct
@@ -484,9 +488,6 @@ typedef struct _stmt_vec_info {
     int inside_of_loop;      /* Statements generated inside loop.  */
   } cost;
 
-  /*  Whether the stmt is SLPed, loop-based vectorized, or both.  */
-  enum slp_vect_type slp_type;
-
   /* The bb_vec_info with respect to which STMT is vectorized.  */
   bb_vec_info bb_vinfo;
 } *stmt_vec_info;

Attachment: gcc-struct-log.org
Description: Text document


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