public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Emit more REG_EQUIV notes for function args (PR42235)
@ 2010-07-14 11:14 Bernd Schmidt
  2010-07-14 18:54 ` Jeff Law
  0 siblings, 1 reply; 15+ messages in thread
From: Bernd Schmidt @ 2010-07-14 11:14 UTC (permalink / raw)
  To: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 980 bytes --]

When moving arguments into pseudos, we are being very careful not to
emit any instructions that could possibly clobber other argument
registers.  Currently, we generate unnecessarily complicated sequences
of code for simple zero or sign extensions.

With this patch, we check can_extend_p and the necessary predicates to
see if an extend insn is available for the conversion we have to do.  If
so, we emit the insn directly, and create a REG_EQUIV note of the form
(sign_extend (mem)).  Reload can't really do anything with these yet,
but there's an optimization in the register allocator to move argument
loads directly before their use if there's only one use.  On Thumb-2
this happens already, we seem to generate better code than before.
Unfortunately Thumb-1, which the PR is about, has some other problems
which I'll try to fix later.

Bootstrapped and regression tested on i686-linux.  Also regression
tested on arm-linux, with my three usual sets of options.  Ok?


Bernd

[-- Attachment #2: more-equiv-notes.diff --]
[-- Type: text/plain, Size: 3323 bytes --]

	PR target/42235
	* function.c (assign_parm_setup_reg): When an optab for extending
	exists, emit the insn directly and create a REG_EQUIV note.

Index: function.c
===================================================================
--- function.c	(revision 162146)
+++ function.c	(working copy)
@@ -2861,10 +2861,12 @@ static void
 assign_parm_setup_reg (struct assign_parm_data_all *all, tree parm,
 		       struct assign_parm_data_one *data)
 {
-  rtx parmreg;
+  rtx parmreg, validated_mem;
+  rtx equiv_stack_parm;
   enum machine_mode promoted_nominal_mode;
   int unsignedp = TYPE_UNSIGNED (TREE_TYPE (parm));
   bool did_conversion = false;
+  bool need_conversion, moved;
 
   /* Store the parm in a pseudoregister during the function, but we may
      need to do it in a wider mode.  Using 2 here makes the result
@@ -2891,10 +2893,46 @@ assign_parm_setup_reg (struct assign_par
 
   assign_parm_remove_parallels (data);
 
+  equiv_stack_parm = data->stack_parm;
+  validated_mem = validize_mem (data->entry_parm);
+
+  need_conversion = (data->nominal_mode != data->passed_mode
+		     || promoted_nominal_mode != data->promoted_mode);
+  moved = false;
+
   /* Copy the value into the register, thus bridging between
      assign_parm_find_data_types and expand_expr_real_1.  */
-  if (data->nominal_mode != data->passed_mode
-      || promoted_nominal_mode != data->promoted_mode)
+  if (need_conversion)
+    {
+      enum insn_code icode;
+      rtx op0, op1;
+
+      icode = can_extend_p (promoted_nominal_mode, data->passed_mode,
+			    unsignedp);
+
+      op0 = parmreg;
+      op1 = validated_mem;
+      if (icode != CODE_FOR_nothing
+	  && insn_data[icode].operand[0].predicate (op0, promoted_nominal_mode)
+	  && insn_data[icode].operand[1].predicate (op1, data->passed_mode))
+	{
+	  enum rtx_code code = unsignedp ? ZERO_EXTEND : SIGN_EXTEND;
+	  rtx insn;
+
+	  insn = gen_extend_insn (op0, op1, promoted_nominal_mode,
+				  data->passed_mode, unsignedp);
+	  emit_insn (insn);
+
+	  equiv_stack_parm = gen_rtx_fmt_e (code, GET_MODE (parmreg),
+					    equiv_stack_parm);
+	  moved = true;
+	}
+    }
+
+  if (moved)
+    /* Nothing to do.  */
+    ;
+  else if (need_conversion)
     {
       int save_tree_used;
 
@@ -2919,7 +2957,7 @@ assign_parm_setup_reg (struct assign_par
 
       rtx tempreg = gen_reg_rtx (GET_MODE (data->entry_parm));
 
-      emit_move_insn (tempreg, validize_mem (data->entry_parm));
+      emit_move_insn (tempreg, validated_mem);
 
       push_to_sequence2 (all->first_conversion_insn, all->last_conversion_insn);
       tempreg = convert_to_mode (data->nominal_mode, tempreg, unsignedp);
@@ -2949,7 +2987,7 @@ assign_parm_setup_reg (struct assign_par
       did_conversion = true;
     }
   else
-    emit_move_insn (parmreg, validize_mem (data->entry_parm));
+    emit_move_insn (parmreg, validated_mem);
 
   /* If we were passed a pointer but the actual value can safely live
      in a register, put it in one.  */
@@ -3034,7 +3072,7 @@ assign_parm_setup_reg (struct assign_par
 	}
       else if ((set = single_set (linsn)) != 0
 	       && SET_DEST (set) == parmreg)
-	set_unique_reg_note (linsn, REG_EQUIV, data->stack_parm);
+	set_unique_reg_note (linsn, REG_EQUIV, equiv_stack_parm);
     }
 
   /* For pointer data type, suggest pointer register.  */

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2010-07-21 22:53 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-07-14 11:14 Emit more REG_EQUIV notes for function args (PR42235) Bernd Schmidt
2010-07-14 18:54 ` Jeff Law
2010-07-14 21:30   ` Bernd Schmidt
2010-07-14 22:28     ` Jeff Law
2010-07-15 17:14       ` Bernd Schmidt
2010-07-15 21:26         ` Jeff Law
2010-07-19  9:55         ` Bernd Schmidt
2010-07-19 16:51           ` Jeff Law
2010-07-19 16:53             ` Bernd Schmidt
2010-07-19 16:59               ` Richard Henderson
2010-07-19 17:09               ` Jeff Law
2010-07-19 19:06               ` John David Anglin
2010-07-21 22:53             ` Bernd Schmidt
2010-07-14 21:48   ` Bernd Schmidt
2010-07-14 22:22     ` Jeff Law

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).