There are several cut-and-pasted loops in expand_asm_stmt that could be
parameterized by the functions used to access the particular operands.
The patch below does that.

Tested on x86_64-unknown-linux-gnu.  OK to commit?

-Nathan

         * stmt.c (chain_asm_ops): New function.
        (expand_asm_stmt): Call it.

diff --git a/gcc/stmt.c b/gcc/stmt.c
index 1a9f9e5..1fc09e9 100644
--- a/gcc/stmt.c
+++ b/gcc/stmt.c
@@ -1114,13 +1114,34 @@ expand_asm_operands (tree string, tree outputs, tree 
inputs,
   free_temp_slots ();
 }
 
+/* Return the operands of STMT, a GIMPLE_ASM, as described by OP_FN and
+   N_OPS connected via TREE_CHAIN.  */
+
+static tree
+chain_asm_ops (const_gimple stmt, unsigned (*n_ops) (const_gimple),
+              tree (*op_fn) (const_gimple, unsigned))
+{
+  unsigned i, n;
+  tree ret = NULL_TREE, t;
+
+  n = (*n_ops) (stmt);
+  if (n > 0)
+    {
+      t = ret = (*op_fn) (stmt, 0);
+      for (i = 1; i < n; i++)
+       t = TREE_CHAIN (t) = (*op_fn) (stmt, i);
+    }
+
+  return ret;
+}
+
 void
 expand_asm_stmt (gimple stmt)
 {
   int noutputs;
-  tree outputs, tail, t;
+  tree outputs, tail;
   tree *o;
-  size_t i, n;
+  size_t i;
   const char *s;
   tree str, out, in, cl, labels;
   location_t locus = gimple_location (stmt);
@@ -1128,41 +1149,10 @@ expand_asm_stmt (gimple stmt)
   /* Meh... convert the gimple asm operands into real tree lists.
      Eventually we should make all routines work on the vectors instead
      of relying on TREE_CHAIN.  */
-  out = NULL_TREE;
-  n = gimple_asm_noutputs (stmt);
-  if (n > 0)
-    {
-      t = out = gimple_asm_output_op (stmt, 0);
-      for (i = 1; i < n; i++)
-       t = TREE_CHAIN (t) = gimple_asm_output_op (stmt, i);
-    }
-
-  in = NULL_TREE;
-  n = gimple_asm_ninputs (stmt);
-  if (n > 0)
-    {
-      t = in = gimple_asm_input_op (stmt, 0);
-      for (i = 1; i < n; i++)
-       t = TREE_CHAIN (t) = gimple_asm_input_op (stmt, i);
-    }
-
-  cl = NULL_TREE;
-  n = gimple_asm_nclobbers (stmt);
-  if (n > 0)
-    {
-      t = cl = gimple_asm_clobber_op (stmt, 0);
-      for (i = 1; i < n; i++)
-       t = TREE_CHAIN (t) = gimple_asm_clobber_op (stmt, i);
-    }
-
-  labels = NULL_TREE;
-  n = gimple_asm_nlabels (stmt);
-  if (n > 0)
-    {
-      t = labels = gimple_asm_label_op (stmt, 0);
-      for (i = 1; i < n; i++)
-       t = TREE_CHAIN (t) = gimple_asm_label_op (stmt, i);
-    }
+  out = chain_asm_ops (stmt, gimple_asm_noutputs, gimple_asm_output_op);
+  in = chain_asm_ops (stmt, gimple_asm_ninputs, gimple_asm_input_op);
+  cl = chain_asm_ops (stmt, gimple_asm_nclobbers, gimple_asm_clobber_op);
+  labels = chain_asm_ops (stmt, gimple_asm_nlabels, gimple_asm_label_op);
 
   s = gimple_asm_string (stmt);
   str = build_string (strlen (s), s);

Reply via email to