public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: "Christopher Matthews" <chrismatthews@google.com>
To: Diego <dnovillo@google.com>, "Aldy Hernandez" <aldyh@redhat.com>,
	        gcc-patches@gcc.gnu.org
Subject: [tuples] adding gimple_asm
Date: Fri, 03 Aug 2007 04:06:00 -0000	[thread overview]
Message-ID: <5794c4c80708022105w68072b23scdd10346e194d8ec@mail.gmail.com> (raw)

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

This patch adds support to the gimplifier for asm statements.

    * gimplify.c (gimplify_asm_expr): Created new gimple tuple.
    * gimple-pretty-printer.c (dump_gimple_asm): Added function to dump a
    GIMPLE_ASM statement.
    (dump_gimple_stmt): Updated to use the dump_gimple_asm function.
    * gimple.c (gss_for_code): Made asm statements return as with_mem_ops.
    (build_gimple_with_ops): Asm statements are added as a specal case for
    allocation because they have extra fields that are not allocated correctly
    in the current generic op allocator.
    (build_gimple_asm_1): Added a helper function to setup the basics of a
    GIMPLE_ASM tuple.
    (build_gimple_asm_vec): Create a GIMPLE_ASM tuple from vector arguments.
    (build_gimple_asm): Changed to call the new helper function.

[-- Attachment #2: gimple_asm.diff --]
[-- Type: text/x-patch, Size: 10687 bytes --]

Index: gcc/testsuite/gcc.dg/gimple/gimple_asm1.c
===================================================================
--- gcc/testsuite/gcc.dg/gimple/gimple_asm1.c	(revision 0)
+++ gcc/testsuite/gcc.dg/gimple/gimple_asm1.c	(revision 0)
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+
+/* Test GIMPLE_ASSIGN.  */
+
+void asm1()
+{
+  int a=10, b;
+  asm ("movl %1, %%eax; "
+        "movl %%eax, %0;"
+        :"=r"(b)        /* output */
+        :"r"(a)         /* input */
+        :"%eax"         /* clobbered register */
+ );
+}
+/* { dg-final { scan-tree-dump-times "asm \{" 1 "gimple"} } */
+/* { dg-final { scan-tree-dump-times "movl %1, %%eax; movl %%eax, %0;" 1 "gimple"} } */
+/* { dg-final { scan-tree-dump-times ":b" 1 "gimple"} } */
+/* { dg-final { scan-tree-dump-times ":a" 1 "gimple"} } */
+/* { dg-final { scan-tree-dump-times ":\\\"%eax\\\"" 1 "gimple"} } */
+
Index: gcc/testsuite/gcc.dg/gimple/gimple_asm2.c
===================================================================
--- gcc/testsuite/gcc.dg/gimple/gimple_asm2.c	(revision 0)
+++ gcc/testsuite/gcc.dg/gimple/gimple_asm2.c	(revision 0)
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+
+/* Test GIMPLE_ASSIGN.  */
+
+void asm2()
+{
+  int a=10, b;
+  asm ("movl %1, %%eax; "
+        "movl %%eax, %0;"
+        :               /* output */
+        :               /* input */
+        :"%eax"         /* clobbered register */
+ );
+}
+/* { dg-final { scan-tree-dump-times "asm \{" 1 "gimple"} } */
+/* { dg-final { scan-tree-dump-times "movl %1, %%eax; movl %%eax, %0;" 1 "gimple"} } */
+/* { dg-final { scan-tree-dump-times ":\\\"%eax\\\"" 1 "gimple"} } */
Index: gcc/testsuite/gcc.dg/gimple/gimple_asm.c
===================================================================
--- gcc/testsuite/gcc.dg/gimple/gimple_asm.c	(revision 0)
+++ gcc/testsuite/gcc.dg/gimple/gimple_asm.c	(revision 0)
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+
+/* Test GIMPLE_ASSIGN.  */
+
+void asm0()
+{
+  asm("movl %ecx %eax"); 
+}
+/* { dg-final { scan-tree-dump-times "asm \{" 1 "gimple"} } */
+/* { dg-final { scan-tree-dump-times "movl %ecx %eax" 1 "gimple"} } */
+  
+  
Index: gcc/gimple-pretty-print.c
===================================================================
--- gcc/gimple-pretty-print.c	(revision 127164)
+++ gcc/gimple-pretty-print.c	(working copy)
@@ -360,6 +360,41 @@ dump_gimple_try (pretty_printer *buffer,
   pp_character (buffer, '}');
 }
 
+/* Dump a GIMPLE_ASM tuple on the pretty_printer BUFFER, SPC spaces of
+   indent.  FLAGS specifies details to show in the dump (see TDF_* in
+   tree.h).  */
+
+static void
+dump_gimple_asm (pretty_printer *buffer, gimple gs, int spc, int flags)
+{
+  unsigned int i;
+  newline_and_indent (buffer, spc);
+  pp_string (buffer, "asm {");
+  newline_and_indent (buffer, spc + 2);
+
+  pp_string (buffer, gimple_asm_string (gs));
+  
+  newline_and_indent (buffer, spc);
+  pp_string (buffer, "}");
+  
+  if(gimple_asm_ninputs (gs)
+      || gimple_asm_noutputs (gs) 
+      || gimple_asm_nclobbered (gs))
+    {
+      pp_string (buffer, ":");
+      for (i = 0; i < gimple_asm_ninputs (gs); i++)
+        dump_generic_node (buffer, gimple_asm_input_op (gs,i),spc, flags, false);
+      newline_and_indent (buffer, spc);
+      pp_string (buffer, ":");
+      for (i = 0; i < gimple_asm_noutputs (gs); i++)
+        dump_generic_node (buffer, gimple_asm_output_op (gs,i),spc, flags, false);
+      newline_and_indent (buffer, spc);
+      pp_string (buffer, ":");
+      for (i = 0; i < gimple_asm_nclobbered (gs); i++)
+        dump_generic_node (buffer, gimple_asm_clobber_op (gs,i),spc, flags, false);
+    }
+}
+
 
 /* Dump the gimple statement GS on the pretty_printer BUFFER, SPC
    spaces of indent.  FLAGS specifies details to show in the dump (see
@@ -373,6 +408,11 @@ dump_gimple_stmt (pretty_printer *buffer
 
   switch (gimple_code (gs))
     {
+      
+    case GIMPLE_ASM:
+      dump_gimple_asm (buffer, gs, spc, flags);
+      break;
+
     case GIMPLE_ASSIGN:
       dump_gimple_assign (buffer, gs, spc, flags);
       break;
Index: gcc/ChangeLog.tuples
===================================================================
--- gcc/ChangeLog.tuples	(revision 127164)
+++ gcc/ChangeLog.tuples	(working copy)
@@ -1,3 +1,18 @@
+2007-08-02  Chris Matthews  <chrismatthews@google.com>
+
+	* gimplify.c (gimplify_asm_expr): Created new gimple tuple.
+	* gimple-pretty-printer.c (dump_gimple_asm): Added function to dump a
+	GIMPLE_ASM statement.
+	(dump_gimple_stmt): Updated to use the dump_gimple_asm function.
+	* gimple.c (gss_for_code): Made asm statements return as with_mem_ops.
+	(build_gimple_with_ops): Asm statements are added as a specal case for
+	allocation because they have extra fields that are not allocated correctly
+	in the current generic op allocator.
+	(build_gimple_asm_1): Added a helper function to setup the basics of a
+	GIMPLE_ASM tuple.
+	(build_gimple_asm_vec): Create a GIMPLE_ASM tuple from vector arguments.
+	(build_gimple_asm): Changed to call the new helper function.
+
 2007-08-01  Diego Novillo  <dnovillo@google.com>
 
 	* gimplify.c (gimplify_switch_expr): Remove switch_body_seq_.
Index: gcc/gimplify.c
===================================================================
--- gcc/gimplify.c	(revision 127164)
+++ gcc/gimplify.c	(working copy)
@@ -4113,7 +4113,15 @@ gimplify_asm_expr (tree *expr_p, gimple_
   const char *constraint;
   bool allows_mem, allows_reg, is_inout;
   enum gimplify_status ret, tret;
-
+  
+  gimple stmt;
+  VEC(tree, gc) *inputs;
+  VEC(tree, gc) *outputs;
+  VEC(tree, gc) *clobbers;
+  inputs = VEC_alloc (tree, gc, 5);
+  outputs = VEC_alloc (tree, gc, 5);
+  clobbers = VEC_alloc (tree, gc, 5);
+  
   ret = GS_ALL_DONE;
   for (i = 0, link = ASM_OUTPUTS (expr); link; ++i, link = TREE_CHAIN (link))
     {
@@ -4139,6 +4147,8 @@ gimplify_asm_expr (tree *expr_p, gimple_
 	  ret = tret;
 	}
 
+      VEC_safe_push (tree, gc, outputs, TREE_VALUE (link));
+
       if (is_inout)
 	{
 	  /* An input/output operand.  To give the optimizers more
@@ -4271,8 +4281,15 @@ gimplify_asm_expr (tree *expr_p, gimple_
 	  if (tret == GS_ERROR)
 	    ret = tret;
 	}
+      VEC_safe_push (tree, gc, inputs, TREE_VALUE (link));
     }
-
+  
+  for (link = ASM_CLOBBERS (expr); link; ++i, link = TREE_CHAIN (link))
+      VEC_safe_push (tree, gc, clobbers, TREE_VALUE (link));
+    
+    stmt = build_gimple_asm_vec (TREE_STRING_POINTER (ASM_STRING(expr)),
+                           inputs, outputs, clobbers);
+  gimple_add (pre_p, stmt);
   return ret;
 }
 
Index: gcc/gimple.c
===================================================================
--- gcc/gimple.c	(revision 127164)
+++ gcc/gimple.c	(working copy)
@@ -82,12 +82,12 @@ gss_for_code (enum gimple_code code)
     {
     case GIMPLE_ASSIGN:
     case GIMPLE_CALL:
+    case GIMPLE_ASM:
     case GIMPLE_RETURN:		return GSS_WITH_MEM_OPS;
     case GIMPLE_COND:
     case GIMPLE_GOTO:
     case GIMPLE_LABEL:
     case GIMPLE_SWITCH:		return GSS_WITH_OPS;
-    case GIMPLE_ASM:		return GSS_ASM;
     case GIMPLE_BIND:		return GSS_BIND;
     case GIMPLE_CATCH:		return GSS_CATCH;
     case GIMPLE_EH_FILTER:	return GSS_EH_FILTER;
@@ -120,7 +120,9 @@ build_gimple_with_ops (enum gimple_code 
   gimple s;
   enum gimple_statement_structure_enum gss = gss_for_code (code);
   
-  if (gss == GSS_WITH_OPS)
+  if (code == GIMPLE_ASM)
+    s = ggc_alloc_cleared (sizeof (struct gimple_statement_asm));
+    else if (gss == GSS_WITH_OPS)
     s = ggc_alloc_cleared (sizeof (struct gimple_statement_with_ops));
   else if (gss == GSS_WITH_MEM_OPS)
     s = ggc_alloc_cleared (sizeof (struct gimple_statement_with_memory_ops));
@@ -322,6 +324,53 @@ build_gimple_bind (tree vars, gimple_seq
   return p;
 }
 
+/* Helper function to set the simple fields of a asm stmt. */
+
+gimple
+build_gimple_asm_1 (const char *string, unsigned ninputs, unsigned noutputs, 
+                    unsigned nclobbers)
+{
+  gimple p;
+  p = build_gimple_with_ops (GIMPLE_ASM, 0, ninputs + noutputs + nclobbers);
+
+  p->gimple_asm.ni = ninputs;
+  p->gimple_asm.no = noutputs;
+  p->gimple_asm.nc = nclobbers;
+  p->gimple_asm.string = string;
+  
+  return p;
+}
+
+/* Construct a GIMPLE_ASM statement.
+
+   STRING is the assembly code.
+   NINPUT is the number of register inputs.
+   NOUTPUT is the number of register outputs.
+   NCLOBBERS is the number of clobbered registers.
+   INPUTS is a vector of the input register parameters.  
+   OUTPUTS is a vector of the output register parameters.  
+   CLOBBERS is a vector of the clobbered register parameters.  
+   */
+
+gimple
+build_gimple_asm_vec (const char *string, VEC(tree,gc)* inputs, 
+                      VEC(tree,gc)* outputs, VEC(tree,gc)* clobbers)
+{
+  gimple p;
+  unsigned int i;
+  p = build_gimple_asm_1(string, VEC_length(tree, inputs),
+                         VEC_length(tree, outputs), VEC_length(tree, clobbers));
+  
+  for (i = 0; i < VEC_length (tree, inputs); i++)
+    gimple_asm_set_input_op (p, i, VEC_index (tree, inputs, i));
+  for (i = 0; i < VEC_length (tree, outputs); i++)
+    gimple_asm_set_output_op (p, i, VEC_index (tree, outputs, i));
+  for (i = 0; i < VEC_length (tree, clobbers); i++)
+    gimple_asm_set_clobber_op (p, i, VEC_index (tree, clobbers, i));
+  
+  return p;
+}
+
 /* Construct a GIMPLE_ASM statement.
 
    STRING is the assembly code.
@@ -337,14 +386,8 @@ build_gimple_asm (const char *string, un
   gimple p;
   unsigned i;
   va_list ap;
-
-  p = ggc_alloc_cleared (sizeof (struct gimple_statement_asm)
-                         + sizeof (tree) * (ninputs + noutputs + nclobbers - 1));
-  set_gimple_code (p, GIMPLE_ASM);
-  p->gimple_asm.ni = ninputs;
-  p->gimple_asm.no = noutputs;
-  p->gimple_asm.nc = nclobbers;
-  p->gimple_asm.string = string;
+  
+  p = build_gimple_asm_1(string, ninputs, noutputs, nclobbers);
   
   va_start (ap, nclobbers);
 
Index: gcc/gimple.h
===================================================================
--- gcc/gimple.h	(revision 127164)
+++ gcc/gimple.h	(working copy)
@@ -396,6 +396,9 @@ extern gimple build_gimple_nop (void);
 extern gimple build_gimple_bind (tree, gimple_seq);
 extern gimple build_gimple_asm (const char *, unsigned, unsigned, unsigned,
                                 ...);
+extern gimple build_gimple_asm_vec (const char *, VEC(tree,gc) * , 
+                                    VEC(tree,gc) *, VEC(tree,gc) *);
+extern gimple build_gimple_asm_1 (const char *, unsigned, unsigned, unsigned);
 extern gimple build_gimple_catch (tree, gimple_seq);
 extern gimple build_gimple_eh_filter (tree, gimple_seq);
 extern gimple build_gimple_try (gimple_seq, gimple_seq, unsigned int);

             reply	other threads:[~2007-08-03  4:06 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-08-03  4:06 Christopher Matthews [this message]
2007-08-03 14:33 ` Diego Novillo
2007-08-03 16:08   ` Aldy Hernandez
2007-08-07  1:30     ` Christopher Matthews
2007-08-07 14:25       ` Diego Novillo

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=5794c4c80708022105w68072b23scdd10346e194d8ec@mail.gmail.com \
    --to=chrismatthews@google.com \
    --cc=aldyh@redhat.com \
    --cc=dnovillo@google.com \
    --cc=gcc-patches@gcc.gnu.org \
    /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).