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);
next 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).