There is a bad interaction between inlined C++ member functions
and LTO + profiledbootstrap, which leads to
LTO bootstrap to fail with bootstrap-profile:
Existing SSA name for symbol marked for renaming: aloop_37
In member function \u2018__base_ctor \u2019:
lto1: internal compiler error: SSA corruption
0xcd84eb update_ssa(unsigned int)
/export/project/git/gcc-regression/gcc/gcc/tree-into-ssa.c:3246
0xa5814c input_function
/export/project/git/gcc-regression/gcc/gcc/lto-streamer-in.c:1006
0xa5814c lto_read_body
/export/project/git/gcc-regression/gcc/gcc/lto-streamer-in.c:1070
0xa5814c lto_input_function_body(lto_file_decl_data*, cgraph_node*, char
const*)
/export/project/git/gcc-regression/gcc/gcc/lto-streamer-in.c:1112
0x66d2bc cgraph_get_body(cgraph_node*)
/export/project/git/gcc-regression/gcc/gcc/cgraph.c:2981
0x99aa58 ipa_merge_profiles(cgraph_node*, cgraph_node*)
/export/project/git/gcc-regression/gcc/gcc/ipa-utils.c:699
0x595a86 lto_cgraph_replace_node
/export/project/git/gcc-regression/gcc/gcc/lto/lto-symtab.c:82
0x596159 lto_symtab_merge_symbols_1
/export/project/git/gcc-regression/gcc/gcc/lto/lto-symtab.c:561
0x596159 lto_symtab_merge_symbols()
/export/project/git/gcc-regression/gcc/gcc/lto/lto-symtab.c:589
0x5850dd read_cgraph_and_symbols
/export/project/git/gcc-regression/gcc/gcc/lto/lto.c:2946
0x5850dd lto_main()
/export/project/git/gcc-regression/gcc/gcc/lto/lto.c:3255
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <http://gcc.gnu.org/bugs.html> for instructions.
There are only 2 files which don't inline all loop_iterator
member function and may be miscompiled:
File: ipa-inline-analysis.o
Symbol table '.symtab' contains 454 entries:
Num: Value Size Type Bind Vis Ndx Name
...
262: 0000000000000000 0 NOTYPE LOCAL DEFAULT 5
loop_iterator::loop_iterator(loop**, unsigned int)
...
352: 0000000000000000 89 FUNC WEAK DEFAULT 27
loop_iterator::next()
353: 0000000000000000 748 FUNC WEAK DEFAULT 30
loop_iterator::loop_iterator(loop**, unsigned int)
354: 0000000000000000 748 FUNC WEAK DEFAULT 30
loop_iterator::loop_iterator(loop**, unsigned int)
...
File: tree-cfg.o
Symbol table '.symtab' contains 783 entries:
Num: Value Size Type Bind Vis Ndx Name
...
385: 0000000000000000 0 NOTYPE LOCAL DEFAULT 5
loop_iterator::loop_iterator(loop**, unsigned int)
...
536: 0000000000000000 748 FUNC WEAK DEFAULT 34
loop_iterator::loop_iterator(loop**, unsigned int)
...
538: 0000000000000000 748 FUNC WEAK DEFAULT 34
loop_iterator::loop_iterator(loop**, unsigned int)
...
When either loop_iterator::next or loop_iterator::loop_iterator
inlined, bootstrap fails with the similar error. This patch
works around the problem by not inlining those 2 functions.
On Nehalem machine using "make -j8", without the patch, I got
17836.13user 638.12system 55:49.72elapsed
for bootstrap and
32362.67user 4313.11system 1:29:59elapsed
for running testsuite. With the patch, I got
7900.41user 640.39system 55:03.14elapsed
for bootstrap and
31891.96user 4251.23system 1:31:41elapse
for running testsuite. There is very little performance
difference and the binaries are also a little bit smaller:
16787252 34920 1098648 17920820 1117334
build-x86_64-linux/gcc/cc1
16809748 34920 1098648 17943316 111cb14
build-x86_64-linux.old/gcc/cc1
19188340 35008 1126552 20349900 13683cc
build-x86_64-linux/gcc/cc1objplus
18865150 35008 1121848 20022006 13182f6
build-x86_64-linux/gcc/cc1plus
19210836 35008 1126552 20372396 136dbac
build-x86_64-linux.old/gcc/cc1objplus
18887646 35008 1121848 20044502 131dad6
build-x86_64-linux.old/gcc/cc1plus
17274027 44056 1104024 18422107 119195b
build-x86_64-linux/gcc/f951
17296523 44056 1104024 18444603 119713b
build-x86_64-linux.old/gcc/f951
17354837 51424 1105752 18512013 11a788d
build-x86_64-linux/gcc/go1
17377333 51424 1105752 18534509 11ad06d
build-x86_64-linux.old/gcc/go1
20815529 43928 6289304 27148761 19e41d9
build-x86_64-linux/gcc/gnat1
20838025 43928 6289304 27171257 19e99b9
build-x86_64-linux.old/gcc/gnat1
15944305 35688 1095064 17075057 1048b71
build-x86_64-linux/gcc/jc1
15966801 35688 1095064 17097553 104e351
build-x86_64-linux.old/gcc/jc1
Should this patch be applied to restore LTO bootstrap with
bootstrap-profile?
Thanks.
H.J.
---
2013-11-28 H.J. Lu <[email protected]>
PR bootstrap/59199
* cfgloop.h (loop_iterator::next, loop_iterator::loop_iterator):
Moved to ...
* cfgloop.c (loop_iterator::next, loop_iterator::loop_iterator):
Here.
diff --git a/gcc/cfgloop.c b/gcc/cfgloop.c
index 0b12e73..3e34850 100644
--- a/gcc/cfgloop.c
+++ b/gcc/cfgloop.c
@@ -1919,3 +1919,95 @@ bb_loop_depth (const_basic_block bb)
{
return bb->loop_father ? loop_depth (bb->loop_father) : 0;
}
+
+loop_p
+loop_iterator::next ()
+{
+ int anum;
+
+ while (this->to_visit.iterate (this->idx, &anum))
+ {
+ this->idx++;
+ loop_p loop = get_loop (cfun, anum);
+ if (loop)
+ return loop;
+ }
+
+ return NULL;
+}
+
+loop_iterator::loop_iterator (loop_p *loop, unsigned flags)
+{
+ struct loop *aloop;
+ unsigned i;
+ int mn;
+
+ this->idx = 0;
+ if (!current_loops)
+ {
+ this->to_visit.create (0);
+ *loop = NULL;
+ return;
+ }
+
+ this->to_visit.create (number_of_loops (cfun));
+ mn = (flags & LI_INCLUDE_ROOT) ? 0 : 1;
+
+ if (flags & LI_ONLY_INNERMOST)
+ {
+ for (i = 0; vec_safe_iterate (current_loops->larray, i, &aloop); i++)
+ if (aloop != NULL
+ && aloop->inner == NULL
+ && aloop->num >= mn)
+ this->to_visit.quick_push (aloop->num);
+ }
+ else if (flags & LI_FROM_INNERMOST)
+ {
+ /* Push the loops to LI->TO_VISIT in postorder. */
+ for (aloop = current_loops->tree_root;
+ aloop->inner != NULL;
+ aloop = aloop->inner)
+ continue;
+
+ while (1)
+ {
+ if (aloop->num >= mn)
+ this->to_visit.quick_push (aloop->num);
+
+ if (aloop->next)
+ {
+ for (aloop = aloop->next;
+ aloop->inner != NULL;
+ aloop = aloop->inner)
+ continue;
+ }
+ else if (!loop_outer (aloop))
+ break;
+ else
+ aloop = loop_outer (aloop);
+ }
+ }
+ else
+ {
+ /* Push the loops to LI->TO_VISIT in preorder. */
+ aloop = current_loops->tree_root;
+ while (1)
+ {
+ if (aloop->num >= mn)
+ this->to_visit.quick_push (aloop->num);
+
+ if (aloop->inner != NULL)
+ aloop = aloop->inner;
+ else
+ {
+ while (aloop != NULL && aloop->next == NULL)
+ aloop = loop_outer (aloop);
+ if (aloop == NULL)
+ break;
+ aloop = aloop->next;
+ }
+ }
+ }
+
+ *loop = this->next ();
+}
diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h
index 68285a6..a76d243 100644
--- a/gcc/cfgloop.h
+++ b/gcc/cfgloop.h
@@ -547,7 +547,7 @@ struct loop_iterator
loop_iterator (loop_p *loop, unsigned flags);
~loop_iterator ();
- inline loop_p next ();
+ loop_p next ();
/* The list of loops to visit. */
vec<int> to_visit;
@@ -556,99 +556,6 @@ struct loop_iterator
unsigned idx;
};
-inline loop_p
-loop_iterator::next ()
-{
- int anum;
-
- while (this->to_visit.iterate (this->idx, &anum))
- {
- this->idx++;
- loop_p loop = get_loop (cfun, anum);
- if (loop)
- return loop;
- }
-
- return NULL;
-}
-
-inline
-loop_iterator::loop_iterator (loop_p *loop, unsigned flags)
-{
- struct loop *aloop;
- unsigned i;
- int mn;
-
- this->idx = 0;
- if (!current_loops)
- {
- this->to_visit.create (0);
- *loop = NULL;
- return;
- }
-
- this->to_visit.create (number_of_loops (cfun));
- mn = (flags & LI_INCLUDE_ROOT) ? 0 : 1;
-
- if (flags & LI_ONLY_INNERMOST)
- {
- for (i = 0; vec_safe_iterate (current_loops->larray, i, &aloop); i++)
- if (aloop != NULL
- && aloop->inner == NULL
- && aloop->num >= mn)
- this->to_visit.quick_push (aloop->num);
- }
- else if (flags & LI_FROM_INNERMOST)
- {
- /* Push the loops to LI->TO_VISIT in postorder. */
- for (aloop = current_loops->tree_root;
- aloop->inner != NULL;
- aloop = aloop->inner)
- continue;
-
- while (1)
- {
- if (aloop->num >= mn)
- this->to_visit.quick_push (aloop->num);
-
- if (aloop->next)
- {
- for (aloop = aloop->next;
- aloop->inner != NULL;
- aloop = aloop->inner)
- continue;
- }
- else if (!loop_outer (aloop))
- break;
- else
- aloop = loop_outer (aloop);
- }
- }
- else
- {
- /* Push the loops to LI->TO_VISIT in preorder. */
- aloop = current_loops->tree_root;
- while (1)
- {
- if (aloop->num >= mn)
- this->to_visit.quick_push (aloop->num);
-
- if (aloop->inner != NULL)
- aloop = aloop->inner;
- else
- {
- while (aloop != NULL && aloop->next == NULL)
- aloop = loop_outer (aloop);
- if (aloop == NULL)
- break;
- aloop = aloop->next;
- }
- }
- }
-
- *loop = this->next ();
-}
-
inline
loop_iterator::~loop_iterator ()
{