home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / ae / AE / ae-rd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-02-28  |  18.2 KB  |  684 lines

  1. /* Reaching definition (RD) flow analysis for AE.
  2.    Adapted from GCC's flow.c.
  3.    Copyright (C) 1987, 1988 Free Software Foundation, Inc.
  4.    Copyright (C) 1989, 1990 James R. Larus (larus@cs.wisc.edu)
  5.  
  6.    AE and AEC are free software; you can redistribute it and/or modify it
  7.    under the terms of the GNU General Public License as published by the
  8.    Free Software Foundation; either version 1, or (at your option) any
  9.    later version.
  10.  
  11.    AE and AEC are distributed in the hope that it will be useful, but
  12.    WITHOUT ANY WARRANTY; without even the implied warranty of
  13.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14.    General Public License for more details.
  15.  
  16.    You should have received a copy of the GNU General Public License
  17.    along with GNU CC; see the file COPYING.  If not, write to James R.
  18.    Larus, Computer Sciences Department, University of Wisconsin--Madison,
  19.    1210 West Dayton Street, Madison, WI 53706, USA or to the Free
  20.    Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
  21.  
  22.  
  23. /* $Header: /var/home/larus/AE/AE/RCS/ae-rd.c,v 2.0 90/02/09 17:20:07 larus Exp Locker: larus $ */
  24.  
  25.  
  26. #include <stdio.h>
  27. #include "config.h"
  28. #include "rtl.h"
  29. #include "basic-block.h"
  30. #include "regs.h"
  31. #include "ae.h"
  32.  
  33. #include "obstack.h"
  34. #define obstack_chunk_alloc xmalloc
  35. #define obstack_chunk_free free
  36.  
  37. extern int xmalloc ();
  38. extern void free ();
  39.  
  40.  
  41. /* Get the basic block number of an insn.  This info lasts until we
  42.    finish compiling the function. */
  43.  
  44. #define BLOCK_NUM(INSN)  uid_block_number [INSN_UID (INSN)]
  45.  
  46.  
  47. /* This is where the BLOCK_NUM values are really stored. */
  48.  
  49. short *uid_block_number;
  50.  
  51.  
  52. /* Not used in rd_analysis, but computed by find_basic_blocks. */
  53.  
  54. char *uid_volatile;
  55.  
  56.  
  57. /* Number of basic blocks in the current function.  */
  58.  
  59. int n_basic_blocks;
  60.  
  61.  
  62. /* Maximum register number used in this function, plus one.  */
  63.  
  64. int max_regno;
  65.  
  66.  
  67. /* Either analyze all registers or just the hardware registers (saves
  68.    some space). */
  69.  
  70. #ifdef RD_SYMBOLIC_REGS
  71. #define MAX_REGNO max_regno
  72. #else
  73. #define MAX_REGNO FIRST_PSEUDO_REGISTER
  74. #endif
  75.  
  76.  
  77. /* Maximum UID for an instruction in this function. */
  78.  
  79. int max_uid = 0;
  80.  
  81.  
  82. /* Size of a defset for the current function,
  83.    in (1) bytes and (2) elements.  */
  84.  
  85. int defset_bytes;
  86. int defset_size;
  87.  
  88.  
  89. /* Element N is first insn in basic block N.
  90.    This info lasts until we finish compiling the function.  */
  91.  
  92. rtx *basic_block_head;
  93.  
  94.  
  95. /* Element N is last insn in basic block N.
  96.    This info lasts until we finish compiling the function.  */
  97.  
  98. rtx *basic_block_end;
  99.  
  100.  
  101. /* Element N is a defset describing the definitions that reach basic
  102.    block N.  This info lasts until we finish compiling the function.  */
  103.  
  104. regset *basic_block_rd_at_start;
  105.  
  106.  
  107. /* Element N is nonzero if control can drop into basic block N
  108.    from the preceding basic block.  Freed after rd_analysis.  */
  109.  
  110. char *basic_block_drops_in;
  111.  
  112.  
  113. /* Element N is depth within loops of basic block number N.
  114.    This info lasts until we finish compiling the function.  */
  115.  
  116. short *basic_block_loop_depth;
  117.  
  118.  
  119. /* Element N is a defset describing the definitions that modify register
  120.    N.  This info lasts until we finish compiling the function.  */
  121.  
  122. regset *defn_of_reg;
  123.  
  124.  
  125. /* Maximum definition number in this function. */
  126.  
  127. int max_defn_no = 0;
  128.  
  129.  
  130. /* Entry N is definition N.  This info lasts until we finish compiling
  131.    the function. */
  132.  
  133. rtx *n_to_defn;
  134.  
  135.  
  136. /* Entry N is the min/max register defined by definition N. */
  137.  
  138. short *defn_min_reg;
  139. short *defn_max_reg;
  140.  
  141.  
  142. /* Entry N is I if instruction N corresponds to definition I and -1
  143.    otherwise.  This info lasts until we finish compiling the function. */
  144.  
  145. int *insn_to_defn;
  146.  
  147.  
  148. /* Use these functions from flow analysis: */
  149. void find_basic_blocks ();
  150. void init_regset_vector ();
  151.  
  152. /* Use these function from AE: */
  153. int simplejump_p ();
  154. int condjump_p ();
  155. int multiway_jump_p ();
  156. rtx jump_target ();
  157.  
  158.  
  159. /* Forward declarations */
  160. static void rd_analysis ();
  161. static void find_reg_defns ();
  162. static void compute_block_gen_kill ();
  163. static void insn_defines_regs ();
  164. void dump_rd_info ();
  165.  
  166.  
  167.  
  168. /* Find basic blocks of the current function and perform reaching
  169.    definition analysis.  F is the first insn of the function and NREGS the
  170.    number of register numbers in use.  */
  171.  
  172. void
  173. reaching_defn_analysis (f, nregs, file)
  174.      rtx f;
  175.      int nregs;
  176.      FILE *file;
  177. {
  178.   register rtx insn;
  179.   register int i;
  180.   int min_reg, max_reg;
  181.  
  182.   /* Count the basic blocks.  Also find maximum insn uid value used.  */
  183.  
  184.   {
  185.     register RTX_CODE prev_code = JUMP_INSN;
  186.     register RTX_CODE code;
  187.  
  188.     max_defn_no = 0;
  189.  
  190.     for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
  191.       {
  192.     code = GET_CODE (insn);
  193.     if (INSN_UID (insn) > max_uid)
  194.       max_uid = INSN_UID (insn);
  195.     if (code == CODE_LABEL
  196.         || (prev_code != INSN && prev_code != CALL_INSN
  197.         && prev_code != CODE_LABEL
  198.         && (code == INSN || code == CALL_INSN || code == JUMP_INSN)))
  199.       i++;
  200.     if (code != NOTE)
  201.       prev_code = code;
  202.     insn_defines_regs (insn, &min_reg, &max_reg);
  203.     if (min_reg <= max_reg)
  204.       max_defn_no += 1;
  205.       }
  206.   }
  207.  
  208.   /* Allocate some tables that last till end of compiling this function
  209.      and some needed only in find_basic_blocks and rd_analysis.  */
  210.  
  211.   n_basic_blocks = i;
  212.   basic_block_head = (rtx *) oballoc (n_basic_blocks * sizeof (rtx));
  213.   basic_block_end = (rtx *) oballoc (n_basic_blocks * sizeof (rtx));
  214.   basic_block_drops_in = (char *) alloca (n_basic_blocks);
  215.   basic_block_loop_depth = (short *) oballoc (n_basic_blocks * sizeof (short));
  216.   uid_block_number = (short *) oballoc ((max_uid + 1) * sizeof (short));
  217.   uid_volatile = (char *) alloca (max_uid + 1);
  218.   bzero (uid_volatile, max_uid + 1);
  219.  
  220.   n_to_defn = (rtx *) oballoc (max_defn_no * sizeof (rtx));
  221.   defn_min_reg = (short *) oballoc (max_defn_no * sizeof (short));
  222.   defn_max_reg = (short *) oballoc (max_defn_no * sizeof (short));
  223.   insn_to_defn = (int *) oballoc ((max_uid + 1) * sizeof (int));
  224.   for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
  225.     {
  226.       insn_defines_regs (insn, &min_reg, &max_reg);
  227.       if (min_reg <= max_reg)
  228.       {
  229.     insn_to_defn [INSN_UID (insn)] = i;
  230.     defn_min_reg [i] = min_reg;
  231.     defn_max_reg [i] = max_reg;
  232.     n_to_defn [i ++] = insn;
  233.       }
  234.       else
  235.     insn_to_defn [INSN_UID (insn)] = -1;
  236.     }
  237.  
  238.   find_basic_blocks (f);
  239.   rd_analysis (f, nregs);
  240.   if (file)
  241.     dump_rd_info (file);
  242.  
  243.   basic_block_drops_in = 0;
  244. }
  245.  
  246.  
  247.  
  248. /* Determine which registers are live at the start of each basic block in
  249.    the function whose first insn is F.  NREGS is the number of registers
  250.    used in F.  We allocate the vector basic_block_rd_at_start and the
  251.    defsets that it points to, and fill them with the data.  defset_size and
  252.    defset_bytes are also set here.  */
  253.  
  254. static void
  255. rd_analysis (f, nregs)
  256.      rtx f;
  257.      int nregs;
  258. {
  259.   register regset tem;
  260.   int first_pass;
  261.   int changed;
  262.   /* For each basic block, a bitmask of defns reaching end of block. */
  263.   register regset *bb_rd_at_end;
  264.   /* For each basic block, a bitmask of defns reaching entry to a
  265.      successor-block of this block.  If this does not match
  266.      basic_block_rd_at_start, that must be updated. */
  267.   register regset *bb_new_rd_at_start;
  268.   /* For each basic block, a bitmask of defns produced in the block. */
  269.   register regset *bb_gen;
  270.   /* For each basic block, a bitmask of defns killed in the block. */
  271.   register regset *bb_kill;
  272.   register int i;
  273.  
  274.   struct obstack flow_obstack;
  275.  
  276.   obstack_init (&flow_obstack);
  277.  
  278.   max_regno = nregs;
  279.  
  280.   /* Allocate and zero out data structures that will record the data from
  281.      RD analysis.  */
  282.  
  283.   defset_size = ((max_defn_no + REGSET_ELT_BITS - 1) / REGSET_ELT_BITS);
  284.   defset_bytes = defset_size * sizeof (*(regset)0);
  285.  
  286.   basic_block_rd_at_start =
  287.     (regset *) oballoc (n_basic_blocks * sizeof (regset));
  288.   tem = (regset) oballoc (n_basic_blocks * defset_bytes);
  289.   bzero (tem, n_basic_blocks * defset_bytes);
  290.   init_regset_vector (basic_block_rd_at_start, tem, n_basic_blocks,
  291.               defset_bytes);
  292.  
  293.   defn_of_reg = (regset *) oballoc (MAX_REGNO * sizeof (regset));
  294.   tem = (regset) oballoc (MAX_REGNO * defset_bytes);
  295.   bzero (tem, MAX_REGNO * defset_bytes);
  296.   init_regset_vector (defn_of_reg, tem, MAX_REGNO, defset_bytes);
  297.  
  298.  
  299.   /* Set up regset-vectors used internally within this function. */
  300.  
  301.   bb_rd_at_end = (regset *) alloca (n_basic_blocks * sizeof (regset));
  302.   /* Don't use alloca since that leads to a crash rather than an error message
  303.      if there isn't enough space.
  304.      Don't use oballoc since we may need to allocate other things during
  305.      this function on the temporary obstack.  */
  306.   tem = (regset) obstack_alloc (&flow_obstack, n_basic_blocks * defset_bytes);
  307.   bzero (tem, n_basic_blocks * defset_bytes);
  308.   init_regset_vector (bb_rd_at_end, tem, n_basic_blocks, defset_bytes);
  309.  
  310.   bb_new_rd_at_start = (regset *) alloca (n_basic_blocks * sizeof (regset));
  311.   tem = (regset) obstack_alloc (&flow_obstack, n_basic_blocks * defset_bytes);
  312.   bzero (tem, n_basic_blocks * defset_bytes);
  313.   init_regset_vector (bb_new_rd_at_start, tem, n_basic_blocks, defset_bytes);
  314.  
  315.   bb_gen = (regset *) alloca (n_basic_blocks * sizeof (regset));
  316.   tem = (regset) obstack_alloc (&flow_obstack, n_basic_blocks * defset_bytes);
  317.   bzero (tem, n_basic_blocks * defset_bytes);
  318.   init_regset_vector (bb_gen , tem, n_basic_blocks, defset_bytes);
  319.  
  320.   bb_kill = (regset *) alloca (n_basic_blocks * sizeof (regset));
  321.   tem = (regset) obstack_alloc (&flow_obstack, n_basic_blocks * defset_bytes);
  322.   bzero (tem, n_basic_blocks * defset_bytes);
  323.   init_regset_vector (bb_kill, tem, n_basic_blocks, defset_bytes);
  324.  
  325.  
  326.   /* Find which registers each instruction defines. */
  327.   find_reg_defns (f);
  328.  
  329.   for (i = 0; i < n_basic_blocks; i ++)
  330.     compute_block_gen_kill (bb_gen [i], bb_kill [i],
  331.                 basic_block_head [i], basic_block_end [i]);
  332.  
  333.   /* Propagate RD info through the basic blocks in the graph of blocks.
  334.  
  335.      This is a relaxation process: each time a new definition reaches the
  336.      start of a basic block, we must determine which definitions, as a
  337.      consequence, reach the end of that block.  These definitions reaching the
  338.      start of all the blocks that are successors to that block.  The process
  339.      continues until it reaches a fixed point.  */
  340.  
  341.   first_pass = 1;
  342.   changed = 1;
  343.   while (changed)
  344.     {
  345.       changed = 0;
  346.       for (i = 0; i < n_basic_blocks; i++)
  347.     {
  348.       int consider = first_pass;
  349.       register int j;
  350.  
  351.       /* Set CONSIDER if this block needs thinking about at all (that
  352.          is, if the regs reaching it are not the same as those that
  353.          reached it when we last thought about it). */
  354.       for (j = 0; j < defset_size; j++)
  355.         if (bb_new_rd_at_start [i][j] & ~basic_block_rd_at_start [i][j])
  356.           {
  357.         consider = 1;
  358.         break;
  359.           }
  360.  
  361.       if (! consider)
  362.         continue;
  363.  
  364.       /* The rd_at_end of this block may change, so another pass
  365.          will be required after this one.  */
  366.       changed = 1;
  367.  
  368.       bcopy (bb_new_rd_at_start [i], basic_block_rd_at_start [i],
  369.          defset_bytes);
  370.  
  371.       for (j = 0; j < defset_size; j++)
  372.         /* RDout = (RDin - KILL) + GEN: */
  373.         bb_rd_at_end [i][j] =
  374.           (basic_block_rd_at_start [i][j] & ~bb_kill [i][j])
  375.         | bb_gen [i][j];
  376.  
  377.       {
  378.         register rtx end = basic_block_end [i];
  379.  
  380.         /* Update the bb_new_rd_at_start's of the block that this
  381.            one falls through into (if any).*/
  382.         if ((i + 1 < n_basic_blocks) && basic_block_drops_in [i + 1])
  383.           {
  384.         register int j;
  385.  
  386.         for (j = 0; j < defset_size; j++)
  387.           bb_new_rd_at_start [i + 1][j] |= bb_rd_at_end [i][j];
  388.           }
  389.  
  390.         /* Update the bb_new_rd_at_start's of all the blocks that
  391.            this one jumps to. */
  392.         if (GET_CODE (end) == JUMP_INSN
  393.         && (simplejump_p (end) || condjump_p (end)))
  394.           {
  395.         register int to_block = BLOCK_NUM (jump_target (end));
  396.         register int j;
  397.  
  398.         for (j = 0; j < defset_size; j++)
  399.           bb_new_rd_at_start [to_block][j] |= bb_rd_at_end [i][j];
  400.           }
  401.         else if (multiway_jump_p (end))
  402.           {
  403.         rtx body =  PATTERN (end);
  404.         register int vlen, j, k;
  405.  
  406.         vlen = XVECLEN (body, 0);
  407.         for (k = 0; k < vlen; k++)
  408.           {
  409.             register int to_block =
  410.               BLOCK_NUM (XEXP (XVECEXP (body, 0, k), 0));
  411.  
  412.             for (j = 0; j < defset_size; j++)
  413.               bb_new_rd_at_start [to_block][j]
  414.             |= bb_rd_at_end [i][j];
  415.           }
  416.           }
  417.       }
  418. #ifdef USE_C_ALLOCA
  419.       alloca (0);
  420. #endif
  421.     }
  422.       first_pass = 0;
  423.     }
  424.   obstack_free (&flow_obstack, 0);
  425. }
  426.  
  427.  
  428.  
  429. #define SET_REGSET_BIT(rs,bn) \
  430.   rs [bn / REGSET_ELT_BITS] |= 1 << (bn % REGSET_ELT_BITS);
  431.  
  432.  
  433. /* For each instruction in the function, record which registers its defines
  434.  in DEFN_OF_REG. */
  435.  
  436. static void
  437. find_reg_defns (insns)
  438.      rtx insns;
  439. {
  440.   register rtx insn;
  441.  
  442.   for (insn = insns; insn != NULL; insn = NEXT_INSN (insn))
  443.     {
  444.       register int r;
  445.       register int defn_id = insn_to_defn [INSN_UID (insn)];
  446.  
  447.       if (defn_id != -1)
  448.     for (r = defn_min_reg [defn_id]; r <= defn_max_reg [defn_id]; r++)
  449.       SET_REGSET_BIT (defn_of_reg [r], defn_id);
  450.     }
  451. }
  452.  
  453.  
  454. static void
  455. compute_block_gen_kill (gen, kill, first, last)
  456.      register regset gen, kill;
  457.      rtx first;
  458.      rtx last;
  459. {
  460.   register rtx insn;
  461.  
  462.   for (insn = first; PREV_INSN (insn) != last ; insn = NEXT_INSN (insn))
  463.     {
  464.       register int defn_id = insn_to_defn [INSN_UID (insn)];
  465.       register int r, i;
  466.  
  467.       if (defn_id != -1)
  468.     {
  469.       for (r = defn_min_reg [defn_id]; r <= defn_max_reg [defn_id]; r++)
  470.         for (i = 0; i < defset_size; i++)
  471.           kill [i] |= defn_of_reg [r][i];
  472.  
  473.       SET_REGSET_BIT (gen, defn_id);
  474.     }
  475.     }
  476. }
  477.  
  478.  
  479. static void find_def_range ();
  480.  
  481. static void
  482. insn_defines_regs (insn, min_reg, max_reg)
  483.      rtx insn;
  484.      int *min_reg, *max_reg;
  485. {
  486.   /* Initially, insn does not define any regs. */
  487.   *min_reg = -1, *max_reg = -2;
  488.  
  489.   if (!INSN_DELETED_P (insn)
  490.       && (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN))
  491.       {
  492.     register rtx x = PATTERN (insn);
  493.     register RTX_CODE code = GET_CODE (x);
  494.  
  495.     if (code == SET || code == CLOBBER)
  496.       find_def_range (x, insn, min_reg, max_reg);
  497.     else if (code == PARALLEL)
  498.       {
  499.         register int i;
  500.         for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
  501.           {
  502.         code = GET_CODE (XVECEXP (x, 0, i));
  503.         if (code == SET || code == CLOBBER)
  504.           find_def_range (XVECEXP (x, 0, i), insn, min_reg, max_reg);
  505.           }
  506.       }
  507.       }
  508. }
  509.  
  510.  
  511. /* Process a single SET rtx, X.  */
  512.  
  513. static void
  514. find_def_range (x, insn, min_reg, max_reg)
  515.      rtx x;
  516.      rtx insn;
  517.      int *min_reg, *max_reg;
  518. {
  519.   register int regno;
  520.   register rtx reg = SET_DEST (x);
  521.   int subreg_p = 0;
  522.  
  523.   if (reg == 0)
  524.     return;
  525.  
  526.   if (GET_CODE (reg) == STRICT_LOW_PART)
  527.     reg = XEXP (reg, 0);
  528.  
  529.   if (GET_CODE (reg) == SUBREG || GET_CODE (reg) == ZERO_EXTRACT
  530.       || GET_CODE (reg) == SIGN_EXTRACT)
  531.     {
  532.       /* Modifying just one hardware register of a multi-reg value or
  533.      just a byte field of a register does not mean the value from before
  534.      this insn is now dead. */
  535.       if (REG_SIZE (SUBREG_REG (reg)) > REG_SIZE (reg))
  536.     subreg_p = 1;
  537.  
  538.       reg = SUBREG_REG (reg);
  539.     }
  540.  
  541.   if (GET_CODE (reg) == REG
  542.       && (regno = REGNO (reg), regno != FRAME_POINTER_REGNUM)
  543.       && regno != ARG_POINTER_REGNUM)
  544.     {
  545.       *min_reg = *max_reg = regno;
  546.  
  547.       /* A hard reg in a wide mode may really be multiple registers. */
  548.       if (regno < FIRST_PSEUDO_REGISTER)
  549.     {
  550.       if (regno == STACK_POINTER_REGNUM)
  551.         return;
  552.  
  553.       *max_reg += HARD_REGNO_NREGS (regno, GET_MODE (reg)) - 1;
  554.     }
  555.     }
  556. }
  557.  
  558.  
  559.  
  560. /* Return a list of the definitions of REG reaching INSN. */
  561.  
  562. list
  563. defns_reaching_insn (insn, reg)
  564.      register rtx insn, reg;
  565. {
  566.   int regno = REGNO (reg);
  567.   int block_no = BLOCK_NUM (insn);
  568.   register rtx block_end = basic_block_end [block_no];
  569.   register regset defns = (regset) alloca (defset_bytes);
  570.   register rtx insns;
  571.   register int i, j;
  572.   list rds = NULL;
  573.  
  574.   bcopy (basic_block_rd_at_start [block_no], defns, defset_bytes);
  575.  
  576.   for (insns = basic_block_head [block_no];
  577.        /* Peephole may delete insn (which may have been block end) */
  578.        insns != insn && insns != block_end && insns != NULL;
  579.        insns = NEXT_INSN (insns))
  580.     {
  581.       register int defn_id = insn_to_defn [INSN_UID (insns)];
  582.       register int r, i;
  583.  
  584.       if (defn_id != -1)
  585.     {
  586.       for (r = defn_min_reg [defn_id]; r <= defn_max_reg [defn_id]; r++)
  587.         for (i = 0; i < defset_size; i++)
  588.           defns [i] &= ~defn_of_reg [r][i];
  589.  
  590.       SET_REGSET_BIT (defns, defn_id);
  591.     }
  592.     }
  593.  
  594.   for (i = 0; i < defset_size; i++)
  595.     {
  596.       /* Only want defns of register REGNO */
  597.       register int x = defns [i] & defn_of_reg [regno][i];
  598.  
  599.       for (j = 0; x != 0 && j < REGSET_ELT_BITS; j ++)
  600.     {
  601.       if (x & 1)
  602.         {
  603.           rtx def_insn = n_to_defn [i * REGSET_ELT_BITS + j];
  604.  
  605.           if (def_insn)
  606.         rds = cons (def_insn, rds);
  607.         }
  608.       x = x >> 1;
  609.     }
  610.     }
  611.  
  612.   return rds;
  613. }
  614.  
  615.  
  616.  
  617. /* Write information about defns and basic blocks into FILE.
  618.    This is part of making a debugging dump.  */
  619.  
  620. void
  621. dump_rd_info (file)
  622.      FILE *file;
  623. {
  624.   register int i, defno;
  625.  
  626.   fprintf (file, "%d insn.\n", max_defn_no);
  627.  
  628.   fprintf (file, "\n%d basic blocks.\n", n_basic_blocks);
  629.   for (i = 0; i < n_basic_blocks; i ++)
  630.     {
  631.       register rtx head, jump;
  632.       fprintf (file, "\nBasic block %d: first insn %d, last %d.\n",
  633.            i,
  634.            INSN_UID (basic_block_head [i]),
  635.            INSN_UID (basic_block_end [i]));
  636.  
  637.       /* The control flow graph's storage is freed when flow_analysis
  638.      returns. Don't try to print it if it is gone.  */
  639.       if (basic_block_drops_in)
  640.     {
  641.       fprintf (file, "Reached from blocks: ");
  642.       head = basic_block_head [i];
  643.       if (GET_CODE (head) == CODE_LABEL)
  644.         for (jump = LABEL_REFS (head);
  645.          jump != head;
  646.          jump = LABEL_NEXTREF (jump))
  647.           {
  648.         register int from_block = BLOCK_NUM (CONTAINING_INSN (jump));
  649.         fprintf (file, " %d", from_block);
  650.           }
  651.       if (basic_block_drops_in [i])
  652.         fprintf (file, " previous");
  653.     }
  654.  
  655.       fprintf (file, "\nDefns reaching start:");
  656.       for (defno = 0; defno < max_defn_no; defno ++)
  657.     {
  658.       register int offset = defno / REGSET_ELT_BITS;
  659.       register int bit = 1 << (defno % REGSET_ELT_BITS);
  660.  
  661.       if (basic_block_rd_at_start [i][offset] & bit)
  662.         fprintf (file, " %d", INSN_UID (n_to_defn [defno]));
  663.     }
  664.       fprintf (file, "\n");
  665.     }
  666.  
  667.   fprintf (file, "%d registers.\n", MAX_REGNO);
  668.   for (i = 0; i < MAX_REGNO; i ++)
  669.     {
  670.       fprintf (file, "Register %d defined by: ", i);
  671.       for (defno = 0; defno < max_defn_no; defno ++)
  672.     {
  673.       register int offset = defno / REGSET_ELT_BITS;
  674.       register int bit = 1 << (defno % REGSET_ELT_BITS);
  675.  
  676.       if (defn_of_reg [i][offset] & bit)
  677.         fprintf (file, " %d", INSN_UID (n_to_defn [defno]));
  678.     }
  679.       fprintf (file, "\n");
  680.     }
  681.  
  682.   fprintf (file, "\n");
  683. }
  684.