OSDN Git Service

1999-08-18 Andrew Haley <aph@cygnus.com>
[pf3gnuchains/gcc-fork.git] / gcc / basic-block.h
index 54b7095..c6a9065 100644 (file)
@@ -1,5 +1,5 @@
 /* Define control and data flow tables, and regsets.
-   Copyright (C) 1987, 1997 Free Software Foundation, Inc.
+   Copyright (C) 1987, 1997, 1998, 1999 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -20,6 +20,8 @@ Boston, MA 02111-1307, USA.  */
 
 
 #include "bitmap.h"
+#include "sbitmap.h"
+#include "varray.h"
 
 typedef bitmap regset;         /* Head of register set linked list.  */
 
@@ -94,24 +96,65 @@ do {                                                                        \
 /* Grow any tables needed when the number of registers is calculated
    or extended.  For the linked list allocation, nothing needs to
    be done, other than zero the statistics on the first allocation.  */
-#define MAX_REGNO_REG_SET(NUM_REGS, NEW_P, RENUMBER_P)
+#define MAX_REGNO_REG_SET(NUM_REGS, NEW_P, RENUMBER_P) 
 
-/* Number of basic blocks in the current function.  */
+/* Control flow edge information.  */
+typedef struct edge_def {
+  /* Links through the predecessor and successor lists.  */
+  struct edge_def *pred_next, *succ_next;
 
-extern int n_basic_blocks;
+  /* The two blocks at the ends of the edge.  */
+  struct basic_block_def *src, *dest;
+
+  /* Instructions queued on the edge.  */
+  rtx insns;
+
+  /* Auxiliary info specific to a pass.  */
+  void *aux;
+
+  int flags;                   /* see EDGE_* below  */
+  int probability;             /* biased by REG_BR_PROB_BASE */
+} *edge;
+
+#define EDGE_FALLTHRU          1
+#define EDGE_CRITICAL          2
+#define EDGE_ABNORMAL          4
+#define EDGE_ABNORMAL_CALL     8
+#define EDGE_EH                        16
+#define EDGE_FAKE              32
+
+
+/* Basic block information indexed by block number.  */
+typedef struct basic_block_def {
+  /* The first and last insns of the block.  */
+  rtx head, end;
+
+  /* The edges into and out of the block.  */
+  edge pred, succ;
+
+  /* Liveness info.  */
+  regset local_set;
+  regset global_live_at_start;
+  regset global_live_at_end;
 
-/* Index by basic block number, get first insn in the block.  */
+  /* Auxiliary info specific to a pass.  */
+  void *aux;
 
-extern rtx *basic_block_head;
+  /* The index of this block.  */
+  int index;
+  /* The loop depth of this block plus one.  */
+  int loop_depth;
+} *basic_block;
 
-/* Index by basic block number, get last insn in the block.  */
+/* Number of basic blocks in the current function.  */
+
+extern int n_basic_blocks;
 
-extern rtx *basic_block_end;
+/* Index by basic block number, get basic block struct info.  */
 
-/* Index by basic block number, get address of regset
-   describing the registers live at the start of that block.  */
+extern varray_type basic_block_info;
 
-extern regset *basic_block_live_at_start;
+#define BASIC_BLOCK(N)  (VARRAY_BB (basic_block_info, (N)))
 
 /* What registers are live at the setjmp call.  */
 
@@ -127,7 +170,7 @@ extern regset regs_live_at_setjmp;
 #define REG_BLOCK_UNKNOWN -1
 #define REG_BLOCK_GLOBAL -2
 
-#define REG_BASIC_BLOCK(N) (reg_n_info[(N)].basic_block)
+#define REG_BASIC_BLOCK(N) (VARRAY_REG (reg_n_info, N)->basic_block)
 
 /* List of integers.
    These are used for storing things like predecessors, etc.
@@ -171,83 +214,81 @@ extern void free_int_list               PROTO ((int_list_block **));
 \f
 /* Stuff for recording basic block info.  */
 
-#define BLOCK_HEAD(B)      basic_block_head[(B)]
-#define BLOCK_END(B)       basic_block_end[(B)]
+#define BLOCK_HEAD(B)      (BASIC_BLOCK (B)->head)
+#define BLOCK_END(B)       (BASIC_BLOCK (B)->end)
 
 /* Special block numbers [markers] for entry and exit.  */
 #define ENTRY_BLOCK (-1)
 #define EXIT_BLOCK (-2)
 
-/* from flow.c */
-extern int *uid_block_number;
-#define BLOCK_NUM(INSN)    uid_block_number[INSN_UID (INSN)]
+/* Similarly, block pointers for the edge list.  */
+extern struct basic_block_def entry_exit_blocks[2];
+#define ENTRY_BLOCK_PTR        (&entry_exit_blocks[0])
+#define EXIT_BLOCK_PTR (&entry_exit_blocks[1])
 
-extern int compute_preds_succs PROTO ((int_list_ptr *, int_list_ptr *,
-                                      int *, int *));
-extern void dump_bb_data       PROTO ((FILE *, int_list_ptr *, int_list_ptr *));
-extern void free_bb_mem        PROTO ((void));
-extern void free_basic_block_vars      PROTO ((int));
+/* from flow.c */
+extern void free_regset_vector         PROTO ((regset *, int nelts));
 
-\f
-/* Simple bitmaps.
-   It's not clear yet whether using bitmap.[ch] will be a win.
-   It should be straightforward to convert so for now we keep things simple
-   while more important issues are dealt with.  */
-
-#define SBITMAP_ELT_BITS HOST_BITS_PER_WIDE_INT
-#define SBITMAP_ELT_TYPE unsigned HOST_WIDE_INT
-
-typedef struct simple_bitmap_def {
-  /* Number of bits.  */
-  int n_bits;
-  /* Size in elements.  */
-  int size;
-  /* Size in bytes.  */
-  int bytes;
-  /* The elements.  */
-  SBITMAP_ELT_TYPE elms[1];
-} *sbitmap;
-
-typedef SBITMAP_ELT_TYPE *sbitmap_ptr;
-
-/* Return the set size needed for N elements.  */
-#define SBITMAP_SET_SIZE(n) (((n) + SBITMAP_ELT_BITS - 1) / SBITMAP_ELT_BITS)
-
-/* set bit number bitno in the bitmap */
-#define SET_BIT(bitmap, bitno) \
-do { \
-  (bitmap)->elms [(bitno) / SBITMAP_ELT_BITS] |= (SBITMAP_ELT_TYPE) 1 << (bitno) % SBITMAP_ELT_BITS; \
-} while (0)
+extern varray_type basic_block_for_insn;
+#define BLOCK_FOR_INSN(INSN)  VARRAY_BB (basic_block_for_insn, INSN_UID (INSN))
+#define BLOCK_NUM(INSN)              (BLOCK_FOR_INSN (INSN)->index + 0)
 
-/* test if bit number bitno in the bitmap is set */
-#define TEST_BIT(bitmap, bitno) \
-((bitmap)->elms [(bitno) / SBITMAP_ELT_BITS] & ((SBITMAP_ELT_TYPE) 1 << (bitno) % SBITMAP_ELT_BITS))
+extern void set_block_for_insn         PROTO ((rtx, basic_block));
 
-/* reset bit number bitno in the bitmap  */
-#define RESET_BIT(bitmap, bitno) \
-do { \
-  (bitmap)->elms [(bitno) / SBITMAP_ELT_BITS] &= ~((SBITMAP_ELT_TYPE) 1 << (bitno) % SBITMAP_ELT_BITS); \
-} while (0)
+extern void dump_bb_data               PROTO ((FILE *, int_list_ptr *,
+                                               int_list_ptr *, int));
+extern void free_bb_mem                        PROTO ((void));
+extern void free_basic_block_vars      PROTO ((int));
 
-extern sbitmap sbitmap_alloc PROTO ((int));
-extern sbitmap *sbitmap_vector_alloc PROTO ((int, int));
-extern void sbitmap_copy PROTO ((sbitmap, sbitmap));
-extern void sbitmap_zero PROTO ((sbitmap));
-extern void sbitmap_ones PROTO ((sbitmap));
-extern void sbitmap_vector_zero PROTO ((sbitmap *, int));
-extern void sbitmap_vector_ones PROTO ((sbitmap *, int));
-extern int sbitmap_union_of_diff PROTO ((sbitmap, sbitmap, sbitmap, sbitmap));
-extern void sbitmap_difference PROTO ((sbitmap, sbitmap, sbitmap));
-extern void sbitmap_not PROTO ((sbitmap, sbitmap));
-extern int sbitmap_a_or_b_and_c PROTO ((sbitmap, sbitmap, sbitmap, sbitmap));
-extern int sbitmap_a_and_b_or_c PROTO ((sbitmap, sbitmap, sbitmap, sbitmap));
-extern int sbitmap_a_and_b PROTO ((sbitmap, sbitmap, sbitmap));
-extern int sbitmap_a_or_b PROTO ((sbitmap, sbitmap, sbitmap));
-extern void sbitmap_intersect_of_predsucc PROTO ((sbitmap, sbitmap *,
-                                                 int, int_list_ptr *));
-extern void sbitmap_intersect_of_predecessors PROTO ((sbitmap, sbitmap *, int,
-                                                     int_list_ptr *));
-extern void sbitmap_intersect_of_successors PROTO ((sbitmap, sbitmap *, int,
-                                                   int_list_ptr *));
-extern void sbitmap_union_of_predecessors PROTO ((sbitmap, sbitmap *, int,
-                                                 int_list_ptr *));
+extern basic_block split_edge          PROTO ((edge));
+extern void insert_insn_on_edge                PROTO ((rtx, edge));
+extern void commit_edge_insertions     PROTO ((void));
+
+/* This structure maintains an edge list vector.  */
+struct edge_list 
+{
+  int num_blocks;
+  int num_edges;
+  edge *index_to_edge;
+};
+
+/* This is the value which indicates no edge is present.  */
+#define EDGE_INDEX_NO_EDGE     -1
+
+/* EDGE_INDEX returns an integer index for an edge, or EDGE_INDEX_NO_EDGE
+   if there is no edge between the 2 basic blocks.  */
+#define EDGE_INDEX(el, pred, succ) (find_edge_index ((el), (pred), (succ)))
+
+/* INDEX_EDGE_PRED_BB and INDEX_EDGE_SUCC_BB return a pointer to the basic
+   block which is either the pred or succ end of the indexed edge.  */
+#define INDEX_EDGE_PRED_BB(el, index)  ((el)->index_to_edge[(index)]->src)
+#define INDEX_EDGE_SUCC_BB(el, index)  ((el)->index_to_edge[(index)]->dest)
+
+/* INDEX_EDGE returns a pointer to the edge.  */
+#define INDEX_EDGE(el, index)           ((el)->index_to_edge[(index)])
+
+/* Number of edges in the compressed edge list.  */
+#define NUM_EDGES(el)                  ((el)->num_edges)
+
+struct edge_list * create_edge_list    PROTO ((void));
+void free_edge_list                    PROTO ((struct edge_list *));
+void print_edge_list                   PROTO ((FILE *, struct edge_list *));
+void verify_edge_list                  PROTO ((FILE *, struct edge_list *));
+int find_edge_index                    PROTO ((struct edge_list *, int, int));
+
+extern void compute_preds_succs                PROTO ((int_list_ptr *, int_list_ptr *,
+                                               int *, int *));
+extern void compute_dominators         PROTO ((sbitmap *, sbitmap *,
+                                               int_list_ptr *,
+                                               int_list_ptr *));
+extern void compute_immediate_dominators       PROTO ((int *, sbitmap *));
+
+/* In lcm.c */
+extern void pre_lcm                    PROTO ((int, int, int_list_ptr *,
+                                               int_list_ptr *,
+                                               sbitmap *, sbitmap *,
+                                               sbitmap *, sbitmap *));
+extern void pre_rev_lcm                PROTO ((int, int, int_list_ptr *,
+                                               int_list_ptr *,
+                                               sbitmap *, sbitmap *,
+                                               sbitmap *, sbitmap *));