]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/ira-build.c
[Ada] Small improvement to Expand_N_Unchecked_Type_Conversion
[thirdparty/gcc.git] / gcc / ira-build.c
index f0d0ed3312cec449925907d0ca98e2da837f6266..0bbdb4d0c4b93fe55c9b2c6f1636074210ec21d3 100644 (file)
@@ -1,5 +1,5 @@
 /* Building internal representation for IRA.
-   Copyright (C) 2006-2015 Free Software Foundation, Inc.
+   Copyright (C) 2006-2020 Free Software Foundation, Inc.
    Contributed by Vladimir Makarov <vmakarov@redhat.com>.
 
 This file is part of GCC.
@@ -21,28 +21,18 @@ along with GCC; see the file COPYING3.  If not see
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
-#include "tm.h"
-#include "rtl.h"
-#include "tm_p.h"
+#include "backend.h"
 #include "target.h"
-#include "regs.h"
-#include "flags.h"
-#include "hard-reg-set.h"
+#include "rtl.h"
 #include "predict.h"
-#include "input.h"
-#include "function.h"
-#include "dominance.h"
-#include "cfg.h"
-#include "basic-block.h"
-#include "insn-config.h"
-#include "recog.h"
-#include "diagnostic-core.h"
-#include "params.h"
 #include "df.h"
-#include "reload.h"
-#include "sparseset.h"
+#include "insn-config.h"
+#include "regs.h"
+#include "memmodel.h"
+#include "ira.h"
 #include "ira-int.h"
-#include "emit-rtl.h"  /* FIXME: Can go away once crtl is moved to rtl.h.  */
+#include "sparseset.h"
+#include "cfgloop.h"
 
 static ira_copy_t find_allocno_copy (ira_allocno_t, ira_allocno_t, rtx_insn *,
                                     ira_loop_tree_node_t);
@@ -54,7 +44,7 @@ ira_loop_tree_node_t ira_loop_tree_root;
 int ira_loop_tree_height;
 
 /* All nodes representing basic blocks are referred through the
-   following array.  We can not use basic block member `aux' for this
+   following array.  We cannot use basic block member `aux' for this
    because it is used for insertion of insns on edges.  */
 ira_loop_tree_node_t ira_bb_nodes;
 
@@ -262,13 +252,13 @@ finish_loop_tree_nodes (void)
    loop designating the whole function when CFG loops are not
    built.  */
 static void
-add_loop_to_tree (struct loop *loop)
+add_loop_to_tree (class loop *loop)
 {
   int loop_num;
-  struct loop *parent;
+  class loop *parent;
   ira_loop_tree_node_t loop_node, parent_node;
 
-  /* We can not use loop node access macros here because of potential
+  /* We cannot use loop node access macros here because of potential
      checking and because the nodes are not initialized enough
      yet.  */
   if (loop != NULL && loop_outer (loop) != NULL)
@@ -340,10 +330,10 @@ static void
 form_loop_tree (void)
 {
   basic_block bb;
-  struct loop *parent;
+  class loop *parent;
   ira_loop_tree_node_t bb_node, loop_node;
 
-  /* We can not use loop/bb node access macros because of potential
+  /* We cannot use loop/bb node access macros because of potential
      checking and because the nodes are not initialized enough
      yet.  */
   FOR_EACH_BB_FN (bb, cfun)
@@ -424,9 +414,9 @@ rebuild_regno_allocno_maps (void)
 \f
 
 /* Pools for allocnos, allocno live ranges and objects.  */
-static pool_allocator<live_range> live_range_pool ("live ranges", 100);
-static pool_allocator<ira_allocno> allocno_pool ("allocnos", 100);
-static pool_allocator<ira_object> object_pool ("objects", 100);
+static object_allocator<live_range> live_range_pool ("live ranges");
+static object_allocator<ira_allocno> allocno_pool ("allocnos");
+static object_allocator<ira_object> object_pool ("objects");
 
 /* Vec containing references to all created allocnos.  It is a
    container of array allocnos.  */
@@ -465,12 +455,10 @@ ira_create_object (ira_allocno_t a, int subword)
   OBJECT_CONFLICT_VEC_P (obj) = false;
   OBJECT_CONFLICT_ARRAY (obj) = NULL;
   OBJECT_NUM_CONFLICTS (obj) = 0;
-  COPY_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj), ira_no_alloc_regs);
-  COPY_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), ira_no_alloc_regs);
-  IOR_COMPL_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj),
-                         reg_class_contents[aclass]);
-  IOR_COMPL_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
-                         reg_class_contents[aclass]);
+  OBJECT_CONFLICT_HARD_REGS (obj) = ira_no_alloc_regs;
+  OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) = ira_no_alloc_regs;
+  OBJECT_CONFLICT_HARD_REGS (obj) |= ~reg_class_contents[aclass];
+  OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= ~reg_class_contents[aclass];
   OBJECT_MIN (obj) = INT_MAX;
   OBJECT_MAX (obj) = -1;
   OBJECT_LIVE_RANGES (obj) = NULL;
@@ -515,6 +503,7 @@ ira_create_allocno (int regno, bool cap_p,
   ALLOCNO_CALL_FREQ (a) = 0;
   ALLOCNO_CALLS_CROSSED_NUM (a) = 0;
   ALLOCNO_CHEAP_CALLS_CROSSED_NUM (a) = 0;
+  ALLOCNO_CROSSED_CALLS_ABIS (a) = 0;
   CLEAR_HARD_REG_SET (ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (a));
 #ifdef STACK_REGS
   ALLOCNO_NO_STACK_REG_P (a) = false;
@@ -558,10 +547,8 @@ ira_set_allocno_class (ira_allocno_t a, enum reg_class aclass)
   ALLOCNO_CLASS (a) = aclass;
   FOR_EACH_ALLOCNO_OBJECT (a, obj, oi)
     {
-      IOR_COMPL_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj),
-                             reg_class_contents[aclass]);
-      IOR_COMPL_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
-                             reg_class_contents[aclass]);
+      OBJECT_CONFLICT_HARD_REGS (obj) |= ~reg_class_contents[aclass];
+      OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= ~reg_class_contents[aclass];
     }
 }
 
@@ -575,7 +562,7 @@ ira_create_allocno_objects (ira_allocno_t a)
   int n = ira_reg_class_max_nregs[aclass][mode];
   int i;
 
-  if (GET_MODE_SIZE (mode) != 2 * UNITS_PER_WORD || n != 2)
+  if (n != 2 || maybe_ne (GET_MODE_SIZE (mode), n * UNITS_PER_WORD))
     n = 1;
 
   ALLOCNO_NUM_OBJECTS (a) = n;
@@ -611,10 +598,10 @@ merge_hard_reg_conflicts (ira_allocno_t from, ira_allocno_t to,
       ira_object_t to_obj = ALLOCNO_OBJECT (to, i);
 
       if (!total_only)
-       IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (to_obj),
-                         OBJECT_CONFLICT_HARD_REGS (from_obj));
-      IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (to_obj),
-                       OBJECT_TOTAL_CONFLICT_HARD_REGS (from_obj));
+       OBJECT_CONFLICT_HARD_REGS (to_obj)
+         |= OBJECT_CONFLICT_HARD_REGS (from_obj);
+      OBJECT_TOTAL_CONFLICT_HARD_REGS (to_obj)
+       |= OBJECT_TOTAL_CONFLICT_HARD_REGS (from_obj);
     }
 #ifdef STACK_REGS
   if (!total_only && ALLOCNO_NO_STACK_REG_P (from))
@@ -627,15 +614,15 @@ merge_hard_reg_conflicts (ira_allocno_t from, ira_allocno_t to,
 /* Update hard register conflict information for all objects associated with
    A to include the regs in SET.  */
 void
-ior_hard_reg_conflicts (ira_allocno_t a, HARD_REG_SET *set)
+ior_hard_reg_conflicts (ira_allocno_t a, const_hard_reg_set set)
 {
   ira_allocno_object_iterator i;
   ira_object_t obj;
 
   FOR_EACH_ALLOCNO_OBJECT (a, obj, i)
     {
-      IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj), *set);
-      IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), *set);
+      OBJECT_CONFLICT_HARD_REGS (obj) |= set;
+      OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= set;
     }
 }
 
@@ -916,8 +903,9 @@ create_cap_allocno (ira_allocno_t a)
 
   ALLOCNO_CALLS_CROSSED_NUM (cap) = ALLOCNO_CALLS_CROSSED_NUM (a);
   ALLOCNO_CHEAP_CALLS_CROSSED_NUM (cap) = ALLOCNO_CHEAP_CALLS_CROSSED_NUM (a);
-  IOR_HARD_REG_SET (ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (cap),
-                   ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (a));
+  ALLOCNO_CROSSED_CALLS_ABIS (cap) = ALLOCNO_CROSSED_CALLS_ABIS (a);
+  ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (cap)
+    = ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (a);
   if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
     {
       fprintf (ira_dump_file, "    Creating cap ");
@@ -1174,7 +1162,7 @@ finish_allocnos (void)
 \f
 
 /* Pools for allocno preferences.  */
-static pool_allocator <ira_allocno_pref> pref_pool ("prefs", 100);
+static object_allocator <ira_allocno_pref> pref_pool ("prefs");
 
 /* Vec containing references to all created preferences.  It is a
    container of array ira_prefs.  */
@@ -1361,7 +1349,7 @@ finish_prefs (void)
 \f
 
 /* Pools for copies.  */
-static pool_allocator<ira_allocno_copy> copy_pool ("copies", 100);
+static object_allocator<ira_allocno_copy> copy_pool ("copies");
 
 /* Vec containing references to all created copies.  It is a
    container of array ira_copies.  */
@@ -1620,7 +1608,7 @@ finish_copies (void)
 \f
 
 /* Pools for cost vectors.  It is defined only for allocno classes.  */
-static pool_allocator<int> * cost_vector_pool[N_REG_CLASSES];
+static pool_allocator *cost_vector_pool[N_REG_CLASSES];
 
 /* The function initiates work with hard register cost vectors.  It
    creates allocation pool for each allocno class.  */
@@ -1633,9 +1621,8 @@ initiate_cost_vectors (void)
   for (i = 0; i < ira_allocno_classes_num; i++)
     {
       aclass = ira_allocno_classes[i];
-      cost_vector_pool[aclass] = new pool_allocator<int>
-       ("cost vectors", 100,
-        sizeof (int) * (ira_class_hard_regs_num[aclass] - 1));
+      cost_vector_pool[aclass] = new pool_allocator
+       ("cost vectors", sizeof (int) * (ira_class_hard_regs_num[aclass]));
     }
 }
 
@@ -1643,7 +1630,7 @@ initiate_cost_vectors (void)
 int *
 ira_allocate_cost_vector (reg_class_t aclass)
 {
-  return cost_vector_pool[(int) aclass]->allocate ();
+  return (int*) cost_vector_pool[(int) aclass]->allocate ();
 }
 
 /* Free a cost vector VEC for ACLASS.  */
@@ -1683,7 +1670,7 @@ finish_cost_vectors (void)
    minimizes the number of chain elements per allocno live range.  If the
    blocks would be visited in a different order, we would still compute a
    correct post-ordering but it would be less likely that two nodes
-   connected by an edge in the CFG are neighbours in the topsort.  */
+   connected by an edge in the CFG are neighbors in the topsort.  */
 
 static vec<ira_loop_tree_node_t>
 ira_loop_tree_body_rev_postorder (ira_loop_tree_node_t loop_node ATTRIBUTE_UNUSED,
@@ -1863,7 +1850,7 @@ create_insn_allocnos (rtx x, rtx outer, bool output_p)
              if (outer != NULL && GET_CODE (outer) == SUBREG)
                {
                  machine_mode wmode = GET_MODE (outer);
-                 if (GET_MODE_SIZE (wmode) > GET_MODE_SIZE (ALLOCNO_WMODE (a)))
+                 if (partial_subreg_p (ALLOCNO_WMODE (a), wmode))
                    ALLOCNO_WMODE (a) = wmode;
                }
            }
@@ -2041,8 +2028,10 @@ propagate_allocno_info (void)
            += ALLOCNO_CALLS_CROSSED_NUM (a);
          ALLOCNO_CHEAP_CALLS_CROSSED_NUM (parent_a)
            += ALLOCNO_CHEAP_CALLS_CROSSED_NUM (a);
-         IOR_HARD_REG_SET (ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (parent_a),
-                           ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (a));
+         ALLOCNO_CROSSED_CALLS_ABIS (parent_a)
+           |= ALLOCNO_CROSSED_CALLS_ABIS (a);
+         ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (parent_a)
+           |= ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (a);
          ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (parent_a)
            += ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a);
          aclass = ALLOCNO_CLASS (a);
@@ -2171,9 +2160,9 @@ low_pressure_loop_node_p (ira_loop_tree_node_t node)
 #ifdef STACK_REGS
 /* Return TRUE if LOOP has a complex enter or exit edge.  We don't
    form a region from such loop if the target use stack register
-   because reg-stack.c can not deal with such edges.  */
+   because reg-stack.c cannot deal with such edges.  */
 static bool
-loop_with_complex_edge_p (struct loop *loop)
+loop_with_complex_edge_p (class loop *loop)
 {
   int i;
   edge_iterator ei;
@@ -2212,7 +2201,8 @@ loop_compare_func (const void *v1p, const void *v2p)
     return -1;
   if (! l1->to_remove_p && l2->to_remove_p)
     return 1;
-  if ((diff = l1->loop->header->frequency - l2->loop->header->frequency) != 0)
+  if ((diff = l1->loop->header->count.to_frequency (cfun)
+             - l2->loop->header->count.to_frequency (cfun)) != 0)
     return diff;
   if ((diff = (int) loop_depth (l1->loop) - (int) loop_depth (l2->loop)) != 0)
     return diff;
@@ -2226,7 +2216,7 @@ loop_compare_func (const void *v1p, const void *v2p)
    hardly helps (for irregular register file architecture it could
    help by choosing a better hard register in the loop but we prefer
    faster allocation even in this case).  We also remove cheap loops
-   if there are more than IRA_MAX_LOOPS_NUM of them.  Loop with EH
+   if there are more than param_ira_max_loops_num of them.  Loop with EH
    exit or enter edges are removed too because the allocation might
    require put pseudo moves on the EH edges (we could still do this
    for pseudos with caller saved hard registers in some cases but it
@@ -2262,7 +2252,7 @@ mark_loops_for_removal (void)
             );
       }
   qsort (sorted_loops, n, sizeof (ira_loop_tree_node_t), loop_compare_func);
-  for (i = 0; n - i + 1 > IRA_MAX_LOOPS_NUM; i++)
+  for (i = 0; i < n - param_ira_max_loops_num; i++)
     {
       sorted_loops[i]->to_remove_p = true;
       if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL)
@@ -2270,7 +2260,7 @@ mark_loops_for_removal (void)
          (ira_dump_file,
           "  Mark loop %d (header %d, freq %d, depth %d) for removal (%s)\n",
           sorted_loops[i]->loop_num, sorted_loops[i]->loop->header->index,
-          sorted_loops[i]->loop->header->frequency,
+          sorted_loops[i]->loop->header->count.to_frequency (cfun),
           loop_depth (sorted_loops[i]->loop),
           low_pressure_loop_node_p (sorted_loops[i]->parent)
           && low_pressure_loop_node_p (sorted_loops[i])
@@ -2303,7 +2293,7 @@ mark_all_loops_for_removal (void)
             "  Mark loop %d (header %d, freq %d, depth %d) for removal\n",
             ira_loop_nodes[i].loop_num,
             ira_loop_nodes[i].loop->header->index,
-            ira_loop_nodes[i].loop->header->frequency,
+            ira_loop_nodes[i].loop->header->count.to_frequency (cfun),
             loop_depth (ira_loop_nodes[i].loop));
       }
 }
@@ -2423,8 +2413,9 @@ propagate_some_info_from_allocno (ira_allocno_t a, ira_allocno_t from_a)
   ALLOCNO_CALLS_CROSSED_NUM (a) += ALLOCNO_CALLS_CROSSED_NUM (from_a);
   ALLOCNO_CHEAP_CALLS_CROSSED_NUM (a)
     += ALLOCNO_CHEAP_CALLS_CROSSED_NUM (from_a);
-  IOR_HARD_REG_SET (ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (a),
-                   ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (from_a));
+  ALLOCNO_CROSSED_CALLS_ABIS (a) |= ALLOCNO_CROSSED_CALLS_ABIS (from_a);
+  ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (a)
+    |= ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (from_a);
 
   ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a)
     += ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (from_a);
@@ -2573,8 +2564,8 @@ remove_low_level_allocnos (void)
          ALLOCNO_NEXT_REGNO_ALLOCNO (a) = NULL;
          ALLOCNO_CAP_MEMBER (a) = NULL;
          FOR_EACH_ALLOCNO_OBJECT (a, obj, oi)
-           COPY_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj),
-                              OBJECT_TOTAL_CONFLICT_HARD_REGS (obj));
+           OBJECT_CONFLICT_HARD_REGS (obj)
+             = OBJECT_TOTAL_CONFLICT_HARD_REGS (obj);
 #ifdef STACK_REGS
          if (ALLOCNO_TOTAL_NO_STACK_REG_P (a))
            ALLOCNO_NO_STACK_REG_P (a) = true;
@@ -2623,8 +2614,8 @@ remove_unnecessary_regions (bool all_p)
 
 /* At this point true value of allocno attribute bad_spill_p means
    that there is an insn where allocno occurs and where the allocno
-   can not be used as memory.  The function updates the attribute, now
-   it can be true only for allocnos which can not be used as memory in
+   cannot be used as memory.  The function updates the attribute, now
+   it can be true only for allocnos which cannot be used as memory in
    an insn and in whose live ranges there is other allocno deaths.
    Spilling allocnos with true value will not improve the code because
    it will not make other allocnos colorable and additional reloads
@@ -2737,7 +2728,13 @@ setup_min_max_allocno_live_range_point (void)
            ira_object_t parent_obj;
 
            if (OBJECT_MAX (obj) < 0)
-             continue;
+             {
+               /* The object is not used and hence does not live.  */
+               ira_assert (OBJECT_LIVE_RANGES (obj) == NULL);
+               OBJECT_MAX (obj) = 0;
+               OBJECT_MIN (obj) = 1;
+               continue;
+             }
            ira_assert (ALLOCNO_CAP_MEMBER (a) == NULL);
            /* Accumulation of range info.  */
            if (ALLOCNO_CAP (a) != NULL)
@@ -2765,8 +2762,8 @@ setup_min_max_allocno_live_range_point (void)
 #ifdef ENABLE_IRA_CHECKING
   FOR_EACH_OBJECT (obj, oi)
     {
-      if ((0 <= OBJECT_MIN (obj) && OBJECT_MIN (obj) <= ira_max_point)
-         && (0 <= OBJECT_MAX (obj) && OBJECT_MAX (obj) <= ira_max_point))
+      if ((OBJECT_MIN (obj) >= 0 && OBJECT_MIN (obj) <= ira_max_point)
+         && (OBJECT_MAX (obj) >= 0 && OBJECT_MAX (obj) <= ira_max_point))
        continue;
       gcc_unreachable ();
     }
@@ -3058,8 +3055,10 @@ copy_info_to_removed_store_destinations (int regno)
        += ALLOCNO_CALLS_CROSSED_NUM (a);
       ALLOCNO_CHEAP_CALLS_CROSSED_NUM (parent_a)
        += ALLOCNO_CHEAP_CALLS_CROSSED_NUM (a);
-      IOR_HARD_REG_SET (ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (parent_a),
-                       ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (a));
+      ALLOCNO_CROSSED_CALLS_ABIS (parent_a)
+       |= ALLOCNO_CROSSED_CALLS_ABIS (a);
+      ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (parent_a)
+       |= ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (a);
       ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (parent_a)
        += ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a);
       merged_p = true;
@@ -3106,8 +3105,8 @@ ira_flattening (int max_regno_before_emit, int ira_max_point_before_emit)
           flattening.  */
        continue;
       FOR_EACH_ALLOCNO_OBJECT (a, obj, oi)
-       COPY_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
-                          OBJECT_CONFLICT_HARD_REGS (obj));
+       OBJECT_TOTAL_CONFLICT_HARD_REGS (obj)
+         = OBJECT_CONFLICT_HARD_REGS (obj);
 #ifdef STACK_REGS
       ALLOCNO_TOTAL_NO_STACK_REG_P (a) = ALLOCNO_NO_STACK_REG_P (a);
 #endif
@@ -3157,6 +3156,9 @@ ira_flattening (int max_regno_before_emit, int ira_max_point_before_emit)
                -= ALLOCNO_CALLS_CROSSED_NUM (a);
              ALLOCNO_CHEAP_CALLS_CROSSED_NUM (parent_a)
                -= ALLOCNO_CHEAP_CALLS_CROSSED_NUM (a);
+             /* Assume that ALLOCNO_CROSSED_CALLS_ABIS and
+                ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS stay the same.
+                We'd need to rebuild the IR to do better.  */
              ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (parent_a)
                -= ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a);
              ira_assert (ALLOCNO_CALLS_CROSSED_NUM (parent_a) >= 0
@@ -3464,7 +3466,7 @@ ira_build (void)
         allocno crossing calls.  */
       FOR_EACH_ALLOCNO (a, ai)
        if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
-         ior_hard_reg_conflicts (a, &call_used_reg_set);
+         ior_hard_reg_conflicts (a, ira_need_caller_save_regs (a));
     }
   if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
     print_copies (ira_dump_file);