* [tuples] adding gimple_asm
@ 2007-08-03 4:06 Christopher Matthews
2007-08-03 14:33 ` Diego Novillo
0 siblings, 1 reply; 5+ messages in thread
From: Christopher Matthews @ 2007-08-03 4:06 UTC (permalink / raw)
To: Diego, Aldy Hernandez, gcc-patches
[-- 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);
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [tuples] adding gimple_asm 2007-08-03 4:06 [tuples] adding gimple_asm Christopher Matthews @ 2007-08-03 14:33 ` Diego Novillo 2007-08-03 16:08 ` Aldy Hernandez 0 siblings, 1 reply; 5+ messages in thread From: Diego Novillo @ 2007-08-03 14:33 UTC (permalink / raw) To: Christopher Matthews; +Cc: Aldy Hernandez, gcc-patches On 8/3/07 12:05 AM, Christopher Matthews wrote: > +/* Test GIMPLE_ASSIGN. */ s/GIMPLE_ASSIGN/GIMPLE_ASM/ > [ ... ] > +/* { dg-final { scan-tree-dump-times ":\\\"%eax\\\"" 1 "gimple"} } */ > + You need to add a cleanup action in all the test cases: /* { dg-final { cleanup-tree-dump "gimple" } } */ > +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); Better follow the format used to dump ASM_EXPRs (see the ASM_EXPR case in tree-pretty-print.c:dump_generic_node). > +/* Helper function to set the simple fields of a asm stmt. */ > + Need documentation for arguments. > +gimple > +build_gimple_asm_1 (const char *string, unsigned ninputs, unsigned noutputs, Better declare static. It will not be called from outside. > + CLOBBERS is a vector of the clobbered register parameters. > + */ Closing comment at end of previous line. > + > + p = build_gimple_asm_1(string, ninputs, noutputs, nclobbers); Space before '('. OK with those changes. ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [tuples] adding gimple_asm 2007-08-03 14:33 ` Diego Novillo @ 2007-08-03 16:08 ` Aldy Hernandez 2007-08-07 1:30 ` Christopher Matthews 0 siblings, 1 reply; 5+ messages in thread From: Aldy Hernandez @ 2007-08-03 16:08 UTC (permalink / raw) To: Diego Novillo; +Cc: Christopher Matthews, gcc-patches By the way, thanks so much for the asm changes. I was trying to avoid tackling GIMPLE_ASM, glad someone else picked it up :). Aldy ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [tuples] adding gimple_asm 2007-08-03 16:08 ` Aldy Hernandez @ 2007-08-07 1:30 ` Christopher Matthews 2007-08-07 14:25 ` Diego Novillo 0 siblings, 1 reply; 5+ messages in thread From: Christopher Matthews @ 2007-08-07 1:30 UTC (permalink / raw) To: Aldy Hernandez; +Cc: Diego Novillo, gcc-patches [-- Attachment #1: Type: text/plain, Size: 247 bytes --] All changes made. And rechecked against gimple.exp On 8/3/07, Aldy Hernandez <aldyh@redhat.com> wrote: > By the way, thanks so much for the asm changes. I was trying to avoid > tackling GIMPLE_ASM, glad someone else picked it up :). > > Aldy > [-- Attachment #2: gimple_asmv2.diff --] [-- Type: text/x-patch, Size: 11717 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,22 @@ +/* { dg-do compile } */ + +/* Test GIMPLE_ASM. */ + +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"} } */ +/* { dg-final { cleanup-tree-dump "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,19 @@ +/* { dg-do compile } */ + +/* Test GIMPLE_ASM. */ + +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"} } */ +/* { dg-final { cleanup-tree-dump "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_ASM. */ + +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"} } */ +/* { dg-final { cleanup-tree-dump "gimple" } } */ + Index: gcc/gimple-pretty-print.c =================================================================== --- gcc/gimple-pretty-print.c (revision 127188) +++ gcc/gimple-pretty-print.c (working copy) @@ -250,7 +250,8 @@ dump_gimple_switch (pretty_printer *buff pp_string (buffer, ") <"); for (i = 0; i < gimple_switch_num_labels (gs); i++) { - dump_generic_node (buffer, gimple_switch_label (gs, i), spc, flags, false); + dump_generic_node (buffer, gimple_switch_label (gs, i), spc, flags, + false); if (i < gimple_switch_num_labels (gs) - 1) pp_string (buffer, ", "); } @@ -380,6 +381,52 @@ 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__ ("); + + pp_string (buffer, gimple_asm_string (gs)); + + if (gimple_asm_ninputs (gs) + || gimple_asm_noutputs (gs) + || gimple_asm_nclobbered (gs)) + { + pp_character (buffer, ' '); + for (i = 0; i < gimple_asm_ninputs (gs); i++) + { + dump_generic_node (buffer, gimple_asm_input_op (gs,i),spc, flags, + false); + if (i < gimple_asm_ninputs (gs) -1) + pp_string (buffer, ": "); + } + 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); + if ( i < gimple_asm_noutputs (gs) -1) + pp_string (buffer, ", "); + } + 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); + if ( i < gimple_asm_nclobbered (gs) -1) + pp_string (buffer, ", "); + } + } + pp_character (buffer, ')'); +} + /* Dump the gimple statement GS on the pretty_printer BUFFER, SPC spaces of indent. FLAGS specifies details to show in the dump (see @@ -393,6 +440,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 127188) +++ 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-03 Diego Novillo <dnovillo@google.com> * gimple-pretty-print.c (INDENT): Tidy. Index: gcc/gimplify.c =================================================================== --- gcc/gimplify.c (revision 127188) +++ gcc/gimplify.c (working copy) @@ -4112,7 +4112,17 @@ 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)) { @@ -4138,6 +4148,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 @@ -4270,8 +4282,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 127188) +++ 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,59 @@ build_gimple_bind (tree vars, gimple_seq return p; } +/* Helper function to set the simple fields of a asm stmt. + + STRING is a pointer to a string that is the asm blocks assembly code. + NINPUT is the number of register inputs. + NOUTPUT is the number of register outputs. + NCLOBBERS is the number of clobbered registers. + */ + +static inline 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 +392,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 127188) +++ gcc/gimple.h (working copy) @@ -396,6 +396,8 @@ 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_catch (tree, gimple_seq); extern gimple build_gimple_eh_filter (tree, gimple_seq); extern gimple build_gimple_try (gimple_seq, gimple_seq, unsigned int); ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [tuples] adding gimple_asm 2007-08-07 1:30 ` Christopher Matthews @ 2007-08-07 14:25 ` Diego Novillo 0 siblings, 0 replies; 5+ messages in thread From: Diego Novillo @ 2007-08-07 14:25 UTC (permalink / raw) To: Christopher Matthews; +Cc: Aldy Hernandez, gcc-patches On 8/6/07 9:29 PM, Christopher Matthews wrote: > All changes made. Looks OK. Thanks. ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2007-08-07 14:25 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2007-08-03 4:06 [tuples] adding gimple_asm Christopher Matthews 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
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).