From: Alexander Monakov Date: Tue, 25 Jul 2017 10:53:58 +0000 (+0300) Subject: domwalk: optimize basic block sorting X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e5df270eeccbc5892b7f40769e7725b13a36f7df;p=gcc.git domwalk: optimize basic block sorting * domwalk.c (cmp_bb_postorder): Simplify. (sort_bbs_postorder): New function. Use it... (dom_walker::walk): ...here to optimize common cases. From-SVN: r250502 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9177c6a8f5b..42697c510a9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2017-07-25 Alexander Monakov + + * domwalk.c (cmp_bb_postorder): Simplify. + (sort_bbs_postorder): New function. Use it... + (dom_walker::walk): ...here to optimize common cases. + 2017-07-25 Martin Liska PR ipa/81520 diff --git a/gcc/domwalk.c b/gcc/domwalk.c index a0daae6b2d8..ff6604e5686 100644 --- a/gcc/domwalk.c +++ b/gcc/domwalk.c @@ -128,19 +128,45 @@ along with GCC; see the file COPYING3. If not see which is currently an abstraction over walking tree statements. Thus the dominator walker is currently only useful for trees. */ +/* Reverse postorder index of each basic block. */ static int *bb_postorder; static int cmp_bb_postorder (const void *a, const void *b) { - basic_block bb1 = *(basic_block *)const_cast(a); - basic_block bb2 = *(basic_block *)const_cast(b); - if (bb1->index == bb2->index) - return 0; + basic_block bb1 = *(const basic_block *)(a); + basic_block bb2 = *(const basic_block *)(b); /* Place higher completion number first (pop off lower number first). */ - if (bb_postorder[bb1->index] > bb_postorder[bb2->index]) - return -1; - return 1; + return bb_postorder[bb2->index] - bb_postorder[bb1->index]; +} + +/* Permute array BBS of N basic blocks in postorder, + i.e. by descending number in BB_POSTORDER array. */ + +static void +sort_bbs_postorder (basic_block *bbs, int n) +{ + if (__builtin_expect (n == 2, true)) + { + basic_block bb0 = bbs[0], bb1 = bbs[1]; + if (bb_postorder[bb0->index] < bb_postorder[bb1->index]) + bbs[0] = bb1, bbs[1] = bb0; + } + else if (__builtin_expect (n == 3, true)) + { + basic_block bb0 = bbs[0], bb1 = bbs[1], bb2 = bbs[2]; + if (bb_postorder[bb0->index] < bb_postorder[bb1->index]) + std::swap (bb0, bb1); + if (bb_postorder[bb1->index] < bb_postorder[bb2->index]) + { + std::swap (bb1, bb2); + if (bb_postorder[bb0->index] < bb_postorder[bb1->index]) + std::swap (bb0, bb1); + } + bbs[0] = bb0, bbs[1] = bb1, bbs[2] = bb2; + } + else + qsort (bbs, n, sizeof *bbs, cmp_bb_postorder); } /* Constructor for a dom walker. @@ -284,16 +310,8 @@ dom_walker::walk (basic_block bb) for (dest = first_dom_son (m_dom_direction, bb); dest; dest = next_dom_son (m_dom_direction, dest)) worklist[sp++] = dest; - if (m_dom_direction == CDI_DOMINATORS) - switch (sp - saved_sp) - { - case 0: - case 1: - break; - default: - qsort (&worklist[saved_sp], sp - saved_sp, - sizeof (basic_block), cmp_bb_postorder); - } + if (sp - saved_sp > 1 && m_dom_direction == CDI_DOMINATORS) + sort_bbs_postorder (&worklist[saved_sp], sp - saved_sp); } /* NULL is used to mark pop operations in the recursion stack. */ while (sp > 0 && !worklist[sp - 1])