]> git.pld-linux.org Git - packages/gcc4.git/blob - gcc4-pr17390.patch
- added from gcc/
[packages/gcc4.git] / gcc4-pr17390.patch
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.181897 seconds and 3 git commands to generate.