Merge expand_asm_operands into expand_asm_stmt
authorRichard Henderson <rth@redhat.com>
Mon, 11 May 2015 23:33:12 +0000 (16:33 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Mon, 11 May 2015 23:33:12 +0000 (16:33 -0700)
Prepatory to converting from tree chains to vectors.

From-SVN: r223023

gcc/ChangeLog
gcc/cfgexpand.c

index 98394eee61bcb441826641f5bcd5d0285981a8ff..f544900002549a7928f631863f0a23c3100f2843 100644 (file)
@@ -1,5 +1,8 @@
 2015-05-11  Richard Henderson  <rth@redhat.com>
 
+       * cfgexpand.c (expand_asm_operands): Merge into...
+       (expand_asm_stmt): ... here.
+
        * cfgexpand.c (expand_asm_operands): Don't call
        resolve_asm_operand_names.
        * stmt.c (resolve_asm_operand_names): Clarify block comment.
index 69d00a00095c3d00644118f4aacc87f74ad638bc..5d44c48b6c4daca55f74212e5c284d3951469a92 100644 (file)
@@ -2522,22 +2522,78 @@ tree_conflicts_with_clobbers_p (tree t, HARD_REG_SET *clobbered_regs)
    VOL nonzero means the insn is volatile; don't optimize it.  */
 
 static void
-expand_asm_operands (tree string, tree outputs, tree inputs,
-                    tree clobbers, tree labels, basic_block fallthru_bb,
-                    int vol, location_t locus)
+expand_asm_stmt (gasm *stmt)
 {
+  int noutputs, ninputs, nclobbers, nlabels, i;
+  tree string, outputs, inputs, clobbers, labels, tail, t;
+  location_t locus = gimple_location (stmt);
+  basic_block fallthru_bb = NULL;
+
+  /* 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.  */
+  outputs = NULL_TREE;
+  noutputs = gimple_asm_noutputs (stmt);
+  if (noutputs > 0)
+    {
+      t = outputs = gimple_asm_output_op (stmt, 0);
+      for (i = 1; i < noutputs; i++)
+       t = TREE_CHAIN (t) = gimple_asm_output_op (stmt, i);
+    }
+
+  inputs = NULL_TREE;
+  ninputs = gimple_asm_ninputs (stmt);
+  if (ninputs > 0)
+    {
+      t = inputs = gimple_asm_input_op (stmt, 0);
+      for (i = 1; i < ninputs; i++)
+       t = TREE_CHAIN (t) = gimple_asm_input_op (stmt, i);
+    }
+
+  clobbers = NULL_TREE;
+  nclobbers = gimple_asm_nclobbers (stmt);
+  if (nclobbers > 0)
+    {
+      t = clobbers = gimple_asm_clobber_op (stmt, 0);
+      for (i = 1; i < nclobbers; i++)
+       t = TREE_CHAIN (t) = gimple_asm_clobber_op (stmt, i);
+    }
+
+  labels = NULL_TREE;
+  nlabels = gimple_asm_nlabels (stmt);
+  if (nlabels > 0)
+    {
+      edge fallthru = find_fallthru_edge (gimple_bb (stmt)->succs);
+      if (fallthru)
+       fallthru_bb = fallthru->dest;
+      t = labels = gimple_asm_label_op (stmt, 0);
+      for (i = 1; i < nlabels; i++)
+       t = TREE_CHAIN (t) = gimple_asm_label_op (stmt, i);
+    }
+
+  {
+    const char *s = gimple_asm_string (stmt);
+    string = build_string (strlen (s), s);
+  }
+
+  if (gimple_asm_input_p (stmt))
+    {
+      expand_asm_loc (string, gimple_asm_volatile_p (stmt), locus);
+      return;
+    }
+
+  /* Record the contents of OUTPUTS before it is modified.  */
+  tree *orig_outputs = XALLOCAVEC (tree, noutputs);
+  for (i = 0; i < noutputs; ++i)
+    orig_outputs[i] = TREE_VALUE (gimple_asm_output_op (stmt, i));
+
+  bool vol = gimple_asm_volatile_p (stmt);
+
   rtvec argvec, constraintvec, labelvec;
   rtx body;
-  int ninputs = list_length (inputs);
-  int noutputs = list_length (outputs);
-  int nlabels = list_length (labels);
   int ninout;
-  int nclobbers;
   HARD_REG_SET clobbered_regs;
   int clobber_conflict_found = 0;
-  tree tail;
-  tree t;
-  int i;
   /* Vector of RTX's of evaluated output operands.  */
   rtx *output_rtx = XALLOCAVEC (rtx, noutputs);
   int *inout_opnum = XALLOCAVEC (int, noutputs);
@@ -2994,101 +3050,22 @@ expand_asm_operands (tree string, tree outputs, tree inputs,
     if (real_output_rtx[i])
       emit_move_insn (real_output_rtx[i], output_rtx[i]);
 
-  crtl->has_asm_statement = 1;
-  free_temp_slots ();
-}
-
-
-static void
-expand_asm_stmt (gasm *stmt)
-{
-  int noutputs;
-  tree outputs, tail, t;
-  tree *o;
-  size_t i, n;
-  const char *s;
-  tree str, out, in, cl, labels;
-  location_t locus = gimple_location (stmt);
-  basic_block fallthru_bb = NULL;
-
-  /* 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)
-    {
-      edge fallthru = find_fallthru_edge (gimple_bb (stmt)->succs);
-      if (fallthru)
-       fallthru_bb = fallthru->dest;
-      t = labels = gimple_asm_label_op (stmt, 0);
-      for (i = 1; i < n; i++)
-       t = TREE_CHAIN (t) = gimple_asm_label_op (stmt, i);
-    }
-
-  s = gimple_asm_string (stmt);
-  str = build_string (strlen (s), s);
-
-  if (gimple_asm_input_p (stmt))
-    {
-      expand_asm_loc (str, gimple_asm_volatile_p (stmt), locus);
-      return;
-    }
-
-  outputs = out;
-  noutputs = gimple_asm_noutputs (stmt);
-  /* o[I] is the place that output number I should be written.  */
-  o = (tree *) alloca (noutputs * sizeof (tree));
-
-  /* Record the contents of OUTPUTS before it is modified.  */
-  for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
-    o[i] = TREE_VALUE (tail);
-
-  /* Generate the ASM_OPERANDS insn; store into the TREE_VALUEs of
-     OUTPUTS some trees for where the values were actually stored.  */
-  expand_asm_operands (str, outputs, in, cl, labels, fallthru_bb,
-                      gimple_asm_volatile_p (stmt), locus);
-
   /* Copy all the intermediate outputs into the specified outputs.  */
   for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
     {
-      if (o[i] != TREE_VALUE (tail))
+      if (orig_outputs[i] != TREE_VALUE (tail))
        {
-         expand_assignment (o[i], TREE_VALUE (tail), false);
+         expand_assignment (orig_outputs[i], TREE_VALUE (tail), false);
          free_temp_slots ();
 
          /* Restore the original value so that it's correct the next
             time we expand this function.  */
-         TREE_VALUE (tail) = o[i];
+         TREE_VALUE (tail) = orig_outputs[i];
        }
     }
+
+  crtl->has_asm_statement = 1;
+  free_temp_slots ();
 }
 
 /* Emit code to jump to the address