1 /* RTL factoring (sequence abstraction).
2 Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 2, or (at your option) any later
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING. If not, write to the Free
18 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
23 #include "coretypes.h"
27 #include "basic-block.h"
35 #include "tree-pass.h"
36 #include "tree-flow.h"
40 #include "addresses.h"
42 /* Sequence abstraction:
44 It is a size optimization method. The main idea of this technique is to
45 find identical sequences of code, which can be turned into procedures and
46 then replace all occurrences with calls to the newly created subroutine.
47 It is kind of an opposite of function inlining.
49 There are four major parts of this file:
52 In order to avoid the comparison of every insn with every other, hash
53 value will be designed for every insn by COMPUTE_HASH.
54 These hash values are used for grouping the sequence candidates. So
55 we only need to compare every insn with every other in same hash group.
57 FILL_HASH_BUCKET creates all hash values and stores into HASH_BUCKETS.
58 The result is used by COLLECT_PATTERN_SEQS.
61 In code matching the algorithm compares every two possible sequence
62 candidates which last insns are in the same hash group. If these
63 sequences are identical they will be stored and do further searches for
64 finding more sequences which are identical with the first one.
66 COLLECT_PATTERN_SEQS does the code matching and stores the results into
70 This part computes the gain of abstraction which could be archived when
71 turning the pattern sequence into a pseudo-function and its matching
72 sequences into pseudo-calls. After it the most effective sequences will
73 be marked for abstraction.
75 RECOMPUTE_GAIN does the gain computation. The sequences with the maximum
76 gain is on the top of PATTERN_SEQS.
79 This part turns the pattern sequence into a pseudo-function and its
80 matching sequences into pseudo-calls.
82 ABSTRACT_BEST_SEQ does the code merging.
87 // Original source // After sequence abstraction
91 jump_label = &&exit_0;
100 jump_label = &&exit_1;
108 jump_label = &&exit_2;
116 jump_label = &&exit_3;
128 - Use REG_ALLOC_ORDER when choosing link register.
129 - Handle JUMP_INSNs. Also handle volatile function calls (handle them
130 similar to unconditional jumps.)
131 - Test command line option -fpic.
134 /* Predicate yielding nonzero iff X is an abstractable insn. Non-jump insns are
136 #define ABSTRACTABLE_INSN_P(X) (INSN_P (X) && !JUMP_P (X))
138 /* First parameter of the htab_create function call. */
139 #define HASH_INIT 1023
141 /* Multiplier for cost of sequence call to avoid abstracting short
143 #ifndef SEQ_CALL_COST_MULTIPLIER
144 #define SEQ_CALL_COST_MULTIPLIER 2
147 /* Recomputes the cost of MSEQ pattern/matching sequence. */
148 #define RECOMPUTE_COST(SEQ) \
153 for (l = 0; l < SEQ->abstracted_length; l++) \
155 SEQ->cost += compute_rtx_cost (x); \
156 x = prev_insn_in_block (x); \
160 /* A sequence matching a pattern sequence. */
161 typedef struct matching_seq_def
163 /* The last insn in the matching sequence. */
166 /* Index of INSN instruction. */
169 /* The number of insns matching in this sequence and the pattern sequence.
173 /* The number of insns selected to abstract from this sequence. Less than
174 or equal to MATCHING_LENGTH. */
175 int abstracted_length;
177 /* The cost of the sequence. */
180 /* The next sequence in the chain matching the same pattern. */
181 struct matching_seq_def *next_matching_seq;
185 /* A pattern instruction sequence. */
186 typedef struct pattern_seq_def
188 /* The last insn in the pattern sequence. */
191 /* Index of INSN instruction. */
194 /* The gain of transforming the pattern sequence into a pseudo-function and
195 the matching sequences into pseudo-calls. */
198 /* The maximum of the ABSTRACTED_LENGTH of the matching sequences. */
199 int abstracted_length;
201 /* The cost of the sequence. */
204 /* The register used to hold the return address during the pseudo-call. */
207 /* The sequences matching this pattern. */
208 matching_seq matching_seqs;
210 /* The next pattern sequence in the chain. */
211 struct pattern_seq_def *next_pattern_seq;
215 /* A block of a pattern sequence. */
216 typedef struct seq_block_def
218 /* The number of insns in the block. */
221 /* The code_label of the block. */
224 /* The sequences entering the pattern sequence at LABEL. */
225 matching_seq matching_seqs;
227 /* The next block in the chain. The blocks are sorted by LENGTH in
229 struct seq_block_def *next_seq_block;
232 /* Contains same sequence candidates for further searching. */
233 typedef struct hash_bucket_def
235 /* The hash value of the group. */
238 /* List of sequence candidates. */
239 htab_t seq_candidates;
241 typedef const struct hash_bucket_def *const_p_hash_bucket;
243 /* Contains the last insn of the sequence, and its index value. */
244 typedef struct hash_elem_def
246 /* Unique index; ordered by FILL_HASH_BUCKET. */
249 /* The last insn in the sequence. */
252 /* The cached length of the insn. */
255 typedef const struct hash_elem_def *const_p_hash_elem;
257 /* The list of same sequence candidates. */
258 static htab_t hash_buckets;
260 /* The pattern sequences collected from the current functions. */
261 static pattern_seq pattern_seqs;
263 /* The blocks of the current pattern sequence. */
264 static seq_block seq_blocks;
266 /* Cost of calling sequence. */
267 static int seq_call_cost;
270 static int seq_jump_cost;
272 /* Cost of returning. */
273 static int seq_return_cost;
275 /* Returns the first insn preceding INSN for which INSN_P is true and belongs to
276 the same basic block. Returns NULL_RTX if no such insn can be found. */
279 prev_insn_in_block (rtx insn)
281 basic_block bb = BLOCK_FOR_INSN (insn);
286 while (insn != BB_HEAD (bb))
288 insn = PREV_INSN (insn);
295 /* Returns the hash value of INSN. */
298 compute_hash (rtx insn)
300 unsigned int hash = 0;
303 hash = INSN_CODE (insn) * 100;
305 prev = prev_insn_in_block (insn);
307 hash += INSN_CODE (prev);
312 /* Compute the cost of INSN rtx for abstraction. */
315 compute_rtx_cost (rtx insn)
317 struct hash_bucket_def tmp_bucket;
318 p_hash_bucket bucket;
319 struct hash_elem_def tmp_elem;
320 p_hash_elem elem = NULL;
323 /* Compute hash value for INSN. */
324 tmp_bucket.hash = compute_hash (insn);
326 /* Select the hash group. */
327 bucket = htab_find (hash_buckets, &tmp_bucket);
331 tmp_elem.insn = insn;
333 /* Select the insn. */
334 elem = htab_find (bucket->seq_candidates, &tmp_elem);
336 /* If INSN is parsed the cost will be the cached length. */
341 /* If we can't parse the INSN cost will be the instruction length. */
344 cost = get_attr_length (insn);
346 /* Cache the length. */
351 /* If we can't get an accurate estimate for a complex instruction,
352 assume that it has the same cost as a single fast instruction. */
353 return cost != 0 ? cost : COSTS_N_INSNS (1);
356 /* Determines the number of common insns in the sequences ending in INSN1 and
357 INSN2. Returns with LEN number of common insns and COST cost of sequence.
361 matching_length (rtx insn1, rtx insn2, int* len, int* cost)
370 while (x1 && x2 && (x1 != insn2) && (x2 != insn1)
371 && rtx_equal_p (PATTERN (x1), PATTERN (x2)))
374 (*cost) += compute_rtx_cost (x1);
375 x1 = prev_insn_in_block (x1);
376 x2 = prev_insn_in_block (x2);
380 /* Adds E0 as a pattern sequence to PATTERN_SEQS with E1 as a matching
384 match_seqs (p_hash_elem e0, p_hash_elem e1)
388 matching_seq mseq, p_prev, p_next;
390 /* Determines the cost of the sequence and return without doing anything
391 if it is too small to produce any gain. */
392 matching_length (e0->insn, e1->insn, &len, &cost);
393 if (cost <= seq_call_cost)
396 /* Prepend a new PATTERN_SEQ to PATTERN_SEQS if the last pattern sequence
397 does not end in E0->INSN. This assumes that once the E0->INSN changes
398 the old value will never appear again. */
399 if (!pattern_seqs || pattern_seqs->insn != e0->insn)
402 (pattern_seq) xmalloc (sizeof (struct pattern_seq_def));
403 pseq->insn = e0->insn;
405 pseq->gain = 0; /* Set to zero to force recomputing. */
406 pseq->abstracted_length = 0;
408 pseq->link_reg = NULL_RTX;
409 pseq->matching_seqs = NULL;
410 pseq->next_pattern_seq = pattern_seqs;
414 /* Find the position of E1 in the matching sequences list. */
416 p_next = pattern_seqs->matching_seqs;
417 while (p_next && p_next->idx < e1->idx)
420 p_next = p_next->next_matching_seq;
423 /* Add a new E1 matching sequence to the pattern sequence. We know that
424 it ends in E0->INSN. */
425 mseq = (matching_seq) xmalloc (sizeof (struct matching_seq_def));
426 mseq->insn = e1->insn;
428 mseq->matching_length = len;
429 mseq->abstracted_length = 0;
433 pattern_seqs->matching_seqs = mseq;
435 p_prev->next_matching_seq = mseq;
436 mseq->next_matching_seq = p_next;
439 /* Collects all pattern sequences and their matching sequences and puts them
440 into PATTERN_SEQS. */
443 collect_pattern_seqs (void)
445 htab_iterator hti0, hti1, hti2;
446 p_hash_bucket hash_bucket;
450 bitmap_head stack_reg_live;
452 /* Extra initialization step to ensure that no stack registers (if present)
453 are live across abnormal edges. Set a flag in STACK_REG_LIVE for an insn
454 if a stack register is live after the insn. */
455 bitmap_initialize (&stack_reg_live, NULL);
463 /* Initialize liveness propagation. */
464 INIT_REG_SET (&live);
465 bitmap_copy (&live, DF_LR_OUT (bb));
466 df_simulate_artificial_refs_at_end (bb, &live);
468 /* Propagate liveness info and mark insns where a stack reg is live. */
470 for (insn = BB_END (bb); ; insn = prev)
472 prev = PREV_INSN (insn);
476 for (reg = FIRST_STACK_REG; reg <= LAST_STACK_REG; reg++)
478 if (REGNO_REG_SET_P (&live, reg))
480 bitmap_set_bit (&stack_reg_live, INSN_UID (insn));
486 if (insn == BB_HEAD (bb))
488 df_simulate_one_insn_backwards (bb, insn, &live);
492 /* Free unused data. */
493 CLEAR_REG_SET (&live);
497 /* Initialize PATTERN_SEQS to empty. */
500 /* Try to match every abstractable insn with every other insn in the same
503 FOR_EACH_HTAB_ELEMENT (hash_buckets, hash_bucket, p_hash_bucket, hti0)
504 if (htab_elements (hash_bucket->seq_candidates) > 1)
505 FOR_EACH_HTAB_ELEMENT (hash_bucket->seq_candidates, e0, p_hash_elem, hti1)
506 FOR_EACH_HTAB_ELEMENT (hash_bucket->seq_candidates, e1, p_hash_elem,
510 && !bitmap_bit_p (&stack_reg_live, INSN_UID (e0->insn))
511 && !bitmap_bit_p (&stack_reg_live, INSN_UID (e1->insn))
516 /* Free unused data. */
517 bitmap_clear (&stack_reg_live);
521 /* Transforms a regset to a HARD_REG_SET. Every hard register in REGS is added
522 to hregs. Additionally, the hard counterpart of every renumbered pseudo
523 register is also added. */
526 renumbered_reg_set_to_hard_reg_set (HARD_REG_SET * hregs, regset regs)
530 REG_SET_TO_HARD_REG_SET (*hregs, regs);
531 for (r = FIRST_PSEUDO_REGISTER; r < max_regno; r++)
532 if (REGNO_REG_SET_P (regs, r) && reg_renumber[r] >= 0)
533 SET_HARD_REG_BIT (*hregs, reg_renumber[r]);
536 /* Clears the bits in REGS for all registers, which are live in the sequence
537 give by its last INSN and its LENGTH. */
540 clear_regs_live_in_seq (HARD_REG_SET * regs, rtx insn, int length)
548 /* Initialize liveness propagation. */
549 bb = BLOCK_FOR_INSN (insn);
550 INIT_REG_SET (&live);
551 bitmap_copy (&live, DF_LR_OUT (bb));
552 df_simulate_artificial_refs_at_end (bb, &live);
554 /* Propagate until INSN if found. */
555 for (x = BB_END (bb); x != insn;)
556 df_simulate_one_insn_backwards (bb, insn, &live);
558 /* Clear registers live after INSN. */
559 renumbered_reg_set_to_hard_reg_set (&hlive, &live);
560 AND_COMPL_HARD_REG_SET (*regs, hlive);
562 /* Clear registers live in and before the sequence. */
563 for (i = 0; i < length;)
565 rtx prev = PREV_INSN (x);
566 df_simulate_one_insn_backwards (bb, insn, &live);
570 renumbered_reg_set_to_hard_reg_set (&hlive, &live);
571 AND_COMPL_HARD_REG_SET (*regs, hlive);
578 /* Free unused data. */
579 CLEAR_REG_SET (&live);
582 /* Computes the gain of turning PSEQ into a pseudo-function and its matching
583 sequences into pseudo-calls. Also computes and caches the number of insns to
584 abstract from the matching sequences. */
587 recompute_gain_for_pattern_seq (pattern_seq pseq)
593 HARD_REG_SET linkregs;
595 /* Initialize data. */
596 SET_HARD_REG_SET (linkregs);
597 pseq->link_reg = NULL_RTX;
598 pseq->abstracted_length = 0;
600 pseq->gain = -(seq_call_cost - seq_jump_cost + seq_return_cost);
602 /* Determine ABSTRACTED_LENGTH and COST for matching sequences of PSEQ.
603 ABSTRACTED_LENGTH may be less than MATCHING_LENGTH if sequences in the
604 same block overlap. */
606 for (mseq = pseq->matching_seqs; mseq; mseq = mseq->next_matching_seq)
608 /* Determine ABSTRACTED_LENGTH. */
609 if (mseq->next_matching_seq)
610 mseq->abstracted_length = (int)(mseq->next_matching_seq->idx -
613 mseq->abstracted_length = mseq->matching_length;
615 if (mseq->abstracted_length > mseq->matching_length)
616 mseq->abstracted_length = mseq->matching_length;
618 /* Compute the cost of sequence. */
619 RECOMPUTE_COST (mseq);
621 /* If COST is big enough registers live in this matching sequence
622 should not be used as a link register. Also set ABSTRACTED_LENGTH
624 if (mseq->cost > seq_call_cost)
626 clear_regs_live_in_seq (&linkregs, mseq->insn,
627 mseq->abstracted_length);
628 if (mseq->abstracted_length > pseq->abstracted_length)
629 pseq->abstracted_length = mseq->abstracted_length;
633 /* Modify ABSTRACTED_LENGTH of PSEQ if pattern sequence overlaps with one
634 of the matching sequences. */
635 for (mseq = pseq->matching_seqs; mseq; mseq = mseq->next_matching_seq)
638 for (i = 0; (i < pseq->abstracted_length) && (x != mseq->insn); i++)
639 x = prev_insn_in_block (x);
640 pseq->abstracted_length = i;
643 /* Compute the cost of pattern sequence. */
644 RECOMPUTE_COST (pseq);
646 /* No gain if COST is too small. */
647 if (pseq->cost <= seq_call_cost)
653 /* Ensure that no matching sequence is longer than the pattern sequence. */
654 for (mseq = pseq->matching_seqs; mseq; mseq = mseq->next_matching_seq)
656 if (mseq->abstracted_length > pseq->abstracted_length)
658 mseq->abstracted_length = pseq->abstracted_length;
659 RECOMPUTE_COST (mseq);
661 /* Once the length is stabilizing the gain can be calculated. */
662 if (mseq->cost > seq_call_cost)
663 pseq->gain += mseq->cost - seq_call_cost;
666 /* No need to do further work if there is no gain. */
670 /* Should not use registers live in the pattern sequence as link register.
672 clear_regs_live_in_seq (&linkregs, pseq->insn, pseq->abstracted_length);
674 /* Determine whether pattern sequence contains a call_insn. */
677 for (i = 0; i < pseq->abstracted_length; i++)
684 x = prev_insn_in_block (x);
687 /* Should not use a register as a link register if - it is a fixed
688 register, or - the sequence contains a call insn and the register is a
689 call used register, or - the register needs to be saved if used in a
690 function but was not used before (since saving it can invalidate already
691 computed frame pointer offsets), or - the register cannot be used as a
694 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
696 #ifdef REGNO_OK_FOR_INDIRECT_JUMP_P
697 || (!REGNO_OK_FOR_INDIRECT_JUMP_P (i, Pmode))
699 || (!ok_for_base_p_1 (i, Pmode, MEM, SCRATCH))
700 || (!reg_class_subset_p (REGNO_REG_CLASS (i),
701 base_reg_class (VOIDmode, MEM, SCRATCH)))
703 || (hascall && call_used_regs[i])
704 || (!call_used_regs[i] && !df_regs_ever_live_p (i)))
705 CLEAR_HARD_REG_BIT (linkregs, i);
707 /* Find an appropriate register to be used as the link register. */
708 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
709 if (TEST_HARD_REG_BIT (linkregs, i))
711 pseq->link_reg = gen_rtx_REG (Pmode, i);
715 /* Abstraction is not possible if no link register is available, so set
721 /* Deallocates memory occupied by PSEQ and its matching seqs. */
724 free_pattern_seq (pattern_seq pseq)
726 while (pseq->matching_seqs)
728 matching_seq mseq = pseq->matching_seqs;
729 pseq->matching_seqs = mseq->next_matching_seq;
736 /* Computes the gain for pattern sequences. Pattern sequences producing no gain
737 are deleted. The pattern sequence with the biggest gain is moved to the first
738 place of PATTERN_SEQS. */
741 recompute_gain (void)
747 for (pseq = &pattern_seqs; *pseq;)
749 if ((*pseq)->gain <= 0)
750 recompute_gain_for_pattern_seq (*pseq);
752 if ((*pseq)->gain > 0)
754 if ((*pseq)->gain > maxgain)
756 pattern_seq temp = *pseq;
757 (*pseq) = temp->next_pattern_seq;
758 temp->next_pattern_seq = pattern_seqs;
760 maxgain = pattern_seqs->gain;
764 pseq = &(*pseq)->next_pattern_seq;
769 pattern_seq temp = *pseq;
770 *pseq = temp->next_pattern_seq;
771 free_pattern_seq (temp);
776 /* Updated those pattern sequences and matching sequences, which overlap with
777 the sequence given by INSN and LEN. Deletes sequences shrinking below a
781 erase_from_pattern_seqs (rtx insn, int len)
791 for (pseq = &pattern_seqs; *pseq;)
795 for (x = (*pseq)->insn; x && (x != insn);
796 x = prev_insn_in_block (x))
799 pcost += compute_rtx_cost (x);
802 if (pcost <= seq_call_cost)
804 pattern_seq temp = *pseq;
805 *pseq = temp->next_pattern_seq;
806 free_pattern_seq (temp);
810 for (mseq = &(*pseq)->matching_seqs; *mseq;)
814 for (x = (*mseq)->insn;
815 x && (x != insn) && (mlen < plen)
816 && (mlen < (*mseq)->matching_length);
817 x = prev_insn_in_block (x))
820 mcost += compute_rtx_cost (x);
823 if (mcost <= seq_call_cost)
825 matching_seq temp = *mseq;
826 *mseq = temp->next_matching_seq;
828 /* Set to 0 to force gain recomputation. */
833 if (mlen < (*mseq)->matching_length)
835 (*mseq)->cost = mcost;
836 (*mseq)->matching_length = mlen;
837 /* Set to 0 to force gain recomputation. */
840 mseq = &(*mseq)->next_matching_seq;
844 pseq = &(*pseq)->next_pattern_seq;
849 insn = prev_insn_in_block (insn);
853 /* Updates those pattern sequences and matching sequences, which overlap with
854 the pattern sequence with the biggest gain and its matching sequences. */
857 update_pattern_seqs (void)
859 pattern_seq bestpseq;
862 bestpseq = pattern_seqs;
863 pattern_seqs = bestpseq->next_pattern_seq;
865 for (mseq = bestpseq->matching_seqs; mseq; mseq = mseq->next_matching_seq)
866 if (mseq->cost > seq_call_cost)
867 erase_from_pattern_seqs (mseq->insn, mseq->abstracted_length);
868 erase_from_pattern_seqs (bestpseq->insn, bestpseq->abstracted_length);
870 bestpseq->next_pattern_seq = pattern_seqs;
871 pattern_seqs = bestpseq;
874 /* Groups together those matching sequences of the best pattern sequence, which
875 have the same ABSTRACTED_LENGTH and puts these groups in ascending order.
876 SEQ_BLOCKS contains the result. */
879 determine_seq_blocks (void)
885 /* Initialize SEQ_BLOCKS to empty. */
888 /* Process all matching sequences. */
889 for (mseq = &pattern_seqs->matching_seqs; *mseq;)
891 /* Deal only with matching sequences being long enough. */
892 if ((*mseq)->cost <= seq_call_cost)
894 mseq = &(*mseq)->next_matching_seq;
898 /* Ensure that SB contains a seq_block with the appropriate length.
899 Insert a new seq_block if necessary. */
900 if (!seq_blocks || ((*mseq)->abstracted_length < seq_blocks->length))
902 sb = (seq_block) xmalloc (sizeof (struct seq_block_def));
903 sb->length = (*mseq)->abstracted_length;
904 sb->label = NULL_RTX;
905 sb->matching_seqs = 0;
906 sb->next_seq_block = seq_blocks;
911 for (sb = seq_blocks; sb; sb = sb->next_seq_block)
913 if ((*mseq)->abstracted_length == sb->length)
915 if (!sb->next_seq_block
916 || ((*mseq)->abstracted_length <
917 sb->next_seq_block->length))
920 (seq_block) xmalloc (sizeof (struct seq_block_def));
921 temp->length = (*mseq)->abstracted_length;
922 temp->label = NULL_RTX;
923 temp->matching_seqs = 0;
924 temp->next_seq_block = sb->next_seq_block;
925 sb->next_seq_block = temp;
930 /* Remove the matching sequence from the linked list of the pattern
931 sequence and link it to SB. */
933 *mseq = m->next_matching_seq;
934 m->next_matching_seq = sb->matching_seqs;
935 sb->matching_seqs = m;
939 /* Builds a symbol_ref for LABEL. */
942 gen_symbol_ref_rtx_for_label (rtx label)
947 ASM_GENERATE_INTERNAL_LABEL (name, "L", CODE_LABEL_NUMBER (label));
948 sym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
949 SYMBOL_REF_FLAGS (sym) = SYMBOL_FLAG_LOCAL;
953 /* Ensures that INSN is the last insn in its block and returns the block label
954 of the next block. */
957 block_label_after (rtx insn)
959 basic_block bb = BLOCK_FOR_INSN (insn);
960 if ((insn == BB_END (bb)) && (bb->next_bb != EXIT_BLOCK_PTR))
961 return block_label (bb->next_bb);
963 return block_label (split_block (bb, insn)->dest);
966 /* Ensures that the last insns of the best pattern and its matching sequences
967 are the last insns in their block. Additionally, extends the live set at the
968 end of the pattern sequence with the live sets at the end of the matching
972 split_blocks_after_seqs (void)
977 block_label_after (pattern_seqs->insn);
978 for (sb = seq_blocks; sb; sb = sb->next_seq_block)
980 for (mseq = sb->matching_seqs; mseq; mseq = mseq->next_matching_seq)
982 block_label_after (mseq->insn);
983 IOR_REG_SET (df_get_live_out (BLOCK_FOR_INSN (pattern_seqs->insn)),
984 df_get_live_out (BLOCK_FOR_INSN (mseq->insn)));
989 /* Splits the best pattern sequence according to SEQ_BLOCKS. Emits pseudo-call
990 and -return insns before and after the sequence. */
993 split_pattern_seq (void)
997 rtx retlabel, retjmp, saveinsn;
1001 insn = pattern_seqs->insn;
1002 bb = BLOCK_FOR_INSN (insn);
1004 /* Get the label after the sequence. This will be the return address. The
1005 label will be referenced using a symbol_ref so protect it from
1007 retlabel = block_label_after (insn);
1008 LABEL_PRESERVE_P (retlabel) = 1;
1010 /* Emit an indirect jump via the link register after the sequence acting
1011 as the return insn. Also emit a barrier and update the basic block. */
1012 retjmp = emit_jump_insn_after (gen_indirect_jump (pattern_seqs->link_reg),
1014 emit_barrier_after (BB_END (bb));
1016 /* Replace all outgoing edges with a new one to the block of RETLABEL. */
1017 while (EDGE_COUNT (bb->succs) != 0)
1018 remove_edge (EDGE_SUCC (bb, 0));
1019 make_edge (bb, BLOCK_FOR_INSN (retlabel), EDGE_ABNORMAL);
1021 /* Split the sequence according to SEQ_BLOCKS and cache the label of the
1022 resulting basic blocks. */
1024 for (sb = seq_blocks; sb; sb = sb->next_seq_block)
1026 for (; i < sb->length; i++)
1027 insn = prev_insn_in_block (insn);
1029 sb->label = block_label (split_block (bb, insn)->dest);
1032 /* Emit an insn saving the return address to the link register before the
1034 saveinsn = emit_insn_after (gen_move_insn (pattern_seqs->link_reg,
1035 gen_symbol_ref_rtx_for_label
1036 (retlabel)), BB_END (bb));
1037 /* Update liveness info. */
1038 SET_REGNO_REG_SET (df_get_live_out (bb),
1039 REGNO (pattern_seqs->link_reg));
1042 /* Deletes the insns of the matching sequences of the best pattern sequence and
1043 replaces them with pseudo-calls to the pattern sequence. */
1046 erase_matching_seqs (void)
1052 rtx retlabel, saveinsn, callinsn;
1055 for (sb = seq_blocks; sb; sb = sb->next_seq_block)
1057 for (mseq = sb->matching_seqs; mseq; mseq = mseq->next_matching_seq)
1060 bb = BLOCK_FOR_INSN (insn);
1062 /* Get the label after the sequence. This will be the return
1063 address. The label will be referenced using a symbol_ref so
1064 protect it from deleting. */
1065 retlabel = block_label_after (insn);
1066 LABEL_PRESERVE_P (retlabel) = 1;
1068 /* Delete the insns of the sequence. */
1069 for (i = 0; i < sb->length; i++)
1070 insn = prev_insn_in_block (insn);
1071 delete_basic_block (split_block (bb, insn)->dest);
1073 /* Emit an insn saving the return address to the link register
1074 before the deleted sequence. */
1075 saveinsn = emit_insn_after (gen_move_insn (pattern_seqs->link_reg,
1076 gen_symbol_ref_rtx_for_label
1079 BLOCK_FOR_INSN (saveinsn) = bb;
1081 /* Emit a jump to the appropriate part of the pattern sequence
1082 after the save insn. Also update the basic block. */
1083 callinsn = emit_jump_insn_after (gen_jump (sb->label), saveinsn);
1084 JUMP_LABEL (callinsn) = sb->label;
1085 LABEL_NUSES (sb->label)++;
1086 BLOCK_FOR_INSN (callinsn) = bb;
1087 BB_END (bb) = callinsn;
1089 /* Maintain control flow and liveness information. */
1090 SET_REGNO_REG_SET (df_get_live_out (bb),
1091 REGNO (pattern_seqs->link_reg));
1092 emit_barrier_after (BB_END (bb));
1093 make_single_succ_edge (bb, BLOCK_FOR_INSN (sb->label), 0);
1094 IOR_REG_SET (df_get_live_out (bb),
1095 df_get_live_in (BLOCK_FOR_INSN (sb->label)));
1097 make_edge (BLOCK_FOR_INSN (seq_blocks->label),
1098 BLOCK_FOR_INSN (retlabel), EDGE_ABNORMAL);
1103 /* Deallocates SEQ_BLOCKS and all the matching sequences. */
1106 free_seq_blocks (void)
1110 seq_block sb = seq_blocks;
1111 while (sb->matching_seqs)
1113 matching_seq mseq = sb->matching_seqs;
1114 sb->matching_seqs = mseq->next_matching_seq;
1117 seq_blocks = sb->next_seq_block;
1122 /* Transforms the best pattern sequence into a pseudo-function and its matching
1123 sequences to pseudo-calls. Afterwards the best pattern sequence is removed
1124 from PATTERN_SEQS. */
1127 abstract_best_seq (void)
1129 pattern_seq bestpseq;
1131 /* Do the abstraction. */
1132 determine_seq_blocks ();
1133 split_blocks_after_seqs ();
1134 split_pattern_seq ();
1135 erase_matching_seqs ();
1138 /* Record the usage of the link register. */
1139 df_set_regs_ever_live (REGNO (pattern_seqs->link_reg), true);
1141 /* Remove the best pattern sequence. */
1142 bestpseq = pattern_seqs;
1143 pattern_seqs = bestpseq->next_pattern_seq;
1144 free_pattern_seq (bestpseq);
1147 /* Prints info on the pattern sequences to the dump file. */
1150 dump_pattern_seqs (void)
1158 fprintf (dump_file, ";; Pattern sequences\n");
1159 for (pseq = pattern_seqs; pseq; pseq = pseq->next_pattern_seq)
1161 fprintf (dump_file, "Pattern sequence at insn %d matches sequences at",
1162 INSN_UID (pseq->insn));
1163 for (mseq = pseq->matching_seqs; mseq; mseq = mseq->next_matching_seq)
1165 fprintf (dump_file, " insn %d (length %d)", INSN_UID (mseq->insn),
1166 mseq->matching_length);
1167 if (mseq->next_matching_seq)
1168 fprintf (dump_file, ",");
1170 fprintf (dump_file, ".\n");
1172 fprintf (dump_file, "\n");
1175 /* Prints info on the best pattern sequence transformed in the ITER-th
1176 iteration to the dump file. */
1179 dump_best_pattern_seq (int iter)
1186 fprintf (dump_file, ";; Iteration %d\n", iter);
1188 "Best pattern sequence with %d gain is at insn %d (length %d).\n",
1189 pattern_seqs->gain, INSN_UID (pattern_seqs->insn),
1190 pattern_seqs->abstracted_length);
1191 fprintf (dump_file, "Matching sequences are at");
1192 for (mseq = pattern_seqs->matching_seqs; mseq;
1193 mseq = mseq->next_matching_seq)
1195 fprintf (dump_file, " insn %d (length %d)", INSN_UID (mseq->insn),
1196 mseq->abstracted_length);
1197 if (mseq->next_matching_seq)
1198 fprintf (dump_file, ",");
1200 fprintf (dump_file, ".\n");
1201 fprintf (dump_file, "Using reg %d as link register.\n\n",
1202 REGNO (pattern_seqs->link_reg));
1205 /* Htab hash function for hash_bucket_def structure. */
1208 htab_hash_bucket (const void *p)
1210 const_p_hash_bucket bucket = (const_p_hash_bucket) p;
1211 return bucket->hash;
1214 /* Htab equal function for hash_bucket_def structure. */
1217 htab_eq_bucket (const void *p0, const void *p1)
1219 return htab_hash_bucket (p0) == htab_hash_bucket (p1);
1222 /* Htab delete function for hash_bucket_def structure. */
1225 htab_del_bucket (void *p)
1227 p_hash_bucket bucket = (p_hash_bucket) p;
1229 if (bucket->seq_candidates)
1230 htab_delete (bucket->seq_candidates);
1235 /* Htab hash function for hash_bucket_def structure. */
1238 htab_hash_elem (const void *p)
1240 const_p_hash_elem elem = (const_p_hash_elem) p;
1241 return htab_hash_pointer (elem->insn);
1244 /* Htab equal function for hash_bucket_def structure. */
1247 htab_eq_elem (const void *p0, const void *p1)
1249 return htab_hash_elem (p0) == htab_hash_elem (p1);
1252 /* Htab delete function for hash_bucket_def structure. */
1255 htab_del_elem (void *p)
1257 p_hash_elem elem = (p_hash_elem) p;
1261 /* Creates a hash value for each sequence candidate and saves them
1265 fill_hash_bucket (void)
1270 p_hash_bucket bucket;
1271 struct hash_bucket_def tmp_bucket;
1273 unsigned long insn_idx;
1278 FOR_BB_INSNS_REVERSE (bb, insn)
1280 if (!ABSTRACTABLE_INSN_P (insn))
1283 /* Compute hash value for INSN. */
1284 tmp_bucket.hash = compute_hash (insn);
1286 /* Select the hash group. */
1287 bucket = htab_find (hash_buckets, &tmp_bucket);
1291 /* Create a new hash group. */
1292 bucket = (p_hash_bucket) xcalloc (1,
1293 sizeof (struct hash_bucket_def));
1294 bucket->hash = tmp_bucket.hash;
1295 bucket->seq_candidates = NULL;
1297 slot = htab_find_slot (hash_buckets, &tmp_bucket, INSERT);
1301 /* Create new list for storing sequence candidates. */
1302 if (!bucket->seq_candidates)
1303 bucket->seq_candidates = htab_create (HASH_INIT,
1308 elem = (p_hash_elem) xcalloc (1, sizeof (struct hash_elem_def));
1310 elem->idx = insn_idx;
1311 elem->length = get_attr_length (insn);
1313 /* Insert INSN into BUCKET hash bucket. */
1314 slot = htab_find_slot (bucket->seq_candidates, elem, INSERT);
1322 /* Computes the cost of calling sequence and the cost of return. */
1325 compute_init_costs (void)
1327 rtx rtx_jump, rtx_store, rtx_return, reg, label;
1334 label = block_label (bb);
1335 reg = gen_rtx_REG (Pmode, 0);
1337 /* Pattern for indirect jump. */
1338 rtx_jump = gen_indirect_jump (reg);
1340 /* Pattern for storing address. */
1341 rtx_store = gen_rtx_SET (VOIDmode, reg, gen_symbol_ref_rtx_for_label (label));
1343 /* Pattern for return insn. */
1344 rtx_return = gen_jump (label);
1346 /* The cost of jump. */
1347 seq_jump_cost = compute_rtx_cost (make_jump_insn_raw (rtx_jump));
1349 /* The cost of calling sequence. */
1350 seq_call_cost = seq_jump_cost + compute_rtx_cost (make_insn_raw (rtx_store));
1352 /* The cost of return. */
1353 seq_return_cost = compute_rtx_cost (make_jump_insn_raw (rtx_return));
1355 /* Simple heuristic for minimal sequence cost. */
1356 seq_call_cost = (int)(seq_call_cost * (double)SEQ_CALL_COST_MULTIPLIER);
1359 /* Finds equivalent insn sequences in the current function and retains only one
1360 instance of them which is turned into a pseudo-function. The additional
1361 copies are erased and replaced by pseudo-calls to the retained sequence. */
1367 df_set_flags (DF_LR_RUN_DCE);
1370 /* Create a hash list for COLLECT_PATTERN_SEQS. */
1371 hash_buckets = htab_create (HASH_INIT, htab_hash_bucket , htab_eq_bucket ,
1373 fill_hash_bucket ();
1375 /* Compute the common cost of abstraction. */
1376 compute_init_costs ();
1378 /* Build an initial set of pattern sequences from the current function. */
1379 collect_pattern_seqs ();
1380 dump_pattern_seqs ();
1382 /* Iterate until there are no sequences to abstract. */
1383 for (iter = 1;; iter++)
1385 /* Recompute gain for sequences if necessary and select sequence with
1390 dump_best_pattern_seq (iter);
1391 /* Update the cached info of the other sequences and force gain
1392 recomputation where needed. */
1393 update_pattern_seqs ();
1394 /* Turn best sequences into pseudo-functions and -calls. */
1395 abstract_best_seq ();
1398 /* Cleanup hash tables. */
1399 htab_delete (hash_buckets);
1402 /* The gate function for TREE_OPT_PASS. */
1405 gate_rtl_seqabstr (void)
1407 return flag_rtl_seqabstr;
1410 /* The entry point of the sequence abstraction algorithm. */
1413 rest_of_rtl_seqabstr (void)
1415 /* Abstract out common insn sequences. */
1420 struct tree_opt_pass pass_rtl_seqabstr = {
1421 "seqabstr", /* name */
1422 gate_rtl_seqabstr, /* gate */
1423 rest_of_rtl_seqabstr, /* execute */
1426 0, /* static_pass_number */
1427 TV_SEQABSTR, /* tv_id */
1428 0, /* properties_required */
1429 0, /* properties_provided */
1430 0, /* properties_destroyed */
1431 0, /* todo_flags_start */
1434 TODO_ggc_collect, /* todo_flags_finish */