Performance/size improvement to single_use when matching GIMPLE.

This patch improves the implementation of single_use as used in code
generated from match.pd for patterns using :s.  The current implementation
contains the logic "has_zero_uses (t) || has_single_use (t)" which
performs a loop over the uses to first check if there are zero non-debug
uses [which is rare], then another loop over these uses to check if there
is exactly one non-debug use.  This can be better implemented using a
single loop.

This function is currently inlined over 800 times in gimple-match.cc,
whose .o on x86_64-pc-linux-gnu is now up to 30 Mbytes, so speeding up
and shrinking this function should help offset the growth in match.pd
for GCC 12.

I've also done an analysis of the stage3 sizes of gimple-match.o on
x86_64-pc-linux-gnu, which I believe is dominated by debug information,
the .o file is 30MB in stage3, but only 4.8M in stage2.  Before my
proposed patch gimple-match.o is 31385160 bytes.  The patch as proposed
yesterday (using a single loop in single_use) reduces that to 31105040
bytes, saving 280120 bytes.  The suggestion to remove the "inline"
keyword saves only 56 more bytes, but annotating ATTRIBUTE_PURE on a
function prototype was curiously effective, saving 1888 bytes.

before:   31385160
after:    31105040	saved 280120
-inline:  31104984	saved 56
+pure:    31103096	saved 1888

2022-03-16  Roger Sayle  <roger@nextmovesoftware.com>
	    Richard Biener  <rguenther@suse.de>

gcc/ChangeLog
	* gimple-match-head.cc (single_use): Implement inline using a
	single loop.
This commit is contained in:
Roger Sayle 2022-03-16 09:27:33 +00:00
parent 7690bee9f3
commit 6aef670e48
1 changed files with 21 additions and 3 deletions

View File

@ -1160,10 +1160,28 @@ types_match (tree t1, tree t2)
non-SSA_NAME (ie constants) and zero uses to cope with uses
that aren't linked up yet. */
static inline bool
single_use (tree t)
static bool
single_use (const_tree) ATTRIBUTE_PURE;
static bool
single_use (const_tree t)
{
return TREE_CODE (t) != SSA_NAME || has_zero_uses (t) || has_single_use (t);
if (TREE_CODE (t) != SSA_NAME)
return true;
/* Inline return has_zero_uses (t) || has_single_use (t); */
const ssa_use_operand_t *const head = &(SSA_NAME_IMM_USE_NODE (t));
const ssa_use_operand_t *ptr;
bool single = false;
for (ptr = head->next; ptr != head; ptr = ptr->next)
if (USE_STMT(ptr) && !is_gimple_debug (USE_STMT (ptr)))
{
if (single)
return false;
single = true;
}
return true;
}
/* Return true if math operations should be canonicalized,