+2014-11-19 David Malcolm <dmalcolm@redhat.com>
+
+ PR jit/63854
+ * config/alpha/alpha.c (alpha_option_override): Remove static from
+ "handle_trap_shadows_info" and "align_insns_info".
+ * config/i386/i386.c (ix86_option_override): Likewise for
+ "insert_vzeroupper_info".
+ * config/rl78/rl78.c (rl78_asm_file_start): Likewise for
+ "rl78_devirt_info" and "rl78_move_elim_info".
+ * config/rs6000/rs6000.c (rs6000_option_override): Likewise for
+ "analyze_swaps_info".
+ * context.c (gcc::context::~context): New.
+ * context.h (gcc::context::~context): New.
+ * dumpfile.c (dump_files): Add "false" initializers for new field
+ "owns_strings".
+ (gcc::dump_manager::~dump_manager): New.
+ (gcc::dump_manager::dump_register): Add param "take_ownership".
+ * dumpfile.h (struct dump_file_info): Add field "owns_strings".
+ (gcc::dump_manager::~dump_manager): New.
+ (gcc::dump_manager::dump_register): Add param "take_ownership".
+ * pass_manager.h (gcc::pass_manager::operator delete): New.
+ (gcc::pass_manager::~pass_manager): New.
+ * passes.c (pass_manager::register_one_dump_file): Pass "true" to
+ new "owns_strings" argument to dump_register.
+ (pass_manager::operator delete): New.
+ (delete_pass_tree): New function.
+ (pass_manager::~pass_manager): New.
+ * statistics.c (statistics_early_init): Pass "false" to
+ new "owns_strings" argument to dump_register.
+ * toplev.c (toplev::finalize): Clean up the context and thus the
+ things it owns.
+
2014-11-19 David Malcolm <dmalcolm@redhat.com>
PR jit/63854
};
opt_pass *pass_handle_trap_shadows = make_pass_handle_trap_shadows (g);
- static struct register_pass_info handle_trap_shadows_info
+ struct register_pass_info handle_trap_shadows_info
= { pass_handle_trap_shadows, "eh_ranges",
1, PASS_POS_INSERT_AFTER
};
opt_pass *pass_align_insns = make_pass_align_insns (g);
- static struct register_pass_info align_insns_info
+ struct register_pass_info align_insns_info
= { pass_align_insns, "shorten",
1, PASS_POS_INSERT_BEFORE
};
ix86_option_override (void)
{
opt_pass *pass_insert_vzeroupper = make_pass_insert_vzeroupper (g);
- static struct register_pass_info insert_vzeroupper_info
+ struct register_pass_info insert_vzeroupper_info
= { pass_insert_vzeroupper, "reload",
1, PASS_POS_INSERT_AFTER
};
}
opt_pass *rl78_devirt_pass = make_pass_rl78_devirt (g);
- static struct register_pass_info rl78_devirt_info =
+ struct register_pass_info rl78_devirt_info =
{
rl78_devirt_pass,
"pro_and_epilogue",
};
opt_pass *rl78_move_elim_pass = make_pass_rl78_move_elim (g);
- static struct register_pass_info rl78_move_elim_info =
+ struct register_pass_info rl78_move_elim_info =
{
rl78_move_elim_pass,
"bbro",
It's convenient to do it here (like i386 does). */
opt_pass *pass_analyze_swaps = make_pass_analyze_swaps (g);
- static struct register_pass_info analyze_swaps_info
+ struct register_pass_info analyze_swaps_info
= { pass_analyze_swaps, "cse1", 1, PASS_POS_INSERT_BEFORE };
register_pass (&analyze_swaps_info);
m_dumps = new gcc::dump_manager ();
m_passes = new gcc::pass_manager (this);
}
+
+gcc::context::~context ()
+{
+ delete m_passes;
+ delete m_dumps;
+}
{
public:
context ();
+ ~context ();
/* The flag shows if there are symbols to be streamed for offloading. */
bool have_offload;
TREE_DUMP_INDEX enumeration in dumpfile.h. */
static struct dump_file_info dump_files[TDI_end] =
{
- {NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0},
+ {NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, false},
{".cgraph", "ipa-cgraph", NULL, NULL, NULL, NULL, NULL, TDF_IPA,
- 0, 0, 0, 0, 0},
+ 0, 0, 0, 0, 0, false},
{".type-inheritance", "ipa-type-inheritance", NULL, NULL, NULL, NULL, NULL, TDF_IPA,
- 0, 0, 0, 0, 0},
+ 0, 0, 0, 0, 0, false},
{".tu", "translation-unit", NULL, NULL, NULL, NULL, NULL, TDF_TREE,
- 0, 0, 0, 0, 1},
+ 0, 0, 0, 0, 1, false},
{".class", "class-hierarchy", NULL, NULL, NULL, NULL, NULL, TDF_TREE,
- 0, 0, 0, 0, 2},
+ 0, 0, 0, 0, 2, false},
{".original", "tree-original", NULL, NULL, NULL, NULL, NULL, TDF_TREE,
- 0, 0, 0, 0, 3},
+ 0, 0, 0, 0, 3, false},
{".gimple", "tree-gimple", NULL, NULL, NULL, NULL, NULL, TDF_TREE,
- 0, 0, 0, 0, 4},
+ 0, 0, 0, 0, 4, false},
{".nested", "tree-nested", NULL, NULL, NULL, NULL, NULL, TDF_TREE,
- 0, 0, 0, 0, 5},
+ 0, 0, 0, 0, 5, false},
#define FIRST_AUTO_NUMBERED_DUMP 6
{NULL, "tree-all", NULL, NULL, NULL, NULL, NULL, TDF_TREE,
- 0, 0, 0, 0, 0},
+ 0, 0, 0, 0, 0, false},
{NULL, "rtl-all", NULL, NULL, NULL, NULL, NULL, TDF_RTL,
- 0, 0, 0, 0, 0},
+ 0, 0, 0, 0, 0, false},
{NULL, "ipa-all", NULL, NULL, NULL, NULL, NULL, TDF_IPA,
- 0, 0, 0, 0, 0},
+ 0, 0, 0, 0, 0, false},
};
/* Define a name->number mapping for a dump flag value. */
{
}
+gcc::dump_manager::~dump_manager ()
+{
+ for (size_t i = 0; i < m_extra_dump_files_in_use; i++)
+ {
+ dump_file_info *dfi = &m_extra_dump_files[i];
+ /* suffix, swtch, glob are statically allocated for the entries
+ in dump_files, and for statistics, but are dynamically allocated
+ for those for passes. */
+ if (dfi->owns_strings)
+ {
+ XDELETEVEC (const_cast <char *> (dfi->suffix));
+ XDELETEVEC (const_cast <char *> (dfi->swtch));
+ XDELETEVEC (const_cast <char *> (dfi->glob));
+ }
+ /* These, if non-NULL, are always dynamically allocated. */
+ XDELETEVEC (const_cast <char *> (dfi->pfilename));
+ XDELETEVEC (const_cast <char *> (dfi->alt_filename));
+ }
+ XDELETEVEC (m_extra_dump_files);
+}
+
unsigned int
gcc::dump_manager::
dump_register (const char *suffix, const char *swtch, const char *glob,
- int flags, int optgroup_flags)
+ int flags, int optgroup_flags,
+ bool take_ownership)
{
int num = m_next_dump++;
m_extra_dump_files[count].pflags = flags;
m_extra_dump_files[count].optgroup_flags = optgroup_flags;
m_extra_dump_files[count].num = num;
+ m_extra_dump_files[count].owns_strings = take_ownership;
return count + TDI_end;
}
int pstate; /* state of pass-specific stream */
int alt_state; /* state of the -fopt-info stream */
int num; /* dump file number */
+ bool owns_strings; /* fields "suffix", "swtch", "glob" can be
+ const strings, or can be dynamically
+ allocated, needing free. */
};
/* In dumpfile.c */
public:
dump_manager ();
+ ~dump_manager ();
+ /* Register a dumpfile.
+
+ TAKE_OWNERSHIP determines whether callee takes ownership of strings
+ SUFFIX, SWTCH, and GLOB. */
unsigned int
dump_register (const char *suffix, const char *swtch, const char *glob,
- int flags, int optgroup_flags);
+ int flags, int optgroup_flags,
+ bool take_ownership);
/* Return the dump_file_info for the given phase. */
struct dump_file_info *
{
public:
void *operator new (size_t sz);
+ void operator delete (void *ptr);
pass_manager (context *ctxt);
+ ~pass_manager ();
void register_pass (struct register_pass_info *pass_info);
void register_one_dump_file (opt_pass *pass);
if (optgroup_flags == OPTGROUP_NONE)
optgroup_flags = OPTGROUP_OTHER;
id = dumps->dump_register (dot_name, flag_name, glob_name, flags,
- optgroup_flags);
+ optgroup_flags,
+ true);
set_pass_for_id (id, pass);
full_name = concat (prefix, pass->name, num, NULL);
register_pass_name (pass, full_name);
return xcalloc (1, sz);
}
+void
+pass_manager::operator delete (void *ptr)
+{
+ free (ptr);
+}
+
pass_manager::pass_manager (context *ctxt)
: all_passes (NULL), all_small_ipa_passes (NULL), all_lowering_passes (NULL),
all_regular_ipa_passes (NULL),
register_dump_files (all_passes);
}
+static void
+delete_pass_tree (opt_pass *pass)
+{
+ while (pass)
+ {
+ /* Recurse into child passes. */
+ delete_pass_tree (pass->sub);
+
+ opt_pass *next = pass->next;
+
+ /* Delete this pass. */
+ delete pass;
+
+ /* Iterate onto sibling passes. */
+ pass = next;
+ }
+}
+
+pass_manager::~pass_manager ()
+{
+ XDELETEVEC (passes_by_id);
+
+ /* Call delete_pass_tree on each of the pass_lists. */
+#define DEF_PASS_LIST(LIST) \
+ delete_pass_tree (*pass_lists[PASS_LIST_NO_##LIST]);
+ GCC_PASS_LISTS
+#undef DEF_PASS_LIST
+
+}
+
/* If we are in IPA mode (i.e., current_function_decl is NULL), call
function CALLBACK for every function in the call graph. Otherwise,
call CALLBACK on the current function. */
gcc::dump_manager *dumps = g->get_dumps ();
statistics_dump_nr = dumps->dump_register (".statistics", "statistics",
"statistics", TDF_TREE,
- OPTGROUP_NONE);
+ OPTGROUP_NONE,
+ false);
}
/* Init the statistics. */
finalize_options_struct (&global_options);
finalize_options_struct (&global_options_set);
+
+ /* Clean up the context (and pass_manager etc). */
+ delete g;
+ g = NULL;
}