OSDN Git Service

2009-10-05 Daniel Kraft <d@domob.eu>
[pf3gnuchains/gcc-fork.git] / gcc / regmove.c
1 /* Move registers around to reduce number of move instructions needed.
2    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997,
3    1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
4    Free Software Foundation, Inc.
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
12
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3.  If not see
20 <http://www.gnu.org/licenses/>.  */
21
22
23 /* This module makes some simple RTL code transformations which
24    improve the subsequent register allocation.  */
25
26 #include "config.h"
27 #include "system.h"
28 #include "coretypes.h"
29 #include "tm.h"
30 #include "rtl.h" /* stdio.h must precede rtl.h for FFS.  */
31 #include "tm_p.h"
32 #include "insn-config.h"
33 #include "recog.h"
34 #include "output.h"
35 #include "regs.h"
36 #include "hard-reg-set.h"
37 #include "flags.h"
38 #include "function.h"
39 #include "expr.h"
40 #include "basic-block.h"
41 #include "except.h"
42 #include "toplev.h"
43 #include "reload.h"
44 #include "timevar.h"
45 #include "tree-pass.h"
46 #include "df.h"
47
48 static int optimize_reg_copy_1 (rtx, rtx, rtx);
49 static void optimize_reg_copy_2 (rtx, rtx, rtx);
50 static void optimize_reg_copy_3 (rtx, rtx, rtx);
51 static void copy_src_to_dest (rtx, rtx, rtx);
52
53 enum match_use
54 {
55   READ,
56   WRITE,
57   READWRITE
58 };
59
60 struct match {
61   int with[MAX_RECOG_OPERANDS];
62   enum match_use use[MAX_RECOG_OPERANDS];
63   int commutative[MAX_RECOG_OPERANDS];
64   int early_clobber[MAX_RECOG_OPERANDS];
65 };
66
67 static int find_matches (rtx, struct match *);
68 static int fixup_match_2 (rtx, rtx, rtx, rtx);
69
70 /* Return nonzero if registers with CLASS1 and CLASS2 can be merged without
71    causing too much register allocation problems.  */
72 static int
73 regclass_compatible_p (enum reg_class class0, enum reg_class class1)
74 {
75   return (class0 == class1
76           || (reg_class_subset_p (class0, class1)
77               && ! CLASS_LIKELY_SPILLED_P (class0))
78           || (reg_class_subset_p (class1, class0)
79               && ! CLASS_LIKELY_SPILLED_P (class1)));
80 }
81
82 \f
83 #ifdef AUTO_INC_DEC
84
85 /* Find the place in the rtx X where REG is used as a memory address.
86    Return the MEM rtx that so uses it.
87    If PLUSCONST is nonzero, search instead for a memory address equivalent to
88    (plus REG (const_int PLUSCONST)).
89
90    If such an address does not appear, return 0.
91    If REG appears more than once, or is used other than in such an address,
92    return (rtx) 1.  */
93
94 static rtx
95 find_use_as_address (rtx x, rtx reg, HOST_WIDE_INT plusconst)
96 {
97   enum rtx_code code = GET_CODE (x);
98   const char * const fmt = GET_RTX_FORMAT (code);
99   int i;
100   rtx value = 0;
101   rtx tem;
102
103   if (code == MEM && XEXP (x, 0) == reg && plusconst == 0)
104     return x;
105
106   if (code == MEM && GET_CODE (XEXP (x, 0)) == PLUS
107       && XEXP (XEXP (x, 0), 0) == reg
108       && CONST_INT_P (XEXP (XEXP (x, 0), 1))
109       && INTVAL (XEXP (XEXP (x, 0), 1)) == plusconst)
110     return x;
111
112   if (code == SIGN_EXTRACT || code == ZERO_EXTRACT)
113     {
114       /* If REG occurs inside a MEM used in a bit-field reference,
115          that is unacceptable.  */
116       if (find_use_as_address (XEXP (x, 0), reg, 0) != 0)
117         return (rtx) (size_t) 1;
118     }
119
120   if (x == reg)
121     return (rtx) (size_t) 1;
122
123   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
124     {
125       if (fmt[i] == 'e')
126         {
127           tem = find_use_as_address (XEXP (x, i), reg, plusconst);
128           if (value == 0)
129             value = tem;
130           else if (tem != 0)
131             return (rtx) (size_t) 1;
132         }
133       else if (fmt[i] == 'E')
134         {
135           int j;
136           for (j = XVECLEN (x, i) - 1; j >= 0; j--)
137             {
138               tem = find_use_as_address (XVECEXP (x, i, j), reg, plusconst);
139               if (value == 0)
140                 value = tem;
141               else if (tem != 0)
142                 return (rtx) (size_t) 1;
143             }
144         }
145     }
146
147   return value;
148 }
149
150
151 /* INC_INSN is an instruction that adds INCREMENT to REG.
152    Try to fold INC_INSN as a post/pre in/decrement into INSN.
153    Iff INC_INSN_SET is nonzero, inc_insn has a destination different from src.
154    Return nonzero for success.  */
155 static int
156 try_auto_increment (rtx insn, rtx inc_insn, rtx inc_insn_set, rtx reg,
157                     HOST_WIDE_INT increment, int pre)
158 {
159   enum rtx_code inc_code;
160
161   rtx pset = single_set (insn);
162   if (pset)
163     {
164       /* Can't use the size of SET_SRC, we might have something like
165          (sign_extend:SI (mem:QI ...  */
166       rtx use = find_use_as_address (pset, reg, 0);
167       if (use != 0 && use != (rtx) (size_t) 1)
168         {
169           int size = GET_MODE_SIZE (GET_MODE (use));
170           if (0
171               || (HAVE_POST_INCREMENT
172                   && pre == 0 && (inc_code = POST_INC, increment == size))
173               || (HAVE_PRE_INCREMENT
174                   && pre == 1 && (inc_code = PRE_INC, increment == size))
175               || (HAVE_POST_DECREMENT
176                   && pre == 0 && (inc_code = POST_DEC, increment == -size))
177               || (HAVE_PRE_DECREMENT
178                   && pre == 1 && (inc_code = PRE_DEC, increment == -size))
179           )
180             {
181               if (inc_insn_set)
182                 validate_change
183                   (inc_insn,
184                    &SET_SRC (inc_insn_set),
185                    XEXP (SET_SRC (inc_insn_set), 0), 1);
186               validate_change (insn, &XEXP (use, 0),
187                                gen_rtx_fmt_e (inc_code, Pmode, reg), 1);
188               if (apply_change_group ())
189                 {
190                   /* If there is a REG_DEAD note on this insn, we must
191                      change this not to REG_UNUSED meaning that the register
192                      is set, but the value is dead.  Failure to do so will
193                      result in sched1 dying -- when it recomputes lifetime
194                      information, the number of REG_DEAD notes will have
195                      changed.  */
196                   rtx note = find_reg_note (insn, REG_DEAD, reg);
197                   if (note)
198                     PUT_REG_NOTE_KIND (note, REG_UNUSED);
199
200                   add_reg_note (insn, REG_INC, reg);
201
202                   if (! inc_insn_set)
203                     delete_insn (inc_insn);
204                   return 1;
205                 }
206             }
207         }
208     }
209   return 0;
210 }
211 #endif
212
213 \f
214 static int *regno_src_regno;
215
216 /* INSN is a copy from SRC to DEST, both registers, and SRC does not die
217    in INSN.
218
219    Search forward to see if SRC dies before either it or DEST is modified,
220    but don't scan past the end of a basic block.  If so, we can replace SRC
221    with DEST and let SRC die in INSN.
222
223    This will reduce the number of registers live in that range and may enable
224    DEST to be tied to SRC, thus often saving one register in addition to a
225    register-register copy.  */
226
227 static int
228 optimize_reg_copy_1 (rtx insn, rtx dest, rtx src)
229 {
230   rtx p, q;
231   rtx note;
232   rtx dest_death = 0;
233   int sregno = REGNO (src);
234   int dregno = REGNO (dest);
235   basic_block bb = BLOCK_FOR_INSN (insn);
236
237   /* We don't want to mess with hard regs if register classes are small.  */
238   if (sregno == dregno
239       || (SMALL_REGISTER_CLASSES
240           && (sregno < FIRST_PSEUDO_REGISTER
241               || dregno < FIRST_PSEUDO_REGISTER))
242       /* We don't see all updates to SP if they are in an auto-inc memory
243          reference, so we must disallow this optimization on them.  */
244       || sregno == STACK_POINTER_REGNUM || dregno == STACK_POINTER_REGNUM)
245     return 0;
246
247   for (p = NEXT_INSN (insn); p; p = NEXT_INSN (p))
248     {
249       if (! INSN_P (p))
250         continue;
251       if (BLOCK_FOR_INSN (p) != bb)
252         break;
253
254       if (reg_set_p (src, p) || reg_set_p (dest, p)
255           /* If SRC is an asm-declared register, it must not be replaced
256              in any asm.  Unfortunately, the REG_EXPR tree for the asm
257              variable may be absent in the SRC rtx, so we can't check the
258              actual register declaration easily (the asm operand will have
259              it, though).  To avoid complicating the test for a rare case,
260              we just don't perform register replacement for a hard reg
261              mentioned in an asm.  */
262           || (sregno < FIRST_PSEUDO_REGISTER
263               && asm_noperands (PATTERN (p)) >= 0
264               && reg_overlap_mentioned_p (src, PATTERN (p)))
265           /* Don't change hard registers used by a call.  */
266           || (CALL_P (p) && sregno < FIRST_PSEUDO_REGISTER
267               && find_reg_fusage (p, USE, src))
268           /* Don't change a USE of a register.  */
269           || (GET_CODE (PATTERN (p)) == USE
270               && reg_overlap_mentioned_p (src, XEXP (PATTERN (p), 0))))
271         break;
272
273       /* See if all of SRC dies in P.  This test is slightly more
274          conservative than it needs to be.  */
275       if ((note = find_regno_note (p, REG_DEAD, sregno)) != 0
276           && GET_MODE (XEXP (note, 0)) == GET_MODE (src))
277         {
278           int failed = 0;
279           int d_length = 0;
280           int s_length = 0;
281           int d_n_calls = 0;
282           int s_n_calls = 0;
283           int s_freq_calls = 0;
284           int d_freq_calls = 0;
285
286           /* We can do the optimization.  Scan forward from INSN again,
287              replacing regs as we go.  Set FAILED if a replacement can't
288              be done.  In that case, we can't move the death note for SRC.
289              This should be rare.  */
290
291           /* Set to stop at next insn.  */
292           for (q = next_real_insn (insn);
293                q != next_real_insn (p);
294                q = next_real_insn (q))
295             {
296               if (reg_overlap_mentioned_p (src, PATTERN (q)))
297                 {
298                   /* If SRC is a hard register, we might miss some
299                      overlapping registers with validate_replace_rtx,
300                      so we would have to undo it.  We can't if DEST is
301                      present in the insn, so fail in that combination
302                      of cases.  */
303                   if (sregno < FIRST_PSEUDO_REGISTER
304                       && reg_mentioned_p (dest, PATTERN (q)))
305                     failed = 1;
306                   
307                   /* Attempt to replace all uses.  */
308                   else if (!validate_replace_rtx (src, dest, q))
309                     failed = 1;
310
311                   /* If this succeeded, but some part of the register
312                      is still present, undo the replacement.  */
313                   else if (sregno < FIRST_PSEUDO_REGISTER
314                            && reg_overlap_mentioned_p (src, PATTERN (q)))
315                     {
316                       validate_replace_rtx (dest, src, q);
317                       failed = 1;
318                     }
319                 }
320
321               /* For SREGNO, count the total number of insns scanned.
322                  For DREGNO, count the total number of insns scanned after
323                  passing the death note for DREGNO.  */
324               if (!DEBUG_INSN_P (p))
325                 {
326                   s_length++;
327                   if (dest_death)
328                     d_length++;
329                 }
330
331               /* If the insn in which SRC dies is a CALL_INSN, don't count it
332                  as a call that has been crossed.  Otherwise, count it.  */
333               if (q != p && CALL_P (q))
334                 {
335                   /* Similarly, total calls for SREGNO, total calls beyond
336                      the death note for DREGNO.  */
337                   s_n_calls++;
338                   s_freq_calls += REG_FREQ_FROM_BB  (BLOCK_FOR_INSN (q));
339                   if (dest_death)
340                     {
341                       d_n_calls++;
342                       d_freq_calls += REG_FREQ_FROM_BB  (BLOCK_FOR_INSN (q));
343                     }
344                 }
345
346               /* If DEST dies here, remove the death note and save it for
347                  later.  Make sure ALL of DEST dies here; again, this is
348                  overly conservative.  */
349               if (dest_death == 0
350                   && (dest_death = find_regno_note (q, REG_DEAD, dregno)) != 0)
351                 {
352                   if (GET_MODE (XEXP (dest_death, 0)) != GET_MODE (dest))
353                     failed = 1, dest_death = 0;
354                   else
355                     remove_note (q, dest_death);
356                 }
357             }
358
359           if (! failed)
360             {
361               /* These counters need to be updated if and only if we are
362                  going to move the REG_DEAD note.  */
363               if (sregno >= FIRST_PSEUDO_REGISTER)
364                 {
365                   if (REG_LIVE_LENGTH (sregno) >= 0)
366                     {
367                       REG_LIVE_LENGTH (sregno) -= s_length;
368                       /* REG_LIVE_LENGTH is only an approximation after
369                          combine if sched is not run, so make sure that we
370                          still have a reasonable value.  */
371                       if (REG_LIVE_LENGTH (sregno) < 2)
372                         REG_LIVE_LENGTH (sregno) = 2;
373                     }
374
375                   REG_N_CALLS_CROSSED (sregno) -= s_n_calls;
376                   REG_FREQ_CALLS_CROSSED (sregno) -= s_freq_calls;
377                 }
378
379               /* Move death note of SRC from P to INSN.  */
380               remove_note (p, note);
381               XEXP (note, 1) = REG_NOTES (insn);
382               REG_NOTES (insn) = note;
383             }
384
385           /* DEST is also dead if INSN has a REG_UNUSED note for DEST.  */
386           if (! dest_death
387               && (dest_death = find_regno_note (insn, REG_UNUSED, dregno)))
388             {
389               PUT_REG_NOTE_KIND (dest_death, REG_DEAD);
390               remove_note (insn, dest_death);
391             }
392
393           /* Put death note of DEST on P if we saw it die.  */
394           if (dest_death)
395             {
396               XEXP (dest_death, 1) = REG_NOTES (p);
397               REG_NOTES (p) = dest_death;
398
399               if (dregno >= FIRST_PSEUDO_REGISTER)
400                 {
401                   /* If and only if we are moving the death note for DREGNO,
402                      then we need to update its counters.  */
403                   if (REG_LIVE_LENGTH (dregno) >= 0)
404                     REG_LIVE_LENGTH (dregno) += d_length;
405                   REG_N_CALLS_CROSSED (dregno) += d_n_calls;
406                   REG_FREQ_CALLS_CROSSED (dregno) += d_freq_calls;
407                 }
408             }
409
410           return ! failed;
411         }
412
413       /* If SRC is a hard register which is set or killed in some other
414          way, we can't do this optimization.  */
415       else if (sregno < FIRST_PSEUDO_REGISTER
416                && dead_or_set_p (p, src))
417         break;
418     }
419   return 0;
420 }
421 \f
422 /* INSN is a copy of SRC to DEST, in which SRC dies.  See if we now have
423    a sequence of insns that modify DEST followed by an insn that sets
424    SRC to DEST in which DEST dies, with no prior modification of DEST.
425    (There is no need to check if the insns in between actually modify
426    DEST.  We should not have cases where DEST is not modified, but
427    the optimization is safe if no such modification is detected.)
428    In that case, we can replace all uses of DEST, starting with INSN and
429    ending with the set of SRC to DEST, with SRC.  We do not do this
430    optimization if a CALL_INSN is crossed unless SRC already crosses a
431    call or if DEST dies before the copy back to SRC.
432
433    It is assumed that DEST and SRC are pseudos; it is too complicated to do
434    this for hard registers since the substitutions we may make might fail.  */
435
436 static void
437 optimize_reg_copy_2 (rtx insn, rtx dest, rtx src)
438 {
439   rtx p, q;
440   rtx set;
441   int sregno = REGNO (src);
442   int dregno = REGNO (dest);
443   basic_block bb = BLOCK_FOR_INSN (insn);
444
445   for (p = NEXT_INSN (insn); p; p = NEXT_INSN (p))
446     {
447       if (! INSN_P (p))
448         continue;
449       if (BLOCK_FOR_INSN (p) != bb)
450         break;
451
452       set = single_set (p);
453       if (set && SET_SRC (set) == dest && SET_DEST (set) == src
454           && find_reg_note (p, REG_DEAD, dest))
455         {
456           /* We can do the optimization.  Scan forward from INSN again,
457              replacing regs as we go.  */
458
459           /* Set to stop at next insn.  */
460           for (q = insn; q != NEXT_INSN (p); q = NEXT_INSN (q))
461             if (INSN_P (q))
462               {
463                 if (reg_mentioned_p (dest, PATTERN (q)))
464                   {
465                     rtx note;
466
467                     PATTERN (q) = replace_rtx (PATTERN (q), dest, src);
468                     note = FIND_REG_INC_NOTE (q, dest);
469                     if (note)
470                       {
471                         remove_note (q, note);
472                         add_reg_note (q, REG_INC, src);
473                       }
474                     df_insn_rescan (q);
475                   }
476
477                 if (CALL_P (q))
478                   {
479                     int freq = REG_FREQ_FROM_BB  (BLOCK_FOR_INSN (q));
480                     REG_N_CALLS_CROSSED (dregno)--;
481                     REG_N_CALLS_CROSSED (sregno)++;
482                     REG_FREQ_CALLS_CROSSED (dregno) -= freq;
483                     REG_FREQ_CALLS_CROSSED (sregno) += freq;
484                   }
485               }
486
487           remove_note (p, find_reg_note (p, REG_DEAD, dest));
488           REG_N_DEATHS (dregno)--;
489           remove_note (insn, find_reg_note (insn, REG_DEAD, src));
490           REG_N_DEATHS (sregno)--;
491           return;
492         }
493
494       if (reg_set_p (src, p)
495           || find_reg_note (p, REG_DEAD, dest)
496           || (CALL_P (p) && REG_N_CALLS_CROSSED (sregno) == 0))
497         break;
498     }
499 }
500
501 /* INSN is a ZERO_EXTEND or SIGN_EXTEND of SRC to DEST.
502    Look if SRC dies there, and if it is only set once, by loading
503    it from memory.  If so, try to incorporate the zero/sign extension
504    into the memory read, change SRC to the mode of DEST, and alter
505    the remaining accesses to use the appropriate SUBREG.  This allows
506    SRC and DEST to be tied later.  */
507 static void
508 optimize_reg_copy_3 (rtx insn, rtx dest, rtx src)
509 {
510   rtx src_reg = XEXP (src, 0);
511   int src_no = REGNO (src_reg);
512   int dst_no = REGNO (dest);
513   rtx p, set;
514   enum machine_mode old_mode;
515   basic_block bb = BLOCK_FOR_INSN (insn);
516
517   if (src_no < FIRST_PSEUDO_REGISTER
518       || dst_no < FIRST_PSEUDO_REGISTER
519       || ! find_reg_note (insn, REG_DEAD, src_reg)
520       || REG_N_DEATHS (src_no) != 1
521       || REG_N_SETS (src_no) != 1)
522     return;
523
524   for (p = PREV_INSN (insn); p && ! reg_set_p (src_reg, p); p = PREV_INSN (p))
525     if (INSN_P (p) && BLOCK_FOR_INSN (p) != bb)
526       break;
527   
528   if (! p || BLOCK_FOR_INSN (p) != bb)
529     return;
530
531   if (! (set = single_set (p))
532       || !MEM_P (SET_SRC (set))
533       /* If there's a REG_EQUIV note, this must be an insn that loads an
534          argument.  Prefer keeping the note over doing this optimization.  */
535       || find_reg_note (p, REG_EQUIV, NULL_RTX)
536       || SET_DEST (set) != src_reg)
537     return;
538
539   /* Be conservative: although this optimization is also valid for
540      volatile memory references, that could cause trouble in later passes.  */
541   if (MEM_VOLATILE_P (SET_SRC (set)))
542     return;
543
544   /* Do not use a SUBREG to truncate from one mode to another if truncation
545      is not a nop.  */
546   if (GET_MODE_BITSIZE (GET_MODE (src_reg)) <= GET_MODE_BITSIZE (GET_MODE (src))
547       && !TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (GET_MODE (src)),
548                                  GET_MODE_BITSIZE (GET_MODE (src_reg))))
549     return;
550
551   old_mode = GET_MODE (src_reg);
552   PUT_MODE (src_reg, GET_MODE (src));
553   XEXP (src, 0) = SET_SRC (set);
554
555   /* Include this change in the group so that it's easily undone if
556      one of the changes in the group is invalid.  */
557   validate_change (p, &SET_SRC (set), src, 1);
558
559   /* Now walk forward making additional replacements.  We want to be able
560      to undo all the changes if a later substitution fails.  */
561   while (p = NEXT_INSN (p), p != insn)
562     {
563       if (! INSN_P (p))
564         continue;
565
566       /* Make a tentative change.  */
567       validate_replace_rtx_group (src_reg,
568                                   gen_lowpart_SUBREG (old_mode, src_reg),
569                                   p);
570     }
571
572   validate_replace_rtx_group (src, src_reg, insn);
573
574   /* Now see if all the changes are valid.  */
575   if (! apply_change_group ())
576     {
577       /* One or more changes were no good.  Back out everything.  */
578       PUT_MODE (src_reg, old_mode);
579       XEXP (src, 0) = src_reg;
580     }
581   else
582     {
583       rtx note = find_reg_note (p, REG_EQUAL, NULL_RTX);
584       if (note)
585         remove_note (p, note);
586     }
587 }
588
589 \f
590 /* If we were not able to update the users of src to use dest directly, try
591    instead moving the value to dest directly before the operation.  */
592
593 static void
594 copy_src_to_dest (rtx insn, rtx src, rtx dest)
595 {
596   rtx seq;
597   rtx link;
598   rtx next;
599   rtx set;
600   rtx move_insn;
601   rtx *p_insn_notes;
602   rtx *p_move_notes;
603   int src_regno;
604   int dest_regno;
605   int insn_uid;
606   int move_uid;
607
608   /* A REG_LIVE_LENGTH of -1 indicates the register is equivalent to a constant
609      or memory location and is used infrequently; a REG_LIVE_LENGTH of -2 is
610      parameter when there is no frame pointer that is not allocated a register.
611      For now, we just reject them, rather than incrementing the live length.  */
612
613   if (REG_P (src)
614       && REG_LIVE_LENGTH (REGNO (src)) > 0
615       && REG_P (dest)
616       && REG_LIVE_LENGTH (REGNO (dest)) > 0
617       && (set = single_set (insn)) != NULL_RTX
618       && !reg_mentioned_p (dest, SET_SRC (set))
619       && GET_MODE (src) == GET_MODE (dest))
620     {
621       int old_num_regs = reg_rtx_no;
622
623       /* Generate the src->dest move.  */
624       start_sequence ();
625       emit_move_insn (dest, src);
626       seq = get_insns ();
627       end_sequence ();
628       /* If this sequence uses new registers, we may not use it.  */
629       if (old_num_regs != reg_rtx_no
630           || ! validate_replace_rtx (src, dest, insn))
631         {
632           /* We have to restore reg_rtx_no to its old value, lest
633              recompute_reg_usage will try to compute the usage of the
634              new regs, yet reg_n_info is not valid for them.  */
635           reg_rtx_no = old_num_regs;
636           return;
637         }
638       emit_insn_before (seq, insn);
639       move_insn = PREV_INSN (insn);
640       p_move_notes = &REG_NOTES (move_insn);
641       p_insn_notes = &REG_NOTES (insn);
642
643       /* Move any notes mentioning src to the move instruction.  */
644       for (link = REG_NOTES (insn); link != NULL_RTX; link = next)
645         {
646           next = XEXP (link, 1);
647           if (XEXP (link, 0) == src)
648             {
649               *p_move_notes = link;
650               p_move_notes = &XEXP (link, 1);
651             }
652           else
653             {
654               *p_insn_notes = link;
655               p_insn_notes = &XEXP (link, 1);
656             }
657         }
658
659       *p_move_notes = NULL_RTX;
660       *p_insn_notes = NULL_RTX;
661
662       insn_uid = INSN_UID (insn);
663       move_uid = INSN_UID (move_insn);
664
665       /* Update the various register tables.  */
666       dest_regno = REGNO (dest);
667       INC_REG_N_SETS (dest_regno, 1);
668       REG_LIVE_LENGTH (dest_regno)++;
669       src_regno = REGNO (src);
670       if (! find_reg_note (move_insn, REG_DEAD, src))
671         REG_LIVE_LENGTH (src_regno)++;
672     }
673 }
674
675 /* reg_set_in_bb[REGNO] points to basic block iff the register is set
676    only once in the given block and has REG_EQUAL note.  */
677
678 static basic_block *reg_set_in_bb;
679
680 /* Size of reg_set_in_bb array.  */
681 static unsigned int max_reg_computed;
682
683 \f
684 /* Return whether REG is set in only one location, and is set to a
685    constant, but is set in a different basic block from INSN (an
686    instructions which uses REG).  In this case REG is equivalent to a
687    constant, and we don't want to break that equivalence, because that
688    may increase register pressure and make reload harder.  If REG is
689    set in the same basic block as INSN, we don't worry about it,
690    because we'll probably need a register anyhow (??? but what if REG
691    is used in a different basic block as well as this one?).  */
692
693 static bool
694 reg_is_remote_constant_p (rtx reg, rtx insn)
695 {
696   basic_block bb;
697   rtx p;
698   int max;
699
700   if (!reg_set_in_bb)
701     {
702       max_reg_computed = max = max_reg_num ();
703       reg_set_in_bb = XCNEWVEC (basic_block, max);
704
705       FOR_EACH_BB (bb)
706         FOR_BB_INSNS (bb, p)
707           {
708             rtx s;
709
710             if (!INSN_P (p))
711               continue;
712             s = single_set (p);
713             /* This is the instruction which sets REG.  If there is a
714                REG_EQUAL note, then REG is equivalent to a constant.  */
715             if (s != 0
716                 && REG_P (SET_DEST (s))
717                 && REG_N_SETS (REGNO (SET_DEST (s))) == 1
718                 && find_reg_note (p, REG_EQUAL, NULL_RTX))
719               reg_set_in_bb[REGNO (SET_DEST (s))] = bb;
720           }
721     }
722
723   gcc_assert (REGNO (reg) < max_reg_computed);
724   if (reg_set_in_bb[REGNO (reg)] == NULL)
725     return false;
726   return (reg_set_in_bb[REGNO (reg)] != BLOCK_FOR_INSN (insn));
727 }
728
729 /* INSN is adding a CONST_INT to a REG.  We search backwards looking for
730    another add immediate instruction with the same source and dest registers,
731    and if we find one, we change INSN to an increment, and return 1.  If
732    no changes are made, we return 0.
733
734    This changes
735      (set (reg100) (plus reg1 offset1))
736      ...
737      (set (reg100) (plus reg1 offset2))
738    to
739      (set (reg100) (plus reg1 offset1))
740      ...
741      (set (reg100) (plus reg100 offset2-offset1))  */
742
743 /* ??? What does this comment mean?  */
744 /* cse disrupts preincrement / postdecrement sequences when it finds a
745    hard register as ultimate source, like the frame pointer.  */
746
747 static int
748 fixup_match_2 (rtx insn, rtx dst, rtx src, rtx offset)
749 {
750   rtx p, dst_death = 0;
751   int length, num_calls = 0, freq_calls = 0;
752   basic_block bb = BLOCK_FOR_INSN (insn);
753
754   /* If SRC dies in INSN, we'd have to move the death note.  This is
755      considered to be very unlikely, so we just skip the optimization
756      in this case.  */
757   if (find_regno_note (insn, REG_DEAD, REGNO (src)))
758     return 0;
759
760   /* Scan backward to find the first instruction that sets DST.  */
761
762   for (length = 0, p = PREV_INSN (insn); p; p = PREV_INSN (p))
763     {
764       rtx pset;
765
766       if (! INSN_P (p))
767         continue;
768       if (BLOCK_FOR_INSN (p) != bb)
769         break;
770
771       if (find_regno_note (p, REG_DEAD, REGNO (dst)))
772         dst_death = p;
773       if (! dst_death && !DEBUG_INSN_P (p))
774         length++;
775
776       pset = single_set (p);
777       if (pset && SET_DEST (pset) == dst
778           && GET_CODE (SET_SRC (pset)) == PLUS
779           && XEXP (SET_SRC (pset), 0) == src
780           && CONST_INT_P (XEXP (SET_SRC (pset), 1)))
781         {
782           HOST_WIDE_INT newconst
783             = INTVAL (offset) - INTVAL (XEXP (SET_SRC (pset), 1));
784           rtx add = gen_add3_insn (dst, dst, GEN_INT (newconst));
785
786           if (add && validate_change (insn, &PATTERN (insn), add, 0))
787             {
788               /* Remove the death note for DST from DST_DEATH.  */
789               if (dst_death)
790                 {
791                   remove_death (REGNO (dst), dst_death);
792                   REG_LIVE_LENGTH (REGNO (dst)) += length;
793                   REG_N_CALLS_CROSSED (REGNO (dst)) += num_calls;
794                   REG_FREQ_CALLS_CROSSED (REGNO (dst)) += freq_calls;
795                 }
796
797               if (dump_file)
798                 fprintf (dump_file,
799                          "Fixed operand of insn %d.\n",
800                           INSN_UID (insn));
801
802 #ifdef AUTO_INC_DEC
803               for (p = PREV_INSN (insn); p; p = PREV_INSN (p))
804                 {
805                   if (! INSN_P (p))
806                     continue;
807                   if (BLOCK_FOR_INSN (p) != bb)
808                     break;
809                   if (reg_overlap_mentioned_p (dst, PATTERN (p)))
810                     {
811                       if (try_auto_increment (p, insn, 0, dst, newconst, 0))
812                         return 1;
813                       break;
814                     }
815                 }
816               for (p = NEXT_INSN (insn); p; p = NEXT_INSN (p))
817                 {
818                   if (! INSN_P (p))
819                     continue;
820                   if (BLOCK_FOR_INSN (p) != bb)
821                     break;
822                   if (reg_overlap_mentioned_p (dst, PATTERN (p)))
823                     {
824                       try_auto_increment (p, insn, 0, dst, newconst, 1);
825                       break;
826                     }
827                 }
828 #endif
829               return 1;
830             }
831         }
832
833       if (reg_set_p (dst, PATTERN (p)))
834         break;
835
836       /* If we have passed a call instruction, and the
837          pseudo-reg SRC is not already live across a call,
838          then don't perform the optimization.  */
839       /* reg_set_p is overly conservative for CALL_INSNS, thinks that all
840          hard regs are clobbered.  Thus, we only use it for src for
841          non-call insns.  */
842       if (CALL_P (p))
843         {
844           if (! dst_death)
845             {
846               num_calls++;
847               freq_calls += REG_FREQ_FROM_BB  (BLOCK_FOR_INSN (p));
848             }
849
850           if (REG_N_CALLS_CROSSED (REGNO (src)) == 0)
851             break;
852
853           if (call_used_regs [REGNO (dst)]
854               || find_reg_fusage (p, CLOBBER, dst))
855             break;
856         }
857       else if (reg_set_p (src, PATTERN (p)))
858         break;
859     }
860
861   return 0;
862 }
863
864 /* A forward pass.  Replace output operands with input operands.  */
865
866 static void
867 regmove_forward_pass (void)
868 {
869   basic_block bb;
870   rtx insn;
871
872   if (! flag_expensive_optimizations)
873     return;
874
875   if (dump_file)
876     fprintf (dump_file, "Starting forward pass...\n");
877
878   FOR_EACH_BB (bb)
879     {
880       FOR_BB_INSNS (bb, insn)
881         {
882           rtx set = single_set (insn);
883           if (! set)
884             continue;
885
886           if ((GET_CODE (SET_SRC (set)) == SIGN_EXTEND
887                || GET_CODE (SET_SRC (set)) == ZERO_EXTEND)
888               && REG_P (XEXP (SET_SRC (set), 0))
889               && REG_P (SET_DEST (set)))
890             optimize_reg_copy_3 (insn, SET_DEST (set), SET_SRC (set));
891
892           if (REG_P (SET_SRC (set))
893               && REG_P (SET_DEST (set)))
894             {
895               /* If this is a register-register copy where SRC is not dead,
896                  see if we can optimize it.  If this optimization succeeds,
897                  it will become a copy where SRC is dead.  */
898               if ((find_reg_note (insn, REG_DEAD, SET_SRC (set))
899                    || optimize_reg_copy_1 (insn, SET_DEST (set), SET_SRC (set)))
900                   && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
901                 {
902                   /* Similarly for a pseudo-pseudo copy when SRC is dead.  */
903                   if (REGNO (SET_SRC (set)) >= FIRST_PSEUDO_REGISTER)
904                     optimize_reg_copy_2 (insn, SET_DEST (set), SET_SRC (set));
905                   if (regno_src_regno[REGNO (SET_DEST (set))] < 0
906                       && SET_SRC (set) != SET_DEST (set))
907                     {
908                       int srcregno = REGNO (SET_SRC (set));
909                       if (regno_src_regno[srcregno] >= 0)
910                         srcregno = regno_src_regno[srcregno];
911                       regno_src_regno[REGNO (SET_DEST (set))] = srcregno;
912                     }
913                 }
914             }
915         }
916     }
917 }
918
919 /* A backward pass.  Replace input operands with output operands.  */
920
921 static void
922 regmove_backward_pass (void)
923 {
924   basic_block bb;
925   rtx insn, prev;
926
927   if (dump_file)
928     fprintf (dump_file, "Starting backward pass...\n");
929
930   FOR_EACH_BB_REVERSE (bb)
931     {
932       /* ??? Use the safe iterator because fixup_match_2 can remove
933              insns via try_auto_increment.  */ 
934       FOR_BB_INSNS_REVERSE_SAFE (bb, insn, prev)
935         {
936           struct match match;
937           rtx copy_src, copy_dst;
938           int op_no, match_no;
939           int success = 0;
940
941           if (! INSN_P (insn))
942             continue;
943
944           if (! find_matches (insn, &match))
945             continue;
946
947           /* Now scan through the operands looking for a destination operand
948              which is supposed to match a source operand.
949              Then scan backward for an instruction which sets the source
950              operand.  If safe, then replace the source operand with the
951              dest operand in both instructions.  */
952
953           copy_src = NULL_RTX;
954           copy_dst = NULL_RTX;
955           for (op_no = 0; op_no < recog_data.n_operands; op_no++)
956             {
957               rtx set, p, src, dst;
958               rtx src_note, dst_note;
959               int num_calls = 0, freq_calls = 0;
960               enum reg_class src_class, dst_class;
961               int length;
962
963               match_no = match.with[op_no];
964
965               /* Nothing to do if the two operands aren't supposed to match.  */
966               if (match_no < 0)
967                 continue;
968
969               dst = recog_data.operand[match_no];
970               src = recog_data.operand[op_no];
971
972               if (!REG_P (src))
973                 continue;
974
975               if (!REG_P (dst)
976                   || REGNO (dst) < FIRST_PSEUDO_REGISTER
977                   || REG_LIVE_LENGTH (REGNO (dst)) < 0
978                   || GET_MODE (src) != GET_MODE (dst))
979                 continue;
980
981               /* If the operands already match, then there is nothing to do.  */
982               if (operands_match_p (src, dst))
983                 continue;
984
985               if (match.commutative[op_no] >= 0)
986                 {
987                   rtx comm = recog_data.operand[match.commutative[op_no]];
988                   if (operands_match_p (comm, dst))
989                     continue;
990                 }
991
992               set = single_set (insn);
993               if (! set)
994                 continue;
995
996               /* Note that single_set ignores parts of a parallel set for
997                  which one of the destinations is REG_UNUSED.  We can't
998                  handle that here, since we can wind up rewriting things
999                  such that a single register is set twice within a single
1000                  parallel.  */
1001               if (reg_set_p (src, insn))
1002                 continue;
1003
1004               /* match_no/dst must be a write-only operand, and
1005                  operand_operand/src must be a read-only operand.  */
1006               if (match.use[op_no] != READ
1007                   || match.use[match_no] != WRITE)
1008                 continue;
1009
1010               if (match.early_clobber[match_no]
1011                   && count_occurrences (PATTERN (insn), src, 0) > 1)
1012                 continue;
1013
1014               /* Make sure match_no is the destination.  */
1015               if (recog_data.operand[match_no] != SET_DEST (set))
1016                 continue;
1017
1018               if (REGNO (src) < FIRST_PSEUDO_REGISTER)
1019                 {
1020                   if (GET_CODE (SET_SRC (set)) == PLUS
1021                       && CONST_INT_P (XEXP (SET_SRC (set), 1))
1022                       && XEXP (SET_SRC (set), 0) == src
1023                       && fixup_match_2 (insn, dst, src,
1024                                         XEXP (SET_SRC (set), 1)))
1025                     break;
1026                   continue;
1027                 }
1028               src_class = reg_preferred_class (REGNO (src));
1029               dst_class = reg_preferred_class (REGNO (dst));
1030
1031               if (! (src_note = find_reg_note (insn, REG_DEAD, src)))
1032                 {
1033                   /* We used to force the copy here like in other cases, but
1034                      it produces worse code, as it eliminates no copy
1035                      instructions and the copy emitted will be produced by
1036                      reload anyway.  On patterns with multiple alternatives,
1037                      there may be better solution available.
1038
1039                      In particular this change produced slower code for numeric
1040                      i387 programs.  */
1041
1042                   continue;
1043                 }
1044
1045               if (! regclass_compatible_p (src_class, dst_class))
1046                 {
1047                   if (!copy_src)
1048                     {
1049                       copy_src = src;
1050                       copy_dst = dst;
1051                     }
1052                   continue;
1053                 }
1054
1055               /* Can not modify an earlier insn to set dst if this insn
1056                  uses an old value in the source.  */
1057               if (reg_overlap_mentioned_p (dst, SET_SRC (set)))
1058                 {
1059                   if (!copy_src)
1060                     {
1061                       copy_src = src;
1062                       copy_dst = dst;
1063                     }
1064                   continue;
1065                 }
1066
1067               /* If src is set once in a different basic block,
1068                  and is set equal to a constant, then do not use
1069                  it for this optimization, as this would make it
1070                  no longer equivalent to a constant.  */
1071
1072               if (reg_is_remote_constant_p (src, insn))
1073                 {
1074                   if (!copy_src)
1075                     {
1076                       copy_src = src;
1077                       copy_dst = dst;
1078                     }
1079                   continue;
1080                 }
1081
1082
1083               if (dump_file)
1084                 fprintf (dump_file,
1085                          "Could fix operand %d of insn %d matching operand %d.\n",
1086                          op_no, INSN_UID (insn), match_no);
1087
1088               /* Scan backward to find the first instruction that uses
1089                  the input operand.  If the operand is set here, then
1090                  replace it in both instructions with match_no.  */
1091
1092               for (length = 0, p = PREV_INSN (insn); p; p = PREV_INSN (p))
1093                 {
1094                   rtx pset;
1095
1096                   if (! INSN_P (p))
1097                     continue;
1098                   if (BLOCK_FOR_INSN (p) != bb)
1099                     break;
1100
1101                   if (!DEBUG_INSN_P (p))
1102                     length++;
1103
1104                   /* ??? See if all of SRC is set in P.  This test is much
1105                      more conservative than it needs to be.  */
1106                   pset = single_set (p);
1107                   if (pset && SET_DEST (pset) == src)
1108                     {
1109                       /* We use validate_replace_rtx, in case there
1110                          are multiple identical source operands.  All
1111                          of them have to be changed at the same time:
1112                          when validate_replace_rtx() calls
1113                          apply_change_group().  */
1114                       validate_change (p, &SET_DEST (pset), dst, 1);
1115                       if (validate_replace_rtx (src, dst, insn))
1116                         success = 1;
1117                       break;
1118                     }
1119
1120                   /* We can't make this change if SRC is read or
1121                      partially written in P, since we are going to
1122                      eliminate SRC. We can't make this change 
1123                      if DST is mentioned at all in P,
1124                      since we are going to change its value.  */
1125                   if (reg_overlap_mentioned_p (src, PATTERN (p)))
1126                     {
1127                       if (DEBUG_INSN_P (p))
1128                         validate_replace_rtx_group (dst, src, insn);
1129                       else
1130                         break;
1131                     }
1132                   if (reg_mentioned_p (dst, PATTERN (p)))
1133                     {
1134                       if (DEBUG_INSN_P (p))
1135                         validate_change (p, &INSN_VAR_LOCATION_LOC (p),
1136                                          gen_rtx_UNKNOWN_VAR_LOC (), 1);
1137                       else
1138                         break;
1139                     }
1140
1141                   /* If we have passed a call instruction, and the
1142                      pseudo-reg DST is not already live across a call,
1143                      then don't perform the optimization.  */
1144                   if (CALL_P (p))
1145                     {
1146                       num_calls++;
1147                       freq_calls += REG_FREQ_FROM_BB  (BLOCK_FOR_INSN (p));
1148
1149                       if (REG_N_CALLS_CROSSED (REGNO (dst)) == 0)
1150                         break;
1151                     }
1152                 }
1153
1154               if (success)
1155                 {
1156                   int dstno, srcno;
1157
1158                   /* Remove the death note for SRC from INSN.  */
1159                   remove_note (insn, src_note);
1160                   /* Move the death note for SRC to P if it is used
1161                      there.  */
1162                   if (reg_overlap_mentioned_p (src, PATTERN (p)))
1163                     {
1164                       XEXP (src_note, 1) = REG_NOTES (p);
1165                       REG_NOTES (p) = src_note;
1166                     }
1167                   /* If there is a REG_DEAD note for DST on P, then remove
1168                      it, because DST is now set there.  */
1169                   if ((dst_note = find_reg_note (p, REG_DEAD, dst)))
1170                     remove_note (p, dst_note);
1171
1172                   dstno = REGNO (dst);
1173                   srcno = REGNO (src);
1174
1175                   INC_REG_N_SETS (dstno, 1);
1176                   INC_REG_N_SETS (srcno, -1);
1177
1178                   REG_N_CALLS_CROSSED (dstno) += num_calls;
1179                   REG_N_CALLS_CROSSED (srcno) -= num_calls;
1180                   REG_FREQ_CALLS_CROSSED (dstno) += freq_calls;
1181                   REG_FREQ_CALLS_CROSSED (srcno) -= freq_calls;
1182
1183                   REG_LIVE_LENGTH (dstno) += length;
1184                   if (REG_LIVE_LENGTH (srcno) >= 0)
1185                     {
1186                       REG_LIVE_LENGTH (srcno) -= length;
1187                       /* REG_LIVE_LENGTH is only an approximation after
1188                          combine if sched is not run, so make sure that we
1189                          still have a reasonable value.  */
1190                       if (REG_LIVE_LENGTH (srcno) < 2)
1191                         REG_LIVE_LENGTH (srcno) = 2;
1192                     }
1193
1194                   if (dump_file)
1195                     fprintf (dump_file,
1196                              "Fixed operand %d of insn %d matching operand %d.\n",
1197                              op_no, INSN_UID (insn), match_no);
1198
1199                   break;
1200                 }
1201               else if (num_changes_pending () > 0)
1202                 cancel_changes (0);
1203             }
1204
1205           /* If we weren't able to replace any of the alternatives, try an
1206              alternative approach of copying the source to the destination.  */
1207           if (!success && copy_src != NULL_RTX)
1208             copy_src_to_dest (insn, copy_src, copy_dst);
1209         }
1210     }
1211 }
1212
1213 /* Main entry for the register move optimization.  */
1214
1215 static unsigned int
1216 regmove_optimize (void)
1217 {
1218   int i;
1219   int nregs = max_reg_num ();
1220
1221   df_note_add_problem ();
1222   df_analyze ();
1223
1224   regstat_init_n_sets_and_refs ();
1225   regstat_compute_ri ();
1226
1227   regno_src_regno = XNEWVEC (int, nregs);
1228   for (i = nregs; --i >= 0; )
1229     regno_src_regno[i] = -1;
1230
1231   /* A forward pass.  Replace output operands with input operands.  */
1232   regmove_forward_pass ();
1233
1234   /* A backward pass.  Replace input operands with output operands.  */
1235   regmove_backward_pass ();
1236
1237   /* Clean up.  */
1238   free (regno_src_regno);
1239   if (reg_set_in_bb)
1240     {
1241       free (reg_set_in_bb);
1242       reg_set_in_bb = NULL;
1243     }
1244   regstat_free_n_sets_and_refs ();
1245   regstat_free_ri ();
1246   return 0;
1247 }
1248
1249 /* Returns nonzero if INSN's pattern has matching constraints for any operand.
1250    Returns 0 if INSN can't be recognized, or if the alternative can't be
1251    determined.
1252
1253    Initialize the info in MATCHP based on the constraints.  */
1254
1255 static int
1256 find_matches (rtx insn, struct match *matchp)
1257 {
1258   int likely_spilled[MAX_RECOG_OPERANDS];
1259   int op_no;
1260   int any_matches = 0;
1261
1262   extract_insn (insn);
1263   if (! constrain_operands (0))
1264     return 0;
1265
1266   /* Must initialize this before main loop, because the code for
1267      the commutative case may set matches for operands other than
1268      the current one.  */
1269   for (op_no = recog_data.n_operands; --op_no >= 0; )
1270     matchp->with[op_no] = matchp->commutative[op_no] = -1;
1271
1272   for (op_no = 0; op_no < recog_data.n_operands; op_no++)
1273     {
1274       const char *p;
1275       char c;
1276       int i = 0;
1277
1278       p = recog_data.constraints[op_no];
1279
1280       likely_spilled[op_no] = 0;
1281       matchp->use[op_no] = READ;
1282       matchp->early_clobber[op_no] = 0;
1283       if (*p == '=')
1284         matchp->use[op_no] = WRITE;
1285       else if (*p == '+')
1286         matchp->use[op_no] = READWRITE;
1287
1288       for (;*p && i < which_alternative; p++)
1289         if (*p == ',')
1290           i++;
1291
1292       while ((c = *p) != '\0' && c != ',')
1293         {
1294           switch (c)
1295             {
1296             case '=':
1297               break;
1298             case '+':
1299               break;
1300             case '&':
1301               matchp->early_clobber[op_no] = 1;
1302               break;
1303             case '%':
1304               matchp->commutative[op_no] = op_no + 1;
1305               matchp->commutative[op_no + 1] = op_no;
1306               break;
1307
1308             case '0': case '1': case '2': case '3': case '4':
1309             case '5': case '6': case '7': case '8': case '9':
1310               {
1311                 char *end;
1312                 unsigned long match_ul = strtoul (p, &end, 10);
1313                 int match = match_ul;
1314
1315                 p = end;
1316
1317                 if (match < op_no && likely_spilled[match])
1318                   continue;
1319                 matchp->with[op_no] = match;
1320                 any_matches = 1;
1321                 if (matchp->commutative[op_no] >= 0)
1322                   matchp->with[matchp->commutative[op_no]] = match;
1323               }
1324             continue;
1325
1326           case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'h':
1327           case 'j': case 'k': case 'l': case 'p': case 'q': case 't': case 'u':
1328           case 'v': case 'w': case 'x': case 'y': case 'z': case 'A': case 'B':
1329           case 'C': case 'D': case 'W': case 'Y': case 'Z':
1330             if (CLASS_LIKELY_SPILLED_P (REG_CLASS_FROM_CONSTRAINT ((unsigned char) c, p) ))
1331               likely_spilled[op_no] = 1;
1332             break;
1333           }
1334           p += CONSTRAINT_LEN (c, p);
1335         }
1336     }
1337   return any_matches;
1338 }
1339
1340 \f
1341
1342 static bool
1343 gate_handle_regmove (void)
1344 {
1345   return (optimize > 0 && flag_regmove);
1346 }
1347
1348
1349 struct rtl_opt_pass pass_regmove =
1350 {
1351  {
1352   RTL_PASS,
1353   "regmove",                            /* name */
1354   gate_handle_regmove,                  /* gate */
1355   regmove_optimize,                     /* execute */
1356   NULL,                                 /* sub */
1357   NULL,                                 /* next */
1358   0,                                    /* static_pass_number */
1359   TV_REGMOVE,                           /* tv_id */
1360   0,                                    /* properties_required */
1361   0,                                    /* properties_provided */
1362   0,                                    /* properties_destroyed */
1363   0,                                    /* todo_flags_start */
1364   TODO_df_finish | TODO_verify_rtl_sharing |
1365   TODO_dump_func |
1366   TODO_ggc_collect                      /* todo_flags_finish */
1367  }
1368 };