2006-02-25 Thomas Koenig <Thomas.Koenig@online.de>
[official-gcc.git] / gcc / rtl-factoring.c
blob864836e07b92b60590385867712b515cbb669e2f
1 /* RTL factoring (sequence abstraction).
2 Copyright (C) 2004, 2005, 2006 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
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 COPYING. If not, write to the Free
18 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301, USA. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "rtl.h"
26 #include "obstack.h"
27 #include "basic-block.h"
28 #include "resource.h"
29 #include "flags.h"
30 #include "ggc.h"
31 #include "regs.h"
32 #include "params.h"
33 #include "expr.h"
34 #include "tm_p.h"
35 #include "tree-pass.h"
36 #include "tree-flow.h"
37 #include "timevar.h"
38 #include "output.h"
40 /* Sequence abstraction:
42 It is a size optimization method. The main idea of this technique is to
43 find identical sequences of code, which can be turned into procedures and
44 then replace all occurrences with calls to the newly created subroutine.
45 It is kind of an opposite of function inlining.
47 There are four major parts of this file:
49 sequence fingerprint
50 In order to avoid the comparison of every insn with every other, hash
51 value will be designed for every insn by COMPUTE_HASH.
52 These hash values are used for grouping the sequence candidates. So
53 we only need to compare every insn with every other in same hash group.
55 FILL_HASH_BUCKET creates all hash values and stores into HASH_BUCKETS.
56 The result is used by COLLECT_PATTERN_SEQS.
58 code matching
59 In code matching the algorithm compares every two possible sequence
60 candidates which last insns are in the same hash group. If these
61 sequences are identical they will be stored and do further searches for
62 finding more sequences which are identical with the first one.
64 COLLECT_PATTERN_SEQS does the code matching and stores the results into
65 PATTERN_SEQS.
67 gain computation
68 This part computes the gain of abstraction which could be archived when
69 turning the pattern sequence into a pseudo-function and its matching
70 sequences into pseudo-calls. After it the most effective sequences will
71 be marked for abstraction.
73 RECOMPUTE_GAIN does the gain computation. The sequences with the maximum
74 gain is on the top of PATTERN_SEQS.
76 abstract code
77 This part turns the pattern sequence into a pseudo-function and its
78 matching sequences into pseudo-calls.
80 ABSTRACT_BEST_SEQ does the code merging.
83 C code example:
85 // Original source // After sequence abstraction
86 { {
87 void *jump_label;
88 ... ...
89 jump_label = &&exit_0;
90 entry_0:
91 I0; I0;
92 I1; I1;
93 I2; I2;
94 I3; I3;
95 goto *jump_label;
96 exit_0:
97 ... ...
98 jump_label = &&exit_1;
99 goto entry_0;
104 exit_1:
105 ... ...
106 jump_label = &&exit_2;
107 goto entry_0;
112 exit_2:
113 ... ...
114 jump_label = &&exit_3;
115 goto entry_0;
120 exit_3:
121 ... ...
125 TODO:
126 - Use REG_ALLOC_ORDER when choosing link register.
127 - Handle JUMP_INSNs. Also handle volatile function calls (handle them
128 simmilar to unconditional jumps.)
129 - Test command line option -fpic.
132 /* Predicate yielding nonzero iff X is an abstractable insn. Non-jump insns are
133 abstractable. */
134 #define ABSTRACTABLE_INSN_P(X) (INSN_P (X) && !JUMP_P (X))
136 /* First parameter of the htab_create function call. */
137 #define HASH_INIT 1023
139 /* Multiplier for cost of sequence call to avoid abstracting short
140 sequences. */
141 #ifndef SEQ_CALL_COST_MULTIPLIER
142 #define SEQ_CALL_COST_MULTIPLIER 2
143 #endif
145 /* Recomputes the cost of MSEQ pattern/matching sequence. */
146 #define RECOMPUTE_COST(SEQ) \
148 int l; \
149 rtx x = SEQ->insn; \
150 SEQ->cost = 0; \
151 for (l = 0; l < SEQ->abstracted_length; l++) \
153 SEQ->cost += compute_rtx_cost (x); \
154 x = prev_insn_in_block (x); \
158 /* A sequence matching a pattern sequence. */
159 typedef struct matching_seq_def
161 /* The last insn in the matching sequence. */
162 rtx insn;
164 /* Index of INSN instruction. */
165 unsigned long idx;
167 /* The number of insns matching in this sequence and the pattern sequence.
169 int matching_length;
171 /* The number of insns selected to abstract from this sequence. Less than
172 or equal to MATCHING_LENGTH. */
173 int abstracted_length;
175 /* The cost of the sequence. */
176 int cost;
178 /* The next sequence in the chain matching the same pattern. */
179 struct matching_seq_def *next_matching_seq;
180 } *matching_seq;
183 /* A pattern instruction sequence. */
184 typedef struct pattern_seq_def
186 /* The last insn in the pattern sequence. */
187 rtx insn;
189 /* Index of INSN instruction. */
190 unsigned long idx;
192 /* The gain of transforming the pattern sequence into a pseudo-function and
193 the matching sequences into pseudo-calls. */
194 int gain;
196 /* The maximum of the ABSTRACTED_LENGTH of the matching sequences. */
197 int abstracted_length;
199 /* The cost of the sequence. */
200 int cost;
202 /* The register used to hold the return address during the pseudo-call. */
203 rtx link_reg;
205 /* The sequences matching this pattern. */
206 matching_seq matching_seqs;
208 /* The next pattern sequence in the chain. */
209 struct pattern_seq_def *next_pattern_seq;
210 } *pattern_seq;
213 /* A block of a pattern sequence. */
214 typedef struct seq_block_def
216 /* The number of insns in the block. */
217 int length;
219 /* The code_label of the block. */
220 rtx label;
222 /* The sequences entering the pattern sequence at LABEL. */
223 matching_seq matching_seqs;
225 /* The next block in the chain. The blocks are sorted by LENGTH in
226 ascending order. */
227 struct seq_block_def *next_seq_block;
228 } *seq_block;
230 /* Contains same sequence candidates for futher searching. */
231 typedef struct hash_bucket_def
233 /* The hash value of the group. */
234 unsigned int hash;
236 /* List of sequence candidates. */
237 htab_t seq_candidates;
238 } *p_hash_bucket;
240 /* Contains the last insn of the sequence, and its index value. */
241 typedef struct hash_elem_def
243 /* Unique index; ordered by FILL_HASH_BUCKET. */
244 unsigned long idx;
246 /* The last insn in the sequence. */
247 rtx insn;
249 /* The cached length of the insn. */
250 int length;
251 } *p_hash_elem;
253 /* The list of same sequence candidates. */
254 static htab_t hash_buckets;
256 /* The pattern sequences collected from the current functions. */
257 static pattern_seq pattern_seqs;
259 /* The blocks of the current pattern sequence. */
260 static seq_block seq_blocks;
262 /* Cost of calling sequence. */
263 static int seq_call_cost;
265 /* Cost of jump. */
266 static int seq_jump_cost;
268 /* Cost of returning. */
269 static int seq_return_cost;
271 /* Returns the first insn preceding INSN for which INSN_P is true and belongs to
272 the same basic block. Returns NULL_RTX if no such insn can be found. */
274 static rtx
275 prev_insn_in_block (rtx insn)
277 basic_block bb = BLOCK_FOR_INSN (insn);
279 if (!bb)
280 return NULL_RTX;
282 while (insn != BB_HEAD (bb))
284 insn = PREV_INSN (insn);
285 if (INSN_P (insn))
286 return insn;
288 return NULL_RTX;
291 /* Returns the hash value of INSN. */
293 static unsigned int
294 compute_hash (rtx insn)
296 unsigned int hash = 0;
297 rtx prev;
299 hash = INSN_CODE (insn) * 100;
301 prev = prev_insn_in_block (insn);
302 if (prev)
303 hash += INSN_CODE (prev);
305 return hash;
308 /* Compute the cost of INSN rtx for abstraction. */
310 static int
311 compute_rtx_cost (rtx insn)
313 struct hash_bucket_def tmp_bucket;
314 p_hash_bucket bucket;
315 struct hash_elem_def tmp_elem;
316 p_hash_elem elem = NULL;
317 int cost = -1;
319 /* Compute hash value for INSN. */
320 tmp_bucket.hash = compute_hash (insn);
322 /* Select the hash group. */
323 bucket = htab_find (hash_buckets, &tmp_bucket);
325 if (bucket)
327 tmp_elem.insn = insn;
329 /* Select the insn. */
330 elem = htab_find (bucket->seq_candidates, &tmp_elem);
332 /* If INSN is parsed the cost will be the cached length. */
333 if (elem)
334 cost = elem->length;
337 /* If we can't parse the INSN cost will be the instruction length. */
338 if (cost == -1)
340 cost = get_attr_length (insn);
342 /* Cache the length. */
343 if (elem)
344 elem->length = cost;
347 /* If we can't get an accurate estimate for a complex instruction,
348 assume that it has the same cost as a single fast instruction. */
349 return cost != 0 ? cost : COSTS_N_INSNS (1);
352 /* Determines the number of common insns in the sequences ending in INSN1 and
353 INSN2. Returns with LEN number of common insns and COST cost of sequence.
356 static void
357 matching_length (rtx insn1, rtx insn2, int* len, int* cost)
359 rtx x1;
360 rtx x2;
362 x1 = insn1;
363 x2 = insn2;
364 *len = 0;
365 *cost = 0;
366 while (x1 && x2 && (x1 != insn2) && (x2 != insn1)
367 && rtx_equal_p (PATTERN (x1), PATTERN (x2)))
369 (*len)++;
370 (*cost) += compute_rtx_cost (x1);
371 x1 = prev_insn_in_block (x1);
372 x2 = prev_insn_in_block (x2);
376 /* Adds E0 as a pattern sequence to PATTERN_SEQS with E1 as a matching
377 sequence. */
379 static void
380 match_seqs (p_hash_elem e0, p_hash_elem e1)
382 int len;
383 int cost;
384 matching_seq mseq, p_prev, p_next;
386 /* Determines the cost of the sequence and return without doing anything
387 if it is too small to produce any gain. */
388 matching_length (e0->insn, e1->insn, &len, &cost);
389 if (cost <= seq_call_cost)
390 return;
392 /* Prepend a new PATTERN_SEQ to PATTERN_SEQS if the last pattern sequence
393 does not end in E0->INSN. This assumes that once the E0->INSN changes
394 the old value will never appear again. */
395 if (!pattern_seqs || pattern_seqs->insn != e0->insn)
397 pattern_seq pseq =
398 (pattern_seq) xmalloc (sizeof (struct pattern_seq_def));
399 pseq->insn = e0->insn;
400 pseq->idx = e0->idx;
401 pseq->gain = 0; /* Set to zero to force recomputing. */
402 pseq->abstracted_length = 0;
403 pseq->cost = 0;
404 pseq->link_reg = NULL_RTX;
405 pseq->matching_seqs = NULL;
406 pseq->next_pattern_seq = pattern_seqs;
407 pattern_seqs = pseq;
410 /* Find the position of E1 in the matching sequences list. */
411 p_prev = NULL;
412 p_next = pattern_seqs->matching_seqs;
413 while (p_next && p_next->idx < e1->idx)
415 p_prev = p_next;
416 p_next = p_next->next_matching_seq;
419 /* Add a new E1 matching sequence to the pattern sequence. We know that
420 it ends in E0->INSN. */
421 mseq = (matching_seq) xmalloc (sizeof (struct matching_seq_def));
422 mseq->insn = e1->insn;
423 mseq->idx = e1->idx;
424 mseq->matching_length = len;
425 mseq->abstracted_length = 0;
426 mseq->cost = cost;
428 if (p_prev == NULL)
429 pattern_seqs->matching_seqs = mseq;
430 else
431 p_prev->next_matching_seq = mseq;
432 mseq->next_matching_seq = p_next;
435 /* Collects all pattern sequences and their matching sequences and puts them
436 into PATTERN_SEQS. */
438 static void
439 collect_pattern_seqs (void)
441 htab_iterator hti0, hti1, hti2;
442 p_hash_bucket hash_bucket;
443 p_hash_elem e0, e1;
444 #ifdef STACK_REGS
445 basic_block bb;
446 bitmap_head stack_reg_live;
448 /* Extra initialization step to ensure that no stack registers (if present)
449 are live across abnormal edges. Set a flag in STACK_REG_LIVE for an insn
450 if a stack register is live after the insn. */
451 bitmap_initialize (&stack_reg_live, NULL);
453 FOR_EACH_BB (bb)
455 regset_head live;
456 struct propagate_block_info *pbi;
457 rtx insn;
459 /* Initialize liveness propagation. */
460 INIT_REG_SET (&live);
461 COPY_REG_SET (&live, bb->il.rtl->global_live_at_end);
462 pbi = init_propagate_block_info (bb, &live, NULL, NULL, 0);
464 /* Propagate liveness info and mark insns where a stack reg is live. */
465 insn = BB_END (bb);
466 while (1)
468 int reg;
469 for (reg = FIRST_STACK_REG; reg <= LAST_STACK_REG; reg++)
471 if (REGNO_REG_SET_P (&live, reg))
473 bitmap_set_bit (&stack_reg_live, INSN_UID (insn));
474 break;
478 if (insn == BB_HEAD (bb))
479 break;
480 insn = propagate_one_insn (pbi, insn);
483 /* Free unused data. */
484 CLEAR_REG_SET (&live);
485 free_propagate_block_info (pbi);
487 #endif
489 /* Initialize PATTERN_SEQS to empty. */
490 pattern_seqs = 0;
492 /* Try to match every abstractable insn with every other insn in the same
493 HASH_BUCKET. */
495 FOR_EACH_HTAB_ELEMENT (hash_buckets, hash_bucket, p_hash_bucket, hti0)
496 if (htab_elements (hash_bucket->seq_candidates) > 1)
497 FOR_EACH_HTAB_ELEMENT (hash_bucket->seq_candidates, e0, p_hash_elem, hti1)
498 FOR_EACH_HTAB_ELEMENT (hash_bucket->seq_candidates, e1, p_hash_elem,
499 hti2)
500 if (e0 != e1
501 #ifdef STACK_REGS
502 && !bitmap_bit_p (&stack_reg_live, INSN_UID (e0->insn))
503 && !bitmap_bit_p (&stack_reg_live, INSN_UID (e1->insn))
504 #endif
506 match_seqs (e0, e1);
507 #ifdef STACK_REGS
508 /* Free unused data. */
509 bitmap_clear (&stack_reg_live);
510 #endif
513 /* Transforms a regset to a HARD_REG_SET. Every hard register in REGS is added
514 to hregs. Additionally, the hard counterpart of every renumbered pseudo
515 register is also added. */
517 static void
518 renumbered_reg_set_to_hard_reg_set (HARD_REG_SET * hregs, regset regs)
520 int r;
522 REG_SET_TO_HARD_REG_SET (*hregs, regs);
523 for (r = FIRST_PSEUDO_REGISTER; r < max_regno; r++)
524 if (REGNO_REG_SET_P (regs, r) && reg_renumber[r] >= 0)
525 SET_HARD_REG_BIT (*hregs, reg_renumber[r]);
528 /* Clears the bits in REGS for all registers, which are live in the sequence
529 give by its last INSN and its LENGTH. */
531 static void
532 clear_regs_live_in_seq (HARD_REG_SET * regs, rtx insn, int length)
534 basic_block bb;
535 regset_head live;
536 HARD_REG_SET hlive;
537 struct propagate_block_info *pbi;
538 rtx x;
539 int i;
541 /* Initialize liveness propagation. */
542 bb = BLOCK_FOR_INSN (insn);
543 INIT_REG_SET (&live);
544 COPY_REG_SET (&live, bb->il.rtl->global_live_at_end);
545 pbi = init_propagate_block_info (bb, &live, NULL, NULL, 0);
547 /* Propagate until INSN if found. */
548 for (x = BB_END (bb); x != insn;)
549 x = propagate_one_insn (pbi, x);
551 /* Clear registers live after INSN. */
552 renumbered_reg_set_to_hard_reg_set (&hlive, &live);
553 AND_COMPL_HARD_REG_SET (*regs, hlive);
555 /* Clear registers live in and before the sequence. */
556 for (i = 0; i < length;)
558 rtx prev = propagate_one_insn (pbi, x);
560 if (INSN_P (x))
562 renumbered_reg_set_to_hard_reg_set (&hlive, &live);
563 AND_COMPL_HARD_REG_SET (*regs, hlive);
564 i++;
567 x = prev;
570 /* Free unused data. */
571 free_propagate_block_info (pbi);
572 CLEAR_REG_SET (&live);
575 /* Computes the gain of turning PSEQ into a pseudo-function and its matching
576 sequences into pseudo-calls. Also computes and caches the number of insns to
577 abstract from the matching sequences. */
579 static void
580 recompute_gain_for_pattern_seq (pattern_seq pseq)
582 matching_seq mseq;
583 rtx x;
584 int i;
585 int hascall;
586 HARD_REG_SET linkregs;
588 /* Initialize data. */
589 SET_HARD_REG_SET (linkregs);
590 pseq->link_reg = NULL_RTX;
591 pseq->abstracted_length = 0;
593 pseq->gain = -(seq_call_cost - seq_jump_cost + seq_return_cost);
595 /* Determine ABSTRACTED_LENGTH and COST for matching sequences of PSEQ.
596 ABSTRACTED_LENGTH may be less than MATCHING_LENGTH if sequences in the
597 same block overlap. */
599 for (mseq = pseq->matching_seqs; mseq; mseq = mseq->next_matching_seq)
601 /* Determine ABSTRACTED_LENGTH. */
602 if (mseq->next_matching_seq)
603 mseq->abstracted_length = (int)(mseq->next_matching_seq->idx -
604 mseq->idx);
605 else
606 mseq->abstracted_length = mseq->matching_length;
608 if (mseq->abstracted_length > mseq->matching_length)
609 mseq->abstracted_length = mseq->matching_length;
611 /* Compute the cost of sequence. */
612 RECOMPUTE_COST (mseq);
614 /* If COST is big enough registers live in this matching sequence
615 should not be used as a link register. Also set ABSTRACTED_LENGTH
616 of PSEQ. */
617 if (mseq->cost > seq_call_cost)
619 clear_regs_live_in_seq (&linkregs, mseq->insn,
620 mseq->abstracted_length);
621 if (mseq->abstracted_length > pseq->abstracted_length)
622 pseq->abstracted_length = mseq->abstracted_length;
626 /* Modify ABSTRACTED_LENGTH of PSEQ if pattern sequence overlaps with one
627 of the matching sequences. */
628 for (mseq = pseq->matching_seqs; mseq; mseq = mseq->next_matching_seq)
630 x = pseq->insn;
631 for (i = 0; (i < pseq->abstracted_length) && (x != mseq->insn); i++)
632 x = prev_insn_in_block (x);
633 pseq->abstracted_length = i;
636 /* Compute the cost of pattern sequence. */
637 RECOMPUTE_COST (pseq);
639 /* No gain if COST is too small. */
640 if (pseq->cost <= seq_call_cost)
642 pseq->gain = -1;
643 return;
646 /* Ensure that no matching sequence is longer than the pattern sequence. */
647 for (mseq = pseq->matching_seqs; mseq; mseq = mseq->next_matching_seq)
649 if (mseq->abstracted_length > pseq->abstracted_length)
651 mseq->abstracted_length = pseq->abstracted_length;
652 RECOMPUTE_COST (mseq);
654 /* Once the length is stabilizing the gain can be calculated. */
655 if (mseq->cost > seq_call_cost)
656 pseq->gain += mseq->cost - seq_call_cost;
659 /* No need to do further work if there is no gain. */
660 if (pseq->gain <= 0)
661 return;
663 /* Should not use registers live in the pattern sequence as link register.
665 clear_regs_live_in_seq (&linkregs, pseq->insn, pseq->abstracted_length);
667 /* Determine whether pattern sequence contains a call_insn. */
668 hascall = 0;
669 x = pseq->insn;
670 for (i = 0; i < pseq->abstracted_length; i++)
672 if (CALL_P (x))
674 hascall = 1;
675 break;
677 x = prev_insn_in_block (x);
680 /* Should not use a register as a link register if - it is a fixed
681 register, or - the sequence contains a call insn and the register is a
682 call used register, or - the register needs to be saved if used in a
683 function but was not used before (since saving it can invalidate already
684 computed frame pointer offsets), or - the register cannot be used as a
685 base register. */
687 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
688 if (fixed_regs[i]
689 #ifdef REGNO_OK_FOR_INDIRECT_JUMP_P
690 || (!REGNO_OK_FOR_INDIRECT_JUMP_P (i, Pmode))
691 #else
692 || (!REGNO_MODE_OK_FOR_BASE_P (i, Pmode))
693 || (!reg_class_subset_p (REGNO_REG_CLASS (i), BASE_REG_CLASS))
694 #endif
695 || (hascall && call_used_regs[i])
696 || (!call_used_regs[i] && !regs_ever_live[i]))
697 CLEAR_HARD_REG_BIT (linkregs, i);
699 /* Find an appropriate register to be used as the link register. */
700 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
701 if (TEST_HARD_REG_BIT (linkregs, i))
703 pseq->link_reg = gen_rtx_REG (Pmode, i);
704 break;
707 /* Abstraction is not possible if no link register is available, so set
708 gain to 0. */
709 if (!pseq->link_reg)
710 pseq->gain = 0;
713 /* Deallocates memory occupied by PSEQ and its matching seqs. */
715 static void
716 free_pattern_seq (pattern_seq pseq)
718 while (pseq->matching_seqs)
720 matching_seq mseq = pseq->matching_seqs;
721 pseq->matching_seqs = mseq->next_matching_seq;
722 free (mseq);
724 free (pseq);
728 /* Computes the gain for pattern sequences. Pattern sequences producing no gain
729 are deleted. The pattern sequence with the biggest gain is moved to the first
730 place of PATTERN_SEQS. */
732 static void
733 recompute_gain (void)
735 pattern_seq *pseq;
736 int maxgain;
738 maxgain = 0;
739 for (pseq = &pattern_seqs; *pseq;)
741 if ((*pseq)->gain <= 0)
742 recompute_gain_for_pattern_seq (*pseq);
744 if ((*pseq)->gain > 0)
746 if ((*pseq)->gain > maxgain)
748 pattern_seq temp = *pseq;
749 (*pseq) = temp->next_pattern_seq;
750 temp->next_pattern_seq = pattern_seqs;
751 pattern_seqs = temp;
752 maxgain = pattern_seqs->gain;
754 else
756 pseq = &(*pseq)->next_pattern_seq;
759 else
761 pattern_seq temp = *pseq;
762 *pseq = temp->next_pattern_seq;
763 free_pattern_seq (temp);
768 /* Updated those pattern sequences and matching sequences, which overlap with
769 the sequence given by INSN and LEN. Deletes sequences shrinking below a
770 limit. */
772 static void
773 erase_from_pattern_seqs (rtx insn, int len)
775 pattern_seq *pseq;
776 matching_seq *mseq;
777 rtx x;
778 int plen, mlen;
779 int pcost, mcost;
781 while (len > 0)
783 for (pseq = &pattern_seqs; *pseq;)
785 plen = 0;
786 pcost = 0;
787 for (x = (*pseq)->insn; x && (x != insn);
788 x = prev_insn_in_block (x))
790 plen++;
791 pcost += compute_rtx_cost (x);
794 if (pcost <= seq_call_cost)
796 pattern_seq temp = *pseq;
797 *pseq = temp->next_pattern_seq;
798 free_pattern_seq (temp);
800 else
802 for (mseq = &(*pseq)->matching_seqs; *mseq;)
804 mlen = 0;
805 mcost = 0;
806 for (x = (*mseq)->insn;
807 x && (x != insn) && (mlen < plen)
808 && (mlen < (*mseq)->matching_length);
809 x = prev_insn_in_block (x))
811 mlen++;
812 mcost += compute_rtx_cost (x);
815 if (mcost <= seq_call_cost)
817 matching_seq temp = *mseq;
818 *mseq = temp->next_matching_seq;
819 free (temp);
820 /* Set to 0 to force gain recomputation. */
821 (*pseq)->gain = 0;
823 else
825 if (mlen < (*mseq)->matching_length)
827 (*mseq)->cost = mcost;
828 (*mseq)->matching_length = mlen;
829 /* Set to 0 to force gain recomputation. */
830 (*pseq)->gain = 0;
832 mseq = &(*mseq)->next_matching_seq;
836 pseq = &(*pseq)->next_pattern_seq;
840 len--;
841 insn = prev_insn_in_block (insn);
845 /* Updates those pattern sequences and matching sequences, which overlap with
846 the pattern sequence with the biggest gain and its matching sequences. */
848 static void
849 update_pattern_seqs (void)
851 pattern_seq bestpseq;
852 matching_seq mseq;
854 bestpseq = pattern_seqs;
855 pattern_seqs = bestpseq->next_pattern_seq;
857 for (mseq = bestpseq->matching_seqs; mseq; mseq = mseq->next_matching_seq)
858 if (mseq->cost > seq_call_cost)
859 erase_from_pattern_seqs (mseq->insn, mseq->abstracted_length);
860 erase_from_pattern_seqs (bestpseq->insn, bestpseq->abstracted_length);
862 bestpseq->next_pattern_seq = pattern_seqs;
863 pattern_seqs = bestpseq;
866 /* Groups together those matching sequences of the best pattern sequence, which
867 have the same ABSTRACTED_LENGTH and puts these groups in ascending order.
868 SEQ_BLOCKS contains the result. */
870 static void
871 determine_seq_blocks (void)
873 seq_block sb;
874 matching_seq *mseq;
875 matching_seq m;
877 /* Initialize SEQ_BLOCKS to empty. */
878 seq_blocks = 0;
880 /* Process all matching sequences. */
881 for (mseq = &pattern_seqs->matching_seqs; *mseq;)
883 /* Deal only with matching sequences being long enough. */
884 if ((*mseq)->cost <= seq_call_cost)
886 mseq = &(*mseq)->next_matching_seq;
887 continue;
890 /* Ensure that SB contains a seq_block with the appropriate length.
891 Insert a new seq_block if neccessary. */
892 if (!seq_blocks || ((*mseq)->abstracted_length < seq_blocks->length))
894 sb = (seq_block) xmalloc (sizeof (struct seq_block_def));
895 sb->length = (*mseq)->abstracted_length;
896 sb->label = NULL_RTX;
897 sb->matching_seqs = 0;
898 sb->next_seq_block = seq_blocks;
899 seq_blocks = sb;
901 else
903 for (sb = seq_blocks; sb; sb = sb->next_seq_block)
905 if ((*mseq)->abstracted_length == sb->length)
906 break;
907 if (!sb->next_seq_block
908 || ((*mseq)->abstracted_length <
909 sb->next_seq_block->length))
911 seq_block temp =
912 (seq_block) xmalloc (sizeof (struct seq_block_def));
913 temp->length = (*mseq)->abstracted_length;
914 temp->label = NULL_RTX;
915 temp->matching_seqs = 0;
916 temp->next_seq_block = sb->next_seq_block;
917 sb->next_seq_block = temp;
922 /* Remove the matching sequence from the linked list of the pattern
923 sequence and link it to SB. */
924 m = *mseq;
925 *mseq = m->next_matching_seq;
926 m->next_matching_seq = sb->matching_seqs;
927 sb->matching_seqs = m;
931 /* Builds a symbol_ref for LABEL. */
933 static rtx
934 gen_symbol_ref_rtx_for_label (rtx label)
936 char name[20];
937 rtx sym;
939 ASM_GENERATE_INTERNAL_LABEL (name, "L", CODE_LABEL_NUMBER (label));
940 sym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
941 SYMBOL_REF_FLAGS (sym) = SYMBOL_FLAG_LOCAL;
942 return sym;
945 /* Ensures that INSN is the last insn in its block and returns the block label
946 of the next block. */
948 static rtx
949 block_label_after (rtx insn)
951 basic_block bb = BLOCK_FOR_INSN (insn);
952 if ((insn == BB_END (bb)) && (bb->next_bb != EXIT_BLOCK_PTR))
953 return block_label (bb->next_bb);
954 else
955 return block_label (split_block (bb, insn)->dest);
958 /* Ensures that the last insns of the best pattern and its matching sequences
959 are the last insns in their block. Additionally, extends the live set at the
960 end of the pattern sequence with the live sets at the end of the matching
961 sequences. */
963 static void
964 split_blocks_after_seqs (void)
966 seq_block sb;
967 matching_seq mseq;
969 block_label_after (pattern_seqs->insn);
970 for (sb = seq_blocks; sb; sb = sb->next_seq_block)
972 for (mseq = sb->matching_seqs; mseq; mseq = mseq->next_matching_seq)
974 block_label_after (mseq->insn);
975 IOR_REG_SET (BLOCK_FOR_INSN (pattern_seqs->insn)->
976 il.rtl->global_live_at_end,
977 BLOCK_FOR_INSN (mseq->insn)->il.rtl->global_live_at_end);
982 /* Splits the best pattern sequence accoring to SEQ_BLOCKS. Emits pseudo-call
983 and -return insns before and after the sequence. */
985 static void
986 split_pattern_seq (void)
988 rtx insn;
989 basic_block bb;
990 rtx retlabel, retjmp, saveinsn;
991 int i;
992 seq_block sb;
994 insn = pattern_seqs->insn;
995 bb = BLOCK_FOR_INSN (insn);
997 /* Get the label after the sequence. This will be the return address. The
998 label will be referenced using a symbol_ref so protect it from
999 deleting. */
1000 retlabel = block_label_after (insn);
1001 LABEL_PRESERVE_P (retlabel) = 1;
1003 /* Emit an indirect jump via the link register after the sequence acting
1004 as the return insn. Also emit a barrier and update the basic block. */
1005 retjmp = emit_jump_insn_after (gen_indirect_jump (pattern_seqs->link_reg),
1006 BB_END (bb));
1007 emit_barrier_after (BB_END (bb));
1009 /* Replace all outgoing edges with a new one to the block of RETLABEL. */
1010 while (EDGE_COUNT (bb->succs) != 0)
1011 remove_edge (EDGE_SUCC (bb, 0));
1012 make_edge (bb, BLOCK_FOR_INSN (retlabel), EDGE_ABNORMAL);
1014 /* Split the sequence according to SEQ_BLOCKS and cache the label of the
1015 resulting basic blocks. */
1016 i = 0;
1017 for (sb = seq_blocks; sb; sb = sb->next_seq_block)
1019 for (; i < sb->length; i++)
1020 insn = prev_insn_in_block (insn);
1022 sb->label = block_label (split_block (bb, insn)->dest);
1025 /* Emit an insn saving the return address to the link register before the
1026 sequence. */
1027 saveinsn = emit_insn_after (gen_move_insn (pattern_seqs->link_reg,
1028 gen_symbol_ref_rtx_for_label
1029 (retlabel)), BB_END (bb));
1030 /* Update liveness info. */
1031 SET_REGNO_REG_SET (bb->il.rtl->global_live_at_end,
1032 REGNO (pattern_seqs->link_reg));
1035 /* Deletes the insns of the matching sequences of the best pattern sequence and
1036 replaces them with pseudo-calls to the pattern sequence. */
1038 static void
1039 erase_matching_seqs (void)
1041 seq_block sb;
1042 matching_seq mseq;
1043 rtx insn;
1044 basic_block bb;
1045 rtx retlabel, saveinsn, callinsn;
1046 int i;
1048 for (sb = seq_blocks; sb; sb = sb->next_seq_block)
1050 for (mseq = sb->matching_seqs; mseq; mseq = mseq->next_matching_seq)
1052 insn = mseq->insn;
1053 bb = BLOCK_FOR_INSN (insn);
1055 /* Get the label after the sequence. This will be the return
1056 address. The label will be referenced using a symbol_ref so
1057 protect it from deleting. */
1058 retlabel = block_label_after (insn);
1059 LABEL_PRESERVE_P (retlabel) = 1;
1061 /* Delete the insns of the sequence. */
1062 for (i = 0; i < sb->length; i++)
1063 insn = prev_insn_in_block (insn);
1064 delete_basic_block (split_block (bb, insn)->dest);
1066 /* Emit an insn saving the return address to the link register
1067 before the deleted sequence. */
1068 saveinsn = emit_insn_after (gen_move_insn (pattern_seqs->link_reg,
1069 gen_symbol_ref_rtx_for_label
1070 (retlabel)),
1071 BB_END (bb));
1072 BLOCK_FOR_INSN (saveinsn) = bb;
1074 /* Emit a jump to the appropriate part of the pattern sequence
1075 after the save insn. Also update the basic block. */
1076 callinsn = emit_jump_insn_after (gen_jump (sb->label), saveinsn);
1077 JUMP_LABEL (callinsn) = sb->label;
1078 LABEL_NUSES (sb->label)++;
1079 BLOCK_FOR_INSN (callinsn) = bb;
1080 BB_END (bb) = callinsn;
1082 /* Maintain control flow and liveness information. */
1083 SET_REGNO_REG_SET (bb->il.rtl->global_live_at_end,
1084 REGNO (pattern_seqs->link_reg));
1085 emit_barrier_after (BB_END (bb));
1086 make_single_succ_edge (bb, BLOCK_FOR_INSN (sb->label), 0);
1087 IOR_REG_SET (bb->il.rtl->global_live_at_end,
1088 BLOCK_FOR_INSN (sb->label)->il.rtl->global_live_at_start);
1090 make_edge (BLOCK_FOR_INSN (seq_blocks->label),
1091 BLOCK_FOR_INSN (retlabel), EDGE_ABNORMAL);
1096 /* Deallocates SEQ_BLOCKS and all the matching sequences. */
1098 static void
1099 free_seq_blocks (void)
1101 while (seq_blocks)
1103 seq_block sb = seq_blocks;
1104 while (sb->matching_seqs)
1106 matching_seq mseq = sb->matching_seqs;
1107 sb->matching_seqs = mseq->next_matching_seq;
1108 free (mseq);
1110 seq_blocks = sb->next_seq_block;
1111 free (sb);
1115 /* Transforms the best pattern sequence into a pseudo-function and its matching
1116 sequences to pseudo-calls. Afterwards the best pattern sequence is removed
1117 from PATTERN_SEQS. */
1119 static void
1120 abstract_best_seq (void)
1122 pattern_seq bestpseq;
1124 /* Do the abstraction. */
1125 determine_seq_blocks ();
1126 split_blocks_after_seqs ();
1127 split_pattern_seq ();
1128 erase_matching_seqs ();
1129 free_seq_blocks ();
1131 /* Record the usage of the link register. */
1132 regs_ever_live[REGNO (pattern_seqs->link_reg)] = 1;
1134 /* Remove the best pattern sequence. */
1135 bestpseq = pattern_seqs;
1136 pattern_seqs = bestpseq->next_pattern_seq;
1137 free_pattern_seq (bestpseq);
1140 /* Prints info on the pattern sequences to the dump file. */
1142 static void
1143 dump_pattern_seqs (void)
1145 pattern_seq pseq;
1146 matching_seq mseq;
1148 if (!dump_file)
1149 return;
1151 fprintf (dump_file, ";; Pattern sequences\n");
1152 for (pseq = pattern_seqs; pseq; pseq = pseq->next_pattern_seq)
1154 fprintf (dump_file, "Pattern sequence at insn %d matches sequences at",
1155 INSN_UID (pseq->insn));
1156 for (mseq = pseq->matching_seqs; mseq; mseq = mseq->next_matching_seq)
1158 fprintf (dump_file, " insn %d (length %d)", INSN_UID (mseq->insn),
1159 mseq->matching_length);
1160 if (mseq->next_matching_seq)
1161 fprintf (dump_file, ",");
1163 fprintf (dump_file, ".\n");
1165 fprintf (dump_file, "\n");
1168 /* Prints info on the best pattern sequence transformed in the ITER-th
1169 iteration to the dump file. */
1171 static void
1172 dump_best_pattern_seq (int iter)
1174 matching_seq mseq;
1176 if (!dump_file)
1177 return;
1179 fprintf (dump_file, ";; Iteration %d\n", iter);
1180 fprintf (dump_file,
1181 "Best pattern sequence with %d gain is at insn %d (length %d).\n",
1182 pattern_seqs->gain, INSN_UID (pattern_seqs->insn),
1183 pattern_seqs->abstracted_length);
1184 fprintf (dump_file, "Matching sequences are at");
1185 for (mseq = pattern_seqs->matching_seqs; mseq;
1186 mseq = mseq->next_matching_seq)
1188 fprintf (dump_file, " insn %d (length %d)", INSN_UID (mseq->insn),
1189 mseq->abstracted_length);
1190 if (mseq->next_matching_seq)
1191 fprintf (dump_file, ",");
1193 fprintf (dump_file, ".\n");
1194 fprintf (dump_file, "Using reg %d as link register.\n\n",
1195 REGNO (pattern_seqs->link_reg));
1198 /* Htab hash function for hash_bucket_def structure. */
1200 static unsigned int
1201 htab_hash_bucket (const void *p)
1203 p_hash_bucket bucket = (p_hash_bucket) p;
1204 return bucket->hash;
1207 /* Htab equal function for hash_bucket_def structure. */
1209 static int
1210 htab_eq_bucket (const void *p0, const void *p1)
1212 return htab_hash_bucket (p0) == htab_hash_bucket (p1);
1215 /* Htab delete function for hash_bucket_def structure. */
1217 static void
1218 htab_del_bucket (void *p)
1220 p_hash_bucket bucket = (p_hash_bucket) p;
1222 if (bucket->seq_candidates)
1223 htab_delete (bucket->seq_candidates);
1225 free (bucket);
1228 /* Htab hash function for hash_bucket_def structure. */
1230 static unsigned int
1231 htab_hash_elem (const void *p)
1233 p_hash_elem elem = (p_hash_elem) p;
1234 return htab_hash_pointer (elem->insn);
1237 /* Htab equal function for hash_bucket_def structure. */
1239 static int
1240 htab_eq_elem (const void *p0, const void *p1)
1242 return htab_hash_elem (p0) == htab_hash_elem (p1);
1245 /* Htab delete function for hash_bucket_def structure. */
1247 static void
1248 htab_del_elem (void *p)
1250 p_hash_elem elem = (p_hash_elem) p;
1251 free (elem);
1254 /* Creates a hash value for each sequence candidate and saves them
1255 in HASH_BUCKET. */
1257 static void
1258 fill_hash_bucket (void)
1260 basic_block bb;
1261 rtx insn;
1262 void **slot;
1263 p_hash_bucket bucket;
1264 struct hash_bucket_def tmp_bucket;
1265 p_hash_elem elem;
1266 unsigned long insn_idx;
1268 insn_idx = 0;
1269 FOR_EACH_BB (bb)
1271 FOR_BB_INSNS_REVERSE (bb, insn)
1273 if (!ABSTRACTABLE_INSN_P (insn))
1274 continue;
1276 /* Compute hash value for INSN. */
1277 tmp_bucket.hash = compute_hash (insn);
1279 /* Select the hash group. */
1280 bucket = htab_find (hash_buckets, &tmp_bucket);
1282 if (!bucket)
1284 /* Create a new hash group. */
1285 bucket = (p_hash_bucket) xcalloc (1,
1286 sizeof (struct hash_bucket_def));
1287 bucket->hash = tmp_bucket.hash;
1288 bucket->seq_candidates = NULL;
1290 slot = htab_find_slot (hash_buckets, &tmp_bucket, INSERT);
1291 *slot = bucket;
1294 /* Create new list for storing sequence candidates. */
1295 if (!bucket->seq_candidates)
1296 bucket->seq_candidates = htab_create (HASH_INIT,
1297 htab_hash_elem,
1298 htab_eq_elem,
1299 htab_del_elem);
1301 elem = (p_hash_elem) xcalloc (1, sizeof (struct hash_elem_def));
1302 elem->insn = insn;
1303 elem->idx = insn_idx;
1304 elem->length = get_attr_length (insn);
1306 /* Insert INSN into BUCKET hash bucket. */
1307 slot = htab_find_slot (bucket->seq_candidates, elem, INSERT);
1308 *slot = elem;
1310 insn_idx++;
1315 /* Computes the cost of calling sequence and the cost of return. */
1317 static void
1318 compute_init_costs (void)
1320 rtx rtx_jump, rtx_store, rtx_return, reg, label;
1321 basic_block bb;
1323 FOR_EACH_BB (bb)
1324 if (BB_HEAD (bb))
1325 break;
1327 label = block_label (bb);
1328 reg = gen_rtx_REG (Pmode, 0);
1330 /* Pattern for indirect jump. */
1331 rtx_jump = gen_indirect_jump (reg);
1333 /* Pattern for storing address. */
1334 rtx_store = gen_rtx_SET (VOIDmode, reg, gen_symbol_ref_rtx_for_label (label));
1336 /* Pattern for return insn. */
1337 rtx_return = gen_jump (label);
1339 /* The cost of jump. */
1340 seq_jump_cost = compute_rtx_cost (make_jump_insn_raw (rtx_jump));
1342 /* The cost of calling sequence. */
1343 seq_call_cost = seq_jump_cost + compute_rtx_cost (make_insn_raw (rtx_store));
1345 /* The cost of return. */
1346 seq_return_cost = compute_rtx_cost (make_jump_insn_raw (rtx_return));
1348 /* Simple heuristic for minimal sequence cost. */
1349 seq_call_cost = (int)(seq_call_cost * (double)SEQ_CALL_COST_MULTIPLIER);
1352 /* Finds equivalent insn sequences in the current function and retains only one
1353 instance of them which is turned into a pseudo-function. The additional
1354 copies are erased and replaced by pseudo-calls to the retained sequence. */
1356 static void
1357 rtl_seqabstr (void)
1359 int iter;
1361 /* Create a hash list for COLLECT_PATTERN_SEQS. */
1362 hash_buckets = htab_create (HASH_INIT, htab_hash_bucket , htab_eq_bucket ,
1363 htab_del_bucket);
1364 fill_hash_bucket ();
1366 /* Compute the common cost of abstraction. */
1367 compute_init_costs ();
1369 /* Build an initial set of pattern sequences from the current function. */
1370 collect_pattern_seqs ();
1371 dump_pattern_seqs ();
1373 /* Iterate until there are no sequences to abstract. */
1374 for (iter = 1;; iter++)
1376 /* Recompute gain for sequences if neccessary and select sequence with
1377 biggest gain. */
1378 recompute_gain ();
1379 if (!pattern_seqs)
1380 break;
1381 dump_best_pattern_seq (iter);
1382 /* Update the cached info of the other sequences and force gain
1383 recomputation where needed. */
1384 update_pattern_seqs ();
1385 /* Turn best sequences into pseudo-functions and -calls. */
1386 abstract_best_seq ();
1389 /* Cleanup hash tables. */
1390 htab_delete (hash_buckets);
1392 if (iter > 1)
1394 /* Update notes. */
1395 count_or_remove_death_notes (NULL, 1);
1397 life_analysis (PROP_DEATH_NOTES | PROP_SCAN_DEAD_CODE
1398 | PROP_KILL_DEAD_CODE);
1400 /* Extra cleanup. */
1401 cleanup_cfg (CLEANUP_EXPENSIVE |
1402 CLEANUP_UPDATE_LIFE |
1403 (flag_crossjumping ? CLEANUP_CROSSJUMP : 0));
1407 /* The gate function for TREE_OPT_PASS. */
1409 static bool
1410 gate_rtl_seqabstr (void)
1412 return flag_rtl_seqabstr;
1415 /* The entry point of the sequence abstraction algorithm. */
1417 static void
1418 rest_of_rtl_seqabstr (void)
1420 life_analysis (PROP_DEATH_NOTES | PROP_SCAN_DEAD_CODE | PROP_KILL_DEAD_CODE);
1422 cleanup_cfg (CLEANUP_EXPENSIVE |
1423 CLEANUP_UPDATE_LIFE |
1424 (flag_crossjumping ? CLEANUP_CROSSJUMP : 0));
1426 /* Abstract out common insn sequences. */
1427 rtl_seqabstr ();
1430 struct tree_opt_pass pass_rtl_seqabstr = {
1431 "seqabstr", /* name */
1432 gate_rtl_seqabstr, /* gate */
1433 rest_of_rtl_seqabstr, /* execute */
1434 NULL, /* sub */
1435 NULL, /* next */
1436 0, /* static_pass_number */
1437 TV_SEQABSTR, /* tv_id */
1438 0, /* properties_required */
1439 0, /* properties_provided */
1440 0, /* properties_destroyed */
1441 0, /* todo_flags_start */
1442 TODO_dump_func |
1443 TODO_ggc_collect, /* todo_flags_finish */
1444 'Q' /* letter */