diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a2ab54f71e6ad6f32634cd7f9cea78c3109ea22a..66e788246e3158637bd346fc0be529507960ed82 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,15 @@
+Tue Feb 25 12:35:34 CET 2003  Jan Hubicka  <jh@suse.cz>
+
+	* Makefile.in (lcm.o):  Add dependency on function.h
+	* lcm.c (function.h): Include.
+	* i386.c (machine_function, ix86_stack_locals,
+	* ix86_save_varrargs_registers) : Move to
+	...
+	* i386.h (machine_function, ix86_stack_locals,
+	ix86_save_varrargs_registers): ... here; add optimize_mode_switching
+	(ix86_optimize_mode_switching): New.
+	* i386.md (fix patterns): Set ix86_optimize_mode_switching
+
 2003-02-25  Nick Clifton  <nickc@redhat.com>
 
 	* config/d30v/d30v.c (d30v_init_cumulative_args): Fix typo.  Name
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 271f3e040a7de9782752aa38e751ebbe0694d92c..ceb594bf1ee566f53c0146fef988ebc68c98eb13 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1552,7 +1552,7 @@ resource.o : resource.c $(CONFIG_H) $(RTL_H) hard-reg-set.h $(SYSTEM_H) coretype
    $(INSN_ATTR_H) except.h $(PARAMS_H) $(TM_P_H)
 lcm.o : lcm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(REGS_H) \
    hard-reg-set.h flags.h real.h insn-config.h $(INSN_ATTR_H) $(RECOG_H) $(EXPR_H) \
-   $(BASIC_BLOCK_H) $(TM_P_H) df.h
+   $(BASIC_BLOCK_H) $(TM_P_H) df.h function.h
 ssa.o : ssa.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(REGS_H) varray.h \
    $(EXPR_H) hard-reg-set.h flags.h function.h real.h insn-config.h $(RECOG_H) \
    $(BASIC_BLOCK_H) output.h ssa.h
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 89995c7cb782df6236a15bdf7ca57170f12eeee0..c464b6c06748f38d1ed7f6c4401c16850e723076 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -689,18 +689,6 @@ struct stack_local_entry GTY(())
   struct stack_local_entry *next;
 };
 
-
-struct machine_function GTY(())
-{
-  struct stack_local_entry *stack_locals;
-  const char *some_ld_name;
-  int save_varrargs_registers;
-  int accesses_prev_frame;
-};
-
-#define ix86_stack_locals (cfun->machine->stack_locals)
-#define ix86_save_varrargs_registers (cfun->machine->save_varrargs_registers)
-
 /* Structure describing stack frame layout.
    Stack grows downward:
 
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index c8be29650a650ca768e9b7a9147494fa03ffa9a3..e5daa5d5c9367d25764d8782b34214d0f8dbef91 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -3166,7 +3166,7 @@ enum fp_cw_mode {FP_CW_STORED, FP_CW_UNINITIALIZED, FP_CW_ANY};
 /* Define this macro if the port needs extra instructions inserted
    for mode switching in an optimizing compilation.  */
 
-#define OPTIMIZE_MODE_SWITCHING(ENTITY) 1
+#define OPTIMIZE_MODE_SWITCHING(ENTITY) ix86_optimize_mode_switching
 
 /* If you define `OPTIMIZE_MODE_SWITCHING', you have to define this as
    initializer for an array of integers.  Each initializer element N
@@ -3223,6 +3223,19 @@ enum fp_cw_mode {FP_CW_STORED, FP_CW_UNINITIALIZED, FP_CW_ANY};
 #define DLL_IMPORT_EXPORT_PREFIX '#'
 
 #define FASTCALL_PREFIX '@'
+
+struct machine_function GTY(())
+{
+  struct stack_local_entry *stack_locals;
+  const char *some_ld_name;
+  int save_varrargs_registers;
+  int accesses_prev_frame;
+  int optimize_mode_switching;
+};
+
+#define ix86_stack_locals (cfun->machine->stack_locals)
+#define ix86_save_varrargs_registers (cfun->machine->save_varrargs_registers)
+#define ix86_optimize_mode_switching (cfun->machine->optimize_mode_switching)
 
 /*
 Local variables:
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index bb2eb74e551cbb8f045017ac205b721441badd20..d5bc3602bea1e20f3cefecff81ca86d57e44544a 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -4441,6 +4441,7 @@
   "&& 1"
   [(const_int 0)]
 {
+  ix86_optimize_mode_switching = 1;
   operands[2] = assign_386_stack_local (HImode, 1);
   operands[3] = assign_386_stack_local (HImode, 2);
   if (memory_operand (operands[0], VOIDmode))
@@ -4582,6 +4583,7 @@
   "&& 1"
   [(const_int 0)]
 {
+  ix86_optimize_mode_switching = 1;
   operands[2] = assign_386_stack_local (HImode, 1);
   operands[3] = assign_386_stack_local (HImode, 2);
   if (memory_operand (operands[0], VOIDmode))
@@ -4699,6 +4701,7 @@
   ""
   [(const_int 0)]
 {
+  ix86_optimize_mode_switching = 1;
   operands[2] = assign_386_stack_local (HImode, 1);
   operands[3] = assign_386_stack_local (HImode, 2);
   if (memory_operand (operands[0], VOIDmode))
diff --git a/gcc/lcm.c b/gcc/lcm.c
index 8bbe893c82386eaa6c1e849d7dc2a6d207e24ea4..c403485a4487139883581dc968cee42ac186c5c8 100644
--- a/gcc/lcm.c
+++ b/gcc/lcm.c
@@ -63,6 +63,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "basic-block.h"
 #include "output.h"
 #include "tm_p.h"
+#include "function.h"
 
 /* We want target macros for the mode switching code to be able to refer
    to instruction attribute values.  */
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 5e63794c7d7acddcf612edc0ea8b3f113deb6079..89324090f611ec1a7f217c440f63534d519eba72 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -3493,21 +3493,6 @@ rest_of_compilation (decl)
       timevar_pop (TV_RENAME_REGISTERS);
     }
 
-  if (flag_if_conversion2)
-    {
-      timevar_push (TV_IFCVT2);
-      open_dump_file (DFI_ce3, decl);
-
-      if_convert (1);
-
-      close_dump_file (DFI_ce3, print_rtl_with_bb, insns);
-      timevar_pop (TV_IFCVT2);
-    }
-#ifdef STACK_REGS
-  if (optimize)
-    split_all_insns (1);
-#endif
-
   if (optimize > 0)
     {
       timevar_push (TV_REORDER_BLOCKS);
@@ -3530,6 +3515,21 @@ rest_of_compilation (decl)
       timevar_pop (TV_REORDER_BLOCKS);
     }
 
+  if (flag_if_conversion2)
+    {
+      timevar_push (TV_IFCVT2);
+      open_dump_file (DFI_ce3, decl);
+
+      if_convert (1);
+
+      close_dump_file (DFI_ce3, print_rtl_with_bb, insns);
+      timevar_pop (TV_IFCVT2);
+    }
+#ifdef STACK_REGS
+  if (optimize)
+    split_all_insns (1);
+#endif
+
 #ifdef INSN_SCHEDULING
   if (optimize > 0 && flag_schedule_insns_after_reload)
     {