mirror of
https://github.com/gcc-mirror/gcc.git
synced 2026-05-06 14:59:39 +02:00
lto/124289 - Correctly handle toplevel asm with -flto-partition=cache
This patch adds create_asm_partitions to cache partitioning to prevent issues with non-renameable symbols (while partition joining) and static asm symbols (while partition splitting). All other relevant partitionings use create_asm_partitions. This was not used in cache partitioning, because toplevel asm could be in principle special handled in cache partitioning with marginally better results, but I never implemented it. lto/124289 gcc/lto/ChangeLog: * lto-partition.cc (enum map1to1_content): New. (map_1_to_1): Use map1to1_content. (lto_1_to_1_map): Likewise. (create_asm_partitions): Likewise. (lto_max_map): Likewise. (lto_cache_map): Use create_asm_partitions. gcc/testsuite/ChangeLog: * gcc.dg/lto/toplevel-extended-asm-2_0.c: Add padding to asm label. * gcc.dg/lto/toplevel-extended-asm-2_1.c: Add padding to asm label.
This commit is contained in:
@@ -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<lto_file_decl_data *, ltrans_partition> 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<asm_node*>(anode->next))
|
||||
node_into_file_partition (anode, pmap);
|
||||
if (content & map1to1_asm)
|
||||
for (anode = symtab->first_asm_symbol (); anode;
|
||||
anode = safe_as_a<asm_node*>(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<ltrans_partition> 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);
|
||||
|
||||
@@ -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 ();
|
||||
|
||||
@@ -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 ();
|
||||
|
||||
Reference in New Issue
Block a user