]> git.pld-linux.org Git - packages/crossppc-gcc.git/blame - gcc-pr17390.patch
- more
[packages/crossppc-gcc.git] / gcc-pr17390.patch
CommitLineData
2163109e
PS
1--- gcc/gcc/Makefile.in 12 Oct 2005 12:38:00 -0000 1.1547
2+++ gcc/gcc/Makefile.in 21 Oct 2005 11:22:39 -0000
3@@ -2375,7 +2376,7 @@ postreload.o : postreload.c $(CONFIG_H)
4 $(RTL_H) real.h $(FLAGS_H) $(EXPR_H) $(OPTABS_H) reload.h $(REGS_H) \
5 hard-reg-set.h insn-config.h $(BASIC_BLOCK_H) $(RECOG_H) output.h \
6 function.h toplev.h cselib.h $(TM_P_H) except.h $(TREE_H) $(MACHMODE_H) \
7- $(OBSTACK_H) timevar.h tree-pass.h
8+ $(TARGET_H) $(OBSTACK_H) timevar.h tree-pass.h
9 postreload-gcse.o : postreload-gcse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
10 $(TM_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) real.h insn-config.h \
11 $(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) function.h output.h toplev.h \
12--- gcc/gcc/passes.c 11 Oct 2005 19:18:24 -0000 2.117
13+++ gcc/gcc/passes.c 21 Oct 2005 11:22:40 -0000
14@@ -650,6 +650,7 @@ init_optimization_passes (void)
15 NEXT_PASS (pass_postreload_cse);
16 NEXT_PASS (pass_gcse2);
17 NEXT_PASS (pass_flow2);
18+ NEXT_PASS (pass_machine_postreload);
19 NEXT_PASS (pass_stack_adjustments);
20 NEXT_PASS (pass_peephole2);
21 NEXT_PASS (pass_if_after_reload);
22--- gcc/gcc/postreload.c 5 Jul 2005 16:20:09 -0000 2.33
23+++ gcc/gcc/postreload.c 21 Oct 2005 11:22:40 -0000
24@@ -41,6 +41,7 @@ Software Foundation, 51 Franklin Street,
25 #include "output.h"
26 #include "cselib.h"
27 #include "real.h"
28+#include "target.h"
29 #include "toplev.h"
30 #include "except.h"
31 #include "tree.h"
32@@ -1599,3 +1600,33 @@ struct tree_opt_pass pass_postreload_cse
33 'o' /* letter */
34 };
35
36+/* Machine dependent postreload pass. */
37+static bool
38+gate_handle_machine_postreload (void)
39+{
40+ return targetm.machine_dependent_postreload != 0;
41+}
42+
43+
44+static void
45+rest_of_handle_machine_postreload (void)
46+{
47+ targetm.machine_dependent_postreload ();
48+}
49+
50+struct tree_opt_pass pass_machine_postreload =
51+{
52+ "mach-postreload", /* name */
53+ gate_handle_machine_postreload, /* gate */
54+ rest_of_handle_machine_postreload, /* execute */
55+ NULL, /* sub */
56+ NULL, /* next */
57+ 0, /* static_pass_number */
58+ TV_MACH_DEP_AFTER_RELOAD, /* tv_id */
59+ 0, /* properties_required */
60+ 0, /* properties_provided */
61+ 0, /* properties_destroyed */
62+ 0, /* todo_flags_start */
63+ TODO_dump_func, /* todo_flags_finish */
64+ 0 /* letter */
65+};
66--- gcc/gcc/target-def.h 12 Oct 2005 20:54:48 -0000 1.134
67+++ gcc/gcc/target-def.h 21 Oct 2005 11:22:40 -0000
68@@ -395,6 +395,7 @@ Foundation, 51 Franklin Street, Fifth Fl
69
70 #define TARGET_CC_MODES_COMPATIBLE default_cc_modes_compatible
71
72+#define TARGET_MACHINE_DEPENDENT_AFTER_RELOAD 0
73 #define TARGET_MACHINE_DEPENDENT_REORG 0
74
75 #define TARGET_BUILD_BUILTIN_VA_LIST std_build_builtin_va_list
76@@ -587,6 +588,7 @@ Foundation, 51 Franklin Street, Fifth Fl
77 TARGET_DWARF_REGISTER_SPAN, \
78 TARGET_FIXED_CONDITION_CODE_REGS, \
79 TARGET_CC_MODES_COMPATIBLE, \
80+ TARGET_MACHINE_DEPENDENT_AFTER_RELOAD, \
81 TARGET_MACHINE_DEPENDENT_REORG, \
82 TARGET_BUILD_BUILTIN_VA_LIST, \
83 TARGET_GIMPLIFY_VA_ARG_EXPR, \
84--- gcc/gcc/target.h 12 Oct 2005 20:54:48 -0000 1.145
85+++ gcc/gcc/target.h 21 Oct 2005 11:22:40 -0000
86@@ -478,6 +478,10 @@ struct gcc_target
87 enum machine_mode (* cc_modes_compatible) (enum machine_mode,
88 enum machine_mode);
89
90+ /* Do machine-dependent post-reload pass. Called after
91+ flow2 pass. */
92+ void (* machine_dependent_postreload) (void);
93+
94 /* Do machine-dependent code transformations. Called just before
95 delayed-branch scheduling. */
96 void (* machine_dependent_reorg) (void);
97--- gcc/gcc/timevar.def 1 Aug 2005 07:47:23 -0000 1.54
98+++ gcc/gcc/timevar.def 21 Oct 2005 11:22:40 -0000
99@@ -148,8 +148,9 @@ DEFTIMEVAR (TV_SCHED , "
100 DEFTIMEVAR (TV_LOCAL_ALLOC , "local alloc")
101 DEFTIMEVAR (TV_GLOBAL_ALLOC , "global alloc")
102 DEFTIMEVAR (TV_RELOAD_CSE_REGS , "reload CSE regs")
103-DEFTIMEVAR (TV_GCSE_AFTER_RELOAD , "load CSE after reload")
104+DEFTIMEVAR (TV_GCSE_AFTER_RELOAD , "load CSE after reload")
105 DEFTIMEVAR (TV_FLOW2 , "flow 2")
106+DEFTIMEVAR (TV_MACH_DEP_AFTER_RELOAD , "mach-dep after reload")
107 DEFTIMEVAR (TV_IFCVT2 , "if-conversion 2")
108 DEFTIMEVAR (TV_PEEPHOLE2 , "peephole 2")
109 DEFTIMEVAR (TV_RENAME_REGISTERS , "rename registers")
110--- gcc/gcc/tree-pass.h 11 Oct 2005 19:18:24 -0000 2.59
111+++ gcc/gcc/tree-pass.h 21 Oct 2005 11:22:40 -0000
112@@ -352,6 +352,7 @@ extern struct tree_opt_pass pass_remove_
113 extern struct tree_opt_pass pass_postreload_cse;
114 extern struct tree_opt_pass pass_gcse2;
115 extern struct tree_opt_pass pass_flow2;
116+extern struct tree_opt_pass pass_machine_postreload;
117 extern struct tree_opt_pass pass_stack_adjustments;
118 extern struct tree_opt_pass pass_peephole2;
119 extern struct tree_opt_pass pass_if_after_reload;
120--- gcc/gcc/config/i386/i386.c 19 Oct 2005 02:13:37 -0000 1.864
121+++ gcc/gcc/config/i386/i386.c 21 Oct 2005 11:22:43 -0000
122@@ -860,6 +860,7 @@ static void x86_output_mi_thunk (FILE *,
123 HOST_WIDE_INT, tree);
124 static bool x86_can_output_mi_thunk (tree, HOST_WIDE_INT, HOST_WIDE_INT, tree);
125 static void x86_file_start (void);
126+static void ix86_postreload (void);
127 static void ix86_reorg (void);
128 static bool ix86_expand_carry_flag_compare (enum rtx_code, rtx, rtx, rtx*);
129 static tree ix86_build_builtin_va_list (void);
130@@ -1062,6 +1063,9 @@ static void x86_64_elf_select_section (t
131 #undef TARGET_CC_MODES_COMPATIBLE
132 #define TARGET_CC_MODES_COMPATIBLE ix86_cc_modes_compatible
133
134+#undef TARGET_MACHINE_DEPENDENT_AFTER_RELOAD
135+#define TARGET_MACHINE_DEPENDENT_AFTER_RELOAD ix86_postreload
136+
137 #undef TARGET_MACHINE_DEPENDENT_REORG
138 #define TARGET_MACHINE_DEPENDENT_REORG ix86_reorg
139
140@@ -16908,6 +16912,236 @@ min_insn_size (rtx insn)
141 return 2;
142 }
143
144+/* Non-fcomi 387 FP compare sequences can not be CSE'd during cse1 pass.
145+ This function implements elimination of redundant 387 FP compare
146+ sequences. We look for a sequence of:
147+
148+ fucom(p), fcom(p), ficom(p), fcompp, ftst
149+ fnstsw %ax
150+ sahf or test %ax
151+ j<cc>
152+
153+ After the FP compare sequence has been found, redundant instructions in
154+ successor blocks are deleted:
155+
156+ a) fcom/fnstsw combination iff compare arguments
157+ and AX reg were not modified.
158+ b) sahf (test %ax) and fcom/fnstsw iff compare arguments up to compare
159+ insn and CC reg were not modified.
160+
161+ This code is partially based on code from cse_condition_code_reg () and
162+ cse_cc_succs () functions, as found in cse.c source file. */
163+
164+static void
165+ix86_cse_i387_compares (void)
166+{
167+ rtx cc_reg = gen_rtx_REG (CCmode, FLAGS_REG);
168+ rtx ax_reg;
169+ basic_block bb;
170+
171+ FOR_EACH_BB (bb)
172+ {
173+ rtx last_insn;
174+ rtx insn;
175+ rtx cc_src_insn;
176+ rtx cc_src;
177+ rtx ax_src_insn;
178+ rtx ax_src;
179+
180+ bool cc_src_clobbered_pred;
181+
182+ edge e;
183+ edge_iterator ei;
184+
185+ last_insn = BB_END (bb);
186+ if (!JUMP_P (last_insn))
187+ continue;
188+
189+ /* Find CC setting insn. */
190+ if (! reg_referenced_p (cc_reg, PATTERN (last_insn)))
191+ continue;
192+
193+ cc_src_insn = NULL_RTX;
194+ cc_src = NULL_RTX;
195+ for (insn = PREV_INSN (last_insn);
196+ insn && insn != PREV_INSN (BB_HEAD (bb));
197+ insn = PREV_INSN (insn))
198+ {
199+ rtx set;
200+
201+ if (! INSN_P (insn))
202+ continue;
203+
204+ set = single_set (insn);
205+ if (set
206+ && REG_P (SET_DEST (set))
207+ && REGNO (SET_DEST (set)) == REGNO (cc_reg))
208+ {
209+ cc_src_insn = insn;
210+ cc_src = SET_SRC (set);
211+ break;
212+ }
213+ else if (reg_set_p (cc_reg, insn))
214+ break;
215+ }
216+
217+ if (! cc_src_insn)
218+ continue;
219+
220+ /* Check if argument to CC setting insn (AX reg) has been
221+ modified between CC setting insn and jump insn. */
222+ cc_src_clobbered_pred
223+ = modified_between_p (cc_src, cc_src_insn, NEXT_INSN (last_insn))
224+ ? true : false;
225+
226+ /* Find AX setting insn. */
227+ ax_reg = gen_rtx_REG (HImode, 0);
228+
229+ if (! reg_referenced_p (ax_reg, PATTERN (cc_src_insn)))
230+ continue;
231+
232+ ax_src_insn = NULL_RTX;
233+ ax_src = NULL_RTX;
234+ for (insn = PREV_INSN (cc_src_insn);
235+ insn && insn != PREV_INSN (BB_HEAD (bb));
236+ insn = PREV_INSN (insn))
237+ {
238+ rtx set;
239+
240+ if (! INSN_P (insn))
241+ continue;
242+
243+ set = single_set (insn);
244+ if (set
245+ && REG_P (SET_DEST (set))
246+ && REGNO (SET_DEST (set)) == REGNO (ax_reg))
247+ {
248+ ax_src_insn = insn;
249+ ax_src = SET_SRC (set);
250+ break;
251+ }
252+ else if (reg_set_p (ax_reg, insn))
253+ break;
254+ }
255+
256+ if (! ax_src_insn)
257+ continue;
258+
259+ if (! (GET_CODE (ax_src) == UNSPEC
260+ && XINT (ax_src, 1) == UNSPEC_FNSTSW))
261+ continue;
262+
263+ /* Leave this BB if input arguments to AX setting insn (compare)
264+ have been modified between compare and jump insn. */
265+ if (modified_between_p (ax_src, ax_src_insn, NEXT_INSN (last_insn)))
266+ continue;
267+
268+ /* FP compare sequence has been found. Check successor blocks
269+ for redundant insns. */
270+ FOR_EACH_EDGE (e, ei, bb->succs)
271+ {
272+ rtx insn;
273+ rtx end;
274+
275+ rtx delete_cc_src_insn = NULL_RTX;
276+ rtx delete_ax_src_insn = NULL_RTX;
277+ rtx maybe_delete_ax_src_insn = NULL_RTX;
278+
279+ bool cc_src_clobbered;
280+ bool cc_reg_clobbered;
281+
282+ if (e->flags & EDGE_COMPLEX)
283+ continue;
284+
285+ if (EDGE_COUNT (e->dest->preds) != 1
286+ || e->dest == EXIT_BLOCK_PTR)
287+ continue;
288+
289+ end = NEXT_INSN (BB_END (e->dest));
290+
291+ cc_src_clobbered = cc_src_clobbered_pred;
292+ cc_reg_clobbered = false;
293+
294+ for (insn = BB_HEAD (e->dest); insn != end; insn = NEXT_INSN (insn))
295+ {
296+ rtx set;
297+
298+ if (! INSN_P (insn))
299+ continue;
300+
301+ /* If compare arguments are modified, we have to
302+ stop looking for a compare which uses it. */
303+ if (modified_in_p (ax_src, insn)
304+ && maybe_delete_ax_src_insn == NULL_RTX)
305+ break;
306+
307+ set = single_set (insn);
308+
309+ /* A compare insn can be deleted if it sets AX_REG
310+ from AX_SRC and where CC_SRC is not clobbered yet. */
311+ if (set
312+ && REG_P (SET_DEST (set))
313+ && REGNO (SET_DEST (set)) == REGNO (ax_reg)
314+ && rtx_equal_p (ax_src, SET_SRC (set)))
315+ {
316+ maybe_delete_ax_src_insn = insn;
317+ if (!cc_src_clobbered)
318+ {
319+ delete_ax_src_insn = insn;
320+ continue;
321+ }
322+ }
323+
324+ /* A CC setting insn can be deleted if it sets
325+ CC_REG from CC_SRC, and CC is not clobbered yet.
326+ In this case, compare insn should also be deleted. */
327+ if (set
328+ && REG_P (SET_DEST (set))
329+ && REGNO (SET_DEST (set)) == REGNO (cc_reg)
330+ && rtx_equal_p (cc_src, SET_SRC (set))
331+ && !cc_reg_clobbered
332+ /* There should be a compare insn present in front. */
333+ && maybe_delete_ax_src_insn != NULL_RTX)
334+ {
335+ delete_ax_src_insn = maybe_delete_ax_src_insn;
336+ delete_cc_src_insn = insn;
337+ break;
338+ }
339+
340+ if (modified_in_p (cc_src, insn))
341+ cc_src_clobbered = true;
342+
343+ if (modified_in_p (cc_reg, insn))
344+ cc_reg_clobbered = true;
345+
346+ /* No usable register remains unclobbered. */
347+ if (cc_src_clobbered && cc_reg_clobbered)
348+ break;
349+ }
350+
351+ /* Delete comparison. */
352+ if (delete_ax_src_insn)
353+ {
354+ gcc_assert (maybe_delete_ax_src_insn != NULL_RTX);
355+ delete_insn (delete_ax_src_insn);
356+ }
357+
358+ /* Delete CC setting instruction. */
359+ if (delete_cc_src_insn)
360+ delete_insn (delete_cc_src_insn);
361+ }
362+ }
363+}
364+
365+/* Implement machine specific post-reload optimizations. */
366+static void
367+ix86_postreload (void)
368+{
369+ if (TARGET_80387 && !TARGET_CMOVE &&
370+ !flag_trapping_math && flag_expensive_optimizations)
371+ ix86_cse_i387_compares ();
372+}
373+
374 /* AMD K8 core mispredicts jumps when there are more than 3 jumps in 16 byte
375 window. */
376
377--- gcc/gcc/doc/tm.texi 12 Oct 2005 20:54:49 -0000 1.447
378+++ gcc/gcc/doc/tm.texi 21 Oct 2005 11:29:35 -0000
379@@ -9300,6 +9300,15 @@ added to the @code{struct ce_if_block} s
380 by the @code{IFCVT_INIT_EXTRA_FIELDS} macro.
381 @end defmac
382
383+@deftypefn {Target Hook} void TARGET_MACHINE_DEPENDENT_AFTER_RELOAD ()
384+If non-null, this hook performs a target-specific pass over the
385+instruction stream. The compiler will run it at all optimization levels,
386+after instructions have been split in flow2 pass.
387+
388+You need not implement the hook if it has nothing to do. The default
389+definition is null.
390+@end deftypefn
391+
392 @deftypefn {Target Hook} void TARGET_MACHINE_DEPENDENT_REORG ()
393 If non-null, this hook performs a target-specific pass over the
394 instruction stream. The compiler will run it at all optimization levels,
This page took 0.085437 seconds and 4 git commands to generate.