public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Paolo Bonzini <paolo.bonzini@lu.unisi.ch>
To: Richard Guenther <richard.guenther@gmail.com>,
	  GCC Patches <gcc-patches@gcc.gnu.org>
Subject: Re: PR/32004, tree-ssa caused in/out asm constraints to often need  reloads
Date: Thu, 05 Jul 2007 11:48:00 -0000	[thread overview]
Message-ID: <468CD1FD.4000605@lu.unisi.ch> (raw)
In-Reply-To: <84fc9c000707050401h46157b0fye4b32c3e6b1c8063@mail.gmail.com>

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

Richard Guenther wrote:
> On 7/5/07, Paolo Bonzini <paolo.bonzini@lu.unisi.ch> wrote:
>> The cause and solution of the problem are well explained in the PR trail
>> and in the comments to the code.
>>
>> Bootstrapped/regtested i686-pc-linux-gnu with no new failure and fixing
>> pr21291.c, ok for 4.2/4.3?
> 
> -ENOPATCH

diffstat < /Users/bonzinip/cvs/pr32004.patch
  5 files changed, 140 insertions(+)

Note no deletions. This is 100% a new feature :-)

Paolo

[-- Attachment #2: pr32004.patch --]
[-- Type: text/plain, Size: 7252 bytes --]

2007-07-04  Paolo Bonzini  <bonzini@gnu.org>

	* function.c (match_asm_constraints_1, rest_of_match_asm_constraints,
	pass_match_asm_constraints): New.
	* passes.c (init_optimization_passes): Add new pass.
	* stmt.c (expand_asm_operands): Set cfun->has_asm_statement.
	* function.h (struct function): Add has_asm_statement bit.
	(current_function_has_asm_statement): New.
	* tree-pass.h (pass_match_asm_constraints): New.

Index: function.c
===================================================================
--- function.c	(revision 126190)
+++ function.c	(working copy)
@@ -5504,6 +5504,139 @@ struct tree_opt_pass pass_thread_prologu
   TODO_ggc_collect,                     /* todo_flags_finish */
   'w'                                   /* letter */
 };
+\f
+
+/* This mini-pass fixes fall-out from SSA in asm statements that have
+   in-out constraints.  Say you start with 
+
+     orig = inout;
+     asm ("": "+mr" (inout));
+     use (orig);
+
+   which is transformed very early to use explicit output and match operands:
+
+     orig = inout;
+     asm ("": "=mr" (inout) : "0" (inout));
+     use (orig);
+
+   Or, after SSA and copyprop,
+
+     asm ("": "=mr" (inout_2) : "0" (inout_1));
+     use (inout_1);
+
+   Clearly inout_2 and inout_1 can't be coalesced easily anymore, as
+   they represent two separate values, so they will get different pseudo
+   registers during expansion.  Then, since the two operands need to match
+   per the constraints, but use different pseudo registers, reload can
+   only register a reload for these operands.  But reloads can only be
+   satisfied by hardregs, not by memory, so we need a register for this
+   reload, just because we are presented with non-matching operands.
+   So, even though we allow memory for this operand, no memory can be
+   used for it, just because the two operands don't match.  This can
+   cause reload failures on register-starved targets.
+
+   So it's a symptom of reload not being able to use memory for reloads
+   or, alternatively it's also a symptom of both operands not coming into
+   reload as matching (in which case the pseudo could go to memory just
+   fine, as the alternative allows it, and no reload would be necessary).
+   We fix the latter problem here, by transforming
+
+     asm ("": "=mr" (inout_2) : "0" (inout_1));
+
+   back to
+
+     inout_2 = inout_1;
+     asm ("": "=mr" (inout_2) : "0" (inout_2));  */
+
+static void
+match_asm_constraints_1 (rtx insn, rtx *sets, int noutputs)
+{
+  int i;
+  bool changed = false;
+  rtx op = SET_SRC (sets[0]);
+  int ninputs = ASM_OPERANDS_INPUT_LENGTH (op);
+  rtvec inputs = ASM_OPERANDS_INPUT_VEC (op);
+
+  for (i = 0; i < ninputs; i++)
+    {
+      rtx input, output, insns;
+      const char *constraint = ASM_OPERANDS_INPUT_CONSTRAINT (op, i);
+      char *end;
+      int match;
+
+      match = strtoul (constraint, &end, 10);
+      if (end == constraint)
+	continue;
+
+      gcc_assert (match < noutputs);
+      output = SET_DEST (sets[match]);
+      input = RTVEC_ELT (inputs, i);
+      if (rtx_equal_p (output, input))
+	continue;
+
+      start_sequence ();
+      emit_move_insn (output, input);
+      RTVEC_ELT (inputs, i) = copy_rtx (output);
+      insns = get_insns ();
+      end_sequence ();
+
+      emit_insn_before (insns, insn);
+      changed = true;
+    }
+
+  if (changed)
+    df_insn_rescan (insn);
+}
+
+static unsigned
+rest_of_match_asm_constraints (void)
+{
+  basic_block bb;
+  rtx insn, pat;
+
+  if (!cfun->has_asm_statement)
+    return 0;
+
+  df_set_flags (DF_DEFER_INSN_RESCAN);
+  FOR_EACH_BB (bb)
+    {
+      FOR_BB_INSNS (bb, insn)
+	{
+	  if (!INSN_P (insn))
+	    continue;
+
+	  pat = PATTERN (insn);
+	  if (GET_CODE (pat) == PARALLEL
+	      && GET_CODE (XVECEXP (pat, 0, 0)) == SET
+	      && GET_CODE (SET_SRC (XVECEXP (pat, 0, 0))) == ASM_OPERANDS)
+	    match_asm_constraints_1 (insn,
+				     &XVECEXP (pat, 0, 0), XVECLEN (pat, 0));
+
+	  else if (GET_CODE (pat) == SET
+	           && GET_CODE (SET_SRC (pat)) == ASM_OPERANDS)
+	    match_asm_constraints_1 (insn, &pat, 1);
+	 }
+    }
+
+  return TODO_df_finish;
+}
+
+struct tree_opt_pass pass_match_asm_constraints =
+{
+  "asmcons",				/* name */
+  NULL,					/* gate */
+  rest_of_match_asm_constraints,	/* execute */
+  NULL,                                 /* sub */
+  NULL,                                 /* next */
+  0,                                    /* static_pass_number */
+  0,					/* tv_id */
+  0,                                    /* properties_required */
+  0,                                    /* properties_provided */
+  0,                                    /* properties_destroyed */
+  0,					/* todo_flags_start */
+  TODO_dump_func,                       /* todo_flags_finish */
+  0                                     /* letter */
+};
 
 
 #include "gt-function.h"
Index: passes.c
===================================================================
--- passes.c	(revision 126190)
+++ passes.c	(working copy)
@@ -740,6 +740,7 @@ init_optimization_passes (void)
       NEXT_PASS (pass_stack_ptr_mod);
       NEXT_PASS (pass_mode_switching);
       NEXT_PASS (pass_see);
+      NEXT_PASS (pass_match_asm_constraints);
       NEXT_PASS (pass_sms);
       NEXT_PASS (pass_sched);
       NEXT_PASS (pass_subregs_of_mode_init);
Index: stmt.c
===================================================================
--- stmt.c	(revision 126190)
+++ stmt.c	(working copy)
@@ -1078,6 +1078,7 @@ expand_asm_operands (tree string, tree o
     if (real_output_rtx[i])
       emit_move_insn (real_output_rtx[i], output_rtx[i]);
 
+  cfun->has_asm_statement = 1;
   free_temp_slots ();
 }
 
Index: function.h
===================================================================
--- function.h	(revision 126190)
+++ function.h	(working copy)
@@ -414,6 +414,9 @@ struct function GTY(())
   /* Nonzero if function being compiled has nonlocal gotos to parent
      function.  */
   unsigned int has_nonlocal_goto : 1;
+  
+  /* Nonzero if function being compiled has an asm statement.  */
+  unsigned int has_asm_statement : 1;
 
   /* Nonzero if the current function is a thunk, i.e., a lightweight
      function implemented by the output_mi_thunk hook) that just
@@ -517,6 +520,7 @@ extern int trampolines_created;
 #define current_function_has_nonlocal_label (cfun->has_nonlocal_label)
 #define current_function_calls_unwind_init (cfun->calls_unwind_init)
 #define current_function_has_nonlocal_goto (cfun->has_nonlocal_goto)
+#define current_function_has_asm_statement (cfun->has_asm_statement)
 
 #define return_label (cfun->x_return_label)
 #define naked_return_label (cfun->x_naked_return_label)
Index: tree-pass.h
===================================================================
--- tree-pass.h	(revision 126190)
+++ tree-pass.h	(working copy)
@@ -390,6 +390,7 @@ extern struct tree_opt_pass pass_initial
 extern struct tree_opt_pass pass_combine;
 extern struct tree_opt_pass pass_if_after_combine;
 extern struct tree_opt_pass pass_partition_blocks;
+extern struct tree_opt_pass pass_match_asm_constraints;
 extern struct tree_opt_pass pass_regmove;
 extern struct tree_opt_pass pass_split_all_insns;
 extern struct tree_opt_pass pass_lower_subreg2;

  parent reply	other threads:[~2007-07-05 11:12 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-07-05 10:54 Paolo Bonzini
     [not found] ` <84fc9c000707050401h46157b0fye4b32c3e6b1c8063@mail.gmail.com>
2007-07-05 11:48   ` Paolo Bonzini [this message]
2007-07-05 18:34 ` Mark Mitchell
2007-07-05 19:39   ` Paolo Bonzini
2007-07-05 20:24     ` Mark Mitchell
2007-07-05 20:15   ` Paolo Bonzini
2007-07-07 16:29 ` Eric Botcazou
2007-07-07 18:24   ` Andrew Pinski
2007-07-07 18:30     ` Eric Botcazou
2007-07-09  2:23       ` Paolo Bonzini
2007-07-09  6:52         ` Eric Botcazou
2007-07-09 12:09           ` Paolo Bonzini
2007-07-09 12:32           ` Paolo Bonzini
2007-07-09 12:40             ` Richard Guenther
2007-07-09 13:01             ` Eric Botcazou
2007-07-09 13:01               ` Richard Guenther
2007-07-09 13:36                 ` Eric Botcazou
2007-07-09 13:12               ` Paolo Bonzini
2007-07-09 13:23                 ` Andrew Pinski
2007-07-09 13:45                   ` Eric Botcazou
2007-07-09 15:33                   ` Paolo Bonzini
2007-07-09 17:25                     ` Eric Botcazou
2007-07-09 14:00                 ` Eric Botcazou
2007-07-13  9:48       ` Paolo Bonzini
2007-07-13 13:42         ` Eric Botcazou

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=468CD1FD.4000605@lu.unisi.ch \
    --to=paolo.bonzini@lu.unisi.ch \
    --cc=bonzini@gnu.org \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=richard.guenther@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).