Add a function for getting the ABI of a call insn target
[gcc.git] / gcc / var-tracking.c
index ba978384d44ad47199f27461de583119e743f1af..3d069e41323c03fb8aaf33672eb49c9f9c3cd15b 100644 (file)
 #include "rtl-iter.h"
 #include "fibonacci_heap.h"
 #include "print-rtl.h"
+#include "function-abi.h"
 
 typedef fibonacci_heap <long, basic_block_def> bb_heap_t;
 typedef fibonacci_node <long, basic_block_def> bb_heap_node_t;
@@ -929,8 +930,9 @@ static poly_int64 hard_frame_pointer_adjustment = -1;
 
 /* Data for adjust_mems callback.  */
 
-struct adjust_mem_data
+class adjust_mem_data
 {
+public:
   bool store;
   machine_mode mem_mode;
   HOST_WIDE_INT stack_adjust;
@@ -1030,7 +1032,7 @@ use_narrower_mode (rtx x, scalar_int_mode mode, scalar_int_mode wmode)
 static rtx
 adjust_mems (rtx loc, const_rtx old_rtx, void *data)
 {
-  struct adjust_mem_data *amd = (struct adjust_mem_data *) data;
+  class adjust_mem_data *amd = (class adjust_mem_data *) data;
   rtx mem, addr = loc, tem;
   machine_mode mem_mode_save;
   bool store_save;
@@ -1238,7 +1240,7 @@ adjust_insn (basic_block bb, rtx_insn *insn)
   amd.stack_adjust = -VTI (bb)->out.stack_adjust;
 
   amd.store = true;
-  note_stores (PATTERN (insn), adjust_mem_stores, &amd);
+  note_stores (insn, adjust_mem_stores, &amd);
 
   amd.store = false;
   if (GET_CODE (PATTERN (insn)) == PARALLEL
@@ -4899,12 +4901,10 @@ dataflow_set_clear_at_call (dataflow_set *set, rtx_insn *call_insn)
 {
   unsigned int r;
   hard_reg_set_iterator hrsi;
-  HARD_REG_SET invalidated_regs;
 
-  get_call_reg_set_usage (call_insn, &invalidated_regs,
-                         regs_invalidated_by_call);
+  function_abi callee_abi = insn_callee_abi (call_insn);
 
-  EXECUTE_IF_SET_IN_HARD_REG_SET (invalidated_regs, 0, r, hrsi)
+  EXECUTE_IF_SET_IN_HARD_REG_SET (callee_abi.full_reg_clobbers (), 0, r, hrsi)
     var_regno_delete (set, r);
 
   if (MAY_HAVE_DEBUG_BIND_INSNS)
@@ -6292,14 +6292,12 @@ prepare_call_arguments (basic_block bb, rtx_insn *insn)
                  && targetm.calls.struct_value_rtx (type, 0) == 0)
                {
                  tree struct_addr = build_pointer_type (TREE_TYPE (type));
-                 machine_mode mode = TYPE_MODE (struct_addr);
+                 function_arg_info arg (struct_addr, /*named=*/true);
                  rtx reg;
                  INIT_CUMULATIVE_ARGS (args_so_far_v, type, NULL_RTX, fndecl,
                                        nargs + 1);
-                 reg = targetm.calls.function_arg (args_so_far, mode,
-                                                   struct_addr, true);
-                 targetm.calls.function_arg_advance (args_so_far, mode,
-                                                     struct_addr, true);
+                 reg = targetm.calls.function_arg (args_so_far, arg);
+                 targetm.calls.function_arg_advance (args_so_far, arg);
                  if (reg == NULL_RTX)
                    {
                      for (; link; link = XEXP (link, 1))
@@ -6317,11 +6315,9 @@ prepare_call_arguments (basic_block bb, rtx_insn *insn)
                                      nargs);
              if (obj_type_ref && TYPE_ARG_TYPES (type) != void_list_node)
                {
-                 machine_mode mode;
                  t = TYPE_ARG_TYPES (type);
-                 mode = TYPE_MODE (TREE_VALUE (t));
-                 this_arg = targetm.calls.function_arg (args_so_far, mode,
-                                                        TREE_VALUE (t), true);
+                 function_arg_info arg (TREE_VALUE (t), /*named=*/true);
+                 this_arg = targetm.calls.function_arg (args_so_far, arg);
                  if (this_arg && !REG_P (this_arg))
                    this_arg = NULL_RTX;
                  else if (this_arg == NULL_RTX)
@@ -6388,7 +6384,7 @@ prepare_call_arguments (basic_block bb, rtx_insn *insn)
 
            if (!frame_pointer_needed)
              {
-               struct adjust_mem_data amd;
+               class adjust_mem_data amd;
                amd.mem_mode = VOIDmode;
                amd.stack_adjust = -VTI (bb)->out.stack_adjust;
                amd.store = true;
@@ -6429,30 +6425,24 @@ prepare_call_arguments (basic_block bb, rtx_insn *insn)
          }
        if (t && t != void_list_node)
          {
-           tree argtype = TREE_VALUE (t);
-           machine_mode mode = TYPE_MODE (argtype);
            rtx reg;
-           if (pass_by_reference (&args_so_far_v, mode, argtype, true))
-             {
-               argtype = build_pointer_type (argtype);
-               mode = TYPE_MODE (argtype);
-             }
-           reg = targetm.calls.function_arg (args_so_far, mode,
-                                             argtype, true);
-           if (TREE_CODE (argtype) == REFERENCE_TYPE
-               && INTEGRAL_TYPE_P (TREE_TYPE (argtype))
+           function_arg_info arg (TREE_VALUE (t), /*named=*/true);
+           apply_pass_by_reference_rules (&args_so_far_v, arg);
+           reg = targetm.calls.function_arg (args_so_far, arg);
+           if (TREE_CODE (arg.type) == REFERENCE_TYPE
+               && INTEGRAL_TYPE_P (TREE_TYPE (arg.type))
                && reg
                && REG_P (reg)
-               && GET_MODE (reg) == mode
-               && (GET_MODE_CLASS (mode) == MODE_INT
-                   || GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
+               && GET_MODE (reg) == arg.mode
+               && (GET_MODE_CLASS (arg.mode) == MODE_INT
+                   || GET_MODE_CLASS (arg.mode) == MODE_PARTIAL_INT)
                && REG_P (x)
                && REGNO (x) == REGNO (reg)
-               && GET_MODE (x) == mode
+               && GET_MODE (x) == arg.mode
                && item)
              {
                machine_mode indmode
-                 = TYPE_MODE (TREE_TYPE (argtype));
+                 = TYPE_MODE (TREE_TYPE (arg.type));
                rtx mem = gen_rtx_MEM (indmode, x);
                cselib_val *val = cselib_lookup (mem, indmode, 0, VOIDmode);
                if (val && cselib_preserved_value_p (val))
@@ -6492,8 +6482,7 @@ prepare_call_arguments (basic_block bb, rtx_insn *insn)
                        }
                  }
              }
-           targetm.calls.function_arg_advance (args_so_far, mode,
-                                               argtype, true);
+           targetm.calls.function_arg_advance (args_so_far, arg);
            t = TREE_CHAIN (t);
          }
       }
@@ -6642,7 +6631,7 @@ add_with_sets (rtx_insn *insn, struct cselib_set *sets, int n_sets)
      insert notes before it without worrying about any
      notes that MO_USEs might emit after the insn.  */
   cui.store_p = true;
-  note_stores (PATTERN (insn), add_stores, &cui);
+  note_stores (insn, add_stores, &cui);
   n2 = VTI (bb)->mos.length () - 1;
   mos = VTI (bb)->mos.address ();
 
@@ -7182,7 +7171,7 @@ vt_find_locations (void)
                  if (MAY_HAVE_DEBUG_BIND_INSNS)
                    inform (DECL_SOURCE_LOCATION (cfun->decl),
                            "variable tracking size limit exceeded with "
-                           "-fvar-tracking-assignments, retrying without");
+                           "%<-fvar-tracking-assignments%>, retrying without");
                  else
                    inform (DECL_SOURCE_LOCATION (cfun->decl),
                            "variable tracking size limit exceeded");
@@ -7332,7 +7321,7 @@ dump_var (variable *var)
 static void
 dump_vars (variable_table_type *vars)
 {
-  if (vars->elements () > 0)
+  if (!vars->is_empty ())
     {
       fprintf (dump_file, "Variables:\n");
       vars->traverse <void *, dump_var_tracking_slot> (NULL);
@@ -8061,8 +8050,9 @@ delete_variable_part (dataflow_set *set, rtx loc, decl_or_value dv,
 
 /* Structure for passing some other parameters to function
    vt_expand_loc_callback.  */
-struct expand_loc_callback_data
+class expand_loc_callback_data
 {
+public:
   /* The variables and values active at this point.  */
   variable_table_type *vars;
 
@@ -8328,8 +8318,8 @@ static inline rtx
 vt_expand_var_loc_chain (variable *var, bitmap regs, void *data,
                         bool *pendrecp)
 {
-  struct expand_loc_callback_data *elcd
-    = (struct expand_loc_callback_data *) data;
+  class expand_loc_callback_data *elcd
+    = (class expand_loc_callback_data *) data;
   location_chain *loc, *next;
   rtx result = NULL;
   int first_child, result_first_child, last_child;
@@ -8467,8 +8457,8 @@ vt_expand_loc_callback (rtx x, bitmap regs,
                        int max_depth ATTRIBUTE_UNUSED,
                        void *data)
 {
-  struct expand_loc_callback_data *elcd
-    = (struct expand_loc_callback_data *) data;
+  class expand_loc_callback_data *elcd
+    = (class expand_loc_callback_data *) data;
   decl_or_value dv;
   variable *var;
   rtx result, subreg;
@@ -8491,7 +8481,7 @@ vt_expand_loc_callback (rtx x, bitmap regs,
 
       /* Invalid SUBREGs are ok in debug info.  ??? We could try
         alternate expansions for the VALUE as well.  */
-      if (!result)
+      if (!result && GET_MODE (subreg) != VOIDmode)
        result = gen_rtx_raw_SUBREG (GET_MODE (x), subreg, SUBREG_BYTE (x));
 
       return result;
@@ -8625,7 +8615,7 @@ resolve_expansions_pending_recursion (vec<rtx, va_heap> *pending)
 static rtx
 vt_expand_loc (rtx loc, variable_table_type *vars)
 {
-  struct expand_loc_callback_data data;
+  class expand_loc_callback_data data;
   rtx result;
 
   if (!MAY_HAVE_DEBUG_BIND_INSNS)
@@ -8647,7 +8637,7 @@ vt_expand_loc (rtx loc, variable_table_type *vars)
 static rtx
 vt_expand_1pvar (variable *var, variable_table_type *vars)
 {
-  struct expand_loc_callback_data data;
+  class expand_loc_callback_data data;
   rtx loc;
 
   gcc_checking_assert (var->onepart && var->n_var_parts == 1);
@@ -9060,7 +9050,7 @@ emit_notes_for_changes (rtx_insn *insn, enum emit_note_where where,
   emit_note_data data;
   variable_table_type *htab = shared_hash_htab (vars);
 
-  if (!changed_variables->elements ())
+  if (changed_variables->is_empty ())
     return;
 
   if (MAY_HAVE_DEBUG_BIND_INSNS)
@@ -9538,7 +9528,7 @@ vt_emit_notes (void)
   basic_block bb;
   dataflow_set cur;
 
-  gcc_assert (!changed_variables->elements ());
+  gcc_assert (changed_variables->is_empty ());
 
   /* Free memory occupied by the out hash tables, as they aren't used
      anymore.  */