diff mbox

RFA: Add a destructor to target_ira_int

Message ID 87tx4iyvyi.fsf@e105548-lin.cambridge.arm.com
State New
Headers show

Commit Message

Richard Sandiford Sept. 8, 2014, 3:26 p.m. UTC
This patch adds a destructor to target_ira_int, so that the data structures
it points to are freed when the parent target_globals is freed.  It fixes
a memory leak with non-default subtargets.

Tested on x86_64-linux-gnu.  OK to install?

Thanks,
Richard


gcc/
	* ira.h (ira_finish_once): Delete.
	* ira-int.h (target_ira_int::~target_ira_int): Declare.
	(target_ira_int::free_ira_costs): Likewise.
	(target_ira_int::free_register_move_costs): Likewise.
	(ira_finish_costs_once): Delete.
	* ira.c (free_register_move_costs): Replace with...
	(target_ira_int::free_register_move_costs): ...this new function.
	(target_ira_int::~target_ira_int): Define.
	(ira_init): Call free_register_move_costs as a member function rather
	than a global function.
	(ira_finish_once): Delete.
	* ira-costs.c (free_ira_costs): Replace with...
	(target_ira_int::free_ira_costs): ...this new function.
	(ira_init_costs): Call free_ira_costs as a member function rather
	than a global function.
	(ira_finish_costs_once): Delete.
	* target-globals.c (target_globals::~target_globals): Call the
	target_ira_int destructor.
	* toplev.c: Include lra.h.
	(finalize): Call lra_finish_once rather than ira_finish_once.

Comments

Jeff Law Sept. 11, 2014, 8:32 p.m. UTC | #1
On 09/08/14 09:26, Richard Sandiford wrote:
> This patch adds a destructor to target_ira_int, so that the data structures
> it points to are freed when the parent target_globals is freed.  It fixes
> a memory leak with non-default subtargets.
>
> Tested on x86_64-linux-gnu.  OK to install?
>
> Thanks,
> Richard
>
>
> gcc/
> 	* ira.h (ira_finish_once): Delete.
> 	* ira-int.h (target_ira_int::~target_ira_int): Declare.
> 	(target_ira_int::free_ira_costs): Likewise.
> 	(target_ira_int::free_register_move_costs): Likewise.
> 	(ira_finish_costs_once): Delete.
> 	* ira.c (free_register_move_costs): Replace with...
> 	(target_ira_int::free_register_move_costs): ...this new function.
> 	(target_ira_int::~target_ira_int): Define.
> 	(ira_init): Call free_register_move_costs as a member function rather
> 	than a global function.
> 	(ira_finish_once): Delete.
> 	* ira-costs.c (free_ira_costs): Replace with...
> 	(target_ira_int::free_ira_costs): ...this new function.
> 	(ira_init_costs): Call free_ira_costs as a member function rather
> 	than a global function.
> 	(ira_finish_costs_once): Delete.
> 	* target-globals.c (target_globals::~target_globals): Call the
> 	target_ira_int destructor.
> 	* toplev.c: Include lra.h.
> 	(finalize): Call lra_finish_once rather than ira_finish_once.
Consider making target_ira_int a class.  OK for the trunk.

jeff
Richard Sandiford Sept. 12, 2014, 7:25 a.m. UTC | #2
Jeff Law <law@redhat.com> writes:
> On 09/08/14 09:26, Richard Sandiford wrote:
>> This patch adds a destructor to target_ira_int, so that the data structures
>> it points to are freed when the parent target_globals is freed.  It fixes
>> a memory leak with non-default subtargets.
>>
>> Tested on x86_64-linux-gnu.  OK to install?
>>
>> Thanks,
>> Richard
>>
>>
>> gcc/
>> 	* ira.h (ira_finish_once): Delete.
>> 	* ira-int.h (target_ira_int::~target_ira_int): Declare.
>> 	(target_ira_int::free_ira_costs): Likewise.
>> 	(target_ira_int::free_register_move_costs): Likewise.
>> 	(ira_finish_costs_once): Delete.
>> 	* ira.c (free_register_move_costs): Replace with...
>> 	(target_ira_int::free_register_move_costs): ...this new function.
>> 	(target_ira_int::~target_ira_int): Define.
>> 	(ira_init): Call free_register_move_costs as a member function rather
>> 	than a global function.
>> 	(ira_finish_once): Delete.
>> 	* ira-costs.c (free_ira_costs): Replace with...
>> 	(target_ira_int::free_ira_costs): ...this new function.
>> 	(ira_init_costs): Call free_ira_costs as a member function rather
>> 	than a global function.
>> 	(ira_finish_costs_once): Delete.
>> 	* target-globals.c (target_globals::~target_globals): Call the
>> 	target_ira_int destructor.
>> 	* toplev.c: Include lra.h.
>> 	(finalize): Call lra_finish_once rather than ira_finish_once.
> Consider making target_ira_int a class.  OK for the trunk.
>
> jeff

I'd prefer to keep it as a struct if that's OK.  At the moment these
target structures are just collections of variables that are accessed
directly, so it doesn't really feel like a proper OO class "yet".
Also (more minor) changing it from a struct to a class would mean
updating all references to the structure, to avoid the clang warning
about mismatched tags.  There would then be some weird-looking
inconsistencies in the target-globals code.

Thanks,
Richard
Jeff Law Sept. 12, 2014, 8:57 p.m. UTC | #3
On 09/12/14 01:25, Richard Sandiford wrote:
> Jeff Law <law@redhat.com> writes:
>> On 09/08/14 09:26, Richard Sandiford wrote:
>>> This patch adds a destructor to target_ira_int, so that the data structures
>>> it points to are freed when the parent target_globals is freed.  It fixes
>>> a memory leak with non-default subtargets.
>>>
>>> Tested on x86_64-linux-gnu.  OK to install?
>>>
>>> Thanks,
>>> Richard
>>>
>>>
>>> gcc/
>>> 	* ira.h (ira_finish_once): Delete.
>>> 	* ira-int.h (target_ira_int::~target_ira_int): Declare.
>>> 	(target_ira_int::free_ira_costs): Likewise.
>>> 	(target_ira_int::free_register_move_costs): Likewise.
>>> 	(ira_finish_costs_once): Delete.
>>> 	* ira.c (free_register_move_costs): Replace with...
>>> 	(target_ira_int::free_register_move_costs): ...this new function.
>>> 	(target_ira_int::~target_ira_int): Define.
>>> 	(ira_init): Call free_register_move_costs as a member function rather
>>> 	than a global function.
>>> 	(ira_finish_once): Delete.
>>> 	* ira-costs.c (free_ira_costs): Replace with...
>>> 	(target_ira_int::free_ira_costs): ...this new function.
>>> 	(ira_init_costs): Call free_ira_costs as a member function rather
>>> 	than a global function.
>>> 	(ira_finish_costs_once): Delete.
>>> 	* target-globals.c (target_globals::~target_globals): Call the
>>> 	target_ira_int destructor.
>>> 	* toplev.c: Include lra.h.
>>> 	(finalize): Call lra_finish_once rather than ira_finish_once.
>> Consider making target_ira_int a class.  OK for the trunk.
>>
>> jeff
>
> I'd prefer to keep it as a struct if that's OK.  At the moment these
> target structures are just collections of variables that are accessed
> directly, so it doesn't really feel like a proper OO class "yet".
> Also (more minor) changing it from a struct to a class would mean
> updating all references to the structure, to avoid the clang warning
> about mismatched tags.  There would then be some weird-looking
> inconsistencies in the target-globals code.
It's OK with me.  I just wanted you to consider it, clearly you have :-)

jeff
diff mbox

Patch

Index: gcc/ira-costs.c
===================================================================
--- gcc/ira-costs.c	2014-08-26 12:09:31.486621719 +0100
+++ gcc/ira-costs.c	2014-09-08 16:21:58.546319449 +0100
@@ -2047,21 +2047,21 @@  ira_init_costs_once (void)
 }
 
 /* Free allocated temporary cost vectors.  */
-static void
-free_ira_costs (void)
+void
+target_ira_int::free_ira_costs ()
 {
   int i;
 
-  free (init_cost);
-  init_cost = NULL;
+  free (x_init_cost);
+  x_init_cost = NULL;
   for (i = 0; i < MAX_RECOG_OPERANDS; i++)
     {
-      free (op_costs[i]);
-      free (this_op_costs[i]);
-      op_costs[i] = this_op_costs[i] = NULL;
+      free (x_op_costs[i]);
+      free (x_this_op_costs[i]);
+      x_op_costs[i] = x_this_op_costs[i] = NULL;
     }
-  free (temp_costs);
-  temp_costs = NULL;
+  free (x_temp_costs);
+  x_temp_costs = NULL;
 }
 
 /* This is called each time register related information is
@@ -2071,7 +2071,7 @@  ira_init_costs (void)
 {
   int i;
 
-  free_ira_costs ();
+  this_target_ira_int->free_ira_costs ();
   max_struct_costs_size
     = sizeof (struct costs) + sizeof (int) * (ira_important_classes_num - 1);
   /* Don't use ira_allocate because vectors live through several IRA
@@ -2088,13 +2088,6 @@  ira_init_costs (void)
   temp_costs = (struct costs *) xmalloc (max_struct_costs_size);
 }
 
-/* Function called once at the end of compiler work.  */
-void
-ira_finish_costs_once (void)
-{
-  free_ira_costs ();
-}
-
 
 
 /* Common initialization function for ira_costs and
Index: gcc/ira-int.h
===================================================================
--- gcc/ira-int.h	2014-08-26 12:09:21.218740214 +0100
+++ gcc/ira-int.h	2014-09-08 16:21:58.546319449 +0100
@@ -770,6 +770,11 @@  #define FOR_EACH_BIT_IN_MINMAX_SET(VEC,
        minmax_set_iter_next (&(ITER)))
 
 struct target_ira_int {
+  ~target_ira_int ();
+
+  void free_ira_costs ();
+  void free_register_move_costs ();
+
   /* Initialized once.  It is a maximal possible size of the allocated
      struct costs.  */
   int x_max_struct_costs_size;
@@ -1025,7 +1030,6 @@  extern void ira_destroy (void);
 /* ira-costs.c */
 extern void ira_init_costs_once (void);
 extern void ira_init_costs (void);
-extern void ira_finish_costs_once (void);
 extern void ira_costs (void);
 extern void ira_tune_allocno_costs (void);
 
Index: gcc/ira.c
===================================================================
--- gcc/ira.c	2014-08-29 10:05:41.590585897 +0100
+++ gcc/ira.c	2014-09-08 16:21:58.546319449 +0100
@@ -1673,40 +1673,46 @@  ira_init_once (void)
 
 /* Free ira_max_register_move_cost, ira_may_move_in_cost and
    ira_may_move_out_cost for each mode.  */
-static void
-free_register_move_costs (void)
+void
+target_ira_int::free_register_move_costs (void)
 {
   int mode, i;
 
   /* Reset move_cost and friends, making sure we only free shared
      table entries once.  */
   for (mode = 0; mode < MAX_MACHINE_MODE; mode++)
-    if (ira_register_move_cost[mode])
+    if (x_ira_register_move_cost[mode])
       {
 	for (i = 0;
-	     i < mode && (ira_register_move_cost[i]
-			  != ira_register_move_cost[mode]);
+	     i < mode && (x_ira_register_move_cost[i]
+			  != x_ira_register_move_cost[mode]);
 	     i++)
 	  ;
 	if (i == mode)
 	  {
-	    free (ira_register_move_cost[mode]);
-	    free (ira_may_move_in_cost[mode]);
-	    free (ira_may_move_out_cost[mode]);
+	    free (x_ira_register_move_cost[mode]);
+	    free (x_ira_may_move_in_cost[mode]);
+	    free (x_ira_may_move_out_cost[mode]);
 	  }
       }
-  memset (ira_register_move_cost, 0, sizeof ira_register_move_cost);
-  memset (ira_may_move_in_cost, 0, sizeof ira_may_move_in_cost);
-  memset (ira_may_move_out_cost, 0, sizeof ira_may_move_out_cost);
+  memset (x_ira_register_move_cost, 0, sizeof x_ira_register_move_cost);
+  memset (x_ira_may_move_in_cost, 0, sizeof x_ira_may_move_in_cost);
+  memset (x_ira_may_move_out_cost, 0, sizeof x_ira_may_move_out_cost);
   last_mode_for_init_move_cost = -1;
 }
 
+target_ira_int::~target_ira_int ()
+{
+  free_ira_costs ();
+  free_register_move_costs ();
+}
+
 /* This is called every time when register related information is
    changed.  */
 void
 ira_init (void)
 {
-  free_register_move_costs ();
+  this_target_ira_int->free_register_move_costs ();
   setup_reg_mode_hard_regset ();
   setup_alloc_regs (flag_omit_frame_pointer != 0);
   setup_class_subset_and_memory_move_costs ();
@@ -1718,15 +1724,6 @@  ira_init (void)
   ira_init_costs ();
 }
 
-/* Function called once at the end of compiler work.  */
-void
-ira_finish_once (void)
-{
-  ira_finish_costs_once ();
-  free_register_move_costs ();
-  lra_finish_once ();
-}
-
 
 #define ira_prohibited_mode_move_regs_initialized_p \
   (this_target_ira_int->x_ira_prohibited_mode_move_regs_initialized_p)
Index: gcc/ira.h
===================================================================
--- gcc/ira.h	2014-08-29 10:05:41.590585897 +0100
+++ gcc/ira.h	2014-09-08 16:21:58.546319449 +0100
@@ -177,7 +177,6 @@  struct ira_reg_equiv_s
 
 extern void ira_init_once (void);
 extern void ira_init (void);
-extern void ira_finish_once (void);
 extern void ira_setup_eliminable_regset (void);
 extern rtx ira_eliminate_regs (rtx, enum machine_mode);
 extern void ira_set_pseudo_classes (bool, FILE *);
Index: gcc/target-globals.c
===================================================================
--- gcc/target-globals.c	2014-09-05 16:15:31.769306144 +0100
+++ gcc/target-globals.c	2014-09-08 16:21:58.546319449 +0100
@@ -121,6 +121,7 @@  save_target_globals_default_opts ()
 
 target_globals::~target_globals ()
 {
+  ira_int->~target_ira_int ();
   /* default_target_globals points to static data so shouldn't be freed.  */
   if (this != &default_target_globals)
     {
Index: gcc/toplev.c
===================================================================
--- gcc/toplev.c	2014-09-05 15:06:42.917035061 +0100
+++ gcc/toplev.c	2014-09-08 16:21:58.546319449 +0100
@@ -55,6 +55,7 @@  Software Foundation; either version 3, o
 #include "params.h"
 #include "reload.h"
 #include "ira.h"
+#include "lra.h"
 #include "dwarf2asm.h"
 #include "debug.h"
 #include "target.h"
@@ -1887,7 +1888,7 @@  finalize (bool no_backend)
 
       g->get_passes ()->finish_optimization_passes ();
 
-      ira_finish_once ();
+      lra_finish_once ();
     }
 
   if (mem_report)