common.opt (fipa-sra): New switch.

2009-09-17  Martin Jambor  <mjambor@suse.cz>

	* common.opt (fipa-sra): New switch.
	* opts.c (decode_options): Turn flag_ipa_sra on for opt2.
	* timevar.def (TV_IPA_SRA): New timevar.
	* params.def (ipa-sra-ptr-growth-factor): New parameter.
	* doc/invoke.texi: Document -fipa-sra and ipa-sra-ptr-growth-factor.
	* tree-sra.c: Include cgraph.c.
	(enum sra_mode): Added SRA_MODE_EARLY_IPA.
	(struct access): Added fields stmt, grp_maybe_modified, grp_scalar_ptr
	and grp_not_necessarilly_dereferenced.
	(func_param_count): New variable.
	(encountered_apply_args): New variable.
	(bb_dereferences): New variable.
	(final_bbs): New variable.
	(no_accesses_representant): New variable.
	(no_accesses_p): New function.
	(dump_access): Dump the new fields.
	(sra_initialize): Set encountered_apply_args to false.
	(get_ssa_base_param): New function.
	(mark_parm_dereference): New function.
	(create_access): Caring for INIDRECT_REFs and different handling of
	varialble length accesses in early IPA SRA.  Store the stmt - a new
	parameter - to the new access.
	(build_access_from_expr_1): New parameter stmt, passed to
	create_access.  Handle INDIRECT_REFs.
	(build_access_from_expr): Pass the current statement to
	build_access_from_expr_1.
	(disqualify_ops_if_throwing_stmt): Trigger only in intraprocedural
	passes.
	(build_accesses_from_assign): Pass the current statement to
	build_access_from_expr_1.  Do not create assign links in IPA-SRA.
	(scan_function): Call handle_ssa_defs on phi nodes.  Set bits in
	final_bbs when necessary.  Check for calls to __builtin_apply_args.
	Fixup EH info if anythng was changed.
	(is_unused_scalar_param): New function.
	(ptr_parm_has_direct_uses): New function.
	(find_param_candidates): New function.
	(mark_maybe_modified): New function.
	(analyze_modified_params): New function.
	(propagate_dereference_distances): New function.
	(dump_dereferences_table): New function.
	(analyze_caller_dereference_legality): New function.
	(unmodified_by_ref_scalar_representative): New function.
	(splice_param_accesses): New function.
	(decide_one_param_reduction): New function.
	(enum ipa_splicing_result): New type.
	(splice_all_param_accesses): New function.
	(get_param_index): New function.
	(turn_representatives_into_adjustments): New function.
	(analyze_all_param_acesses): New function.
	(get_replaced_param_substitute): New function.
	(get_adjustment_for_base): New function.
	(replace_removed_params_ssa_names): New function.
	(sra_ipa_reset_debug_stmts): New function.
	(sra_ipa_modify_expr): New function.
	(sra_ipa_modify_assign): New function.
	(convert_callers): New function.
	(modify_function): New function.
	(ipa_sra_preliminary_function_checks): New function.
	(ipa_early_sra): New function.
	(ipa_early_sra_gate): New function.
	(pass_early_ipa_sra): New variable.
	* Makefile.in (tree-sra.o): Add cgraph.h to dependencies.
	
	Testsuite:

	* gcc.dg/struct/wo_prof_escape_arg_to_local.c: Do not run IPA-SRA.
	* gcc.dg/ipa/ipa-sra-1.c: New test.
	* gcc.dg/ipa/ipa-sra-2.c: New test.
	* gcc.dg/ipa/ipa-sra-3.c: New test.
	* gcc.dg/ipa/ipa-sra-4.c: New test.
	* gcc.dg/ipa/ipa-sra-5.c: New test.
	* gcc.c-torture/execute/ipa-sra-1.c: New test.
	* gcc.c-torture/execute/ipa-sra-2.c: New test.

From-SVN: r151800
This commit is contained in:
Martin Jambor 2009-09-17 13:35:38 +02:00 committed by Martin Jambor
parent 040c6d51da
commit 07ffa034dd
19 changed files with 1801 additions and 41 deletions

View file

@ -1,3 +1,68 @@
2009-09-17 Martin Jambor <mjambor@suse.cz>
* common.opt (fipa-sra): New switch.
* opts.c (decode_options): Turn flag_ipa_sra on for opt2.
* timevar.def (TV_IPA_SRA): New timevar.
* params.def (ipa-sra-ptr-growth-factor): New parameter.
* doc/invoke.texi: Document -fipa-sra and ipa-sra-ptr-growth-factor.
* tree-sra.c: Include cgraph.c.
(enum sra_mode): Added SRA_MODE_EARLY_IPA.
(struct access): Added fields stmt, grp_maybe_modified, grp_scalar_ptr
and grp_not_necessarilly_dereferenced.
(func_param_count): New variable.
(encountered_apply_args): New variable.
(bb_dereferences): New variable.
(final_bbs): New variable.
(no_accesses_representant): New variable.
(no_accesses_p): New function.
(dump_access): Dump the new fields.
(sra_initialize): Set encountered_apply_args to false.
(get_ssa_base_param): New function.
(mark_parm_dereference): New function.
(create_access): Caring for INIDRECT_REFs and different handling of
varialble length accesses in early IPA SRA. Store the stmt - a new
parameter - to the new access.
(build_access_from_expr_1): New parameter stmt, passed to
create_access. Handle INDIRECT_REFs.
(build_access_from_expr): Pass the current statement to
build_access_from_expr_1.
(disqualify_ops_if_throwing_stmt): Trigger only in intraprocedural
passes.
(build_accesses_from_assign): Pass the current statement to
build_access_from_expr_1. Do not create assign links in IPA-SRA.
(scan_function): Call handle_ssa_defs on phi nodes. Set bits in
final_bbs when necessary. Check for calls to __builtin_apply_args.
Fixup EH info if anythng was changed.
(is_unused_scalar_param): New function.
(ptr_parm_has_direct_uses): New function.
(find_param_candidates): New function.
(mark_maybe_modified): New function.
(analyze_modified_params): New function.
(propagate_dereference_distances): New function.
(dump_dereferences_table): New function.
(analyze_caller_dereference_legality): New function.
(unmodified_by_ref_scalar_representative): New function.
(splice_param_accesses): New function.
(decide_one_param_reduction): New function.
(enum ipa_splicing_result): New type.
(splice_all_param_accesses): New function.
(get_param_index): New function.
(turn_representatives_into_adjustments): New function.
(analyze_all_param_acesses): New function.
(get_replaced_param_substitute): New function.
(get_adjustment_for_base): New function.
(replace_removed_params_ssa_names): New function.
(sra_ipa_reset_debug_stmts): New function.
(sra_ipa_modify_expr): New function.
(sra_ipa_modify_assign): New function.
(convert_callers): New function.
(modify_function): New function.
(ipa_sra_preliminary_function_checks): New function.
(ipa_early_sra): New function.
(ipa_early_sra_gate): New function.
(pass_early_ipa_sra): New variable.
* Makefile.in (tree-sra.o): Add cgraph.h to dependencies.
2009-09-17 Michael Matz <matz@suse.de>
PR middle-end/41347

View file

@ -2891,8 +2891,9 @@ tree-ssa-ccp.o : tree-ssa-ccp.c $(TREE_FLOW_H) $(CONFIG_H) \
$(TREE_DUMP_H) $(BASIC_BLOCK_H) $(TREE_PASS_H) langhooks.h \
tree-ssa-propagate.h value-prof.h $(FLAGS_H) $(TARGET_H) $(TOPLEV_H)
tree-sra.o : tree-sra.c $(CONFIG_H) $(SYSTEM_H) coretypes.h alloc-pool.h \
$(TM_H) $(TREE_H) $(GIMPLE_H) $(TREE_FLOW_H) $(IPA_PROP_H) $(DIAGNOSTIC_H) \
statistics.h $(TREE_DUMP_H) $(TIMEVAR_H) $(PARAMS_H) $(TARGET_H) $(FLAGS_H)
$(TM_H) $(TREE_H) $(GIMPLE_H) $(CGRAPH_H) $(TREE_FLOW_H) $(IPA_PROP_H) \
$(DIAGNOSTIC_H) statistics.h $(TREE_DUMP_H) $(TIMEVAR_H) $(PARAMS_H) \
$(TARGET_H) $(FLAGS_H)
tree-switch-conversion.o : tree-switch-conversion.c $(CONFIG_H) $(SYSTEM_H) \
$(TREE_H) $(TM_P_H) $(TREE_FLOW_H) $(DIAGNOSTIC_H) $(TREE_INLINE_H) \
$(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) $(GIMPLE_H) \

View file

@ -486,6 +486,10 @@ feliminate-dwarf2-dups
Common Report Var(flag_eliminate_dwarf2_dups)
Perform DWARF2 duplicate elimination
fipa-sra
Common Report Var(flag_ipa_sra) Init(0) Optimization
Perform interprocedural reduction of aggregates
feliminate-unused-debug-symbols
Common Report Var(flag_debug_only_used_symbols)
Perform unused type elimination in debug info

View file

@ -335,7 +335,7 @@ Objective-C and Objective-C++ Dialects}.
-fcse-follow-jumps -fcse-skip-blocks -fcx-fortran-rules -fcx-limited-range @gol
-fdata-sections -fdce -fdce @gol
-fdelayed-branch -fdelete-null-pointer-checks -fdse -fdse @gol
-fearly-inlining -fexpensive-optimizations -ffast-math @gol
-fearly-inlining -fipa-sra -fexpensive-optimizations -ffast-math @gol
-ffinite-math-only -ffloat-store -fexcess-precision=@var{style} @gol
-fforward-propagate -ffunction-sections @gol
-fgcse -fgcse-after-reload -fgcse-las -fgcse-lm @gol
@ -5659,6 +5659,7 @@ also turns on the following optimization flags:
-fgcse -fgcse-lm @gol
-finline-small-functions @gol
-findirect-inlining @gol
-fipa-sra @gol
-foptimize-sibling-calls @gol
-fpeephole2 @gol
-fregmove @gol
@ -5819,6 +5820,14 @@ having large chains of nested wrapper functions.
Enabled by default.
@item -fipa-sra
@opindex fipa-sra
Perform interprocedural scalar replacement of aggregates, removal of
unused parameters and replacement of parameters passed by reference
by parameters passed by value.
Enabled at levels @option{-O2}, @option{-O3} and @option{-Os}.
@item -finline-limit=@var{n}
@opindex finline-limit
By default, GCC limits the size of functions that can be inlined. This flag
@ -8127,6 +8136,12 @@ the parameter is reserved exclusively for debug insns created by
@option{-fvar-tracking-assignments}, but debug insns may get
(non-overlapping) uids above it if the reserved range is exhausted.
@item ipa-sra-ptr-growth-factor
IPA-SRA will replace a pointer to an aggregate with one or more new
parameters only when their cumulative size is less or equal to
@option{ipa-sra-ptr-growth-factor} times the size of the original
pointer parameter.
@end table
@end table

View file

@ -898,6 +898,7 @@ decode_options (unsigned int argc, const char **argv)
flag_tree_pre = opt2;
flag_tree_switch_conversion = 1;
flag_ipa_cp = opt2;
flag_ipa_sra = opt2;
/* Track fields in field-sensitive alias analysis. */
set_param_value ("max-fields-for-field-sensitive",

View file

@ -759,6 +759,12 @@ DEFPARAM (PARAM_MIN_NONDEBUG_INSN_UID,
"The minimum UID to be used for a nondebug insn",
0, 1, 0)
DEFPARAM (PARAM_IPA_SRA_PTR_GROWTH_FACTOR,
"ipa-sra-ptr-growth-factor",
"maximum allowed growth of size of new parameters ipa-sra replaces "
"a pointer to an aggregate with",
2, 0, 0)
/*
Local variables:
mode:c

View file

@ -566,6 +566,7 @@ init_optimization_passes (void)
NEXT_PASS (pass_copy_prop);
NEXT_PASS (pass_merge_phi);
NEXT_PASS (pass_cd_dce);
NEXT_PASS (pass_early_ipa_sra);
NEXT_PASS (pass_tail_recursion);
NEXT_PASS (pass_convert_switch);
NEXT_PASS (pass_cleanup_eh);

View file

@ -1,3 +1,14 @@
2009-09-17 Martin Jambor <mjambor@suse.cz>
* gcc.dg/struct/wo_prof_escape_arg_to_local.c: Do not run IPA-SRA.
* gcc.dg/ipa/ipa-sra-1.c: New test.
* gcc.dg/ipa/ipa-sra-2.c: New test.
* gcc.dg/ipa/ipa-sra-3.c: New test.
* gcc.dg/ipa/ipa-sra-4.c: New test.
* gcc.dg/ipa/ipa-sra-5.c: New test.
* gcc.c-torture/execute/ipa-sra-1.c: New test.
* gcc.c-torture/execute/ipa-sra-2.c: New test.
2009-09-17 Michael Matz <matz@suse.de>
PR middle-end/41347

View file

@ -0,0 +1,29 @@
/* Trivially making sure IPA-SRA does not introduce segfaults where they should
not be. */
struct bovid
{
float red;
int green;
void *blue;
};
static int
__attribute__((noinline))
ox (int fail, struct bovid *cow)
{
int r;
if (fail)
r = cow->red;
else
r = 0;
return r;
}
int main (int argc, char *argv[])
{
int r;
r = ox ((argc > 2000), (void *) 0);
return r;
}

View file

@ -0,0 +1,41 @@
struct big
{
int data[1000000];
};
struct small
{
int data[10];
};
union both
{
struct big big;
struct small small;
};
extern void *malloc(__SIZE_TYPE__);
extern void free (void *);
static int
__attribute__((noinline))
foo (int fail, union both *agg)
{
int r;
if (fail)
r = agg->big.data[999999];
else
r = agg->small.data[0];
return r;
}
int main (int argc, char *argv[])
{
union both *agg = malloc (sizeof (struct small));
int r;
r = foo ((argc > 2000), agg);
free (agg);
return r;
}

View file

@ -0,0 +1,41 @@
/* { dg-do run } */
/* { dg-options "-O2 -fdump-tree-eipa_sra-details" } */
struct bovid
{
float red;
int green;
void *blue;
};
extern int printf (const char *, ...);
extern void abort (void);
static int
__attribute__((noinline))
ox (struct bovid cow)
{
if (cow.green != 6)
abort ();
printf ("green: %f\nblue: %p\nblue again: %p\n", cow.green,
cow.blue, cow.blue);
return 0;
}
int
main (int argc, char *argv[])
{
struct bovid cow;
cow.red = 7.4;
cow.green = 6;
cow.blue = &cow;
ox (cow);
return 0;
}
/* { dg-final { scan-tree-dump "About to replace expr cow.green with ISRA" "eipa_sra" } } */
/* { dg-final { scan-tree-dump "About to replace expr cow.blue with ISRA" "eipa_sra" } } */
/* { dg-final { cleanup-tree-dump "eipa_sra" } } */

View file

@ -0,0 +1,52 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-eipa_sra-details" } */
struct bovid
{
float red;
int green;
void *blue;
};
static int
__attribute__((noinline))
ox (struct bovid *cow)
{
cow->red = cow->red + cow->green + cow->green;
return 0;
}
int something;
static int
__attribute__((noinline))
ox_improved (struct bovid *calf)
{
if (something > 0)
calf->red = calf->red + calf->green;
else
calf->red = calf->green + 87;
something = 77;
return 0;
}
int main (int argc, char *argv[])
{
struct bovid cow;
cow.red = 7.4;
cow.green = 6;
cow.blue = &cow;
ox (&cow);
ox_improved (&cow);
return 0;
}
/* { dg-final { scan-tree-dump "About to replace expr cow_.*D.->red with \\*ISRA" "eipa_sra" } } */
/* { dg-final { scan-tree-dump "About to replace expr cow_.*D.->green with ISRA" "eipa_sra" } } */
/* { dg-final { scan-tree-dump "About to replace expr calf_.*D.->red with \\*ISRA" "eipa_sra" } } */
/* { dg-final { scan-tree-dump "About to replace expr calf_.*D.->green with ISRA" "eipa_sra" } } */
/* { dg-final { cleanup-tree-dump "eipa_sra" } } */

View file

@ -0,0 +1,39 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-eipa_sra-details" } */
struct bovid
{
float red;
int green;
void *blue;
};
extern void foo (float, void *, void *, long);
static int
__attribute__((noinline))
ox (struct bovid cow, int z, struct bovid calf, long l)
{
foo (cow.red, cow.blue, cow.blue, l);
return 0;
}
void caller (void)
{
struct bovid cow, calf;
cow.red = 7.4;
cow.green = 6;
cow.blue = &cow;
calf.red = 8.4;
calf.green = 5;
calf.blue = &cow;
ox (cow,4,calf,2);
return;
}
/* { dg-final { scan-tree-dump "base: z, remove_param" "eipa_sra" } } */
/* { dg-final { scan-tree-dump "base: calf, remove_param" "eipa_sra" } } */
/* { dg-final { cleanup-tree-dump "eipa_sra" } } */

View file

@ -0,0 +1,68 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-eipa_sra-details" } */
static int
__attribute__((noinline))
ox (int *i)
{
return *i+4**i;
}
int *holder;
static int
__attribute__((noinline))
ox_ctrl_1 (int *j)
{
holder = j;
return *j+4 * *j+1;
}
static void
__attribute__((noinline))
ox_ctrl_2 (int *k)
{
*k = 8;
}
static int zzz[10];
static int
__attribute__((noinline))
ox_improved (int recurse, int *l)
{
int r = 0;
r = *l;
if (recurse)
{
if (recurse > 2)
l = &zzz[3];
else
l = zzz;
ox_improved (0, l);
}
return r;
}
void caller (void)
{
int a = 1;
int b = 10;
int c;
ox (&a);
ox_ctrl_1 (&a);
ox_ctrl_2 (&a);
*holder = ox_improved (1, &b);
return;
}
/* { dg-final { scan-tree-dump "About to replace expr \\*i_.*D. with ISRA" "eipa_sra" } } */
/* { dg-final { scan-tree-dump "About to replace expr \\*l_.*D. with ISRA" "eipa_sra" } } */
/* { dg-final { scan-tree-dump-times "About to replace expr \*j_.*D. with ISRA" 0 "eipa_sra" } } */
/* { dg-final { scan-tree-dump-times "About to replace expr \*k_.*D. with ISRA" 0 "eipa_sra" } } */
/* { dg-final { cleanup-tree-dump "eipa_sra" } } */

View file

@ -0,0 +1,20 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-eipa_sra-details" } */
static int *
__attribute__((noinline,used))
ox (int *i, int *j)
{
return i;
}
int a;
int *caller (void)
{
int b = 10;
return ox (&a, &b);
}
/* { dg-final { scan-tree-dump-times "base: j, remove_param" 0 "eipa_sra" } } */
/* { dg-final { cleanup-tree-dump "eipa_sra" } } */

View file

@ -1,4 +1,4 @@
/* { dg-options "-O3 -fno-inline -fipa-type-escape -fdump-ipa-all -fipa-struct-reorg -fwhole-program -combine" } */
/* { dg-options "-O3 -fno-inline -fno-ipa-sra -fipa-type-escape -fdump-ipa-all -fipa-struct-reorg -fwhole-program -combine" } */
/* { dg-do compile } */
/* { dg-do run } */

View file

@ -46,6 +46,7 @@ DEFTIMEVAR (TV_IPA_REFERENCE , "ipa reference")
DEFTIMEVAR (TV_IPA_PURE_CONST , "ipa pure const")
DEFTIMEVAR (TV_IPA_TYPE_ESCAPE , "ipa type escape")
DEFTIMEVAR (TV_IPA_PTA , "ipa points-to")
DEFTIMEVAR (TV_IPA_SRA , "ipa SRA")
DEFTIMEVAR (TV_IPA_FREE_LANG_DATA , "ipa free lang data")
/* Time spent by constructing CFG. */
DEFTIMEVAR (TV_CFG , "cfg construction")

View file

@ -327,6 +327,7 @@ extern struct gimple_opt_pass pass_cleanup_eh;
extern struct gimple_opt_pass pass_fixup_cfg;
extern struct gimple_opt_pass pass_sra;
extern struct gimple_opt_pass pass_sra_early;
extern struct gimple_opt_pass pass_early_ipa_sra;
extern struct gimple_opt_pass pass_tail_recursion;
extern struct gimple_opt_pass pass_tail_calls;
extern struct gimple_opt_pass pass_tree_loop;

File diff suppressed because it is too large Load diff