for  gcc/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	PR debug/47590
	* target.def (delay_sched2, delay_vartrack): New.
	* doc/tm.texi.in: Update.
	* doc/tm.texi: Rebuild.
	* sched-rgn.c (gate_handle_sched2): Fail if delay_sched2.
	* var-tracking.c (gate_handle_var_tracking): Likewise.
	* config/bfin/bfin.c (bfin_flag_schedule_insns2): Drop.
	(bfin_flag_var_tracking): Drop.
	(output_file_start): Don't save and override flag_var_tracking.
	(bfin_option_override): Ditto flag_schedule_insns_after_reload.
	(bfin_reorg): Test original variables.
	(TARGET_DELAY_SCHED2, TARGET_DELAY_VARTRACK): Define.
	* config/ia64/ia64.c (ia64_flag_schedule_insns2): Drop.
	(ia64_flag_var_tracking): Drop.
	(TARGET_DELAY_SCHED2, TARGET_DELAY_VARTRACK): Define.
	(ia64_file_start): Don't save and override flag_var_tracking.
	(ia64_override_options_after_change): Ditto
	flag_schedule_insns_after_reload.
	(ia64_reorg): Test original variables.
	* config/picochip/picochip.c (picochip_flag_schedule_insns2): Drop.
	(picochip_flag_var_tracking): Drop.
	(TARGET_DELAY_SCHED2, TARGET_DELAY_VARTRACK): Define.
	(picochip_option_override): Don't save and override
	flag_schedule_insns_after_reload.
	(picochip_asm_file_start): Ditto flag_var_tracking.
	(picochip_reorg): Test original variables.
	* config/spu/spu.c (spu_flag_var_tracking): Drop.
	(TARGET_DELAY_VARTRACK): Define.
	(spu_var_tracking): New.
	(spu_machine_dependent_reorg): Call it.
	(asm_file_start): Don't save and override flag_var_tracking.

Index: gcc/target.def
===================================================================
--- gcc/target.def.orig	2011-05-30 03:53:29.000000000 -0300
+++ gcc/target.def	2011-05-31 17:50:09.733284971 -0300
@@ -2717,6 +2717,16 @@ DEFHOOKPOD
  in particular GDB does not use them.",
  bool, false)
 
+DEFHOOKPOD
+(delay_sched2, "True if sched2 is not to be run at its normal place.  \
+This usually means it will be run as part of machine-specific reorg.",
+bool, false)
+
+DEFHOOKPOD
+(delay_vartrack, "True if vartrack is not to be run at its normal place.  \
+This usually means it will be run as part of machine-specific reorg.",
+bool, false)
+
 /* Leave the boolean fields at the end.  */
 
 /* Close the 'struct gcc_target' definition.  */
Index: gcc/doc/tm.texi.in
===================================================================
--- gcc/doc/tm.texi.in.orig	2011-06-01 19:45:28.725386885 -0300
+++ gcc/doc/tm.texi.in	2011-06-01 19:46:20.062304033 -0300
@@ -9352,6 +9352,20 @@ tables, and hence is desirable if it wor
 @end defmac
 
 @hook TARGET_WANT_DEBUG_PUB_SECTIONS
+True if the @code{.debug_pubtypes} and @code{.debug_pubnames} sections
+should be emitted.  These sections are not used on most platforms, and
+in particular GDB does not use them.
+@end deftypevr
+
+@hook TARGET_DELAY_SCHED2
+True if sched2 is not to be run at its normal place.  This usually means
+it will be run as part of machine-specific reorg.
+@end deftypevr
+
+@hook TARGET_DELAY_VARTRACK
+True if vartrack is not to be run at its normal place.  This usually
+means it will be run as part of machine-specific reorg.
+@end deftypevr
 
 @defmac ASM_OUTPUT_DWARF_DELTA (@var{stream}, @var{size}, @var{label1}, @var{label2})
 A C statement to issue assembly directives that create a difference
Index: gcc/doc/tm.texi
===================================================================
--- gcc/doc/tm.texi.orig	2011-05-30 03:53:29.000000000 -0300
+++ gcc/doc/tm.texi	2011-05-31 17:52:19.841837811 -0300
@@ -9432,6 +9432,14 @@ tables, and hence is desirable if it wor
 True if the @code{.debug_pubtypes} and @code{.debug_pubnames} sections should be emitted.  These sections are not used on most platforms, and in particular GDB does not use them.
 @end deftypevr
 
+@deftypevr {Target Hook} bool TARGET_DELAY_SCHED2
+True if sched2 is not to be run at its normal place.  This usually means it will be run as part of machine-specific reorg.
+@end deftypevr
+
+@deftypevr {Target Hook} bool TARGET_DELAY_VARTRACK
+True if vartrack is not to be run at its normal place.  This usually means it will be run as part of machine-specific reorg.
+@end deftypevr
+
 @defmac ASM_OUTPUT_DWARF_DELTA (@var{stream}, @var{size}, @var{label1}, @var{label2})
 A C statement to issue assembly directives that create a difference
 @var{lab1} minus @var{lab2}, using an integer of the given @var{size}.
Index: gcc/sched-rgn.c
===================================================================
--- gcc/sched-rgn.c.orig	2011-04-06 00:24:12.000000000 -0300
+++ gcc/sched-rgn.c	2011-05-31 17:43:02.584808465 -0300
@@ -3508,7 +3508,7 @@ gate_handle_sched2 (void)
 {
 #ifdef INSN_SCHEDULING
   return optimize > 0 && flag_schedule_insns_after_reload
-    && dbg_cnt (sched2_func);
+    && !targetm.delay_sched2 && dbg_cnt (sched2_func);
 #else
   return 0;
 #endif
Index: gcc/var-tracking.c
===================================================================
--- gcc/var-tracking.c.orig	2011-05-31 13:23:24.000000000 -0300
+++ gcc/var-tracking.c	2011-06-01 17:09:56.545107558 -0300
@@ -9123,7 +9123,7 @@ variable_tracking_main (void)
 static bool
 gate_handle_var_tracking (void)
 {
-  return (flag_var_tracking);
+  return (flag_var_tracking && !targetm.delay_vartrack);
 }
 
 
Index: gcc/config/bfin/bfin.c
===================================================================
--- gcc/config/bfin/bfin.c.orig	2011-05-31 12:51:54.361391409 -0300
+++ gcc/config/bfin/bfin.c	2011-05-31 17:57:54.264722118 -0300
@@ -86,14 +86,6 @@ const char *byte_reg_names[]   =  BYTE_R
 static int arg_regs[] = FUNCTION_ARG_REGISTERS;
 static int ret_regs[] = FUNCTION_RETURN_REGISTERS;
 
-/* Nonzero if -fschedule-insns2 was given.  We override it and
-   call the scheduler ourselves during reorg.  */
-static int bfin_flag_schedule_insns2;
-
-/* Determines whether we run variable tracking in machine dependent
-   reorganization.  */
-static int bfin_flag_var_tracking;
-
 struct bfin_cpu
 {
   const char *name;
@@ -375,13 +367,6 @@ output_file_start (void) 
   FILE *file = asm_out_file;
   int i;
 
-  /* Variable tracking should be run after all optimizations which change order
-     of insns.  It also needs a valid CFG.  This can't be done in
-     bfin_option_override, because flag_var_tracking is finalized after
-     that.  */
-  bfin_flag_var_tracking = flag_var_tracking;
-  flag_var_tracking = 0;
-
   fprintf (file, ".file \"%s\";\n", input_filename);
   
   for (i = 0; arg_regs[i] >= 0; i++)
@@ -2772,11 +2757,6 @@ bfin_option_override (void)
 
   flag_schedule_insns = 0;
 
-  /* Passes after sched2 can break the helpful TImode annotations that
-     haifa-sched puts on every insn.  Just do scheduling in reorg.  */
-  bfin_flag_schedule_insns2 = flag_schedule_insns_after_reload;
-  flag_schedule_insns_after_reload = 0;
-
   init_machine_status = bfin_init_machine_status;
 }
 
@@ -5550,7 +5530,7 @@ bfin_reorg (void)
      with old MDEP_REORGS that are not CFG based.  Recompute it now.  */
   compute_bb_for_insn ();
 
-  if (bfin_flag_schedule_insns2)
+  if (flag_schedule_insns_after_reload)
     {
       splitting_for_sched = 1;
       split_all_insns ();
@@ -5579,7 +5559,7 @@ bfin_reorg (void)
 
   workaround_speculation ();
 
-  if (bfin_flag_var_tracking)
+  if (flag_var_tracking)
     {
       timevar_push (TV_VAR_TRACKING);
       variable_tracking_main ();
@@ -6765,4 +6745,14 @@ bfin_conditional_register_usage (void)
 #undef TARGET_EXTRA_LIVE_ON_ENTRY
 #define TARGET_EXTRA_LIVE_ON_ENTRY bfin_extra_live_on_entry
 
+/* Passes after sched2 can break the helpful TImode annotations that
+   haifa-sched puts on every insn.  Just do scheduling in reorg.  */
+#undef TARGET_DELAY_SCHED2
+#define TARGET_DELAY_SCHED2 true
+
+/* Variable tracking should be run after all optimizations which
+   change order of insns.  It also needs a valid CFG.  */
+#undef TARGET_DELAY_VARTRACK
+#define TARGET_DELAY_VARTRACK true
+
 struct gcc_target targetm = TARGET_INITIALIZER;
Index: gcc/config/ia64/ia64.c
===================================================================
--- gcc/config/ia64/ia64.c.orig	2011-05-31 12:51:54.370391376 -0300
+++ gcc/config/ia64/ia64.c	2011-05-31 17:55:56.311110254 -0300
@@ -103,14 +103,6 @@ static const char * const ia64_local_reg
 static const char * const ia64_output_reg_names[8] =
 { "out0", "out1", "out2", "out3", "out4", "out5", "out6", "out7" };
 
-/* Determines whether we run our final scheduling pass or not.  We always
-   avoid the normal second scheduling pass.  */
-static int ia64_flag_schedule_insns2;
-
-/* Determines whether we run variable tracking in machine dependent
-   reorganization.  */
-static int ia64_flag_var_tracking;
-
 /* Variables which are this size or smaller are put in the sdata/sbss
    sections.  */
 
@@ -640,6 +632,14 @@ static const struct default_options ia64
 #undef TARGET_PREFERRED_RELOAD_CLASS
 #define TARGET_PREFERRED_RELOAD_CLASS ia64_preferred_reload_class
 
+#undef TARGET_DELAY_SCHED2
+#define TARGET_DELAY_SCHED2 true
+
+/* Variable tracking should be run after all optimizations which
+   change order of insns.  It also needs a valid CFG.  */
+#undef TARGET_DELAY_VARTRACK
+#define TARGET_DELAY_VARTRACK true
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 typedef enum
@@ -2390,13 +2390,6 @@ ia64_expand_atomic_op (enum rtx_code cod
 static void
 ia64_file_start (void)
 {
-  /* Variable tracking should be run after all optimizations which change order
-     of insns.  It also needs a valid CFG.  This can't be done in
-     ia64_option_override, because flag_var_tracking is finalized after
-     that.  */
-  ia64_flag_var_tracking = flag_var_tracking;
-  flag_var_tracking = 0;
-
   default_file_start ();
   emit_safe_across_calls ();
 }
@@ -5727,9 +5720,6 @@ ia64_option_override (void)
 static void
 ia64_override_options_after_change (void)
 {
-  ia64_flag_schedule_insns2 = flag_schedule_insns_after_reload;
-  flag_schedule_insns_after_reload = 0;
-
   if (optimize >= 3
       && !global_options_set.x_flag_selective_scheduling
       && !global_options_set.x_flag_selective_scheduling2)
@@ -9401,7 +9391,7 @@ ia64_reorg (void)
   if (optimize == 0)
     split_all_insns ();
 
-  if (optimize && ia64_flag_schedule_insns2
+  if (optimize && flag_schedule_insns_after_reload
       && dbg_cnt (ia64_sched2))
     {
       timevar_push (TV_SCHED2);
@@ -9531,7 +9521,7 @@ ia64_reorg (void)
 
   emit_predicate_relation_info ();
 
-  if (ia64_flag_var_tracking)
+  if (flag_var_tracking)
     {
       timevar_push (TV_VAR_TRACKING);
       variable_tracking_main ();
Index: gcc/config/picochip/picochip.c
===================================================================
--- gcc/config/picochip/picochip.c.orig	2011-05-31 12:51:54.375391358 -0300
+++ gcc/config/picochip/picochip.c	2011-05-31 18:18:19.213997260 -0300
@@ -149,13 +149,6 @@ const char *picochip_regnames[] = REGIST
 
 /* Target scheduling information. */
 
-/* Determine whether we run our final scheduling pass or not.  We always
-   avoid the normal second scheduling pass.  */
-int picochip_flag_schedule_insns2;
-
-/* Check if variable tracking needs to be run. */
-int picochip_flag_var_tracking;
-
 /* This flag indicates whether the next instruction to be output is a
    VLIW continuation instruction.  It is used to communicate between
    final_prescan_insn and asm_output_opcode. */
@@ -343,6 +336,17 @@ static const struct default_options pico
 #undef TARGET_EXCEPT_UNWIND_INFO
 #define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info
 
+/* The 2nd scheduling pass option is switched off, and a machine
+   dependent reorganisation ensures that it is run later on, after the
+   second jump optimisation.  */
+#undef TARGET_DELAY_SCHED2
+#define TARGET_DELAY_SCHED2 true
+
+/* Variable tracking should be run after all optimizations which
+   change order of insns.  It also needs a valid CFG.  */
+#undef TARGET_DELAY_VARTRACK
+#define TARGET_DELAY_VARTRACK true
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 
@@ -356,10 +360,7 @@ picochip_return_in_memory(const_tree typ
   return ((unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 4);
 }
 
-/* Allow some options to be overriden.  In particular, the 2nd
-   scheduling pass option is switched off, and a machine dependent
-   reorganisation ensures that it is run later on, after the second
-   jump optimisation. */
+/* Allow some options to be overriden. */
 
 static void
 picochip_option_override (void)
@@ -396,18 +397,16 @@ picochip_option_override (void)
   if (optimize >= 1)
     flag_section_anchors = 1;
 
-  /* Turn off the second scheduling pass, and move it to
-     picochip_reorg, to avoid having the second jump optimisation
-     trash the instruction modes (e.g., instructions are changed to
-     TImode to mark the beginning of cycles). Two types of DFA
-     scheduling are possible: space and speed. In both cases,
-     instructions are reordered to avoid stalls (e.g., memory loads
-     stall for one cycle). Speed scheduling will also enable VLIW
-     instruction packing. VLIW instructions use more code space, so
-     VLIW scheduling is disabled when scheduling for size. */
-  picochip_flag_schedule_insns2 = flag_schedule_insns_after_reload;
-  flag_schedule_insns_after_reload = 0;
-  if (picochip_flag_schedule_insns2)
+  /* The second scheduling pass runs within picochip_reorg, to avoid
+     having the second jump optimisation trash the instruction modes
+     (e.g., instructions are changed to TImode to mark the beginning
+     of cycles).  Two types of DFA scheduling are possible: space and
+     speed.  In both cases, instructions are reordered to avoid stalls
+     (e.g., memory loads stall for one cycle).  Speed scheduling will
+     also enable VLIW instruction packing.  VLIW instructions use more
+     code space, so VLIW scheduling is disabled when scheduling for
+     size.  */
+  if (flag_schedule_insns_after_reload)
     {
       if (optimize_size)
 	picochip_schedule_type = DFA_TYPE_SPACE;
@@ -461,7 +460,6 @@ picochip_option_override (void)
 	error ("invalid mul type specified (%s) - expected mac, mul or none",
 	       picochip_mul_type_string);
     }
-
 }
 
 
@@ -1813,13 +1811,6 @@ picochip_asm_file_start (void)
     fprintf (asm_out_file, "// Has multiply: Yes (Mac unit)\n");
   else
     fprintf (asm_out_file, "// Has multiply: No\n");
-
-  /* Variable tracking should be run after all optimizations which change order
-     of insns.  It also needs a valid CFG.  This can't be done in
-     picochip_option_override, because flag_var_tracking is finalized after
-     that.  */
-  picochip_flag_var_tracking = flag_var_tracking;
-  flag_var_tracking = 0;
 }
 
 /* Output the end of an ASM file. */
@@ -3376,15 +3367,16 @@ picochip_reorg (void)
 	  delete_insn (prologue_end_note);
 	}
     }
-  if (picochip_flag_var_tracking)
-  {
-    timevar_push (TV_VAR_TRACKING);
-    variable_tracking_main ();
-    /* We also have to deal with variable tracking notes in the middle 
-       of VLIW packets. */
-    reorder_var_tracking_notes();
-    timevar_pop (TV_VAR_TRACKING);
-  }
+
+  if (flag_var_tracking)
+    {
+      timevar_push (TV_VAR_TRACKING);
+      variable_tracking_main ();
+      /* We also have to deal with variable tracking notes in the
+	 middle of VLIW packets. */
+      reorder_var_tracking_notes();
+      timevar_pop (TV_VAR_TRACKING);
+    }
 }
 
 /* Return the ALU character identifier for the current
Index: gcc/config/spu/spu.c
===================================================================
--- gcc/config/spu/spu.c.orig	2011-05-31 12:51:54.386391317 -0300
+++ gcc/config/spu/spu.c	2011-05-31 18:21:34.700448399 -0300
@@ -248,10 +248,6 @@ int spu_tune;
    inserted in pairs, so we round down. */
 int spu_hint_dist = (8*4) - (2*4);
 
-/* Determines whether we run variable tracking in machine dependent
-   reorganization.  */
-static int spu_flag_var_tracking;
-
 enum spu_immediate {
   SPU_NONE,
   SPU_IL,
@@ -509,6 +505,11 @@ static const struct attribute_spec spu_a
 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
 
+/* Variable tracking should be run after all optimizations which
+   change order of insns.  It also needs a valid CFG.  */
+#undef TARGET_DELAY_VARTRACK
+#define TARGET_DELAY_VARTRACK true
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 static void
@@ -2696,6 +2697,19 @@ insert_hbrp (void)
 
 static int in_spu_reorg;
 
+static void
+spu_var_tracking (void)
+{
+  if (flag_var_tracking)
+    {
+      df_analyze ();
+      timevar_push (TV_VAR_TRACKING);
+      variable_tracking_main ();
+      timevar_pop (TV_VAR_TRACKING);
+      df_finish_pass (false);
+    }
+}
+
 /* Insert branch hints.  There are no branch optimizations after this
    pass, so it's safe to set our branch hints now. */
 static void
@@ -2715,6 +2729,7 @@ spu_machine_dependent_reorg (void)
          function might have hinted a call or return. */
       insert_hbrp ();
       pad_bb ();
+      spu_var_tracking ();
       return;
     }
 
@@ -2921,14 +2936,7 @@ spu_machine_dependent_reorg (void)
 	  XVECEXP (unspec, 0, 0) = plus_constant (label_ref, offset);
       }
 
-  if (spu_flag_var_tracking)
-    {
-      df_analyze ();
-      timevar_push (TV_VAR_TRACKING);
-      variable_tracking_main ();
-      timevar_pop (TV_VAR_TRACKING);
-      df_finish_pass (false);
-    }
+  spu_var_tracking ();
 
   free_bb_for_insn ();
 
@@ -7057,19 +7065,6 @@ spu_libgcc_shift_count_mode (void)
 static void
 asm_file_start (void)
 {
-  /* Variable tracking should be run after all optimizations which
-     change order of insns.  It also needs a valid CFG.  Therefore,
-     *if* we make nontrivial changes in machine-dependent reorg,
-     run variable tracking after those.  However, if we do not run
-     our machine-dependent reorg pass, we must still run the normal
-     variable tracking pass (or else we will ICE in final since
-     debug insns have not been removed).  */
-  if (TARGET_BRANCH_HINTS && optimize)
-    {
-      spu_flag_var_tracking = flag_var_tracking;
-      flag_var_tracking = 0;
-    }
-
   default_file_start ();
 }
 
