[committed] Restrict creation of MIPS16 gp pseudo reg

Message ID 8739r48agv.fsf@firetop.home
State New
Headers show

Commit Message

Richard Sandiford Nov. 14, 2010, 10:29 a.m.
This patch fixes three gcc.c-torture/execute tests (931110-1.c,
memcpy-bi.c and pr43220.c) that were failing with -mabi=32/-mips16
on mips64-linux-gnu.  The problem was that rtl optimisation passes
were calling the move expanders with expressions taken from REG_EQUAL
notes, and on MIPS16, those expanders were introducing new uses of
the GP pseudo register.  The moves were then being inserted before
the initialisation of that pseudo register.

This GP pseudo has always been a bit of a hack.  Perhaps we should have
some generic code that targets like MIPS and ARM can call to handle
this sort of thing.  In the meantime though, MIPS really shouldn't
be introducing new uses of the pseudo once it has lost control of the
definition.  The only "safe" time is during expand.

At some point we should probably also switch MIPS over to using
insert_insn_on_edge, like ARM.

Tested on mips64-linux-gnu and applied.


	* config/mips/mips.c (machine_function): Remove
	(mips16_gp_pseudo_reg): Use cfun->machine->mips16_gp_pseudo_rtx to
	detect whether a pseudo has already been created.  Unconditionally
	create a new one if not.
	(mips_pic_base_register): Only call mips16_gp_pseudo_reg when
	expanding to rtl.  Create a new pseudo otherwise, if allowed.


Index: gcc/config/mips/mips.c
--- gcc/config/mips/mips.c	2010-11-13 17:22:18.000000000 +0000
+++ gcc/config/mips/mips.c	2010-11-13 17:24:03.000000000 +0000
@@ -374,10 +374,6 @@  struct GTY(())  machine_function {
      split_insns pass; see mips_must_initialize_gp_p () for details.  */
   bool must_restore_gp_when_clobbered_p;
-  /* True if we have emitted an instruction to initialize
-     mips16_gp_pseudo_rtx.  */
-  bool initialized_mips16_gp_pseudo_p;
   /* True if this is an interrupt handler.  */
   bool interrupt_handler_p;
@@ -2654,16 +2650,11 @@  gen_load_const_gp (rtx reg)
 mips16_gp_pseudo_reg (void)
   if (cfun->machine->mips16_gp_pseudo_rtx == NULL_RTX)
-    cfun->machine->mips16_gp_pseudo_rtx = gen_reg_rtx (Pmode);
-  /* Don't emit an instruction to initialize the pseudo register if
-     we are being called from the tree optimizers' cost-calculation
-     routines.  */
-  if (!cfun->machine->initialized_mips16_gp_pseudo_p
-      && (current_ir_type () != IR_GIMPLE || currently_expanding_to_rtl))
       rtx insn, scan;
+      cfun->machine->mips16_gp_pseudo_rtx = gen_reg_rtx (Pmode);
       push_topmost_sequence ();
       scan = get_insns ();
@@ -2674,8 +2665,6 @@  mips16_gp_pseudo_reg (void)
       emit_insn_after (insn, scan);
       pop_topmost_sequence ();
-      cfun->machine->initialized_mips16_gp_pseudo_p = true;
   return cfun->machine->mips16_gp_pseudo_rtx;
@@ -2690,9 +2679,12 @@  mips_pic_base_register (rtx temp)
   if (!TARGET_MIPS16)
     return pic_offset_table_rtx;
-  if (can_create_pseudo_p ())
+  if (currently_expanding_to_rtl)
     return mips16_gp_pseudo_reg ();
+  if (can_create_pseudo_p ())
+    temp = gen_reg_rtx (Pmode);
     /* The first post-reload split exposes all references to $gp
        (both uses and definitions).  All references must remain