summaryrefslogtreecommitdiffstats
path: root/recipes-devtools/gcc/files/gcc.opt-array-offset.patch
diff options
context:
space:
mode:
authorZhenhua Luo <b19537@freescale.com>2012-03-09 10:57:35 +0000
committerMatthew McClintock <msm@freescale.com>2012-03-13 12:41:42 -0500
commit122c5bfdad95930de96e191aafb0304fded007b2 (patch)
treeea66cb9147fed9ceacd9eacd5913b10bb64734a1 /recipes-devtools/gcc/files/gcc.opt-array-offset.patch
parent4f2d99fbb0afd19376e404583700ee31428f7c2e (diff)
downloadmeta-fsl-ppc-122c5bfdad95930de96e191aafb0304fded007b2.tar.gz
integrate fsl toolchain patches
binutils: bin.e500mc_nop.patch bin.e5500.patch bin.e6500-2.patch eglibc: generate-supported.mk glibc.e500mc_subspecies_of_powerpc_is_not_supported.patch glibc.fixgcc4.6.patch glibc.fix_prof.patch glibc.fix_sqrt.patch glibc.readv_proto.patch glibc.undefined_static.patch gcc: gcc-4.3.1-ARCH_FLAGS_FOR_TARGET.patch gcc.fix_longversionstring.patch gcc.rm_slow_tests.patch gcc.fix_mingw32.patch gcc.fix_cloogstatic2.patch gcc.fix_build-with-cxx.patch gcc.e6500-FSF46.patch gcc.ld_unaligned-460.patch gcc.local_unaligned_altivec.patch gcc.soft_float-460.patch gcc.case_values.patch gcc.builtin_isel.patch gcc.experimental_move.patch gcc.widen_types-46.patch gcc.extelim-v3.patch gcc.e5500_mfocr.patch gcc.opt-array-offset.patch gcc.load_on_store_bypass-462.patch gcc.fix_constvector.patch gcc.fix_MTWX51204-dwarf-vector-reg.patch gcc.fix_ira-loop-pressure.patch optional_libstdc.patch gcc.remove_CCUNSmode_reference.patch gcc.check_path_validity.patch gcc.fix_header_issue.patch gcc.fix_SSIZE_MAX_undefine_issue.patch gettext: gettext.fix_testcase.patch Signed-off-by: Zhenhua Luo <b19537@freescale.com>
Diffstat (limited to 'recipes-devtools/gcc/files/gcc.opt-array-offset.patch')
-rw-r--r--recipes-devtools/gcc/files/gcc.opt-array-offset.patch350
1 files changed, 350 insertions, 0 deletions
diff --git a/recipes-devtools/gcc/files/gcc.opt-array-offset.patch b/recipes-devtools/gcc/files/gcc.opt-array-offset.patch
new file mode 100644
index 0000000..7cdc6f7
--- /dev/null
+++ b/recipes-devtools/gcc/files/gcc.opt-array-offset.patch
@@ -0,0 +1,350 @@
1Implements a GIMPLE pass to optimize array access by factoring
2out expressions that calculate address offset from
3multiple array access. Controls with flag -fopt-array-offset
4
5diff -ruN XLMe500mc/gcc/common.opt XLMe5500/gcc/common.opt
6--- XLMe500mc/gcc/common.opt 2011-10-18 14:49:23.026644000 -0500
7+++ XLMe5500/gcc/common.opt 2011-10-05 12:39:26.242644101 -0500
8@@ -1992,6 +1992,10 @@
9 Common Report Var(flag_tree_vrp) Init(0) Optimization
10 Perform Value Range Propagation on trees
11
12+fopt-array-offset
13+Common Report Var(flag_opt_array_offset)
14+Expand array offset address calculations
15+
16 funit-at-a-time
17 Common Report Var(flag_unit_at_a_time) Init(1) Optimization
18 Compile whole compilation unit at a time
19diff -ruN XLMe500mc/gcc/Makefile.in XLMe5500/gcc/Makefile.in
20--- XLMe500mc/gcc/Makefile.in 2011-10-18 14:49:23.028644000 -0500
21+++ XLMe5500/gcc/Makefile.in 2011-10-05 12:08:28.104643898 -0500
22@@ -1306,6 +1306,7 @@
23 omp-low.o \
24 optabs.o \
25 options.o \
26+ opt-array-offset.o \
27 opts-common.o \
28 opts-global.o \
29 opts.o \
30@@ -2629,7 +2630,10 @@
31 $(FLAGS_H) $(CGRAPH_H) $(PLUGIN_H) \
32 $(TREE_INLINE_H) tree-mudflap.h $(GGC_H) graph.h $(CGRAPH_H) \
33 $(TREE_PASS_H) $(CFGLOOP_H) $(EXCEPT_H) $(REGSET_H)
34-
35+opt-array-offset.o : opt-array-offset.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
36+ $(TM_H) $(FLAGS_H) $(TREE_H) $(TREE_FLOW_H) $(TIMEVAR_H) \
37+ $(TREE_PASS_H) alloc-pool.h $(BASIC_BLOCK_H) $(TARGET_H) \
38+ $(DIAGNOSTIC_H) gimple-pretty-print.h tree-pretty-print.h
39 widen-types.o : widen-types.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(GIMPLE_H) \
40 $(DIAGNOSTIC_H) $(GIMPLE_H) $(TREE_INLINE_H) langhooks.h \
41 $(LANGHOOKS_DEF_H) $(TREE_FLOW_H) $(CGRAPH_H) $(TIMEVAR_H) $(TM_H) \
42diff -ruN XLMe500mc/gcc/opt-array-offset.c XLMe5500/gcc/opt-array-offset.c
43--- XLMe500mc/gcc/opt-array-offset.c 1969-12-31 18:00:00.000000000 -0600
44+++ XLMe5500/gcc/opt-array-offset.c 2011-11-01 15:24:21.746039000 -0500
45@@ -0,0 +1,283 @@
46+/* Optimizing array element access
47+ Copyright (C) 2011
48+ Free Software Foundation, Inc.
49+
50+This file is part of GCC.
51+
52+GCC is free software; you can redistribute it and/or modify it
53+under the terms of the GNU General Public License as published by the
54+Free Software Foundation; either version 3, or (at your option) any
55+later version.
56+
57+GCC is distributed in the hope that it will be useful, but WITHOUT
58+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
59+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
60+for more details.
61+
62+You should have received a copy of the GNU General Public License
63+along with GCC; see the file COPYING3. If not see
64+<http://www.gnu.org/licenses/>. */
65+
66+
67+/* This is a GIMPLE pass over basic block which coverts the stmts:
68+
69+ a = b +/- c1;
70+ c = a * c2;
71+
72+ to:
73+
74+ a = b * c2;
75+ c = a +/- c1 * c2;
76+
77+ in effect expanding the multiplication across addition/substraction.
78+
79+ Motivating example:
80+ Consider the following simple integer array access:
81+
82+ a[i] = c;
83+ a[i + 1] = c;
84+
85+ The following GIMPLE equivalent will be generated:
86+
87+ off_1 = i * 4;
88+ a_i = a + off_1;
89+ *a_i = c;
90+
91+ off_1 = i + 1;
92+ off_2 = off_1 * 4;
93+ a_i1 = a + off_2;
94+ *a_i1 = c;
95+
96+ Notice that a_i1 could simply be a_i + 4. But the calcuation of i+1
97+ is preventing CSE to perform. This pass will essentially convert the
98+ second expr into:
99+
100+ off_1 = i * 4;
101+ off_2 = off_1 + 4;
102+ a_i1 = a + off_2;
103+ ....
104+
105+ Thus allowing the previous index i calculation to be reuse. off_1 + 4
106+ would also be combined into a_i if offset addressing mode is available.
107+ This also have side effect of avoiding redundant sign extension on
108+ i+1 for LP64 model where native integer size is different from pointer size.
109+
110+ The algorithm iterates through all the basic blocks looking for
111+ the above pattern. Care is taken to make sure off_1 only
112+ has the single use otherwise the transformation cannot be perform.
113+*/
114+
115+
116+#include "config.h"
117+#include "system.h"
118+#include "coretypes.h"
119+#include "tm.h"
120+#include "flags.h"
121+#include "tree.h"
122+#include "tree-flow.h"
123+#include "timevar.h"
124+#include "tree-pass.h"
125+#include "alloc-pool.h"
126+#include "basic-block.h"
127+#include "target.h"
128+#include "gimple-pretty-print.h"
129+#include "tree-pretty-print.h"
130+
131+
132+/*
133+ We are looking for:
134+ a = b +/- c1
135+ c = a * c2 (stmt incoming)
136+ d = &arr + c
137+*/
138+static bool
139+is_candidate (gimple stmt)
140+{
141+ tree mul_result = gimple_get_lhs (stmt);
142+ tree rhs1, rhs2;
143+ gimple rhs1_stmt, use_stmt;
144+ use_operand_p use_p;
145+ imm_use_iterator imm_iter;
146+
147+ /* check for a * c2 */
148+ if (gimple_assign_rhs_code (stmt) != MULT_EXPR)
149+ return false;
150+
151+ rhs1 = gimple_assign_rhs1 (stmt);
152+ rhs2 = gimple_assign_rhs2 (stmt);
153+
154+ if (TREE_CODE (rhs2) != INTEGER_CST)
155+ return false;
156+
157+ /* check for b + c1 */
158+ if (TREE_CODE (rhs1) == SSA_NAME)
159+ {
160+ rhs1_stmt = SSA_NAME_DEF_STMT (rhs1);
161+ if (is_gimple_assign (rhs1_stmt))
162+ {
163+ tree rhs1_2;
164+ tree plusminus_result;
165+
166+ if (gimple_assign_rhs_code (rhs1_stmt) != PLUS_EXPR
167+ && gimple_assign_rhs_code (rhs1_stmt) != MINUS_EXPR)
168+ return false;
169+
170+ rhs1_2 = gimple_assign_rhs2 (rhs1_stmt);
171+ if (TREE_CODE (rhs1_2) != INTEGER_CST)
172+ return false;
173+
174+ /* make sure there are no other uses of a
175+ e.g. if a is used as an indcution variable
176+ we cannot modified it
177+ */
178+ plusminus_result = gimple_get_lhs (rhs1_stmt);
179+ FOR_EACH_IMM_USE_FAST (use_p, imm_iter, plusminus_result)
180+ {
181+ use_stmt = USE_STMT (use_p);
182+
183+ /* ignore PHI node */
184+ if (is_gimple_assign (use_stmt) &&
185+ (gimple_assign_rhs_code (use_stmt) == GIMPLE_PHI))
186+ continue;
187+ if (use_stmt != stmt)
188+ return false;
189+ }
190+
191+#if 0
192+ if (gimple_bb(rhs1_stmt) != gimple_bb(stmt))
193+ return false;
194+#endif
195+ }
196+ else
197+ return false;
198+ }
199+ else
200+ return false;
201+
202+ /* now look for uses of c that is a pointer use */
203+ FOR_EACH_IMM_USE_FAST (use_p, imm_iter, mul_result)
204+ {
205+ enum tree_code use_code;
206+
207+ use_stmt = USE_STMT (use_p);
208+
209+ if (is_gimple_debug (use_stmt))
210+ continue;
211+
212+ if (gimple_bb (use_stmt) != gimple_bb (stmt))
213+ return false;
214+
215+ if (!is_gimple_assign (use_stmt))
216+ return false;
217+
218+ use_code = gimple_assign_rhs_code (use_stmt);
219+ if (use_code != POINTER_PLUS_EXPR)
220+ return false;
221+ }
222+
223+ if (dump_file)
224+ {
225+ fprintf (dump_file, "Found candidate:\n");
226+ print_gimple_stmt (dump_file, rhs1_stmt, 0, TDF_SLIM);
227+ print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
228+ print_gimple_stmt (dump_file, use_stmt, 0, TDF_SLIM);
229+ }
230+
231+ return true;
232+}
233+
234+/* Do the actual transformation:
235+ a = b + c1 ==> a = b * c2
236+ c = a * c2 ==> c = a + c1*c2
237+*/
238+static bool
239+expand_plusminus_mult (gimple stmt)
240+{
241+ tree c1, c2, mul_result;
242+ gimple rhs1_stmt;
243+
244+ /* get c2 */
245+ c2 = gimple_assign_rhs2 (stmt);
246+
247+ /* get c1 */
248+ rhs1_stmt = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt));
249+ c1 = gimple_assign_rhs2 (rhs1_stmt);
250+
251+ /* form c1 * c2 */
252+ mul_result = double_int_to_tree (TREE_TYPE(c2), double_int_mul
253+ (tree_to_double_int (c1), tree_to_double_int (c2)));
254+
255+ /* a = b + c1 ==> a = b * c2 */
256+ gimple_assign_set_rhs2 (rhs1_stmt, c2);
257+ gimple_assign_set_rhs_code (rhs1_stmt, MULT_EXPR);
258+ update_stmt (rhs1_stmt);
259+
260+ /* c = a * c2 ==> c = a + c1*c2 */
261+ gimple_assign_set_rhs2 (stmt, mul_result);
262+ /* MINUS_EXPR has already been embedded into c1*c2 */
263+ gimple_assign_set_rhs_code (stmt, PLUS_EXPR);
264+ update_stmt (stmt);
265+
266+ return true;
267+}
268+
269+
270+static unsigned int
271+execute_opt_array_offset (void)
272+{
273+ basic_block bb;
274+ tree fndecl;
275+
276+ FOR_EACH_BB (bb)
277+ {
278+ gimple_stmt_iterator gsi;
279+
280+ for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); gsi_next(&gsi))
281+ {
282+ gimple stmt = gsi_stmt (gsi);
283+ tree lhs,rhs1,rhs2,rhs3;
284+ enum tree_code code;
285+
286+ /* only interested in assign statement */
287+ if (is_gimple_assign (stmt))
288+ {
289+ /* find stmts calculating array offset */
290+ if (is_candidate (stmt))
291+ /* convert stmt */
292+ expand_plusminus_mult(stmt);
293+
294+ }
295+ }
296+ }
297+
298+ return 0;
299+}
300+
301+static bool
302+gate_opt_array_offset (void)
303+{
304+ return flag_opt_array_offset && optimize;
305+}
306+
307+struct gimple_opt_pass pass_opt_array_offset =
308+{
309+ {
310+ GIMPLE_PASS,
311+ "opt_array_offset", /* name */
312+ gate_opt_array_offset, /* gate */
313+ execute_opt_array_offset, /* execute */
314+ NULL, /* sub */
315+ NULL, /* next */
316+ 0, /* static_pass_number */
317+ TV_NONE, /* tv_id */
318+ PROP_ssa, /* properties_required */
319+ 0, /* properties_provided */
320+ 0, /* properties_destroyed */
321+ 0, /* todo_flags_start */
322+ TODO_verify_ssa
323+ | TODO_verify_stmts
324+ | TODO_update_ssa
325+ | TODO_dump_func /* todo_flags_finish */
326+ }
327+};
328+
329diff -ruN XLMe500mc/gcc/passes.c XLMe5500/gcc/passes.c
330--- XLMe500mc/gcc/passes.c 2011-10-18 14:49:23.029644000 -0500
331+++ XLMe5500/gcc/passes.c 2011-10-05 11:19:01.168644127 -0500
332@@ -937,6 +937,7 @@
333 NEXT_PASS (pass_phiopt);
334 NEXT_PASS (pass_fold_builtins);
335 NEXT_PASS (pass_optimize_widening_mul);
336+ NEXT_PASS (pass_opt_array_offset);
337 NEXT_PASS (pass_tail_calls);
338 NEXT_PASS (pass_rename_ssa_copies);
339 NEXT_PASS (pass_uncprop);
340diff -ruN XLMe500mc/gcc/tree-pass.h XLMe5500/gcc/tree-pass.h
341--- XLMe500mc/gcc/tree-pass.h 2011-10-18 14:49:23.029644000 -0500
342+++ XLMe5500/gcc/tree-pass.h 2011-10-05 11:19:59.665643705 -0500
343@@ -421,6 +421,7 @@
344 extern struct gimple_opt_pass pass_cse_sincos;
345 extern struct gimple_opt_pass pass_optimize_bswap;
346 extern struct gimple_opt_pass pass_optimize_widening_mul;
347+extern struct gimple_opt_pass pass_opt_array_offset;
348 extern struct gimple_opt_pass pass_warn_function_return;
349 extern struct gimple_opt_pass pass_warn_function_noreturn;
350 extern struct gimple_opt_pass pass_cselim;