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,
32 @@ -1599,3 +1600,33 @@ struct tree_opt_pass pass_postreload_cse
36 +/* Machine dependent postreload pass. */
38 +gate_handle_machine_postreload (void)
40 + return targetm.machine_dependent_postreload != 0;
45 +rest_of_handle_machine_postreload (void)
47 + targetm.machine_dependent_postreload ();
50 +struct tree_opt_pass pass_machine_postreload =
52 + "mach-postreload", /* name */
53 + gate_handle_machine_postreload, /* gate */
54 + rest_of_handle_machine_postreload, /* execute */
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 */
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
70 #define TARGET_CC_MODES_COMPATIBLE default_cc_modes_compatible
72 +#define TARGET_MACHINE_DEPENDENT_AFTER_RELOAD 0
73 #define TARGET_MACHINE_DEPENDENT_REORG 0
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,
90 + /* Do machine-dependent post-reload pass. Called after
92 + void (* machine_dependent_postreload) (void);
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
134 +#undef TARGET_MACHINE_DEPENDENT_AFTER_RELOAD
135 +#define TARGET_MACHINE_DEPENDENT_AFTER_RELOAD ix86_postreload
137 #undef TARGET_MACHINE_DEPENDENT_REORG
138 #define TARGET_MACHINE_DEPENDENT_REORG ix86_reorg
140 @@ -16908,6 +16912,236 @@ min_insn_size (rtx insn)
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:
148 + fucom(p), fcom(p), ficom(p), fcompp, ftst
153 + After the FP compare sequence has been found, redundant instructions in
154 + successor blocks are deleted:
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.
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. */
165 +ix86_cse_i387_compares (void)
167 + rtx cc_reg = gen_rtx_REG (CCmode, FLAGS_REG);
180 + bool cc_src_clobbered_pred;
185 + last_insn = BB_END (bb);
186 + if (!JUMP_P (last_insn))
189 + /* Find CC setting insn. */
190 + if (! reg_referenced_p (cc_reg, PATTERN (last_insn)))
193 + cc_src_insn = NULL_RTX;
195 + for (insn = PREV_INSN (last_insn);
196 + insn && insn != PREV_INSN (BB_HEAD (bb));
197 + insn = PREV_INSN (insn))
201 + if (! INSN_P (insn))
204 + set = single_set (insn);
206 + && REG_P (SET_DEST (set))
207 + && REGNO (SET_DEST (set)) == REGNO (cc_reg))
209 + cc_src_insn = insn;
210 + cc_src = SET_SRC (set);
213 + else if (reg_set_p (cc_reg, insn))
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))
226 + /* Find AX setting insn. */
227 + ax_reg = gen_rtx_REG (HImode, 0);
229 + if (! reg_referenced_p (ax_reg, PATTERN (cc_src_insn)))
232 + ax_src_insn = NULL_RTX;
234 + for (insn = PREV_INSN (cc_src_insn);
235 + insn && insn != PREV_INSN (BB_HEAD (bb));
236 + insn = PREV_INSN (insn))
240 + if (! INSN_P (insn))
243 + set = single_set (insn);
245 + && REG_P (SET_DEST (set))
246 + && REGNO (SET_DEST (set)) == REGNO (ax_reg))
248 + ax_src_insn = insn;
249 + ax_src = SET_SRC (set);
252 + else if (reg_set_p (ax_reg, insn))
259 + if (! (GET_CODE (ax_src) == UNSPEC
260 + && XINT (ax_src, 1) == UNSPEC_FNSTSW))
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)))
268 + /* FP compare sequence has been found. Check successor blocks
269 + for redundant insns. */
270 + FOR_EACH_EDGE (e, ei, bb->succs)
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;
279 + bool cc_src_clobbered;
280 + bool cc_reg_clobbered;
282 + if (e->flags & EDGE_COMPLEX)
285 + if (EDGE_COUNT (e->dest->preds) != 1
286 + || e->dest == EXIT_BLOCK_PTR)
289 + end = NEXT_INSN (BB_END (e->dest));
291 + cc_src_clobbered = cc_src_clobbered_pred;
292 + cc_reg_clobbered = false;
294 + for (insn = BB_HEAD (e->dest); insn != end; insn = NEXT_INSN (insn))
298 + if (! INSN_P (insn))
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)
307 + set = single_set (insn);
309 + /* A compare insn can be deleted if it sets AX_REG
310 + from AX_SRC and where CC_SRC is not clobbered yet. */
312 + && REG_P (SET_DEST (set))
313 + && REGNO (SET_DEST (set)) == REGNO (ax_reg)
314 + && rtx_equal_p (ax_src, SET_SRC (set)))
316 + maybe_delete_ax_src_insn = insn;
317 + if (!cc_src_clobbered)
319 + delete_ax_src_insn = insn;
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. */
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)
335 + delete_ax_src_insn = maybe_delete_ax_src_insn;
336 + delete_cc_src_insn = insn;
340 + if (modified_in_p (cc_src, insn))
341 + cc_src_clobbered = true;
343 + if (modified_in_p (cc_reg, insn))
344 + cc_reg_clobbered = true;
346 + /* No usable register remains unclobbered. */
347 + if (cc_src_clobbered && cc_reg_clobbered)
351 + /* Delete comparison. */
352 + if (delete_ax_src_insn)
354 + gcc_assert (maybe_delete_ax_src_insn != NULL_RTX);
355 + delete_insn (delete_ax_src_insn);
358 + /* Delete CC setting instruction. */
359 + if (delete_cc_src_insn)
360 + delete_insn (delete_cc_src_insn);
365 +/* Implement machine specific post-reload optimizations. */
367 +ix86_postreload (void)
369 + if (TARGET_80387 && !TARGET_CMOVE &&
370 + !flag_trapping_math && flag_expensive_optimizations)
371 + ix86_cse_i387_compares ();
374 /* AMD K8 core mispredicts jumps when there are more than 3 jumps in 16 byte
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.
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.
388 +You need not implement the hook if it has nothing to do. The default
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,