mirror of
https://github.com/gcc-mirror/gcc.git
synced 2024-11-21 13:40:47 +00:00
ipcp don't propagate where not needed
This patch disables propagation of ipcp information into partitions where all instances of the node are marked to be inlined. Motivation: Incremental LTO needs stable values between compilations to be effective. This requirement fails with following example: void heavily_used_function(int); ... heavily_used_function(__LINE__); Ipcp creates long list of all __LINE__ arguments, and then propagates it with every function clone, even though for inlined functions this information is not useful. gcc/ChangeLog: * ipa-prop.cc (write_ipcp_transformation_info): Disable uneeded value propagation. * lto-cgraph.cc (lto_symtab_encoder_encode): Default values. (lto_symtab_encoder_always_inlined_p): New. (lto_set_symtab_encoder_not_always_inlined): New. (add_node_to): Set always inlined. * lto-streamer.h (struct lto_encoder_entry): New field. (lto_symtab_encoder_always_inlined_p): New.
This commit is contained in:
parent
6d8764cc1f
commit
05e70ff921
@ -5405,9 +5405,15 @@ write_ipcp_transformation_info (output_block *ob, cgraph_node *node,
|
||||
streamer_write_bitpack (&bp);
|
||||
}
|
||||
|
||||
streamer_write_uhwi (ob, vec_safe_length (ts->m_vr));
|
||||
for (const ipa_vr &parm_vr : ts->m_vr)
|
||||
parm_vr.streamer_write (ob);
|
||||
/* If all instances of this node are inlined, ipcp info is not useful. */
|
||||
if (!lto_symtab_encoder_only_for_inlining_p (encoder, node))
|
||||
{
|
||||
streamer_write_uhwi (ob, vec_safe_length (ts->m_vr));
|
||||
for (const ipa_vr &parm_vr : ts->m_vr)
|
||||
parm_vr.streamer_write (ob);
|
||||
}
|
||||
else
|
||||
streamer_write_uhwi (ob, 0);
|
||||
}
|
||||
|
||||
/* Stream in the aggregate value replacement chain for NODE from IB. */
|
||||
|
@ -113,7 +113,7 @@ lto_symtab_encoder_encode (lto_symtab_encoder_t encoder,
|
||||
|
||||
if (!encoder->map)
|
||||
{
|
||||
lto_encoder_entry entry = {node, false, false, false};
|
||||
lto_encoder_entry entry (node);
|
||||
|
||||
ref = encoder->nodes.length ();
|
||||
encoder->nodes.safe_push (entry);
|
||||
@ -123,7 +123,7 @@ lto_symtab_encoder_encode (lto_symtab_encoder_t encoder,
|
||||
size_t *slot = encoder->map->get (node);
|
||||
if (!slot || !*slot)
|
||||
{
|
||||
lto_encoder_entry entry = {node, false, false, false};
|
||||
lto_encoder_entry entry (node);
|
||||
ref = encoder->nodes.length ();
|
||||
if (!slot)
|
||||
encoder->map->put (node, ref + 1);
|
||||
@ -168,6 +168,15 @@ lto_symtab_encoder_delete_node (lto_symtab_encoder_t encoder,
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Return TRUE if the NODE and its clones are always inlined. */
|
||||
|
||||
bool
|
||||
lto_symtab_encoder_only_for_inlining_p (lto_symtab_encoder_t encoder,
|
||||
struct cgraph_node *node)
|
||||
{
|
||||
int index = lto_symtab_encoder_lookup (encoder, node);
|
||||
return encoder->nodes[index].only_for_inlining;
|
||||
}
|
||||
|
||||
/* Return TRUE if we should encode the body of NODE (if any). */
|
||||
|
||||
@ -179,17 +188,6 @@ lto_symtab_encoder_encode_body_p (lto_symtab_encoder_t encoder,
|
||||
return encoder->nodes[index].body;
|
||||
}
|
||||
|
||||
/* Specify that we encode the body of NODE in this partition. */
|
||||
|
||||
static void
|
||||
lto_set_symtab_encoder_encode_body (lto_symtab_encoder_t encoder,
|
||||
struct cgraph_node *node)
|
||||
{
|
||||
int index = lto_symtab_encoder_encode (encoder, node);
|
||||
gcc_checking_assert (encoder->nodes[index].node == node);
|
||||
encoder->nodes[index].body = true;
|
||||
}
|
||||
|
||||
/* Return TRUE if we should encode initializer of NODE (if any). */
|
||||
|
||||
bool
|
||||
@ -797,13 +795,28 @@ output_refs (lto_symtab_encoder_t encoder)
|
||||
|
||||
static void
|
||||
add_node_to (lto_symtab_encoder_t encoder, struct cgraph_node *node,
|
||||
bool include_body)
|
||||
bool include_body, bool not_inlined)
|
||||
{
|
||||
if (node->clone_of)
|
||||
add_node_to (encoder, node->clone_of, include_body);
|
||||
add_node_to (encoder, node->clone_of, include_body, not_inlined);
|
||||
|
||||
int index = lto_symtab_encoder_encode (encoder, node);
|
||||
gcc_checking_assert (encoder->nodes[index].node == node);
|
||||
|
||||
if (include_body)
|
||||
lto_set_symtab_encoder_encode_body (encoder, node);
|
||||
lto_symtab_encoder_encode (encoder, node);
|
||||
encoder->nodes[index].body = true;
|
||||
if (not_inlined)
|
||||
encoder->nodes[index].only_for_inlining = false;
|
||||
}
|
||||
|
||||
/* Add NODE into encoder as well as nodes it is cloned from.
|
||||
Do it in a way so clones appear first. */
|
||||
|
||||
static void
|
||||
add_node_to (lto_symtab_encoder_t encoder, struct cgraph_node *node,
|
||||
bool include_body)
|
||||
{
|
||||
add_node_to (encoder, node, include_body, include_body && !node->inlined_to);
|
||||
}
|
||||
|
||||
/* Add all references in NODE to encoders. */
|
||||
|
@ -443,12 +443,21 @@ struct lto_stats_d
|
||||
/* Entry of LTO symtab encoder. */
|
||||
struct lto_encoder_entry
|
||||
{
|
||||
/* Constructors. */
|
||||
lto_encoder_entry () {}
|
||||
lto_encoder_entry (symtab_node* n)
|
||||
: node (n), in_partition (false), body (false), only_for_inlining (true),
|
||||
initializer (false)
|
||||
{}
|
||||
|
||||
symtab_node *node;
|
||||
/* Is the node in this partition (i.e. ltrans of this partition will
|
||||
be responsible for outputting it)? */
|
||||
unsigned int in_partition:1;
|
||||
/* Do we encode body in this partition? */
|
||||
unsigned int body:1;
|
||||
/* Do we stream this node only for inlining? */
|
||||
unsigned int only_for_inlining:1;
|
||||
/* Do we encode initializer in this partition?
|
||||
For example the readonly variable initializers are encoded to aid
|
||||
constant folding even if they are not in the partition. */
|
||||
@ -911,6 +920,8 @@ void lto_symtab_encoder_delete (lto_symtab_encoder_t);
|
||||
bool lto_symtab_encoder_delete_node (lto_symtab_encoder_t, symtab_node *);
|
||||
bool lto_symtab_encoder_encode_body_p (lto_symtab_encoder_t,
|
||||
struct cgraph_node *);
|
||||
bool lto_symtab_encoder_only_for_inlining_p (lto_symtab_encoder_t,
|
||||
struct cgraph_node *);
|
||||
bool lto_symtab_encoder_in_partition_p (lto_symtab_encoder_t,
|
||||
symtab_node *);
|
||||
void lto_set_symtab_encoder_in_partition (lto_symtab_encoder_t,
|
||||
|
Loading…
Reference in New Issue
Block a user