This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[lto] Add timevars and propagate -v and -save-temps
- From: Diego Novillo <dnovillo at google dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sat, 29 Nov 2008 12:28:22 -0500
- Subject: [lto] Add timevars and propagate -v and -save-temps
This patch adds more timers to lto and whopr modules. It also
changes the ltrans-driver script to:
1- React to -v and -save-temps
2- Try to use parallelism using some simple heuristics. This
probably works only on Linux or similar, but is shouldn't fail
on systems that don't have getconf or awk.
It also fixes a buglet in lto.exp that was causing every dg-based
test to be considered executable (it was leaking
dg-do-what-by-default). This was causing spurious failures.
Tested on x86_64.
2008-11-29 Diego Novillo <dnovillo@google.com>
* timevar.def (TV_IPA_LTO_GIMPLE_IO): Rename from
TV_IPA_LTO_OUT. Update all users.
(TV_IPA_LTO_DECL_IO): New.
(TV_IPA_LTO_CGRAPH_IO): New.
(TV_LTO): New.
(TV_WHOPR_WPA): New.
(TV_WHOPR_LTRANS): New.
(TV_WHOPR_WPA_FIXUP): New.
* lto-cgraph.c (pass_ipa_lto_cgraph): Use TV_IPA_LTO_CGRAPH_IO.
* lto-wpa-fixup.c (pass_ipa_lto_wpa_fixup): Use TV_WHOPR_WPA_FIXUP.
* passes.c (execute_ipa_summary_passes): Start and stop
pass timers, if they are defined.
(ipa_write_summaries_2): Likewise.
(ipa_write_summaries_1): Likewise.
* lto-section-out.c (pass_ipa_lto_finish_out): Replace
timer TV_IPA_LTO_OUT with TV_IPA_LTO_DECL_IO.
lto/ChangeLog:
* lto.c: Include timevar.h.
(lto_materialize_function): Tidy. Add comments.
(lto_wpa_write_files): Tidy.
(lto_execute_ltrans): Tidy.
(lto_main): Add local variable LTO_TIMER. Initialize it
to one of TV_WHOPR_WPA, TV_WHOPR_LTRANS or TV_LTO.
Start and stop the timer.
Tidy comments.
* Make-lang.in (lto.o): Add dependency on timevar.h.
* ltrans-driver: React to -v and -save-temps.
Use simple heuristic to determine how much parallelism to
use when executing make.
testsuite/ChangeLog.lto
* lib/lto.exp: Do not set dg-do-what-default.
Index: lto-function-out.c
===================================================================
--- lto-function-out.c (revision 142242)
+++ lto-function-out.c (working copy)
@@ -2517,7 +2517,7 @@ struct ipa_opt_pass pass_ipa_lto_gimple_
NULL, /* sub */
NULL, /* next */
0, /* static_pass_number */
- TV_IPA_LTO_OUT, /* tv_id */
+ TV_IPA_LTO_GIMPLE_IO, /* tv_id */
0, /* properties_required */
0, /* properties_provided */
0, /* properties_destroyed */
Index: testsuite/lib/lto.exp
===================================================================
--- testsuite/lib/lto.exp (revision 142249)
+++ testsuite/lib/lto.exp (working copy)
@@ -270,7 +270,6 @@ proc lto-execute { src1 sid } {
# unsupported flags.
verbose "lto-execute: $src1" 1
set compile_type "run"
- set dg-do-what-default run
set dg-do-what [list ${dg-do-what-default} "" P]
set extra_flags(0) [lto-get-options-main $src1]
set compile_xfail(0) ""
@@ -284,7 +283,6 @@ proc lto-execute { src1 sid } {
set option_list $LTO_OPTIONS
}
-
# Check whether this test is supported for this target.
if { [lindex ${dg-do-what} 1 ] == "N" } {
unsupported "$src1"
Index: lto-cgraph.c
===================================================================
--- lto-cgraph.c (revision 142242)
+++ lto-cgraph.c (working copy)
@@ -784,7 +784,7 @@ struct ipa_opt_pass pass_ipa_lto_cgraph
NULL, /* sub */
NULL, /* next */
0, /* static_pass_number */
- TV_IPA_LTO_OUT, /* tv_id */
+ TV_IPA_LTO_CGRAPH_IO, /* tv_id */
0, /* properties_required */
0, /* properties_provided */
0, /* properties_destroyed */
Index: timevar.def
===================================================================
--- timevar.def (revision 142242)
+++ timevar.def (working copy)
@@ -42,7 +42,13 @@ DEFTIMEVAR (TV_DUMP , "
DEFTIMEVAR (TV_CGRAPH , "callgraph construction")
DEFTIMEVAR (TV_CGRAPHOPT , "callgraph optimization")
DEFTIMEVAR (TV_IPA_CONSTANT_PROP , "ipa cp")
-DEFTIMEVAR (TV_IPA_LTO_OUT , "ipa lto out")
+DEFTIMEVAR (TV_IPA_LTO_GIMPLE_IO , "ipa lto gimple I/O")
+DEFTIMEVAR (TV_IPA_LTO_DECL_IO , "ipa lto decl I/O")
+DEFTIMEVAR (TV_IPA_LTO_CGRAPH_IO , "ipa lto cgraph I/O")
+DEFTIMEVAR (TV_LTO , "lto")
+DEFTIMEVAR (TV_WHOPR_WPA , "whopr wpa")
+DEFTIMEVAR (TV_WHOPR_LTRANS , "whopr ltrans")
+DEFTIMEVAR (TV_WHOPR_WPA_FIXUP , "whopr wpa fixup")
DEFTIMEVAR (TV_IPA_REFERENCE , "ipa reference")
DEFTIMEVAR (TV_IPA_PURE_CONST , "ipa pure const")
DEFTIMEVAR (TV_IPA_TYPE_ESCAPE , "ipa type escape")
Index: lto-wpa-fixup.c
===================================================================
--- lto-wpa-fixup.c (revision 142242)
+++ lto-wpa-fixup.c (working copy)
@@ -266,7 +266,7 @@ struct ipa_opt_pass pass_ipa_lto_wpa_fix
NULL, /* sub */
NULL, /* next */
0, /* static_pass_number */
- TV_IPA_LTO_OUT, /* tv_id */
+ TV_WHOPR_WPA_FIXUP, /* tv_id */
0, /* properties_required */
0, /* properties_provided */
0, /* properties_destroyed */
Index: lto/lto.c
===================================================================
--- lto/lto.c (revision 142242)
+++ lto/lto.c (working copy)
@@ -46,6 +46,7 @@ Boston, MA 02110-1301, USA. */
#include "pointer-set.h"
#include "ipa-prop.h"
#include "common.h"
+#include "timevar.h"
/* This needs to be included after config.h. Otherwise, _GNU_SOURCE will not
be defined in time to set __USE_GNU in the system headers, and strsignal
@@ -96,6 +97,8 @@ lto_materialize_function (struct cgraph_
allocate_struct_function (decl, false);
+ /* Load the function body only if not operating in WPA mode. In
+ WPA mode, the body of the function is not needed. */
if (!flag_wpa)
lto_input_function_body (file_data, decl, data);
@@ -105,9 +108,7 @@ lto_materialize_function (struct cgraph_
/* Look for initializers of constant variables and private
statics. */
- for (step = fn->local_decls;
- step;
- step = TREE_CHAIN (step))
+ for (step = fn->local_decls; step; step = TREE_CHAIN (step))
{
tree decl = TREE_VALUE (step);
if (TREE_CODE (decl) == VAR_DECL
@@ -120,9 +121,7 @@ lto_materialize_function (struct cgraph_
DECL_EXTERNAL (decl) = 1;
/* Let the middle end know about the function. */
- rest_of_decl_compilation (decl,
- /*top_level=*/1,
- /*at_end=*/0);
+ rest_of_decl_compilation (decl, 1, 0);
if (cgraph_node (decl)->needed)
cgraph_mark_reachable_node (cgraph_node (decl));
}
@@ -720,7 +719,7 @@ lto_wpa_write_files (void)
bitmap decls;
VEC(bitmap,heap) *inlined_decls = NULL;
- /* Include all inlined function. */
+ /* Include all inlined functions. */
for (i = 0; VEC_iterate (cgraph_node_set, lto_cgraph_node_sets, i, set); i++)
{
decls = lto_add_all_inlinees (set);
@@ -741,7 +740,7 @@ lto_wpa_write_files (void)
output_files[i] = temp_filename;
- file = lto_elf_file_open (temp_filename, /*writable=*/true);
+ file = lto_elf_file_open (temp_filename, true);
if (!file)
fatal_error ("lto_elf_file_open() failed");
@@ -858,12 +857,11 @@ lto_execute_ltrans (char *const *files)
errmsg = pex_run (pex, PEX_LAST | PEX_SEARCH, argv[0], argv, NULL, NULL,
&err);
if (errmsg)
- {
- fatal_error ("%s: %s", errmsg, xstrerror (err));
- }
+ fatal_error ("%s: %s", errmsg, xstrerror (err));
if (!pex_get_status (pex, 1, &status))
fatal_error ("can't get program status: %s", xstrerror (errno));
+
pex_free (pex);
if (status)
@@ -880,6 +878,7 @@ lto_execute_ltrans (char *const *files)
}
}
+
typedef struct {
struct pointer_set_t *free_list;
struct pointer_set_t *seen;
@@ -1259,6 +1258,15 @@ lto_main (int debug_p ATTRIBUTE_UNUSED)
FILE *resolution = NULL;
unsigned num_objects;
int t;
+ timevar_id_t lto_timer;
+
+ /* Start the appropriate timer depending on the mode that we are
+ operating in. */
+ lto_timer = (flag_wpa) ? TV_WHOPR_WPA
+ : (flag_ltrans) ? TV_WHOPR_LTRANS
+ : TV_LTO;
+
+ timevar_push (lto_timer);
/* Set the hooks so that all of the ipa passes can read in their data. */
lto_set_in_hooks (all_file_decl_data, get_section_data,
@@ -1308,7 +1316,7 @@ lto_main (int debug_p ATTRIBUTE_UNUSED)
/* Skip over the rest if any errors were found. FIXME lto, this
should be reorganized to use the pass manager. */
if (errorcount)
- return;
+ goto finish;
/* FIXME lto. This loop needs to be changed to use the pass manager to
call the ipa passes directly. */
@@ -1325,9 +1333,10 @@ lto_main (int debug_p ATTRIBUTE_UNUSED)
/* Now that we have input the cgraph, we need to clear all of the aux
nodes and read the functions if we are not running in WPA mode.
- FIXME!!!!! This loop obviously leaves a lot to be desired:
- 1) it loads all of the functions at once.
- 2) it closes and reopens the files over and over again.
+ FIXME lto. When not operating in WPA mode, this loop will:
+
+ 1) Load all of the functions at once.
+ 2) Close and reopen the files over and over again.
It would obviously be better for the cgraph code to look to load
a batch of functions and sort those functions by the file they
@@ -1337,31 +1346,20 @@ lto_main (int debug_p ATTRIBUTE_UNUSED)
small part of what will be a complex set of management
issues. */
for (node = cgraph_nodes; node; node = node->next)
- {
- /* FIXME!!! There really needs to be some check to see if the
- function is really not external here. Currently the only
- check is to see if the section was defined in the file_data
- index. There is of course the value in the node->aux field
- that is nulled out in the previous line, but we should really
- be able to look at the cgraph info at the is point and make
- the proper determination. Honza will fix this. */
- lto_materialize_function (node);
- }
+ lto_materialize_function (node);
+
current_function_decl = NULL;
set_cfun (NULL);
/* Inform the middle end about the global variables we have seen. */
for (i = 0; VEC_iterate (tree, lto_global_var_decls, i, decl); i++)
- rest_of_decl_compilation (decl,
- /*top_level=*/1,
- /*at_end=*/0);
+ rest_of_decl_compilation (decl, 1, 0);
/* Fix up any calls to DECLs that have become not exception throwing. */
lto_fixup_nothrow_decls ();
/* Let the middle end know that we have read and merged all of the
input files. */
- /*cgraph_finalize_compilation_unit ();*/
if (!flag_wpa)
cgraph_optimize ();
else
@@ -1400,6 +1398,10 @@ lto_main (int debug_p ATTRIBUTE_UNUSED)
}
XDELETEVEC (output_files);
}
+
+finish:
+ /* Stop the LTO timer. */
+ timevar_pop (lto_timer);
}
#include "gt-lto-lto.h"
Index: lto/Make-lang.in
===================================================================
--- lto/Make-lang.in (revision 142242)
+++ lto/Make-lang.in (working copy)
@@ -97,7 +97,7 @@ lto/lto.o: lto/lto.c $(CONFIG_H) $(CGRAP
$(LTO_TREE_H) dwarf2out.h tree-ssa-operands.h gt-lto-lto.h \
lto-section.h $(LTO_SECTION_IN_H) tree-pass.h $(LTO_SECTION_OUT_H) \
pointer-set.h vec.h $(BITMAP_H) $(IPA_PROP_H) lto/common.h \
- diagnostic.h lto-utils.h
+ diagnostic.h lto-utils.h timevar.h
lto/lto-elf.o: lto/lto-elf.c $(CONFIG_H) coretypes.h $(SYSTEM_H) \
toplev.h $(LTO_H) $(TM_H)
lto/common.o: lto/common.h
Index: lto/ltrans-driver
===================================================================
--- lto/ltrans-driver (revision 142242)
+++ lto/ltrans-driver (working copy)
@@ -25,6 +25,16 @@
# to be set. It generates a temporary Makefile, and uses it to convert .o
# files to .ltrans.o files.
+# See if CFLAGS includes -v or -save-temps to react accordingly.
+verbose=0
+save_temps=0
+for f in $CFLAGS ; do
+ if [ "$f" = "'-v'" ] ; then
+ verbose=1
+ elif [ "$f" = "'-save-temps'" ] ; then
+ save_temps=1
+ fi
+done
# Create a temporary directory $tmp in $TMPDIR (default /tmp).
# Use mktemp if possible; otherwise fall back on mkdir,
@@ -40,14 +50,17 @@
(umask 077 && mkdir "$tmp")
} || exit $?
-# Remove the temporary directory on exit or if a SIGTERM or SIGINT is received.
-trap 'rm -rf $tmp' TERM INT EXIT
+# Remove the temporary directory on exit or if a SIGTERM or SIGINT is
+# received.
+if [ $save_temps -eq 0 ] ; then
+ trap 'rm -rf $tmp' TERM INT EXIT
+fi
# Create a temporary Makefile.
makefile=$tmp/Makefile
touch $makefile
-# We have to clear these to avoid problems with this make invocations getting
+# We have to clear these to avoid problems with this make invocation getting
# confused with variables set by (for example) "make -j 2 check".
unset MAKEFLAGS
unset MAKEINFO
@@ -67,7 +80,26 @@ done
echo "all: $outputlist" >> $makefile
-${MAKE-make} -f $makefile all > $tmp/make.log 2>&1
-if [ $? -ne 0 ] ; then
- cat $tmp/make.log
+quiet="--quiet"
+if [ $verbose -eq 1 ] ; then
+ quiet=""
+ set -x
+fi
+
+# Use some simple heuristics to determine how much parallelism to use
+# when invoking make. Note that this probably only works reliably on
+# Linux. Also, the load may spike right after the calculation, so
+# it's not foolproof.
+awk=/usr/bin/awk
+uptime=/usr/bin/uptime
+getconf=/usr/bin/getconf
+par=1
+if [ -x $awk -a -x $uptime -a -x $getconf ] ; then
+ loadavg=$($uptime | $awk '{ l = $(NF - 2); print int (strtonum (l)); }')
+ nprocs=$($getconf _NPROCESSORS_ONLN)
+ if [ $loadavg -lt $nprocs ] ; then
+ par=$[($nprocs - $loadavg) * 2]
+ fi
fi
+${MAKE-make} $quiet -f $makefile -j $par all
+exit $?
Index: passes.c
===================================================================
--- passes.c (revision 142242)
+++ passes.c (working copy)
@@ -1195,7 +1195,17 @@ execute_ipa_summary_passes (struct ipa_o
&& ipa_pass->generate_summary)
{
pass_init_dump_file (pass);
+
+ /* If a timevar is present, start it. */
+ if (pass->tv_id)
+ timevar_push (pass->tv_id);
+
ipa_pass->generate_summary ();
+
+ /* Stop timevar. */
+ if (pass->tv_id)
+ timevar_pop (pass->tv_id);
+
pass_fini_dump_file (pass);
}
ipa_pass = (struct ipa_opt_pass *)ipa_pass->pass.next;
@@ -1377,7 +1387,7 @@ static void
ipa_write_summaries_2 (struct opt_pass *pass, cgraph_node_set set,
struct lto_out_decl_state *state)
{
- do
+ while (pass)
{
struct ipa_opt_pass *ipa_pass = (struct ipa_opt_pass *)pass;
gcc_assert (!current_function_decl);
@@ -1386,17 +1396,28 @@ ipa_write_summaries_2 (struct opt_pass *
if (pass->type == IPA_PASS
&& ipa_pass->write_summary
&& (!pass->gate || pass->gate ()))
- ipa_pass->write_summary (set);
+ {
+ /* If a timevar is present, start it. */
+ if (pass->tv_id)
+ timevar_push (pass->tv_id);
+
+ ipa_pass->write_summary (set);
+
+ /* If a timevar is present, start it. */
+ if (pass->tv_id)
+ timevar_pop (pass->tv_id);
+ }
+
if (pass->sub && pass->sub->type != GIMPLE_PASS)
ipa_write_summaries_2 (pass->sub, set, state);
+
pass = pass->next;
}
- while (pass);
}
-/* Helper function of ipa_write_summaries. Creates and destroys the decl state
- and calls ipa_write_summaries_2 for all passes that have summaries. SET is
- the set of nodes to be written. */
+/* Helper function of ipa_write_summaries. Creates and destroys the
+ decl state and calls ipa_write_summaries_2 for all passes that have
+ summaries. SET is the set of nodes to be written. */
static void
ipa_write_summaries_1 (cgraph_node_set set)
@@ -1412,8 +1433,7 @@ ipa_write_summaries_1 (cgraph_node_set s
lto_delete_out_decl_state (state);
}
-/* Write out summaries of all cgraph nodes in SET. If SET is NULL, write out
- all summaries of all nodes. */
+/* Write out summaries for all the nodes in the callgraph. */
void
ipa_write_summaries (void)
@@ -1433,6 +1453,10 @@ ipa_write_summaries (void)
}
}
+
+/* Write all the summaries for the cgraph nodes in SET. If SET is
+ NULL, write out all summaries of all nodes. */
+
void
ipa_write_summaries_of_cgraph_node_set (cgraph_node_set set)
{
@@ -1446,24 +1470,39 @@ ipa_write_summaries_of_cgraph_node_set (
static void
ipa_read_summaries_1 (struct opt_pass *pass)
{
- do
+ while (pass)
{
- struct ipa_opt_pass *ipa_pass = (struct ipa_opt_pass *)pass;
+ struct ipa_opt_pass *ipa_pass = (struct ipa_opt_pass *) pass;
+
gcc_assert (!current_function_decl);
gcc_assert (!cfun);
gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
+
if (pass->gate == NULL || pass->gate ())
{
if (pass->type == IPA_PASS && ipa_pass->read_summary)
- ipa_pass->read_summary ();
+ {
+ /* If a timevar is present, start it. */
+ if (pass->tv_id)
+ timevar_push (pass->tv_id);
+
+ ipa_pass->read_summary ();
+
+ /* Stop timevar. */
+ if (pass->tv_id)
+ timevar_pop (pass->tv_id);
+ }
+
if (pass->sub && pass->sub->type != GIMPLE_PASS)
ipa_read_summaries_1 (pass->sub);
}
pass = pass->next;
}
- while (pass);
}
+
+/* Read all the summaries for all_regular_ipa_passes and all_lto_gen_passes. */
+
void
ipa_read_summaries (void)
{
Index: lto-section-out.c
===================================================================
--- lto-section-out.c (revision 142242)
+++ lto-section-out.c (working copy)
@@ -1335,7 +1335,7 @@ struct ipa_opt_pass pass_ipa_lto_finish_
NULL, /* sub */
NULL, /* next */
0, /* static_pass_number */
- TV_IPA_LTO_OUT, /* tv_id */
+ TV_IPA_LTO_DECL_IO, /* tv_id */
0, /* properties_required */
0, /* properties_provided */
0, /* properties_destroyed */