dma: bump man page date
[dragonfly.git] / contrib / gcc-4.4 / gcc / rtl-factoring.c
blob4c879691e9f32f2d89340e8ef16599e7034ade5a
1 /* RTL factoring (sequence abstraction).
2 Copyright (C) 2004, 2005, 2006, 2007, 2008 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 3, or (at your option) any later
9 version.
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
14 for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "tm.h"
24 #include "rtl.h"
25 #include "obstack.h"
26 #include "basic-block.h"
27 #include "resource.h"
28 #include "flags.h"
29 #include "ggc.h"
30 #include "regs.h"
31 #include "params.h"
32 #include "expr.h"
33 #include "tm_p.h"
34 #include "tree-pass.h"
35 #include "tree-flow.h"
36 #include "timevar.h"
37 #include "output.h"
38 #include "df.h"
39 #include "addresses.h"
41 /* Sequence abstraction:
43 It is a size optimization method. The main idea of this technique is to
44 find identical sequences of code, which can be turned into procedures and
45 then replace all occurrences with calls to the newly created subroutine.
46 It is kind of an opposite of function inlining.
48 There are four major parts of this file:
50 sequence fingerprint
51 In order to avoid the comparison of every insn with every other, hash
52 value will be designed for every insn by COMPUTE_HASH.
53 These hash values are used for grouping the sequence candidates. So
54 we only need to compare every insn with every other in same hash group.
56 FILL_HASH_BUCKET creates all hash values and stores into HASH_BUCKETS.
57 The result is used by COLLECT_PATTERN_SEQS.
59 code matching
60 In code matching the algorithm compares every two possible sequence
61 candidates which last insns are in the same hash group. If these
62 sequences are identical they will be stored and do further searches for
63 finding more sequences which are identical with the first one.
65 COLLECT_PATTERN_SEQS does the code matching and stores the results into
66 PATTERN_SEQS.
68 gain computation
69 This part computes the gain of abstraction which could be archived when
70 turning the pattern sequence into a pseudo-function and its matching
71 sequences into pseudo-calls. After it the most effective sequences will
72 be marked for abstraction.
74 RECOMPUTE_GAIN does the gain computation. The sequences with the maximum
75 gain is on the top of PATTERN_SEQS.
77 abstract code
78 This part turns the pattern sequence into a pseudo-function and its
79 matching sequences into pseudo-calls.
81 ABSTRACT_BEST_SEQ does the code merging.
84 C code example:
86 // Original source // After sequence abstraction
87 { {
88 void *jump_label;
89 ... ...
90 jump_label = &&exit_0;
91 entry_0:
92 I0; I0;
93 I1; I1;
94 I2; I2;
95 I3; I3;
96 goto *jump_label;
97 exit_0:
98 ... ...
99 jump_label = &&exit_1;
100 goto entry_0;
105 exit_1:
106 ... ...
107 jump_label = &&exit_2;
108 goto entry_0;
113 exit_2:
114 ... ...
115 jump_label = &&exit_3;
116 goto entry_0;
121 exit_3:
122 ... ...
126 TODO:
127 - Use REG_ALLOC_ORDER when choosing link register.
128 - Handle JUMP_INSNs. Also handle volatile function calls (handle them
129 similar to unconditional jumps.)
130 - Test command line option -fpic.
133 /* Predicate yielding nonzero iff X is an abstractable insn. Non-jump insns are
134 abstractable. */
135 #define ABSTRACTABLE_INSN_P(X) (INSN_P (X) && !JUMP_P (X))
137 /* First parameter of the htab_create function call. */
138 #define HASH_INIT 1023
140 /* Multiplier for cost of sequence call to avoid abstracting short
141 sequences. */
142 #ifndef SEQ_CALL_COST_MULTIPLIER
143 #define SEQ_CALL_COST_MULTIPLIER 2
144 #endif
146 /* Recomputes the cost of MSEQ pattern/matching sequence. */
147 #define RECOMPUTE_COST(SEQ) \
149 int l; \
150 rtx x = SEQ->insn; \
151 SEQ->cost = 0; \
152 for (l = 0; l < SEQ->abstracted_length; l++) \
154 SEQ->cost += compute_rtx_cost (x); \
155 x = prev_insn_in_block (x); \
159 /* A sequence matching a pattern sequence. */
160 typedef struct matching_seq_def
162 /* The last insn in the matching sequence. */
163 rtx insn;
165 /* Index of INSN instruction. */
166 unsigned long idx;
168 /* The number of insns matching in this sequence and the pattern sequence.
170 int matching_length;
172 /* The number of insns selected to abstract from this sequence. Less than
173 or equal to MATCHING_LENGTH. */
174 int abstracted_length;
176 /* The cost of the sequence. */
177 int cost;
179 /* The next sequence in the chain matching the same pattern. */
180 struct matching_seq_def *next_matching_seq;
181 } *matching_seq;
184 /* A pattern instruction sequence. */
185 typedef struct pattern_seq_def
187 /* The last insn in the pattern sequence. */
188 rtx insn;
190 /* Index of INSN instruction. */
191 unsigned long idx;
193 /* The gain of transforming the pattern sequence into a pseudo-function and
194 the matching sequences into pseudo-calls. */
195 int gain;
197 /* The maximum of the ABSTRACTED_LENGTH of the matching sequences. */
198 int abstracted_length;
200 /* The cost of the sequence. */
201 int cost;
203 /* The register used to hold the return address during the pseudo-call. */
204 rtx link_reg;
206 /* The sequences matching this pattern. */
207 matching_seq matching_seqs;
209 /* The next pattern sequence in the chain. */
210 struct pattern_seq_def *next_pattern_seq;
211 } *pattern_seq;
214 /* A block of a pattern sequence. */
215 typedef struct seq_block_def
217 /* The number of insns in the block. */
218 int length;
220 /* The code_label of the block. */
221 rtx label;
223 /* The sequences entering the pattern sequence at LABEL. */
224 matching_seq matching_seqs;
226 /* The next block in the chain. The blocks are sorted by LENGTH in
227 ascending order. */
228 struct seq_block_def *next_seq_block;
229 } *seq_block;
231 /* Contains same sequence candidates for further searching. */
232 typedef struct hash_bucket_def
234 /* The hash value of the group. */
235 unsigned int hash;
237 /* List of sequence candidates. */
238 htab_t seq_candidates;
239 } *p_hash_bucket;
240 typedef const struct hash_bucket_def *const_p_hash_bucket;
242 /* Contains the last insn of the sequence, and its index value. */
243 typedef struct hash_elem_def
245 /* Unique index; ordered by FILL_HASH_BUCKET. */
246 unsigned long idx;
248 /* The last insn in the sequence. */
249 rtx insn;
251 /* The cached length of the insn. */
252 int length;
253 } *p_hash_elem;
254 typedef const struct hash_elem_def *const_p_hash_elem;
256 /* The list of same sequence candidates. */
257 static htab_t hash_buckets;
259 /* The pattern sequences collected from the current functions. */
260 static pattern_seq pattern_seqs;
262 /* The blocks of the current pattern sequence. */
263 static seq_block seq_blocks;
265 /* Cost of calling sequence. */
266 static int seq_call_cost;
268 /* Cost of jump. */
269 static int seq_jump_cost;
271 /* Cost of returning. */
272 static int seq_return_cost;
274 /* Returns the first insn preceding INSN for which INSN_P is true and belongs to
275 the same basic block. Returns NULL_RTX if no such insn can be found. */
277 static rtx
278 prev_insn_in_block (rtx insn)
280 basic_block bb = BLOCK_FOR_INSN (insn);
282 if (!bb)
283 return NULL_RTX;
285 while (insn != BB_HEAD (bb))
287 insn = PREV_INSN (insn);
288 if (INSN_P (insn))
289 return insn;
291 return NULL_RTX;
294 /* Returns the hash value of INSN. */
296 static unsigned int
297 compute_hash (rtx insn)
299 unsigned int hash = 0;
300 rtx prev;
302 hash = INSN_CODE (insn) * 100;
304 prev = prev_insn_in_block (insn);
305 if (prev)
306 hash += INSN_CODE (prev);
308 return hash;
311 /* Compute the cost of INSN rtx for abstraction. */
313 static int
314 compute_rtx_cost (rtx insn)
316 struct hash_bucket_def tmp_bucket;
317 p_hash_bucket bucket;
318 struct hash_elem_def tmp_elem;
319 p_hash_elem elem = NULL;
320 int cost = -1;
322 /* Compute hash value for INSN. */
323 tmp_bucket.hash = compute_hash (insn);
325 /* Select the hash group. */
326 bucket = (p_hash_bucket) htab_find (hash_buckets, &tmp_bucket);
328 if (bucket)
330 tmp_elem.insn = insn;
332 /* Select the insn. */
333 elem = (p_hash_elem) htab_find (bucket->seq_candidates, &tmp_elem);
335 /* If INSN is parsed the cost will be the cached length. */
336 if (elem)
337 cost = elem->length;
340 /* If we can't parse the INSN cost will be the instruction length. */
341 if (cost == -1)
343 cost = get_attr_length (insn);
345 /* Cache the length. */
346 if (elem)
347 elem->length = cost;
350 /* If we can't get an accurate estimate for a complex instruction,
351 assume that it has the same cost as a single fast instruction. */
352 return cost != 0 ? cost : COSTS_N_INSNS (1);
355 /* Determines the number of common insns in the sequences ending in INSN1 and
356 INSN2. Returns with LEN number of common insns and COST cost of sequence.
359 static void
360 matching_length (rtx insn1, rtx insn2, int* len, int* cost)
362 rtx x1;
363 rtx x2;
365 x1 = insn1;
366 x2 = insn2;
367 *len = 0;
368 *cost = 0;
369 while (x1 && x2 && (x1 != insn2) && (x2 != insn1)
370 && rtx_equal_p (PATTERN (x1), PATTERN (x2)))
372 (*len)++;
373 (*cost) += compute_rtx_cost (x1);
374 x1 = prev_insn_in_block (x1);
375 x2 = prev_insn_in_block (x2);
379 /* Adds E0 as a pattern sequence to PATTERN_SEQS with E1 as a matching
380 sequence. */
382 static void
383 match_seqs (p_hash_elem e0, p_hash_elem e1)
385 int len;
386 int cost;
387 matching_seq mseq, p_prev, p_next;
389 /* Determines the cost of the sequence and return without doing anything
390 if it is too small to produce any gain. */
391 matching_length (e0->insn, e1->insn, &len, &cost);
392 if (cost <= seq_call_cost)
393 return;
395 /* Prepend a new PATTERN_SEQ to PATTERN_SEQS if the last pattern sequence
396 does not end in E0->INSN. This assumes that once the E0->INSN changes
397 the old value will never appear again. */
398 if (!pattern_seqs || pattern_seqs->insn != e0->insn)
400 pattern_seq pseq =
401 (pattern_seq) xmalloc (sizeof (struct pattern_seq_def));
402 pseq->insn = e0->insn;
403 pseq->idx = e0->idx;
404 pseq->gain = 0; /* Set to zero to force recomputing. */
405 pseq->abstracted_length = 0;
406 pseq->cost = 0;
407 pseq->link_reg = NULL_RTX;
408 pseq->matching_seqs = NULL;
409 pseq->next_pattern_seq = pattern_seqs;
410 pattern_seqs = pseq;
413 /* Find the position of E1 in the matching sequences list. */
414 p_prev = NULL;
415 p_next = pattern_seqs->matching_seqs;
416 while (p_next && p_next->idx < e1->idx)
418 p_prev = p_next;
419 p_next = p_next->next_matching_seq;
422 /* Add a new E1 matching sequence to the pattern sequence. We know that
423 it ends in E0->INSN. */
424 mseq = (matching_seq) xmalloc (sizeof (struct matching_seq_def));
425 mseq->insn = e1->insn;
426 mseq->idx = e1->idx;
427 mseq->matching_length = len;
428 mseq->abstracted_length = 0;
429 mseq->cost = cost;
431 if (p_prev == NULL)
432 pattern_seqs->matching_seqs = mseq;
433 else
434 p_prev->next_matching_seq = mseq;
435 mseq->next_matching_seq = p_next;
438 /* Collects all pattern sequences and their matching sequences and puts them
439 into PATTERN_SEQS. */
441 static void
442 collect_pattern_seqs (void)
444 htab_iterator hti0, hti1, hti2;
445 p_hash_bucket hash_bucket;
446 p_hash_elem e0, e1;
447 #if defined STACK_REGS || defined HAVE_cc0
448 basic_block bb;
449 bitmap_head dont_collect;
451 /* Extra initialization step to ensure that no stack registers (if present)
452 or cc0 code (if present) are live across abnormal edges.
453 Set a flag in DONT_COLLECT for an insn if a stack register is live
454 after the insn or the insn is cc0 setter or user. */
455 bitmap_initialize (&dont_collect, NULL);
457 #ifdef STACK_REGS
458 FOR_EACH_BB (bb)
460 regset_head live;
461 rtx insn;
462 rtx prev;
464 /* Initialize liveness propagation. */
465 INIT_REG_SET (&live);
466 bitmap_copy (&live, DF_LR_OUT (bb));
467 df_simulate_initialize_backwards (bb, &live);
469 /* Propagate liveness info and mark insns where a stack reg is live. */
470 insn = BB_END (bb);
471 for (insn = BB_END (bb); ; insn = prev)
473 prev = PREV_INSN (insn);
474 if (INSN_P (insn))
476 int reg;
477 for (reg = FIRST_STACK_REG; reg <= LAST_STACK_REG; reg++)
479 if (REGNO_REG_SET_P (&live, reg))
481 bitmap_set_bit (&dont_collect, INSN_UID (insn));
482 break;
487 if (insn == BB_HEAD (bb))
488 break;
489 df_simulate_one_insn_backwards (bb, insn, &live);
490 insn = prev;
493 /* Free unused data. */
494 CLEAR_REG_SET (&live);
496 #endif
498 #ifdef HAVE_cc0
499 /* Mark CC0 setters and users as ineligible for collection into sequences.
500 This is an over-conservative fix, since it is OK to include
501 a cc0_setter, but only if we also include the corresponding cc0_user,
502 and vice versa. */
503 FOR_EACH_BB (bb)
505 rtx insn;
506 rtx next_tail;
508 next_tail = NEXT_INSN (BB_END (bb));
510 for (insn = BB_HEAD (bb); insn != next_tail; insn = NEXT_INSN (insn))
512 if (INSN_P (insn) && reg_mentioned_p (cc0_rtx, PATTERN (insn)))
513 bitmap_set_bit (&dont_collect, INSN_UID (insn));
516 #endif
518 #endif /* defined STACK_REGS || defined HAVE_cc0 */
520 /* Initialize PATTERN_SEQS to empty. */
521 pattern_seqs = 0;
523 /* Try to match every abstractable insn with every other insn in the same
524 HASH_BUCKET. */
526 FOR_EACH_HTAB_ELEMENT (hash_buckets, hash_bucket, p_hash_bucket, hti0)
527 if (htab_elements (hash_bucket->seq_candidates) > 1)
528 FOR_EACH_HTAB_ELEMENT (hash_bucket->seq_candidates, e0, p_hash_elem, hti1)
529 FOR_EACH_HTAB_ELEMENT (hash_bucket->seq_candidates, e1, p_hash_elem,
530 hti2)
531 if (e0 != e1
532 #if defined STACK_REGS || defined HAVE_cc0
533 && !bitmap_bit_p (&dont_collect, INSN_UID (e0->insn))
534 && !bitmap_bit_p (&dont_collect, INSN_UID (e1->insn))
535 #endif
537 match_seqs (e0, e1);
538 #if defined STACK_REGS || defined HAVE_cc0
539 /* Free unused data. */
540 bitmap_clear (&dont_collect);
541 #endif
544 /* Transforms a regset to a HARD_REG_SET. Every hard register in REGS is added
545 to hregs. Additionally, the hard counterpart of every renumbered pseudo
546 register is also added. */
548 static void
549 renumbered_reg_set_to_hard_reg_set (HARD_REG_SET * hregs, regset regs)
551 int r;
553 REG_SET_TO_HARD_REG_SET (*hregs, regs);
554 for (r = FIRST_PSEUDO_REGISTER; r < max_regno; r++)
555 if (REGNO_REG_SET_P (regs, r) && reg_renumber[r] >= 0)
556 SET_HARD_REG_BIT (*hregs, reg_renumber[r]);
559 /* Clears the bits in REGS for all registers, which are live in the sequence
560 give by its last INSN and its LENGTH. */
562 static void
563 clear_regs_live_in_seq (HARD_REG_SET * regs, rtx insn, int length)
565 basic_block bb;
566 regset_head live;
567 HARD_REG_SET hlive;
568 rtx x;
569 int i;
571 /* Initialize liveness propagation. */
572 bb = BLOCK_FOR_INSN (insn);
573 INIT_REG_SET (&live);
574 bitmap_copy (&live, DF_LR_OUT (bb));
575 df_simulate_initialize_backwards (bb, &live);
577 /* Propagate until INSN if found. */
578 for (x = BB_END (bb); x != insn; x = PREV_INSN (x))
579 df_simulate_one_insn_backwards (bb, x, &live);
581 /* Clear registers live after INSN. */
582 renumbered_reg_set_to_hard_reg_set (&hlive, &live);
583 AND_COMPL_HARD_REG_SET (*regs, hlive);
585 /* Clear registers live in and before the sequence. */
586 for (i = 0; i < length;)
588 rtx prev = PREV_INSN (x);
589 df_simulate_one_insn_backwards (bb, x, &live);
591 if (INSN_P (x))
593 renumbered_reg_set_to_hard_reg_set (&hlive, &live);
594 AND_COMPL_HARD_REG_SET (*regs, hlive);
595 i++;
598 x = prev;
601 /* Free unused data. */
602 CLEAR_REG_SET (&live);
605 /* Computes the gain of turning PSEQ into a pseudo-function and its matching
606 sequences into pseudo-calls. Also computes and caches the number of insns to
607 abstract from the matching sequences. */
609 static void
610 recompute_gain_for_pattern_seq (pattern_seq pseq)
612 matching_seq mseq;
613 rtx x;
614 int i;
615 int hascall;
616 HARD_REG_SET linkregs;
618 /* Initialize data. */
619 SET_HARD_REG_SET (linkregs);
620 pseq->link_reg = NULL_RTX;
621 pseq->abstracted_length = 0;
623 pseq->gain = -(seq_call_cost - seq_jump_cost + seq_return_cost);
625 /* Determine ABSTRACTED_LENGTH and COST for matching sequences of PSEQ.
626 ABSTRACTED_LENGTH may be less than MATCHING_LENGTH if sequences in the
627 same block overlap. */
629 for (mseq = pseq->matching_seqs; mseq; mseq = mseq->next_matching_seq)
631 /* Determine ABSTRACTED_LENGTH. */
632 if (mseq->next_matching_seq)
633 mseq->abstracted_length = (int)(mseq->next_matching_seq->idx -
634 mseq->idx);
635 else
636 mseq->abstracted_length = mseq->matching_length;
638 if (mseq->abstracted_length > mseq->matching_length)
639 mseq->abstracted_length = mseq->matching_length;
641 /* Compute the cost of sequence. */
642 RECOMPUTE_COST (mseq);
644 /* If COST is big enough registers live in this matching sequence
645 should not be used as a link register. Also set ABSTRACTED_LENGTH
646 of PSEQ. */
647 if (mseq->cost > seq_call_cost)
649 clear_regs_live_in_seq (&linkregs, mseq->insn,
650 mseq->abstracted_length);
651 if (mseq->abstracted_length > pseq->abstracted_length)
652 pseq->abstracted_length = mseq->abstracted_length;
656 /* Modify ABSTRACTED_LENGTH of PSEQ if pattern sequence overlaps with one
657 of the matching sequences. */
658 for (mseq = pseq->matching_seqs; mseq; mseq = mseq->next_matching_seq)
660 x = pseq->insn;
661 for (i = 0; (i < pseq->abstracted_length) && (x != mseq->insn); i++)
662 x = prev_insn_in_block (x);
663 pseq->abstracted_length = i;
666 /* Compute the cost of pattern sequence. */
667 RECOMPUTE_COST (pseq);
669 /* No gain if COST is too small. */
670 if (pseq->cost <= seq_call_cost)
672 pseq->gain = -1;
673 return;
676 /* Ensure that no matching sequence is longer than the pattern sequence. */
677 for (mseq = pseq->matching_seqs; mseq; mseq = mseq->next_matching_seq)
679 if (mseq->abstracted_length > pseq->abstracted_length)
681 mseq->abstracted_length = pseq->abstracted_length;
682 RECOMPUTE_COST (mseq);
684 /* Once the length is stabilizing the gain can be calculated. */
685 if (mseq->cost > seq_call_cost)
686 pseq->gain += mseq->cost - seq_call_cost;
689 /* No need to do further work if there is no gain. */
690 if (pseq->gain <= 0)
691 return;
693 /* Should not use registers live in the pattern sequence as link register.
695 clear_regs_live_in_seq (&linkregs, pseq->insn, pseq->abstracted_length);
697 /* Determine whether pattern sequence contains a call_insn. */
698 hascall = 0;
699 x = pseq->insn;
700 for (i = 0; i < pseq->abstracted_length; i++)
702 if (CALL_P (x))
704 hascall = 1;
705 break;
707 x = prev_insn_in_block (x);
710 /* Should not use a register as a link register if - it is a fixed
711 register, or - the sequence contains a call insn and the register is a
712 call used register, or - the register needs to be saved if used in a
713 function but was not used before (since saving it can invalidate already
714 computed frame pointer offsets), or - the register cannot be used as a
715 base register. */
717 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
718 if (fixed_regs[i]
719 #ifdef REGNO_OK_FOR_INDIRECT_JUMP_P
720 || (!REGNO_OK_FOR_INDIRECT_JUMP_P (i, Pmode))
721 #else
722 || (!ok_for_base_p_1 (i, Pmode, MEM, SCRATCH))
723 || (!reg_class_subset_p (REGNO_REG_CLASS (i),
724 base_reg_class (VOIDmode, MEM, SCRATCH)))
725 #endif
726 || (hascall && call_used_regs[i])
727 || (!call_used_regs[i] && !df_regs_ever_live_p (i)))
728 CLEAR_HARD_REG_BIT (linkregs, i);
730 /* Find an appropriate register to be used as the link register. */
731 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
732 if (TEST_HARD_REG_BIT (linkregs, i))
734 pseq->link_reg = gen_rtx_REG (Pmode, i);
735 break;
738 /* Abstraction is not possible if no link register is available, so set
739 gain to 0. */
740 if (!pseq->link_reg)
741 pseq->gain = 0;
744 /* Deallocates memory occupied by PSEQ and its matching seqs. */
746 static void
747 free_pattern_seq (pattern_seq pseq)
749 while (pseq->matching_seqs)
751 matching_seq mseq = pseq->matching_seqs;
752 pseq->matching_seqs = mseq->next_matching_seq;
753 free (mseq);
755 free (pseq);
759 /* Computes the gain for pattern sequences. Pattern sequences producing no gain
760 are deleted. The pattern sequence with the biggest gain is moved to the first
761 place of PATTERN_SEQS. */
763 static void
764 recompute_gain (void)
766 pattern_seq *pseq;
767 int maxgain;
769 maxgain = 0;
770 for (pseq = &pattern_seqs; *pseq;)
772 if ((*pseq)->gain <= 0)
773 recompute_gain_for_pattern_seq (*pseq);
775 if ((*pseq)->gain > 0)
777 if ((*pseq)->gain > maxgain)
779 pattern_seq temp = *pseq;
780 (*pseq) = temp->next_pattern_seq;
781 temp->next_pattern_seq = pattern_seqs;
782 pattern_seqs = temp;
783 maxgain = pattern_seqs->gain;
785 else
787 pseq = &(*pseq)->next_pattern_seq;
790 else
792 pattern_seq temp = *pseq;
793 *pseq = temp->next_pattern_seq;
794 free_pattern_seq (temp);
799 /* Updated those pattern sequences and matching sequences, which overlap with
800 the sequence given by INSN and LEN. Deletes sequences shrinking below a
801 limit. */
803 static void
804 erase_from_pattern_seqs (rtx insn, int len)
806 pattern_seq *pseq;
807 matching_seq *mseq;
808 rtx x;
809 int plen, mlen;
810 int pcost, mcost;
812 while (len > 0)
814 for (pseq = &pattern_seqs; *pseq;)
816 plen = 0;
817 pcost = 0;
818 for (x = (*pseq)->insn; x && (x != insn);
819 x = prev_insn_in_block (x))
821 plen++;
822 pcost += compute_rtx_cost (x);
825 if (pcost <= seq_call_cost)
827 pattern_seq temp = *pseq;
828 *pseq = temp->next_pattern_seq;
829 free_pattern_seq (temp);
831 else
833 for (mseq = &(*pseq)->matching_seqs; *mseq;)
835 mlen = 0;
836 mcost = 0;
837 for (x = (*mseq)->insn;
838 x && (x != insn) && (mlen < plen)
839 && (mlen < (*mseq)->matching_length);
840 x = prev_insn_in_block (x))
842 mlen++;
843 mcost += compute_rtx_cost (x);
846 if (mcost <= seq_call_cost)
848 matching_seq temp = *mseq;
849 *mseq = temp->next_matching_seq;
850 free (temp);
851 /* Set to 0 to force gain recomputation. */
852 (*pseq)->gain = 0;
854 else
856 if (mlen < (*mseq)->matching_length)
858 (*mseq)->cost = mcost;
859 (*mseq)->matching_length = mlen;
860 /* Set to 0 to force gain recomputation. */
861 (*pseq)->gain = 0;
863 mseq = &(*mseq)->next_matching_seq;
867 pseq = &(*pseq)->next_pattern_seq;
871 len--;
872 insn = prev_insn_in_block (insn);
876 /* Updates those pattern sequences and matching sequences, which overlap with
877 the pattern sequence with the biggest gain and its matching sequences. */
879 static void
880 update_pattern_seqs (void)
882 pattern_seq bestpseq;
883 matching_seq mseq;
885 bestpseq = pattern_seqs;
886 pattern_seqs = bestpseq->next_pattern_seq;
888 for (mseq = bestpseq->matching_seqs; mseq; mseq = mseq->next_matching_seq)
889 if (mseq->cost > seq_call_cost)
890 erase_from_pattern_seqs (mseq->insn, mseq->abstracted_length);
891 erase_from_pattern_seqs (bestpseq->insn, bestpseq->abstracted_length);
893 bestpseq->next_pattern_seq = pattern_seqs;
894 pattern_seqs = bestpseq;
897 /* Groups together those matching sequences of the best pattern sequence, which
898 have the same ABSTRACTED_LENGTH and puts these groups in ascending order.
899 SEQ_BLOCKS contains the result. */
901 static void
902 determine_seq_blocks (void)
904 seq_block sb;
905 matching_seq *mseq;
906 matching_seq m;
908 /* Initialize SEQ_BLOCKS to empty. */
909 seq_blocks = 0;
911 /* Process all matching sequences. */
912 for (mseq = &pattern_seqs->matching_seqs; *mseq;)
914 /* Deal only with matching sequences being long enough. */
915 if ((*mseq)->cost <= seq_call_cost)
917 mseq = &(*mseq)->next_matching_seq;
918 continue;
921 /* Ensure that SB contains a seq_block with the appropriate length.
922 Insert a new seq_block if necessary. */
923 if (!seq_blocks || ((*mseq)->abstracted_length < seq_blocks->length))
925 sb = (seq_block) xmalloc (sizeof (struct seq_block_def));
926 sb->length = (*mseq)->abstracted_length;
927 sb->label = NULL_RTX;
928 sb->matching_seqs = 0;
929 sb->next_seq_block = seq_blocks;
930 seq_blocks = sb;
932 else
934 for (sb = seq_blocks; sb; sb = sb->next_seq_block)
936 if ((*mseq)->abstracted_length == sb->length)
937 break;
938 if (!sb->next_seq_block
939 || ((*mseq)->abstracted_length <
940 sb->next_seq_block->length))
942 seq_block temp =
943 (seq_block) xmalloc (sizeof (struct seq_block_def));
944 temp->length = (*mseq)->abstracted_length;
945 temp->label = NULL_RTX;
946 temp->matching_seqs = 0;
947 temp->next_seq_block = sb->next_seq_block;
948 sb->next_seq_block = temp;
953 /* Remove the matching sequence from the linked list of the pattern
954 sequence and link it to SB. */
955 m = *mseq;
956 *mseq = m->next_matching_seq;
957 m->next_matching_seq = sb->matching_seqs;
958 sb->matching_seqs = m;
962 /* Builds a symbol_ref for LABEL. */
964 static rtx
965 gen_symbol_ref_rtx_for_label (const_rtx label)
967 char name[20];
968 rtx sym;
970 ASM_GENERATE_INTERNAL_LABEL (name, "L", CODE_LABEL_NUMBER (label));
971 sym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
972 SYMBOL_REF_FLAGS (sym) = SYMBOL_FLAG_LOCAL;
973 return sym;
976 /* Splits basic block at the requested insn and rebuilds dataflow. */
978 static basic_block
979 split_block_and_df_analyze (basic_block bb, rtx insn)
981 basic_block next;
982 next = split_block (bb, insn)->dest;
983 df_analyze ();
984 return next;
987 /* Ensures that INSN is the last insn in its block and returns the block label
988 of the next block. */
990 static rtx
991 block_label_after (rtx insn)
993 basic_block bb = BLOCK_FOR_INSN (insn);
994 if ((insn == BB_END (bb)) && (bb->next_bb != EXIT_BLOCK_PTR))
995 return block_label (bb->next_bb);
996 else
997 return block_label (split_block_and_df_analyze (bb, insn));
1000 /* Ensures that the last insns of the best pattern and its matching sequences
1001 are the last insns in their block. Additionally, extends the live set at the
1002 end of the pattern sequence with the live sets at the end of the matching
1003 sequences. */
1005 static void
1006 split_blocks_after_seqs (void)
1008 seq_block sb;
1009 matching_seq mseq;
1011 block_label_after (pattern_seqs->insn);
1012 for (sb = seq_blocks; sb; sb = sb->next_seq_block)
1014 for (mseq = sb->matching_seqs; mseq; mseq = mseq->next_matching_seq)
1016 block_label_after (mseq->insn);
1017 IOR_REG_SET (df_get_live_out (BLOCK_FOR_INSN (pattern_seqs->insn)),
1018 df_get_live_out (BLOCK_FOR_INSN (mseq->insn)));
1023 /* Splits the best pattern sequence according to SEQ_BLOCKS. Emits pseudo-call
1024 and -return insns before and after the sequence. */
1026 static void
1027 split_pattern_seq (void)
1029 rtx insn;
1030 basic_block bb;
1031 rtx retlabel, retjmp, saveinsn;
1032 int i;
1033 seq_block sb;
1035 insn = pattern_seqs->insn;
1036 bb = BLOCK_FOR_INSN (insn);
1038 /* Get the label after the sequence. This will be the return address. The
1039 label will be referenced using a symbol_ref so protect it from
1040 deleting. */
1041 retlabel = block_label_after (insn);
1042 LABEL_PRESERVE_P (retlabel) = 1;
1044 /* Emit an indirect jump via the link register after the sequence acting
1045 as the return insn. Also emit a barrier and update the basic block. */
1046 if (!find_reg_note (BB_END (bb), REG_NORETURN, NULL))
1047 retjmp = emit_jump_insn_after (gen_indirect_jump (pattern_seqs->link_reg),
1048 BB_END (bb));
1049 emit_barrier_after (BB_END (bb));
1051 /* Replace all outgoing edges with a new one to the block of RETLABEL. */
1052 while (EDGE_COUNT (bb->succs) != 0)
1053 remove_edge (EDGE_SUCC (bb, 0));
1054 make_edge (bb, BLOCK_FOR_INSN (retlabel), EDGE_ABNORMAL);
1056 /* Split the sequence according to SEQ_BLOCKS and cache the label of the
1057 resulting basic blocks. */
1058 i = 0;
1059 for (sb = seq_blocks; sb; sb = sb->next_seq_block)
1061 for (; i < sb->length; i++)
1062 insn = prev_insn_in_block (insn);
1064 sb->label = block_label (split_block_and_df_analyze (bb, insn));
1067 /* Emit an insn saving the return address to the link register before the
1068 sequence. */
1069 saveinsn = emit_insn_after (gen_move_insn (pattern_seqs->link_reg,
1070 gen_symbol_ref_rtx_for_label
1071 (retlabel)), BB_END (bb));
1072 /* Update liveness info. */
1073 SET_REGNO_REG_SET (df_get_live_out (bb),
1074 REGNO (pattern_seqs->link_reg));
1077 /* Deletes the insns of the matching sequences of the best pattern sequence and
1078 replaces them with pseudo-calls to the pattern sequence. */
1080 static void
1081 erase_matching_seqs (void)
1083 seq_block sb;
1084 matching_seq mseq;
1085 rtx insn;
1086 basic_block bb;
1087 rtx retlabel, saveinsn, callinsn;
1088 int i;
1090 for (sb = seq_blocks; sb; sb = sb->next_seq_block)
1092 for (mseq = sb->matching_seqs; mseq; mseq = mseq->next_matching_seq)
1094 insn = mseq->insn;
1095 bb = BLOCK_FOR_INSN (insn);
1097 /* Get the label after the sequence. This will be the return
1098 address. The label will be referenced using a symbol_ref so
1099 protect it from deleting. */
1100 retlabel = block_label_after (insn);
1101 LABEL_PRESERVE_P (retlabel) = 1;
1103 /* Delete the insns of the sequence. */
1104 for (i = 0; i < sb->length; i++)
1105 insn = prev_insn_in_block (insn);
1106 delete_basic_block (split_block_and_df_analyze (bb, insn));
1108 /* Emit an insn saving the return address to the link register
1109 before the deleted sequence. */
1110 saveinsn = emit_insn_after (gen_move_insn (pattern_seqs->link_reg,
1111 gen_symbol_ref_rtx_for_label
1112 (retlabel)),
1113 BB_END (bb));
1114 BLOCK_FOR_INSN (saveinsn) = bb;
1116 /* Emit a jump to the appropriate part of the pattern sequence
1117 after the save insn. Also update the basic block. */
1118 callinsn = emit_jump_insn_after (gen_jump (sb->label), saveinsn);
1119 JUMP_LABEL (callinsn) = sb->label;
1120 LABEL_NUSES (sb->label)++;
1121 BLOCK_FOR_INSN (callinsn) = bb;
1122 BB_END (bb) = callinsn;
1124 /* Maintain control flow and liveness information. */
1125 SET_REGNO_REG_SET (df_get_live_out (bb),
1126 REGNO (pattern_seqs->link_reg));
1127 emit_barrier_after (BB_END (bb));
1128 make_single_succ_edge (bb, BLOCK_FOR_INSN (sb->label), 0);
1129 IOR_REG_SET (df_get_live_out (bb),
1130 df_get_live_in (BLOCK_FOR_INSN (sb->label)));
1132 make_edge (BLOCK_FOR_INSN (seq_blocks->label),
1133 BLOCK_FOR_INSN (retlabel), EDGE_ABNORMAL);
1138 /* Deallocates SEQ_BLOCKS and all the matching sequences. */
1140 static void
1141 free_seq_blocks (void)
1143 while (seq_blocks)
1145 seq_block sb = seq_blocks;
1146 while (sb->matching_seqs)
1148 matching_seq mseq = sb->matching_seqs;
1149 sb->matching_seqs = mseq->next_matching_seq;
1150 free (mseq);
1152 seq_blocks = sb->next_seq_block;
1153 free (sb);
1157 /* Transforms the best pattern sequence into a pseudo-function and its matching
1158 sequences to pseudo-calls. Afterwards the best pattern sequence is removed
1159 from PATTERN_SEQS. */
1161 static void
1162 abstract_best_seq (void)
1164 pattern_seq bestpseq;
1166 /* Do the abstraction. */
1167 determine_seq_blocks ();
1168 split_blocks_after_seqs ();
1169 split_pattern_seq ();
1170 erase_matching_seqs ();
1171 free_seq_blocks ();
1173 /* Record the usage of the link register. */
1174 df_set_regs_ever_live (REGNO (pattern_seqs->link_reg), true);
1176 /* Remove the best pattern sequence. */
1177 bestpseq = pattern_seqs;
1178 pattern_seqs = bestpseq->next_pattern_seq;
1179 free_pattern_seq (bestpseq);
1182 /* Prints info on the pattern sequences to the dump file. */
1184 static void
1185 dump_pattern_seqs (void)
1187 pattern_seq pseq;
1188 matching_seq mseq;
1190 if (!dump_file)
1191 return;
1193 fprintf (dump_file, ";; Pattern sequences\n");
1194 for (pseq = pattern_seqs; pseq; pseq = pseq->next_pattern_seq)
1196 fprintf (dump_file, "Pattern sequence at insn %d matches sequences at",
1197 INSN_UID (pseq->insn));
1198 for (mseq = pseq->matching_seqs; mseq; mseq = mseq->next_matching_seq)
1200 fprintf (dump_file, " insn %d (length %d)", INSN_UID (mseq->insn),
1201 mseq->matching_length);
1202 if (mseq->next_matching_seq)
1203 fprintf (dump_file, ",");
1205 fprintf (dump_file, ".\n");
1207 fprintf (dump_file, "\n");
1210 /* Prints info on the best pattern sequence transformed in the ITER-th
1211 iteration to the dump file. */
1213 static void
1214 dump_best_pattern_seq (int iter)
1216 matching_seq mseq;
1218 if (!dump_file)
1219 return;
1221 fprintf (dump_file, ";; Iteration %d\n", iter);
1222 fprintf (dump_file,
1223 "Best pattern sequence with %d gain is at insn %d (length %d).\n",
1224 pattern_seqs->gain, INSN_UID (pattern_seqs->insn),
1225 pattern_seqs->abstracted_length);
1226 fprintf (dump_file, "Matching sequences are at");
1227 for (mseq = pattern_seqs->matching_seqs; mseq;
1228 mseq = mseq->next_matching_seq)
1230 fprintf (dump_file, " insn %d (length %d)", INSN_UID (mseq->insn),
1231 mseq->abstracted_length);
1232 if (mseq->next_matching_seq)
1233 fprintf (dump_file, ",");
1235 fprintf (dump_file, ".\n");
1236 fprintf (dump_file, "Using reg %d as link register.\n\n",
1237 REGNO (pattern_seqs->link_reg));
1240 /* Htab hash function for hash_bucket_def structure. */
1242 static unsigned int
1243 htab_hash_bucket (const void *p)
1245 const_p_hash_bucket bucket = (const_p_hash_bucket) p;
1246 return bucket->hash;
1249 /* Htab equal function for hash_bucket_def structure. */
1251 static int
1252 htab_eq_bucket (const void *p0, const void *p1)
1254 return htab_hash_bucket (p0) == htab_hash_bucket (p1);
1257 /* Htab delete function for hash_bucket_def structure. */
1259 static void
1260 htab_del_bucket (void *p)
1262 p_hash_bucket bucket = (p_hash_bucket) p;
1264 if (bucket->seq_candidates)
1265 htab_delete (bucket->seq_candidates);
1267 free (bucket);
1270 /* Htab hash function for hash_bucket_def structure. */
1272 static unsigned int
1273 htab_hash_elem (const void *p)
1275 const_p_hash_elem elem = (const_p_hash_elem) p;
1276 return htab_hash_pointer (elem->insn);
1279 /* Htab equal function for hash_bucket_def structure. */
1281 static int
1282 htab_eq_elem (const void *p0, const void *p1)
1284 return htab_hash_elem (p0) == htab_hash_elem (p1);
1287 /* Htab delete function for hash_bucket_def structure. */
1289 static void
1290 htab_del_elem (void *p)
1292 p_hash_elem elem = (p_hash_elem) p;
1293 free (elem);
1296 /* Creates a hash value for each sequence candidate and saves them
1297 in HASH_BUCKET. */
1299 static void
1300 fill_hash_bucket (void)
1302 basic_block bb;
1303 rtx insn;
1304 void **slot;
1305 p_hash_bucket bucket;
1306 struct hash_bucket_def tmp_bucket;
1307 p_hash_elem elem;
1308 unsigned long insn_idx;
1310 insn_idx = 0;
1311 FOR_EACH_BB (bb)
1313 FOR_BB_INSNS_REVERSE (bb, insn)
1315 if (!ABSTRACTABLE_INSN_P (insn))
1316 continue;
1318 /* Compute hash value for INSN. */
1319 tmp_bucket.hash = compute_hash (insn);
1321 /* Select the hash group. */
1322 bucket = (p_hash_bucket) htab_find (hash_buckets, &tmp_bucket);
1324 if (!bucket)
1326 /* Create a new hash group. */
1327 bucket = (p_hash_bucket) xcalloc (1,
1328 sizeof (struct hash_bucket_def));
1329 bucket->hash = tmp_bucket.hash;
1330 bucket->seq_candidates = NULL;
1332 slot = htab_find_slot (hash_buckets, &tmp_bucket, INSERT);
1333 *slot = bucket;
1336 /* Create new list for storing sequence candidates. */
1337 if (!bucket->seq_candidates)
1338 bucket->seq_candidates = htab_create (HASH_INIT,
1339 htab_hash_elem,
1340 htab_eq_elem,
1341 htab_del_elem);
1343 elem = (p_hash_elem) xcalloc (1, sizeof (struct hash_elem_def));
1344 elem->insn = insn;
1345 elem->idx = insn_idx;
1346 elem->length = get_attr_length (insn);
1348 /* Insert INSN into BUCKET hash bucket. */
1349 slot = htab_find_slot (bucket->seq_candidates, elem, INSERT);
1350 *slot = elem;
1352 insn_idx++;
1357 /* Computes the cost of calling sequence and the cost of return. */
1359 static void
1360 compute_init_costs (void)
1362 rtx rtx_jump, rtx_store, rtx_return, reg, label;
1363 basic_block bb;
1365 FOR_EACH_BB (bb)
1366 if (BB_HEAD (bb))
1367 break;
1369 label = block_label (bb);
1370 reg = gen_rtx_REG (Pmode, 0);
1372 /* Pattern for indirect jump. */
1373 rtx_jump = gen_indirect_jump (reg);
1375 /* Pattern for storing address. */
1376 rtx_store = gen_rtx_SET (VOIDmode, reg, gen_symbol_ref_rtx_for_label (label));
1378 /* Pattern for return insn. */
1379 rtx_return = gen_jump (label);
1381 /* The cost of jump. */
1382 seq_jump_cost = compute_rtx_cost (make_jump_insn_raw (rtx_jump));
1384 /* The cost of calling sequence. */
1385 seq_call_cost = seq_jump_cost + compute_rtx_cost (make_insn_raw (rtx_store));
1387 /* The cost of return. */
1388 seq_return_cost = compute_rtx_cost (make_jump_insn_raw (rtx_return));
1390 /* Simple heuristic for minimal sequence cost. */
1391 seq_call_cost = (int)(seq_call_cost * (double)SEQ_CALL_COST_MULTIPLIER);
1394 /* Finds equivalent insn sequences in the current function and retains only one
1395 instance of them which is turned into a pseudo-function. The additional
1396 copies are erased and replaced by pseudo-calls to the retained sequence. */
1398 static void
1399 rtl_seqabstr (void)
1401 int iter;
1402 df_set_flags (DF_LR_RUN_DCE);
1403 df_analyze ();
1405 /* Create a hash list for COLLECT_PATTERN_SEQS. */
1406 hash_buckets = htab_create (HASH_INIT, htab_hash_bucket , htab_eq_bucket ,
1407 htab_del_bucket);
1408 fill_hash_bucket ();
1410 /* Compute the common cost of abstraction. */
1411 compute_init_costs ();
1413 /* Build an initial set of pattern sequences from the current function. */
1414 collect_pattern_seqs ();
1415 dump_pattern_seqs ();
1417 /* Iterate until there are no sequences to abstract. */
1418 for (iter = 1;; iter++)
1420 /* Recompute gain for sequences if necessary and select sequence with
1421 biggest gain. */
1422 recompute_gain ();
1423 if (!pattern_seqs)
1424 break;
1425 dump_best_pattern_seq (iter);
1426 /* Update the cached info of the other sequences and force gain
1427 recomputation where needed. */
1428 update_pattern_seqs ();
1429 /* Turn best sequences into pseudo-functions and -calls. */
1430 abstract_best_seq ();
1433 /* Cleanup hash tables. */
1434 htab_delete (hash_buckets);
1437 /* The gate function for TREE_OPT_PASS. */
1439 static bool
1440 gate_rtl_seqabstr (void)
1442 return flag_rtl_seqabstr;
1445 /* The entry point of the sequence abstraction algorithm. */
1447 static unsigned int
1448 rest_of_rtl_seqabstr (void)
1450 /* Abstract out common insn sequences. */
1451 rtl_seqabstr ();
1452 return 0;
1455 struct rtl_opt_pass pass_rtl_seqabstr =
1458 RTL_PASS,
1459 "seqabstr", /* name */
1460 gate_rtl_seqabstr, /* gate */
1461 rest_of_rtl_seqabstr, /* execute */
1462 NULL, /* sub */
1463 NULL, /* next */
1464 0, /* static_pass_number */
1465 TV_SEQABSTR, /* tv_id */
1466 0, /* properties_required */
1467 0, /* properties_provided */
1468 0, /* properties_destroyed */
1469 0, /* todo_flags_start */
1470 TODO_df_finish | TODO_verify_rtl_sharing |
1471 TODO_dump_func |
1472 TODO_ggc_collect /* todo_flags_finish */