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. This patch has been tested on x86_64-pc-linux-gnu with make bootstrap and make -k check with no new failures. Ok for mainline? 2022-03-15 Roger Sayle <ro...@nextmovesoftware.com> gcc/ChangeLog * gimple-match-head.cc (single_use): Implement inline using a single loop. Thanks in advance, Roger --
diff --git a/gcc/gimple-match-head.cc b/gcc/gimple-match-head.cc index 74d5818..fc537b9 100644 --- a/gcc/gimple-match-head.cc +++ b/gcc/gimple-match-head.cc @@ -1163,7 +1163,22 @@ types_match (tree t1, tree t2) static inline bool single_use (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,