diff --git a/gcc/lto/lto-partition.cc b/gcc/lto/lto-partition.cc index 3eef5d9ddf2..4812142c48d 100644 --- a/gcc/lto/lto-partition.cc +++ b/gcc/lto/lto-partition.cc @@ -366,10 +366,25 @@ node_into_file_partition (toplevel_node* node, add_symbol_to_partition (partition, node); } +/* map_1_to_1 is able to partition a subset of symbols/asm. + map1to1_forced covers symbols/asm that we are forced to partition + with 1_to_1 partitioning, otherwise they may become broken. + Other symbols may be partitioned arbitrarily. */ +enum map1to1_content { + /* Forced symbols are always attempted. */ + map1to1_forced_symbols = 0, + + map1to1_asm = 1, + map1to1_other_symbols = 2, + map1to1_symbols = map1to1_forced_symbols | map1to1_other_symbols, + map1to1_forced = map1to1_asm | map1to1_forced_symbols, + map1to1_all = map1to1_symbols | map1to1_asm, +}; + /* Group cgraph nodes by input files. Used for symbols that must remain together. */ static void -map_1_to_1 (bool forced_symbols_only) +map_1_to_1 (map1to1_content content) { symtab_node *node; hash_map pmap; @@ -380,7 +395,7 @@ map_1_to_1 (bool forced_symbols_only) || symbol_partitioned_p (node)) continue; - if (forced_symbols_only && !node->must_remain_in_tu_name + if (!(content & map1to1_other_symbols) && !node->must_remain_in_tu_name && !node->must_remain_in_tu_body && !node->no_reorder) continue; @@ -388,8 +403,10 @@ map_1_to_1 (bool forced_symbols_only) } struct asm_node *anode; - for (anode = symtab->first_asm_symbol (); anode; anode = safe_as_a(anode->next)) - node_into_file_partition (anode, pmap); + if (content & map1to1_asm) + for (anode = symtab->first_asm_symbol (); anode; + anode = safe_as_a(anode->next)) + node_into_file_partition (anode, pmap); /* Order partitions by order of symbols because they are linked into binary that way. */ @@ -402,7 +419,7 @@ map_1_to_1 (bool forced_symbols_only) void lto_1_to_1_map (void) { - map_1_to_1 (false); + map_1_to_1 (map1to1_all); create_partition_if_empty (); } @@ -420,7 +437,7 @@ create_asm_partitions (int64_t target_size) { if (!symtab->first_asm_symbol ()) return; - map_1_to_1 (true); + map_1_to_1 (map1to1_forced); size_t join_into = 0; size_t join_from = 0; @@ -486,7 +503,7 @@ lto_max_map (void) ltrans_partition partition; /* Needed for toplevel assembly. */ - map_1_to_1 (true); + map_1_to_1 (map1to1_forced); FOR_EACH_SYMBOL (node) { @@ -1111,15 +1128,29 @@ private: void lto_cache_map (int n_lto_partitions, int max_partition_size) { - lto_1_to_1_map (); + cgraph_node *node; + int64_t total_size = 0; + FOR_EACH_DEFINED_FUNCTION (node) + if (node->get_partitioning_class () == SYMBOL_PARTITION && !node->alias) + total_size += ipa_size_summaries->get (node)->size; + + /* Separates toplevel asm into its own partitions and handles name conflicts. + + We could do this directly in cache partitioning without separating asm + into its own partitions in most cases. */ + create_asm_partitions (total_size / n_lto_partitions); + unsigned asm_n = ltrans_partitions.length (); + + map_1_to_1 (map1to1_symbols); + create_partition_if_empty (); std::vector partitions; - for (unsigned i = 0; i < ltrans_partitions.length (); ++i) + for (unsigned i = asm_n; i < ltrans_partitions.length (); ++i) { ltrans_partition part = ltrans_partitions[i]; partitions.push_back (part); } - ltrans_partitions.truncate (0); + ltrans_partitions.truncate (asm_n); partitioner_default partitioner = partitioner_default (param_min_partition_size, max_partition_size); diff --git a/gcc/testsuite/gcc.dg/lto/toplevel-extended-asm-2_0.c b/gcc/testsuite/gcc.dg/lto/toplevel-extended-asm-2_0.c index 84a7284d669..089ce2e0460 100644 --- a/gcc/testsuite/gcc.dg/lto/toplevel-extended-asm-2_0.c +++ b/gcc/testsuite/gcc.dg/lto/toplevel-extended-asm-2_0.c @@ -6,7 +6,7 @@ extern int use_statics (); extern int asm_var; static int a; -asm (".local %cc0\n %cc0:" :: ":"(&a)); +asm (".local %cc0\n %cc0: .long 0" :: ":"(&a)); int main() { return a + use_statics (); diff --git a/gcc/testsuite/gcc.dg/lto/toplevel-extended-asm-2_1.c b/gcc/testsuite/gcc.dg/lto/toplevel-extended-asm-2_1.c index 2b6c5539177..f0a6ec3fdf5 100644 --- a/gcc/testsuite/gcc.dg/lto/toplevel-extended-asm-2_1.c +++ b/gcc/testsuite/gcc.dg/lto/toplevel-extended-asm-2_1.c @@ -7,7 +7,7 @@ extern int asm_var; asm("%cc0:" :: ":" (&asm_var)); static int a; -asm (".local %cc0\n %cc0:" :: ":"(&a)); +asm (".local %cc0\n %cc0: .long 0" :: ":"(&a)); int use_statics () { static_asm_fn ();