From e1dc98b235434b298aaa3672e0f716721d98bd36 Mon Sep 17 00:00:00 2001 From: Olga Golovanevsky Date: Wed, 24 Oct 2007 10:36:30 +0000 Subject: [PATCH] ipa-type-escape.h: Expose function is_array_access_through_pointer_and_index. 2007-10-24 Olga Golovanevsky * ipa-type-escape.h: Expose function is_array_access_through_pointer_and_index. * ipa-type-escape.c (is_array_access_through_pointer_and_index): Add three new parameters. Add support of POINTER_PLUS_EXPR tree code. 2007-10-24 Olga Golovanevsky * ipa-struct-reorg.c, ipa-struct-reorg.h: New files. * tree-pass.h: Add pass_ipa_struct_reorg. * common.opt: Add ipa-struct-reorg flag. * Makefile.in: Add ipa-strcut-reorg.o compilation. * passes.c: Add pass pass_ipa_struct_reorg. * params.h: Add STRUCT_REORG_COLD_STRUCT_RATIO. * params.def: Add PARAM_STRUCT_REORG_COLD_STRUCT_RATIO. From-SVN: r129600 --- gcc/ChangeLog | 19 +++++++ gcc/Makefile.in | 7 ++- gcc/common.opt | 5 ++ gcc/ipa-type-escape.c | 112 ++++++++++++++++++++++++++++-------------- gcc/ipa-type-escape.h | 2 + gcc/params.def | 10 ++++ gcc/params.h | 2 + gcc/passes.c | 1 + gcc/tree-pass.h | 1 + 9 files changed, 121 insertions(+), 38 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7ace9f99cba..5d05108948e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,22 @@ +2007-10-24 Olga Golovanevsky + + * ipa-type-escape.h: Expose function + is_array_access_through_pointer_and_index. + * ipa-type-escape.c + (is_array_access_through_pointer_and_index): + Add three new parameters. Add support of + POINTER_PLUS_EXPR tree code. + +2007-10-24 Olga Golovanevsky + + * ipa-struct-reorg.c, ipa-struct-reorg.h: New files. + * tree-pass.h: Add pass_ipa_struct_reorg. + * common.opt: Add ipa-struct-reorg flag. + * Makefile.in: Add ipa-strcut-reorg.o compilation. + * passes.c: Add pass pass_ipa_struct_reorg. + * params.h: Add STRUCT_REORG_COLD_STRUCT_RATIO. + * params.def: Add PARAM_STRUCT_REORG_COLD_STRUCT_RATIO. + 2007-10-24 Ira Rosen PR tree-optimization/33804 diff --git a/gcc/Makefile.in b/gcc/Makefile.in index ad62c6ac4ba..eb655f13186 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1235,6 +1235,7 @@ OBJS-archive = \ ipa-prop.o \ ipa-pure-const.o \ ipa-reference.o \ + ipa-struct-reorg.o \ ipa-type-escape.o \ ipa-utils.o \ ipa.o \ @@ -2514,6 +2515,10 @@ ipa-type-escape.o : ipa-type-escape.c $(CONFIG_H) $(SYSTEM_H) \ pointer-set.h $(GGC_H) $(IPA_TYPE_ESCAPE_H) $(IPA_UTILS_H) $(C_COMMON_H) \ $(TREE_GIMPLE_H) $(CGRAPH_H) output.h $(FLAGS_H) tree-pass.h \ $(DIAGNOSTIC_H) $(FUNCTION_H) +ipa-struct-reorg.o: ipa-struct-reorg.c ipa-struct-reorg.h $(CONFIG_H) $(SYSTEM_H) \ + coretypes.h $(TM_H) $(RTL_H) $(TREE_H) $(FLAGS_H) output.h $(REGS_H) \ + $(EXPR_H) $(FUNCTION_H) toplev.h $(GGC_H) $(TARGET_H) langhooks.h $(COVERAGE_H) \ + libfuncs.h gt-coverage.h $(HASHTAB_H) $(IPA_TYPE_ESCAPE_H) coverage.o : coverage.c $(GCOV_IO_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TM_H) $(RTL_H) $(TREE_H) $(FLAGS_H) output.h $(REGS_H) $(EXPR_H) \ @@ -3086,7 +3091,7 @@ GTFILES = $(srcdir)/input.h $(srcdir)/coretypes.h \ $(srcdir)/reload.h $(srcdir)/caller-save.c \ $(srcdir)/alias.c $(srcdir)/bitmap.c $(srcdir)/cselib.c $(srcdir)/cgraph.c \ $(srcdir)/ipa-prop.c $(srcdir)/ipa-cp.c $(srcdir)/ipa-inline.c $(srcdir)/matrix-reorg.c \ - $(srcdir)/dbxout.c $(srcdir)/dwarf2out.c $(srcdir)/dwarf2asm.c \ + $(srcdir)/dbxout.c $(srcdir)/ipa-struct-reorg.c $(srcdir)/dwarf2out.c $(srcdir)/dwarf2asm.c \ $(srcdir)/dojump.c \ $(srcdir)/emit-rtl.c $(srcdir)/except.c $(srcdir)/explow.c $(srcdir)/expr.c \ $(srcdir)/function.c $(srcdir)/except.h \ diff --git a/gcc/common.opt b/gcc/common.opt index 4d9f9b85e4d..c468b3b198f 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -618,6 +618,11 @@ Common Report Var(flag_ipa_matrix_reorg) Optimization Perform matrix layout flattening and transposing based on profiling information. +fipa-struct-reorg +Common Report Var(flag_ipa_struct_reorg) +Perform structure layout optimizations based +on profiling information. + fivopts Common Report Var(flag_ivopts) Init(1) Optimization Optimize induction variables on trees diff --git a/gcc/ipa-type-escape.c b/gcc/ipa-type-escape.c index 5303e79ec26..2aedb95987e 100644 --- a/gcc/ipa-type-escape.c +++ b/gcc/ipa-type-escape.c @@ -926,56 +926,89 @@ is_cast_from_non_pointer (tree var, tree def_stmt, void *data) */ -static bool -is_array_access_through_pointer_and_index (tree op0, tree op1) +bool +is_array_access_through_pointer_and_index (enum tree_code code, tree op0, + tree op1, tree *base, tree *offset, + tree *offset_cast_stmt) { - tree base, offset, offset_cast_stmt; tree before_cast, before_cast_def_stmt; cast_t op0_cast, op1_cast; + *base = NULL; + *offset = NULL; + *offset_cast_stmt = NULL; + /* Check 1. */ + if (code == POINTER_PLUS_EXPR) + { + tree op0type = TYPE_MAIN_VARIANT (TREE_TYPE (op0)); + tree op1type = TYPE_MAIN_VARIANT (TREE_TYPE (op1)); - /* Init data for walk_use_def_chains function. */ - op0_cast.type = op1_cast.type = 0; - op0_cast.stmt = op1_cast.stmt = NULL; + /* One of op0 and op1 is of pointer type and the other is numerical. */ + if (POINTER_TYPE_P (op0type) && NUMERICAL_TYPE_CHECK (op1type)) + { + *base = op0; + *offset = op1; + } + else if (POINTER_TYPE_P (op1type) && NUMERICAL_TYPE_CHECK (op0type)) + { + *base = op1; + *offset = op0; + } + else + return false; + } + else + { + /* Init data for walk_use_def_chains function. */ + op0_cast.type = op1_cast.type = 0; + op0_cast.stmt = op1_cast.stmt = NULL; - visited_stmts = pointer_set_create (); - walk_use_def_chains (op0, is_cast_from_non_pointer,(void *)(&op0_cast), false); - pointer_set_destroy (visited_stmts); + visited_stmts = pointer_set_create (); + walk_use_def_chains (op0, is_cast_from_non_pointer,(void *)(&op0_cast), + false); + pointer_set_destroy (visited_stmts); - visited_stmts = pointer_set_create (); - walk_use_def_chains (op1, is_cast_from_non_pointer,(void *)(&op1_cast), false); - pointer_set_destroy (visited_stmts); + visited_stmts = pointer_set_create (); + walk_use_def_chains (op1, is_cast_from_non_pointer,(void *)(&op1_cast), + false); + pointer_set_destroy (visited_stmts); - if (op0_cast.type == 1 && op1_cast.type == 0) - { - base = op1; - offset = op0; - offset_cast_stmt = op0_cast.stmt; - } - else if (op0_cast.type == 0 && op1_cast.type == 1) - { - base = op0; - offset = op1; - offset_cast_stmt = op1_cast.stmt; + if (op0_cast.type == 1 && op1_cast.type == 0) + { + *base = op1; + *offset = op0; + *offset_cast_stmt = op0_cast.stmt; + } + else if (op0_cast.type == 0 && op1_cast.type == 1) + { + *base = op0; + *offset = op1; + *offset_cast_stmt = op1_cast.stmt; + } + else + return false; } - else - return false; - + /* Check 2. offset_cast_stmt is of the form: D.1606_7 = (struct str_t *) D.1605_6; */ - before_cast = SINGLE_SSA_TREE_OPERAND (offset_cast_stmt, SSA_OP_USE); - if (!before_cast) - return false; + if (*offset_cast_stmt) + { + before_cast = SINGLE_SSA_TREE_OPERAND (*offset_cast_stmt, SSA_OP_USE); + if (!before_cast) + return false; - if (SSA_NAME_IS_DEFAULT_DEF(before_cast)) - return false; + if (SSA_NAME_IS_DEFAULT_DEF (before_cast)) + return false; - before_cast_def_stmt = SSA_NAME_DEF_STMT (before_cast); - if (!before_cast_def_stmt) - return false; + before_cast_def_stmt = SSA_NAME_DEF_STMT (before_cast); + if (!before_cast_def_stmt) + return false; + } + else + before_cast_def_stmt = SSA_NAME_DEF_STMT (*offset); /* before_cast_def_stmt should be of the form: D.1605_6 = i.1_5 * 16; */ @@ -1449,7 +1482,6 @@ static bool okay_pointer_operation (enum tree_code code, tree op0, tree op1) { tree op0type = TYPE_MAIN_VARIANT (TREE_TYPE (op0)); - tree op1type = TYPE_MAIN_VARIANT (TREE_TYPE (op1)); switch (code) { @@ -1459,11 +1491,17 @@ okay_pointer_operation (enum tree_code code, tree op0, tree op1) break; case MINUS_EXPR: case PLUS_EXPR: + case POINTER_PLUS_EXPR: { - if (POINTER_TYPE_P (op1type) + tree base, offset, offset_cast_stmt; + + if (POINTER_TYPE_P (op0type) && TREE_CODE (op0) == SSA_NAME && TREE_CODE (op1) == SSA_NAME - && is_array_access_through_pointer_and_index (op0, op1)) + && is_array_access_through_pointer_and_index (code, op0, op1, + &base, + &offset, + &offset_cast_stmt)) return true; else { diff --git a/gcc/ipa-type-escape.h b/gcc/ipa-type-escape.h index 170494f5175..c851a2707be 100644 --- a/gcc/ipa-type-escape.h +++ b/gcc/ipa-type-escape.h @@ -26,6 +26,8 @@ bool ipa_type_escape_type_contained_p (tree type); bool ipa_type_escape_field_does_not_clobber_p (tree record_type, tree field_type); int ipa_type_escape_star_count_of_interesting_type (tree type); int ipa_type_escape_star_count_of_interesting_or_array_type (tree type); +bool is_array_access_through_pointer_and_index (enum tree_code, tree, tree, + tree *, tree *, tree *); #endif /* GCC_IPA_TYPE_ESCAPE_H */ diff --git a/gcc/params.def b/gcc/params.def index 5cb1f6da7c2..8973c9ac4e0 100644 --- a/gcc/params.def +++ b/gcc/params.def @@ -83,6 +83,16 @@ DEFPARAM (PARAM_SRA_FIELD_STRUCTURE_RATIO, "The threshold ratio between instantiated fields and the total structure size", 75, 0, 100) +/* The threshold ratio between current and hotest structure counts. + We say that if the ratio of the current structure count, + calculated by profiling, to the hotest structure count + in the program is less than this parameter, then structure + reorganization is not applied. The default is 10%. */ +DEFPARAM (PARAM_STRUCT_REORG_COLD_STRUCT_RATIO, + "struct-reorg-cold-struct-ratio", + "The threshold ratio between current and hotest structure counts", + 10, 0, 100) + /* The single function inlining limit. This is the maximum size of a function counted in internal gcc instructions (not in real machine instructions) that is eligible for inlining diff --git a/gcc/params.h b/gcc/params.h index 71e6b21ef71..7c54b5da292 100644 --- a/gcc/params.h +++ b/gcc/params.h @@ -103,6 +103,8 @@ typedef enum compiler_param PARAM_VALUE (PARAM_SRA_MAX_STRUCTURE_COUNT) #define SRA_FIELD_STRUCTURE_RATIO \ PARAM_VALUE (PARAM_SRA_FIELD_STRUCTURE_RATIO) +#define STRUCT_REORG_COLD_STRUCT_RATIO \ + PARAM_VALUE (PARAM_STRUCT_REORG_COLD_STRUCT_RATIO) #define MAX_INLINE_INSNS_SINGLE \ PARAM_VALUE (PARAM_MAX_INLINE_INSNS_SINGLE) #define MAX_INLINE_INSNS \ diff --git a/gcc/passes.c b/gcc/passes.c index 25644bc8b5a..c0f11edf212 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -546,6 +546,7 @@ init_optimization_passes (void) NEXT_PASS (pass_ipa_pure_const); NEXT_PASS (pass_ipa_type_escape); NEXT_PASS (pass_ipa_pta); + NEXT_PASS (pass_ipa_struct_reorg); *p = NULL; /* These passes are run after IPA passes on every function that is being diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h index 1f748e82635..e22827d3dfb 100644 --- a/gcc/tree-pass.h +++ b/gcc/tree-pass.h @@ -340,6 +340,7 @@ extern struct tree_opt_pass pass_ipa_reference; extern struct tree_opt_pass pass_ipa_pure_const; extern struct tree_opt_pass pass_ipa_type_escape; extern struct tree_opt_pass pass_ipa_pta; +extern struct tree_opt_pass pass_ipa_struct_reorg; extern struct tree_opt_pass pass_early_local_passes; extern struct tree_opt_pass pass_ipa_increase_alignment; extern struct tree_opt_pass pass_ipa_function_and_variable_visibility; -- 2.30.2