diff options
Diffstat (limited to 'contrib/gcc/df.c')
-rw-r--r-- | contrib/gcc/df.c | 1092 |
1 files changed, 402 insertions, 690 deletions
diff --git a/contrib/gcc/df.c b/contrib/gcc/df.c index fb434ff..d91f95e 100644 --- a/contrib/gcc/df.c +++ b/contrib/gcc/df.c @@ -1,5 +1,6 @@ /* Dataflow support routines. - Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 + Free Software Foundation, Inc. Contributed by Michael P. Hayes (m.hayes@elec.canterbury.ac.nz, mhayes@redhat.com) @@ -54,7 +55,8 @@ Here's an example of using the dataflow routines. df_init simply creates a poor man's object (df) that needs to be passed to all the dataflow routines. df_finish destroys this -object and frees up any allocated memory. +object and frees up any allocated memory. DF_ALL says to analyse +everything. df_analyse performs the following: @@ -112,6 +114,7 @@ rather than searching the def or use bitmaps. If the insns are in SSA form then the reg-def and use-def lists should only contain the single defining ref. + TODO: 1) Incremental dataflow analysis. @@ -129,9 +132,7 @@ insns so when df_analyse is called we can easily determine all the new or deleted refs. Currently the global dataflow information is recomputed from scratch but this could be propagated more efficiently. -2) Improved global data flow computation using depth first search. - -3) Reduced memory requirements. +2) Reduced memory requirements. We could operate a pool of ref structures. When a ref is deleted it gets returned to the pool (say by linking on to a chain of free refs). @@ -140,28 +141,47 @@ tell which ones have been changed. Alternatively, we could periodically squeeze the def and use tables and associated bitmaps and renumber the def and use ids. -4) Ordering of reg-def and reg-use lists. +3) Ordering of reg-def and reg-use lists. Should the first entry in the def list be the first def (within a BB)? Similarly, should the first entry in the use list be the last use (within a BB)? -5) Working with a sub-CFG. +4) Working with a sub-CFG. -Often the whole CFG does not need to be analysed, for example, -when optimising a loop, only certain registers are of interest. +Often the whole CFG does not need to be analyzed, for example, +when optimizing a loop, only certain registers are of interest. Perhaps there should be a bitmap argument to df_analyse to specify - which registers should be analysed? */ +which registers should be analyzed? + + +NOTES: + +Embedded addressing side-effects, such as POST_INC or PRE_INC, generate +both a use and a def. These are both marked read/write to show that they +are dependent. For example, (set (reg 40) (mem (post_inc (reg 42)))) +will generate a use of reg 42 followed by a def of reg 42 (both marked +read/write). Similarly, (set (reg 40) (mem (pre_dec (reg 41)))) +generates a use of reg 41 then a def of reg 41 (both marked read/write), +even though reg 41 is decremented before it is used for the memory +address in this second example. + +A set to a REG inside a ZERO_EXTRACT, SIGN_EXTRACT, or SUBREG invokes +a read-modify write operation. We generate both a use and a def +and again mark them read/write. +*/ #include "config.h" #include "system.h" +#include "coretypes.h" +#include "tm.h" #include "rtl.h" #include "tm_p.h" #include "insn-config.h" #include "recog.h" #include "function.h" #include "regs.h" -#include "obstack.h" +#include "alloc-pool.h" #include "hard-reg-set.h" #include "basic-block.h" #include "sbitmap.h" @@ -178,120 +198,107 @@ Perhaps there should be a bitmap argument to df_analyse to specify } \ while (0) -static struct obstack df_ref_obstack; +static alloc_pool df_ref_pool; +static alloc_pool df_link_pool; static struct df *ddf; -static void df_reg_table_realloc PARAMS((struct df *, int)); +static void df_reg_table_realloc (struct df *, int); +static void df_insn_table_realloc (struct df *, unsigned int); +static void df_bitmaps_alloc (struct df *, int); +static void df_bitmaps_free (struct df *, int); +static void df_free (struct df *); +static void df_alloc (struct df *, int); + +static rtx df_reg_clobber_gen (unsigned int); +static rtx df_reg_use_gen (unsigned int); + +static inline struct df_link *df_link_create (struct ref *, struct df_link *); +static struct df_link *df_ref_unlink (struct df_link **, struct ref *); +static void df_def_unlink (struct df *, struct ref *); +static void df_use_unlink (struct df *, struct ref *); +static void df_insn_refs_unlink (struct df *, basic_block, rtx); #if 0 -static void df_def_table_realloc PARAMS((struct df *, int)); -#endif -static void df_insn_table_realloc PARAMS((struct df *, unsigned int)); -static void df_bitmaps_alloc PARAMS((struct df *, int)); -static void df_bitmaps_free PARAMS((struct df *, int)); -static void df_free PARAMS((struct df *)); -static void df_alloc PARAMS((struct df *, int)); - -static rtx df_reg_clobber_gen PARAMS((unsigned int)); -static rtx df_reg_use_gen PARAMS((unsigned int)); - -static inline struct df_link *df_link_create PARAMS((struct ref *, - struct df_link *)); -static struct df_link *df_ref_unlink PARAMS((struct df_link **, struct ref *)); -static void df_def_unlink PARAMS((struct df *, struct ref *)); -static void df_use_unlink PARAMS((struct df *, struct ref *)); -static void df_insn_refs_unlink PARAMS ((struct df *, basic_block, rtx)); -#if 0 -static void df_bb_refs_unlink PARAMS ((struct df *, basic_block)); -static void df_refs_unlink PARAMS ((struct df *, bitmap)); +static void df_bb_refs_unlink (struct df *, basic_block); +static void df_refs_unlink (struct df *, bitmap); #endif -static struct ref *df_ref_create PARAMS((struct df *, - rtx, rtx *, rtx, - enum df_ref_type, enum df_ref_flags)); -static void df_ref_record_1 PARAMS((struct df *, rtx, rtx *, - rtx, enum df_ref_type, - enum df_ref_flags)); -static void df_ref_record PARAMS((struct df *, rtx, rtx *, - rtx, enum df_ref_type, - enum df_ref_flags)); -static void df_def_record_1 PARAMS((struct df *, rtx, basic_block, rtx)); -static void df_defs_record PARAMS((struct df *, rtx, basic_block, rtx)); -static void df_uses_record PARAMS((struct df *, rtx *, - enum df_ref_type, basic_block, rtx, - enum df_ref_flags)); -static void df_insn_refs_record PARAMS((struct df *, basic_block, rtx)); -static void df_bb_refs_record PARAMS((struct df *, basic_block)); -static void df_refs_record PARAMS((struct df *, bitmap)); - -static void df_bb_reg_def_chain_create PARAMS((struct df *, basic_block)); -static void df_reg_def_chain_create PARAMS((struct df *, bitmap)); -static void df_bb_reg_use_chain_create PARAMS((struct df *, basic_block)); -static void df_reg_use_chain_create PARAMS((struct df *, bitmap)); -static void df_bb_du_chain_create PARAMS((struct df *, basic_block, bitmap)); -static void df_du_chain_create PARAMS((struct df *, bitmap)); -static void df_bb_ud_chain_create PARAMS((struct df *, basic_block)); -static void df_ud_chain_create PARAMS((struct df *, bitmap)); -static void df_bb_rd_local_compute PARAMS((struct df *, basic_block)); -static void df_rd_local_compute PARAMS((struct df *, bitmap)); -static void df_bb_ru_local_compute PARAMS((struct df *, basic_block)); -static void df_ru_local_compute PARAMS((struct df *, bitmap)); -static void df_bb_lr_local_compute PARAMS((struct df *, basic_block)); -static void df_lr_local_compute PARAMS((struct df *, bitmap)); -static void df_bb_reg_info_compute PARAMS((struct df *, basic_block, bitmap)); -static void df_reg_info_compute PARAMS((struct df *, bitmap)); - -static int df_bb_luids_set PARAMS((struct df *df, basic_block)); -static int df_luids_set PARAMS((struct df *df, bitmap)); - -static int df_modified_p PARAMS ((struct df *, bitmap)); -static int df_refs_queue PARAMS ((struct df *)); -static int df_refs_process PARAMS ((struct df *)); -static int df_bb_refs_update PARAMS ((struct df *, basic_block)); -static int df_refs_update PARAMS ((struct df *)); -static void df_analyse_1 PARAMS((struct df *, bitmap, int, int)); - -static void df_insns_modify PARAMS((struct df *, basic_block, - rtx, rtx)); -static int df_rtx_mem_replace PARAMS ((rtx *, void *)); -static int df_rtx_reg_replace PARAMS ((rtx *, void *)); -void df_refs_reg_replace PARAMS ((struct df *, bitmap, - struct df_link *, rtx, rtx)); - -static int df_def_dominates_all_uses_p PARAMS((struct df *, struct ref *def)); -static int df_def_dominates_uses_p PARAMS((struct df *, - struct ref *def, bitmap)); -static struct ref *df_bb_regno_last_use_find PARAMS((struct df *, basic_block, - unsigned int)); -static struct ref *df_bb_regno_first_def_find PARAMS((struct df *, basic_block, - unsigned int)); -static struct ref *df_bb_insn_regno_last_use_find PARAMS((struct df *, - basic_block, - rtx, unsigned int)); -static struct ref *df_bb_insn_regno_first_def_find PARAMS((struct df *, - basic_block, - rtx, unsigned int)); - -static void df_chain_dump PARAMS((struct df_link *, FILE *file)); -static void df_chain_dump_regno PARAMS((struct df_link *, FILE *file)); -static void df_regno_debug PARAMS ((struct df *, unsigned int, FILE *)); -static void df_ref_debug PARAMS ((struct df *, struct ref *, FILE *)); -static void df_rd_transfer_function PARAMS ((int, int *, bitmap, bitmap, - bitmap, bitmap, void *)); -static void df_ru_transfer_function PARAMS ((int, int *, bitmap, bitmap, - bitmap, bitmap, void *)); -static void df_lr_transfer_function PARAMS ((int, int *, bitmap, bitmap, - bitmap, bitmap, void *)); -static void hybrid_search_bitmap PARAMS ((basic_block, bitmap *, bitmap *, - bitmap *, bitmap *, enum df_flow_dir, - enum df_confluence_op, - transfer_function_bitmap, - sbitmap, sbitmap, void *)); -static void hybrid_search_sbitmap PARAMS ((basic_block, sbitmap *, sbitmap *, - sbitmap *, sbitmap *, enum df_flow_dir, - enum df_confluence_op, - transfer_function_sbitmap, - sbitmap, sbitmap, void *)); -static inline bool read_modify_subreg_p PARAMS ((rtx)); +static struct ref *df_ref_create (struct df *, rtx, rtx *, rtx, + enum df_ref_type, enum df_ref_flags); +static void df_ref_record_1 (struct df *, rtx, rtx *, rtx, enum df_ref_type, + enum df_ref_flags); +static void df_ref_record (struct df *, rtx, rtx *, rtx, enum df_ref_type, + enum df_ref_flags); +static void df_def_record_1 (struct df *, rtx, basic_block, rtx); +static void df_defs_record (struct df *, rtx, basic_block, rtx); +static void df_uses_record (struct df *, rtx *, enum df_ref_type, + basic_block, rtx, enum df_ref_flags); +static void df_insn_refs_record (struct df *, basic_block, rtx); +static void df_bb_refs_record (struct df *, basic_block); +static void df_refs_record (struct df *, bitmap); + +static void df_bb_reg_def_chain_create (struct df *, basic_block); +static void df_reg_def_chain_create (struct df *, bitmap); +static void df_bb_reg_use_chain_create (struct df *, basic_block); +static void df_reg_use_chain_create (struct df *, bitmap); +static void df_bb_du_chain_create (struct df *, basic_block, bitmap); +static void df_du_chain_create (struct df *, bitmap); +static void df_bb_ud_chain_create (struct df *, basic_block); +static void df_ud_chain_create (struct df *, bitmap); +static void df_bb_rd_local_compute (struct df *, basic_block); +static void df_rd_local_compute (struct df *, bitmap); +static void df_bb_ru_local_compute (struct df *, basic_block); +static void df_ru_local_compute (struct df *, bitmap); +static void df_bb_lr_local_compute (struct df *, basic_block); +static void df_lr_local_compute (struct df *, bitmap); +static void df_bb_reg_info_compute (struct df *, basic_block, bitmap); +static void df_reg_info_compute (struct df *, bitmap); + +static int df_bb_luids_set (struct df *df, basic_block); +static int df_luids_set (struct df *df, bitmap); + +static int df_modified_p (struct df *, bitmap); +static int df_refs_queue (struct df *); +static int df_refs_process (struct df *); +static int df_bb_refs_update (struct df *, basic_block); +static int df_refs_update (struct df *); +static void df_analyse_1 (struct df *, bitmap, int, int); + +static void df_insns_modify (struct df *, basic_block, rtx, rtx); +static int df_rtx_mem_replace (rtx *, void *); +static int df_rtx_reg_replace (rtx *, void *); +void df_refs_reg_replace (struct df *, bitmap, struct df_link *, rtx, rtx); + +static int df_def_dominates_all_uses_p (struct df *, struct ref *def); +static int df_def_dominates_uses_p (struct df *, struct ref *def, bitmap); +static struct ref *df_bb_regno_last_use_find (struct df *, basic_block, + unsigned int); +static struct ref *df_bb_regno_first_def_find (struct df *, basic_block, + unsigned int); +static struct ref *df_bb_insn_regno_last_use_find (struct df *, basic_block, + rtx, unsigned int); +static struct ref *df_bb_insn_regno_first_def_find (struct df *, basic_block, + rtx, unsigned int); + +static void df_chain_dump (struct df_link *, FILE *file); +static void df_chain_dump_regno (struct df_link *, FILE *file); +static void df_regno_debug (struct df *, unsigned int, FILE *); +static void df_ref_debug (struct df *, struct ref *, FILE *); +static void df_rd_transfer_function (int, int *, bitmap, bitmap, bitmap, + bitmap, void *); +static void df_ru_transfer_function (int, int *, bitmap, bitmap, bitmap, + bitmap, void *); +static void df_lr_transfer_function (int, int *, bitmap, bitmap, bitmap, + bitmap, void *); +static void hybrid_search_bitmap (basic_block, bitmap *, bitmap *, + bitmap *, bitmap *, enum df_flow_dir, + enum df_confluence_op, + transfer_function_bitmap, + sbitmap, sbitmap, void *); +static void hybrid_search_sbitmap (basic_block, sbitmap *, sbitmap *, + sbitmap *, sbitmap *, enum df_flow_dir, + enum df_confluence_op, + transfer_function_sbitmap, + sbitmap, sbitmap, void *); /* Local memory allocation/deallocation routines. */ @@ -300,20 +307,17 @@ static inline bool read_modify_subreg_p PARAMS ((rtx)); /* Increase the insn info table to have space for at least SIZE + 1 elements. */ static void -df_insn_table_realloc (df, size) - struct df *df; - unsigned int size; +df_insn_table_realloc (struct df *df, unsigned int size) { size++; if (size <= df->insn_size) return; - /* Make the table a little larger than requested, so we don't need + /* Make the table a little larger than requested, so we do not need to enlarge it so often. */ size += df->insn_size / 4; - df->insns = (struct insn_info *) - xrealloc (df->insns, size * sizeof (struct insn_info)); + df->insns = xrealloc (df->insns, size * sizeof (struct insn_info)); memset (df->insns + df->insn_size, 0, (size - df->insn_size) * sizeof (struct insn_info)); @@ -330,9 +334,7 @@ df_insn_table_realloc (df, size) /* Increase the reg info table by SIZE more elements. */ static void -df_reg_table_realloc (df, size) - struct df *df; - int size; +df_reg_table_realloc (struct df *df, int size) { /* Make table 25 percent larger by default. */ if (! size) @@ -342,8 +344,7 @@ df_reg_table_realloc (df, size) if (size < max_reg_num ()) size = max_reg_num (); - df->regs = (struct reg_info *) - xrealloc (df->regs, size * sizeof (struct reg_info)); + df->regs = xrealloc (df->regs, size * sizeof (struct reg_info)); /* Zero the new entries. */ memset (df->regs + df->reg_size, 0, @@ -353,43 +354,9 @@ df_reg_table_realloc (df, size) } -#if 0 -/* Not currently used. */ -static void -df_def_table_realloc (df, size) - struct df *df; - int size; -{ - int i; - struct ref *refs; - - /* Make table 25 percent larger by default. */ - if (! size) - size = df->def_size / 4; - - df->def_size += size; - df->defs = xrealloc (df->defs, - df->def_size * sizeof (*df->defs)); - - /* Allocate a new block of memory and link into list of blocks - that will need to be freed later. */ - - refs = xmalloc (size * sizeof (*refs)); - - /* Link all the new refs together, overloading the chain field. */ - for (i = 0; i < size - 1; i++) - refs[i].chain = (struct df_link *) (refs + i + 1); - refs[size - 1].chain = 0; -} -#endif - - - /* Allocate bitmaps for each basic block. */ static void -df_bitmaps_alloc (df, flags) - struct df *df; - int flags; +df_bitmaps_alloc (struct df *df, int flags) { int dflags = 0; basic_block bb; @@ -454,9 +421,7 @@ df_bitmaps_alloc (df, flags) /* Free bitmaps for each basic block. */ static void -df_bitmaps_free (df, flags) - struct df *df ATTRIBUTE_UNUSED; - int flags; +df_bitmaps_free (struct df *df, int flags) { basic_block bb; @@ -512,14 +477,14 @@ df_bitmaps_free (df, flags) /* Allocate and initialize dataflow memory. */ static void -df_alloc (df, n_regs) - struct df *df; - int n_regs; +df_alloc (struct df *df, int n_regs) { int n_insns; basic_block bb; - gcc_obstack_init (&df_ref_obstack); + df_link_pool = create_alloc_pool ("df_link pool", sizeof (struct df_link), + 100); + df_ref_pool = create_alloc_pool ("df_ref pool", sizeof (struct ref), 100); /* Perhaps we should use LUIDs to save memory for the insn_refs table. This is only a small saving; a few pointers. */ @@ -562,8 +527,7 @@ df_alloc (df, n_regs) /* Free all the dataflow info. */ static void -df_free (df) - struct df *df; +df_free (struct df *df) { df_bitmaps_free (df, DF_ALL); @@ -604,14 +568,15 @@ df_free (df) BITMAP_XFREE (df->all_blocks); df->all_blocks = 0; - obstack_free (&df_ref_obstack, NULL); + free_alloc_pool (df_ref_pool); + free_alloc_pool (df_link_pool); + } /* Local miscellaneous routines. */ /* Return a USE for register REGNO. */ -static rtx df_reg_use_gen (regno) - unsigned int regno; +static rtx df_reg_use_gen (unsigned int regno) { rtx reg; rtx use; @@ -624,8 +589,7 @@ static rtx df_reg_use_gen (regno) /* Return a CLOBBER for register REGNO. */ -static rtx df_reg_clobber_gen (regno) - unsigned int regno; +static rtx df_reg_clobber_gen (unsigned int regno) { rtx reg; rtx use; @@ -640,14 +604,11 @@ static rtx df_reg_clobber_gen (regno) /* Create a link in a def-use or use-def chain. */ static inline struct df_link * -df_link_create (ref, next) - struct ref *ref; - struct df_link *next; +df_link_create (struct ref *ref, struct df_link *next) { struct df_link *link; - link = (struct df_link *) obstack_alloc (&df_ref_obstack, - sizeof (*link)); + link = pool_alloc (df_link_pool); link->next = next; link->ref = ref; return link; @@ -656,9 +617,7 @@ df_link_create (ref, next) /* Add REF to chain head pointed to by PHEAD. */ static struct df_link * -df_ref_unlink (phead, ref) - struct df_link **phead; - struct ref *ref; +df_ref_unlink (struct df_link **phead, struct ref *ref) { struct df_link *link = *phead; @@ -700,9 +659,7 @@ df_ref_unlink (phead, ref) /* Unlink REF from all def-use/use-def chains, etc. */ int -df_ref_remove (df, ref) - struct df *df; - struct ref *ref; +df_ref_remove (struct df *df, struct ref *ref) { if (DF_REF_REG_DEF_P (ref)) { @@ -720,9 +677,7 @@ df_ref_remove (df, ref) /* Unlink DEF from use-def and reg-def chains. */ static void -df_def_unlink (df, def) - struct df *df ATTRIBUTE_UNUSED; - struct ref *def; +df_def_unlink (struct df *df ATTRIBUTE_UNUSED, struct ref *def) { struct df_link *du_link; unsigned int dregno = DF_REF_REGNO (def); @@ -746,9 +701,7 @@ df_def_unlink (df, def) /* Unlink use from def-use and reg-use chains. */ static void -df_use_unlink (df, use) - struct df *df ATTRIBUTE_UNUSED; - struct ref *use; +df_use_unlink (struct df *df ATTRIBUTE_UNUSED, struct ref *use) { struct df_link *ud_link; unsigned int uregno = DF_REF_REGNO (use); @@ -775,26 +728,18 @@ df_use_unlink (df, use) /* Create a new ref of type DF_REF_TYPE for register REG at address LOC within INSN of BB. */ static struct ref * -df_ref_create (df, reg, loc, insn, ref_type, ref_flags) - struct df *df; - rtx reg; - rtx *loc; - rtx insn; - enum df_ref_type ref_type; - enum df_ref_flags ref_flags; +df_ref_create (struct df *df, rtx reg, rtx *loc, rtx insn, + enum df_ref_type ref_type, enum df_ref_flags ref_flags) { struct ref *this_ref; - unsigned int uid; - this_ref = (struct ref *) obstack_alloc (&df_ref_obstack, - sizeof (*this_ref)); + this_ref = pool_alloc (df_ref_pool); DF_REF_REG (this_ref) = reg; DF_REF_LOC (this_ref) = loc; DF_REF_INSN (this_ref) = insn; DF_REF_CHAIN (this_ref) = 0; DF_REF_TYPE (this_ref) = ref_type; DF_REF_FLAGS (this_ref) = ref_flags; - uid = INSN_UID (insn); if (ref_type == DF_REF_REG_DEF) { @@ -827,13 +772,8 @@ df_ref_create (df, reg, loc, insn, ref_type, ref_flags) /* Create a new reference of type DF_REF_TYPE for a single register REG, used inside the LOC rtx of INSN. */ static void -df_ref_record_1 (df, reg, loc, insn, ref_type, ref_flags) - struct df *df; - rtx reg; - rtx *loc; - rtx insn; - enum df_ref_type ref_type; - enum df_ref_flags ref_flags; +df_ref_record_1 (struct df *df, rtx reg, rtx *loc, rtx insn, + enum df_ref_type ref_type, enum df_ref_flags ref_flags) { df_ref_create (df, reg, loc, insn, ref_type, ref_flags); } @@ -842,13 +782,8 @@ df_ref_record_1 (df, reg, loc, insn, ref_type, ref_flags) /* Create new references of type DF_REF_TYPE for each part of register REG at address LOC within INSN of BB. */ static void -df_ref_record (df, reg, loc, insn, ref_type, ref_flags) - struct df *df; - rtx reg; - rtx *loc; - rtx insn; - enum df_ref_type ref_type; - enum df_ref_flags ref_flags; +df_ref_record (struct df *df, rtx reg, rtx *loc, rtx insn, + enum df_ref_type ref_type, enum df_ref_flags ref_flags) { unsigned int regno; @@ -867,6 +802,7 @@ df_ref_record (df, reg, loc, insn, ref_type, ref_flags) { loc = &SUBREG_REG (reg); reg = *loc; + ref_flags |= DF_REF_STRIPPED; } regno = REGNO (GET_CODE (reg) == SUBREG ? SUBREG_REG (reg) : reg); @@ -878,9 +814,9 @@ df_ref_record (df, reg, loc, insn, ref_type, ref_flags) if (! (df->flags & DF_HARD_REGS)) return; - /* GET_MODE (reg) is correct here. We don't want to go into a SUBREG + /* GET_MODE (reg) is correct here. We do not want to go into a SUBREG for the mode, because we only want to add references to regs, which - are really referenced. E.g. a (subreg:SI (reg:DI 0) 0) does _not_ + are really referenced. E.g., a (subreg:SI (reg:DI 0) 0) does _not_ reference the whole reg 0 in DI mode (which would also include reg 1, at least, if 0 and 1 are SImode registers). */ endregno = HARD_REGNO_NREGS (regno, GET_MODE (reg)); @@ -899,39 +835,38 @@ df_ref_record (df, reg, loc, insn, ref_type, ref_flags) } } -/* Writes to paradoxical subregs, or subregs which are too narrow - are read-modify-write. */ -static inline bool -read_modify_subreg_p (x) - rtx x; +/* Return nonzero if writes to paradoxical SUBREGs, or SUBREGs which + are too narrow, are read-modify-write. */ +bool +read_modify_subreg_p (rtx x) { unsigned int isize, osize; if (GET_CODE (x) != SUBREG) return false; isize = GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))); osize = GET_MODE_SIZE (GET_MODE (x)); - if (isize <= osize) - return true; - if (isize <= UNITS_PER_WORD) - return false; - if (osize >= UNITS_PER_WORD) - return false; - return true; + /* Paradoxical subreg writes don't leave a trace of the old content. */ + return (isize > osize && isize > UNITS_PER_WORD); } + /* Process all the registers defined in the rtx, X. */ static void -df_def_record_1 (df, x, bb, insn) - struct df *df; - rtx x; - basic_block bb; - rtx insn; -{ - rtx *loc = &SET_DEST (x); - rtx dst = *loc; +df_def_record_1 (struct df *df, rtx x, basic_block bb, rtx insn) +{ + rtx *loc; + rtx dst; enum df_ref_flags flags = 0; + /* We may recursively call ourselves on EXPR_LIST when dealing with PARALLEL + construct. */ + if (GET_CODE (x) == EXPR_LIST || GET_CODE (x) == CLOBBER) + loc = &XEXP (x, 0); + else + loc = &SET_DEST (x); + dst = *loc; + /* Some targets place small structures in registers for return values of functions. */ if (GET_CODE (dst) == PARALLEL && GET_MODE (dst) == BLKmode) @@ -939,37 +874,30 @@ df_def_record_1 (df, x, bb, insn) int i; for (i = XVECLEN (dst, 0) - 1; i >= 0; i--) - df_def_record_1 (df, XVECEXP (dst, 0, i), bb, insn); + { + rtx temp = XVECEXP (dst, 0, i); + if (GET_CODE (temp) == EXPR_LIST || GET_CODE (temp) == CLOBBER + || GET_CODE (temp) == SET) + df_def_record_1 (df, temp, bb, insn); + } return; } -#ifdef CLASS_CANNOT_CHANGE_MODE - if (GET_CODE (dst) == SUBREG - && CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (SUBREG_REG (dst)), - GET_MODE (dst))) - flags |= DF_REF_MODE_CHANGE; -#endif - - /* May be, we should flag the use of strict_low_part somehow. Might be - handy for the reg allocator. */ + /* Maybe, we should flag the use of STRICT_LOW_PART somehow. It might + be handy for the reg allocator. */ while (GET_CODE (dst) == STRICT_LOW_PART || GET_CODE (dst) == ZERO_EXTRACT || GET_CODE (dst) == SIGN_EXTRACT - || read_modify_subreg_p (dst)) + || ((df->flags & DF_FOR_REGALLOC) == 0 + && read_modify_subreg_p (dst))) { - /* Strict low part always contains SUBREG, but we don't want to make + /* Strict low part always contains SUBREG, but we do not want to make it appear outside, as whole register is always considered. */ if (GET_CODE (dst) == STRICT_LOW_PART) { loc = &XEXP (dst, 0); dst = *loc; } -#ifdef CLASS_CANNOT_CHANGE_MODE - if (GET_CODE (dst) == SUBREG - && CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (SUBREG_REG (dst)), - GET_MODE (dst))) - flags |= DF_REF_MODE_CHANGE; -#endif loc = &XEXP (dst, 0); dst = *loc; flags |= DF_REF_READ_WRITE; @@ -983,11 +911,7 @@ df_def_record_1 (df, x, bb, insn) /* Process all the registers defined in the pattern rtx, X. */ static void -df_defs_record (df, x, bb, insn) - struct df *df; - rtx x; - basic_block bb; - rtx insn; +df_defs_record (struct df *df, rtx x, basic_block bb, rtx insn) { RTX_CODE code = GET_CODE (x); @@ -1013,13 +937,8 @@ df_defs_record (df, x, bb, insn) /* Process all the registers used in the rtx at address LOC. */ static void -df_uses_record (df, loc, ref_type, bb, insn, flags) - struct df *df; - rtx *loc; - enum df_ref_type ref_type; - basic_block bb; - rtx insn; - enum df_ref_flags flags; +df_uses_record (struct df *df, rtx *loc, enum df_ref_type ref_type, + basic_block bb, rtx insn, enum df_ref_flags flags) { RTX_CODE code; rtx x; @@ -1053,29 +972,22 @@ df_uses_record (df, loc, ref_type, bb, insn, flags) return; case MEM: - df_uses_record (df, &XEXP (x, 0), DF_REF_REG_MEM_LOAD, bb, insn, flags); + df_uses_record (df, &XEXP (x, 0), DF_REF_REG_MEM_LOAD, bb, insn, 0); return; case SUBREG: /* While we're here, optimize this case. */ - /* In case the SUBREG is not of a register, don't optimize. */ + /* In case the SUBREG is not of a REG, do not optimize. */ if (GET_CODE (SUBREG_REG (x)) != REG) { loc = &SUBREG_REG (x); df_uses_record (df, loc, ref_type, bb, insn, flags); return; } -#ifdef CLASS_CANNOT_CHANGE_MODE - if (CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (x), - GET_MODE (SUBREG_REG (x)))) - flags |= DF_REF_MODE_CHANGE; -#endif - /* ... Fall through ... */ case REG: - /* See a register (or subreg) other than being set. */ df_ref_record (df, x, loc, insn, ref_type, flags); return; @@ -1087,21 +999,15 @@ df_uses_record (df, loc, ref_type, bb, insn, flags) switch (GET_CODE (dst)) { - enum df_ref_flags use_flags; case SUBREG: - if (read_modify_subreg_p (dst)) + if ((df->flags & DF_FOR_REGALLOC) == 0 + && read_modify_subreg_p (dst)) { - use_flags = DF_REF_READ_WRITE; -#ifdef CLASS_CANNOT_CHANGE_MODE - if (CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (dst), - GET_MODE (SUBREG_REG (dst)))) - use_flags |= DF_REF_MODE_CHANGE; -#endif df_uses_record (df, &SUBREG_REG (dst), DF_REF_REG_USE, bb, - insn, use_flags); + insn, DF_REF_READ_WRITE); break; } - /* ... FALLTHRU ... */ + /* Fall through. */ case REG: case PARALLEL: case PC: @@ -1113,18 +1019,12 @@ df_uses_record (df, loc, ref_type, bb, insn, flags) bb, insn, 0); break; case STRICT_LOW_PART: - /* A strict_low_part uses the whole reg not only the subreg. */ + /* A strict_low_part uses the whole REG and not just the SUBREG. */ dst = XEXP (dst, 0); if (GET_CODE (dst) != SUBREG) abort (); - use_flags = DF_REF_READ_WRITE; -#ifdef CLASS_CANNOT_CHANGE_MODE - if (CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (dst), - GET_MODE (SUBREG_REG (dst)))) - use_flags |= DF_REF_MODE_CHANGE; -#endif df_uses_record (df, &SUBREG_REG (dst), DF_REF_REG_USE, bb, - insn, use_flags); + insn, DF_REF_READ_WRITE); break; case ZERO_EXTRACT: case SIGN_EXTRACT: @@ -1221,10 +1121,7 @@ df_uses_record (df, loc, ref_type, bb, insn, flags) /* Record all the df within INSN of basic block BB. */ static void -df_insn_refs_record (df, bb, insn) - struct df *df; - basic_block bb; - rtx insn; +df_insn_refs_record (struct df *df, basic_block bb, rtx insn) { int i; @@ -1232,7 +1129,7 @@ df_insn_refs_record (df, bb, insn) { rtx note; - /* Record register defs */ + /* Record register defs. */ df_defs_record (df, PATTERN (insn), bb, insn); if (df->flags & DF_EQUIV_NOTES) @@ -1286,7 +1183,6 @@ df_insn_refs_record (df, bb, insn) df_uses_record (df, &PATTERN (insn), DF_REF_REG_USE, bb, insn, 0); - if (GET_CODE (insn) == CALL_INSN) { rtx note; @@ -1315,21 +1211,19 @@ df_insn_refs_record (df, bb, insn) /* Record all the refs within the basic block BB. */ static void -df_bb_refs_record (df, bb) - struct df *df; - basic_block bb; +df_bb_refs_record (struct df *df, basic_block bb) { rtx insn; /* Scan the block an insn at a time from beginning to end. */ - for (insn = bb->head; ; insn = NEXT_INSN (insn)) + for (insn = BB_HEAD (bb); ; insn = NEXT_INSN (insn)) { if (INSN_P (insn)) { /* Record defs within INSN. */ df_insn_refs_record (df, bb, insn); } - if (insn == bb->end) + if (insn == BB_END (bb)) break; } } @@ -1337,9 +1231,7 @@ df_bb_refs_record (df, bb) /* Record all the refs in the basic blocks specified by BLOCKS. */ static void -df_refs_record (df, blocks) - struct df *df; - bitmap blocks; +df_refs_record (struct df *df, bitmap blocks) { basic_block bb; @@ -1355,9 +1247,7 @@ df_refs_record (df, blocks) /* Create reg-def chains for basic block BB. These are a list of definitions for each register. */ static void -df_bb_reg_def_chain_create (df, bb) - struct df *df; - basic_block bb; +df_bb_reg_def_chain_create (struct df *df, basic_block bb) { rtx insn; @@ -1366,7 +1256,7 @@ df_bb_reg_def_chain_create (df, bb) scan the basic blocks in reverse order so that the first defs appear at the start of the chain. */ - for (insn = bb->end; insn && insn != PREV_INSN (bb->head); + for (insn = BB_END (bb); insn && insn != PREV_INSN (BB_HEAD (bb)); insn = PREV_INSN (insn)) { struct df_link *link; @@ -1379,9 +1269,11 @@ df_bb_reg_def_chain_create (df, bb) { struct ref *def = link->ref; unsigned int dregno = DF_REF_REGNO (def); - /* Don't add ref's to the chain two times. I.e. only add - new refs. XXX the same could be done by testing if the current - insn is a modified (or a new) one. This would be faster. */ + + /* Do not add ref's to the chain twice, i.e., only add new + refs. XXX the same could be done by testing if the + current insn is a modified (or a new) one. This would be + faster. */ if (DF_REF_ID (def) < df->def_id_save) continue; @@ -1395,9 +1287,7 @@ df_bb_reg_def_chain_create (df, bb) /* Create reg-def chains for each basic block within BLOCKS. These are a list of definitions for each register. */ static void -df_reg_def_chain_create (df, blocks) - struct df *df; - bitmap blocks; +df_reg_def_chain_create (struct df *df, bitmap blocks) { basic_block bb; @@ -1411,16 +1301,14 @@ df_reg_def_chain_create (df, blocks) /* Create reg-use chains for basic block BB. These are a list of uses for each register. */ static void -df_bb_reg_use_chain_create (df, bb) - struct df *df; - basic_block bb; +df_bb_reg_use_chain_create (struct df *df, basic_block bb) { rtx insn; - /* Scan in forward order so that the last uses appear at the - start of the chain. */ + /* Scan in forward order so that the last uses appear at the start + of the chain. */ - for (insn = bb->head; insn && insn != NEXT_INSN (bb->end); + for (insn = BB_HEAD (bb); insn && insn != NEXT_INSN (BB_END (bb)); insn = NEXT_INSN (insn)) { struct df_link *link; @@ -1433,9 +1321,11 @@ df_bb_reg_use_chain_create (df, bb) { struct ref *use = link->ref; unsigned int uregno = DF_REF_REGNO (use); - /* Don't add ref's to the chain two times. I.e. only add - new refs. XXX the same could be done by testing if the current - insn is a modified (or a new) one. This would be faster. */ + + /* Do not add ref's to the chain twice, i.e., only add new + refs. XXX the same could be done by testing if the + current insn is a modified (or a new) one. This would be + faster. */ if (DF_REF_ID (use) < df->use_id_save) continue; @@ -1449,9 +1339,7 @@ df_bb_reg_use_chain_create (df, bb) /* Create reg-use chains for each basic block within BLOCKS. These are a list of uses for each register. */ static void -df_reg_use_chain_create (df, blocks) - struct df *df; - bitmap blocks; +df_reg_use_chain_create (struct df *df, bitmap blocks) { basic_block bb; @@ -1464,10 +1352,7 @@ df_reg_use_chain_create (df, blocks) /* Create def-use chains from reaching use bitmaps for basic block BB. */ static void -df_bb_du_chain_create (df, bb, ru) - struct df *df; - basic_block bb; - bitmap ru; +df_bb_du_chain_create (struct df *df, basic_block bb, bitmap ru) { struct bb_info *bb_info = DF_BB_INFO (df, bb); rtx insn; @@ -1476,7 +1361,7 @@ df_bb_du_chain_create (df, bb, ru) /* For each def in BB create a linked list (chain) of uses reached from the def. */ - for (insn = bb->end; insn && insn != PREV_INSN (bb->head); + for (insn = BB_END (bb); insn && insn != PREV_INSN (BB_HEAD (bb)); insn = PREV_INSN (insn)) { struct df_link *def_link; @@ -1525,9 +1410,7 @@ df_bb_du_chain_create (df, bb, ru) /* Create def-use chains from reaching use bitmaps for basic blocks in BLOCKS. */ static void -df_du_chain_create (df, blocks) - struct df *df; - bitmap blocks; +df_du_chain_create (struct df *df, bitmap blocks) { bitmap ru; basic_block bb; @@ -1545,9 +1428,7 @@ df_du_chain_create (df, blocks) /* Create use-def chains from reaching def bitmaps for basic block BB. */ static void -df_bb_ud_chain_create (df, bb) - struct df *df; - basic_block bb; +df_bb_ud_chain_create (struct df *df, basic_block bb) { struct bb_info *bb_info = DF_BB_INFO (df, bb); struct ref **reg_def_last = df->reg_def_last; @@ -1557,7 +1438,7 @@ df_bb_ud_chain_create (df, bb) /* For each use in BB create a linked list (chain) of defs that reach the use. */ - for (insn = bb->head; insn && insn != NEXT_INSN (bb->end); + for (insn = BB_HEAD (bb); insn && insn != NEXT_INSN (BB_END (bb)); insn = NEXT_INSN (insn)) { unsigned int uid = INSN_UID (insn); @@ -1606,7 +1487,7 @@ df_bb_ud_chain_create (df, bb) } - /* For each def in insn...record the last def of each reg. */ + /* For each def in insn... record the last def of each reg. */ for (def_link = df->insns[uid].defs; def_link; def_link = def_link->next) { struct ref *def = def_link->ref; @@ -1621,9 +1502,7 @@ df_bb_ud_chain_create (df, bb) /* Create use-def chains from reaching def bitmaps for basic blocks within BLOCKS. */ static void -df_ud_chain_create (df, blocks) - struct df *df; - bitmap blocks; +df_ud_chain_create (struct df *df, bitmap blocks) { basic_block bb; @@ -1636,30 +1515,27 @@ df_ud_chain_create (df, blocks) static void -df_rd_transfer_function (bb, changed, in, out, gen, kill, data) - int bb ATTRIBUTE_UNUSED; - int *changed; - bitmap in, out, gen, kill; - void *data ATTRIBUTE_UNUSED; +df_rd_transfer_function (int bb ATTRIBUTE_UNUSED, int *changed, bitmap in, + bitmap out, bitmap gen, bitmap kill, + void *data ATTRIBUTE_UNUSED) { *changed = bitmap_union_of_diff (out, gen, in, kill); } + + static void -df_ru_transfer_function (bb, changed, in, out, gen, kill, data) - int bb ATTRIBUTE_UNUSED; - int *changed; - bitmap in, out, gen, kill; - void *data ATTRIBUTE_UNUSED; +df_ru_transfer_function (int bb ATTRIBUTE_UNUSED, int *changed, bitmap in, + bitmap out, bitmap gen, bitmap kill, + void *data ATTRIBUTE_UNUSED) { *changed = bitmap_union_of_diff (in, gen, out, kill); } + static void -df_lr_transfer_function (bb, changed, in, out, use, def, data) - int bb ATTRIBUTE_UNUSED; - int *changed; - bitmap in, out, use, def; - void *data ATTRIBUTE_UNUSED; +df_lr_transfer_function (int bb ATTRIBUTE_UNUSED, int *changed, bitmap in, + bitmap out, bitmap use, bitmap def, + void *data ATTRIBUTE_UNUSED) { *changed = bitmap_union_of_diff (in, use, out, def); } @@ -1667,14 +1543,12 @@ df_lr_transfer_function (bb, changed, in, out, use, def, data) /* Compute local reaching def info for basic block BB. */ static void -df_bb_rd_local_compute (df, bb) - struct df *df; - basic_block bb; +df_bb_rd_local_compute (struct df *df, basic_block bb) { struct bb_info *bb_info = DF_BB_INFO (df, bb); rtx insn; - for (insn = bb->head; insn && insn != NEXT_INSN (bb->end); + for (insn = BB_HEAD (bb); insn && insn != NEXT_INSN (BB_END (bb)); insn = NEXT_INSN (insn)) { unsigned int uid = INSN_UID (insn); @@ -1714,9 +1588,7 @@ df_bb_rd_local_compute (df, bb) /* Compute local reaching def info for each basic block within BLOCKS. */ static void -df_rd_local_compute (df, blocks) - struct df *df; - bitmap blocks; +df_rd_local_compute (struct df *df, bitmap blocks) { basic_block bb; @@ -1730,9 +1602,7 @@ df_rd_local_compute (df, blocks) /* Compute local reaching use (upward exposed use) info for basic block BB. */ static void -df_bb_ru_local_compute (df, bb) - struct df *df; - basic_block bb; +df_bb_ru_local_compute (struct df *df, basic_block bb) { /* This is much more tricky than computing reaching defs. With reaching defs, defs get killed by other defs. With upwards @@ -1742,7 +1612,7 @@ df_bb_ru_local_compute (df, bb) rtx insn; - for (insn = bb->end; insn && insn != PREV_INSN (bb->head); + for (insn = BB_END (bb); insn && insn != PREV_INSN (BB_HEAD (bb)); insn = PREV_INSN (insn)) { unsigned int uid = INSN_UID (insn); @@ -1787,9 +1657,7 @@ df_bb_ru_local_compute (df, bb) /* Compute local reaching use (upward exposed use) info for each basic block within BLOCKS. */ static void -df_ru_local_compute (df, blocks) - struct df *df; - bitmap blocks; +df_ru_local_compute (struct df *df, bitmap blocks) { basic_block bb; @@ -1802,14 +1670,12 @@ df_ru_local_compute (df, blocks) /* Compute local live variable info for basic block BB. */ static void -df_bb_lr_local_compute (df, bb) - struct df *df; - basic_block bb; +df_bb_lr_local_compute (struct df *df, basic_block bb) { struct bb_info *bb_info = DF_BB_INFO (df, bb); rtx insn; - for (insn = bb->end; insn && insn != PREV_INSN (bb->head); + for (insn = BB_END (bb); insn && insn != PREV_INSN (BB_HEAD (bb)); insn = PREV_INSN (insn)) { unsigned int uid = INSN_UID (insn); @@ -1842,9 +1708,7 @@ df_bb_lr_local_compute (df, bb) /* Compute local live variable info for each basic block within BLOCKS. */ static void -df_lr_local_compute (df, blocks) - struct df *df; - bitmap blocks; +df_lr_local_compute (struct df *df, bitmap blocks) { basic_block bb; @@ -1858,10 +1722,7 @@ df_lr_local_compute (df, blocks) /* Compute register info: lifetime, bb, and number of defs and uses for basic block BB. */ static void -df_bb_reg_info_compute (df, bb, live) - struct df *df; - basic_block bb; - bitmap live; +df_bb_reg_info_compute (struct df *df, basic_block bb, bitmap live) { struct reg_info *reg_info = df->regs; struct bb_info *bb_info = DF_BB_INFO (df, bb); @@ -1869,7 +1730,7 @@ df_bb_reg_info_compute (df, bb, live) bitmap_copy (live, bb_info->lr_out); - for (insn = bb->end; insn && insn != PREV_INSN (bb->head); + for (insn = BB_END (bb); insn && insn != PREV_INSN (BB_HEAD (bb)); insn = PREV_INSN (insn)) { unsigned int uid = INSN_UID (insn); @@ -1910,9 +1771,7 @@ df_bb_reg_info_compute (df, bb, live) /* Compute register info: lifetime, bb, and number of defs and uses. */ static void -df_reg_info_compute (df, blocks) - struct df *df; - bitmap blocks; +df_reg_info_compute (struct df *df, bitmap blocks) { basic_block bb; bitmap live; @@ -1930,22 +1789,20 @@ df_reg_info_compute (df, blocks) /* Assign LUIDs for BB. */ static int -df_bb_luids_set (df, bb) - struct df *df; - basic_block bb; +df_bb_luids_set (struct df *df, basic_block bb) { rtx insn; int luid = 0; /* The LUIDs are monotonically increasing for each basic block. */ - for (insn = bb->head; ; insn = NEXT_INSN (insn)) + for (insn = BB_HEAD (bb); ; insn = NEXT_INSN (insn)) { if (INSN_P (insn)) DF_INSN_LUID (df, insn) = luid++; DF_INSN_LUID (df, insn) = luid; - if (insn == bb->end) + if (insn == BB_END (bb)) break; } return luid; @@ -1954,9 +1811,7 @@ df_bb_luids_set (df, bb) /* Assign LUIDs for each basic block within BLOCKS. */ static int -df_luids_set (df, blocks) - struct df *df; - bitmap blocks; +df_luids_set (struct df *df, bitmap blocks) { basic_block bb; int total = 0; @@ -1968,14 +1823,11 @@ df_luids_set (df, blocks) return total; } + /* Perform dataflow analysis using existing DF structure for blocks within BLOCKS. If BLOCKS is zero, use all basic blocks in the CFG. */ static void -df_analyse_1 (df, blocks, flags, update) - struct df *df; - bitmap blocks; - int flags; - int update; +df_analyse_1 (struct df *df, bitmap blocks, int flags, int update) { int aflags; int dflags; @@ -2077,7 +1929,7 @@ df_analyse_1 (df, blocks, flags, update) kill[bb->index] = DF_BB_INFO (df, bb)->rd_kill; } iterative_dataflow_bitmap (in, out, gen, kill, df->all_blocks, - FORWARD, UNION, df_rd_transfer_function, + DF_FORWARD, DF_UNION, df_rd_transfer_function, df->inverse_rc_map, NULL); free (in); free (out); @@ -2113,7 +1965,7 @@ df_analyse_1 (df, blocks, flags, update) kill[bb->index] = DF_BB_INFO (df, bb)->ru_kill; } iterative_dataflow_bitmap (in, out, gen, kill, df->all_blocks, - BACKWARD, UNION, df_ru_transfer_function, + DF_BACKWARD, DF_UNION, df_ru_transfer_function, df->inverse_rts_map, NULL); free (in); free (out); @@ -2152,7 +2004,7 @@ df_analyse_1 (df, blocks, flags, update) def[bb->index] = DF_BB_INFO (df, bb)->lr_def; } iterative_dataflow_bitmap (in, out, use, def, df->all_blocks, - BACKWARD, UNION, df_lr_transfer_function, + DF_BACKWARD, DF_UNION, df_lr_transfer_function, df->inverse_rts_map, NULL); free (in); free (out); @@ -2165,6 +2017,7 @@ df_analyse_1 (df, blocks, flags, update) { df_reg_info_compute (df, df->all_blocks); } + free (df->dfs_order); free (df->rc_order); free (df->rts_order); @@ -2176,7 +2029,7 @@ df_analyse_1 (df, blocks, flags, update) /* Initialize dataflow analysis. */ struct df * -df_init () +df_init (void) { struct df *df; @@ -2191,8 +2044,7 @@ df_init () /* Start queuing refs. */ static int -df_refs_queue (df) - struct df *df; +df_refs_queue (struct df *df) { df->def_id_save = df->def_id; df->use_id_save = df->use_id; @@ -2204,8 +2056,7 @@ df_refs_queue (df) /* Process queued refs. */ static int -df_refs_process (df) - struct df *df; +df_refs_process (struct df *df) { unsigned int i; @@ -2236,19 +2087,17 @@ df_refs_process (df) /* Update refs for basic block BB. */ static int -df_bb_refs_update (df, bb) - struct df *df; - basic_block bb; +df_bb_refs_update (struct df *df, basic_block bb) { rtx insn; int count = 0; - /* While we have to scan the chain of insns for this BB, we don't + /* While we have to scan the chain of insns for this BB, we do not need to allocate and queue a long chain of BB/INSN pairs. Using a bitmap for insns_modified saves memory and avoids queuing duplicates. */ - for (insn = bb->head; ; insn = NEXT_INSN (insn)) + for (insn = BB_HEAD (bb); ; insn = NEXT_INSN (insn)) { unsigned int uid; @@ -2264,7 +2113,7 @@ df_bb_refs_update (df, bb) count++; } - if (insn == bb->end) + if (insn == BB_END (bb)) break; } return count; @@ -2273,8 +2122,7 @@ df_bb_refs_update (df, bb) /* Process all the modified/deleted insns that were queued. */ static int -df_refs_update (df) - struct df *df; +df_refs_update (struct df *df) { basic_block bb; int count = 0; @@ -2297,9 +2145,7 @@ df_refs_update (df) /* Return nonzero if any of the requested blocks in the bitmap BLOCKS have been modified. */ static int -df_modified_p (df, blocks) - struct df *df; - bitmap blocks; +df_modified_p (struct df *df, bitmap blocks) { int update = 0; basic_block bb; @@ -2319,14 +2165,11 @@ df_modified_p (df, blocks) } -/* Analyse dataflow info for the basic blocks specified by the bitmap +/* Analyze dataflow info for the basic blocks specified by the bitmap BLOCKS, or for the whole CFG if BLOCKS is zero, or just for the modified blocks if BLOCKS is -1. */ int -df_analyse (df, blocks, flags) - struct df *df; - bitmap blocks; - int flags; +df_analyse (struct df *df, bitmap blocks, int flags) { int update; @@ -2369,8 +2212,7 @@ df_analyse (df, blocks, flags) /* Free all the dataflow info and the DF structure. */ void -df_finish (df) - struct df *df; +df_finish (struct df *df) { df_free (df); free (df); @@ -2379,10 +2221,7 @@ df_finish (df) /* Unlink INSN from its reference information. */ static void -df_insn_refs_unlink (df, bb, insn) - struct df *df; - basic_block bb ATTRIBUTE_UNUSED; - rtx insn; +df_insn_refs_unlink (struct df *df, basic_block bb ATTRIBUTE_UNUSED, rtx insn) { struct df_link *link; unsigned int uid; @@ -2405,21 +2244,19 @@ df_insn_refs_unlink (df, bb, insn) #if 0 /* Unlink all the insns within BB from their reference information. */ static void -df_bb_refs_unlink (df, bb) - struct df *df; - basic_block bb; +df_bb_refs_unlink (struct df *df, basic_block bb) { rtx insn; /* Scan the block an insn at a time from beginning to end. */ - for (insn = bb->head; ; insn = NEXT_INSN (insn)) + for (insn = BB_HEAD (bb); ; insn = NEXT_INSN (insn)) { if (INSN_P (insn)) { /* Unlink refs for INSN. */ df_insn_refs_unlink (df, bb, insn); } - if (insn == bb->end) + if (insn == BB_END (bb)) break; } } @@ -2428,9 +2265,7 @@ df_bb_refs_unlink (df, bb) /* Unlink all the refs in the basic blocks specified by BLOCKS. Not currently used. */ static void -df_refs_unlink (df, blocks) - struct df *df; - bitmap blocks; +df_refs_unlink (struct df *df, bitmap blocks) { basic_block bb; @@ -2454,16 +2289,13 @@ df_refs_unlink (df, blocks) /* Delete INSN and all its reference information. */ rtx -df_insn_delete (df, bb, insn) - struct df *df; - basic_block bb ATTRIBUTE_UNUSED; - rtx insn; +df_insn_delete (struct df *df, basic_block bb ATTRIBUTE_UNUSED, rtx insn) { /* If the insn is a jump, we should perhaps call delete_insn to handle the JUMP_LABEL? */ /* We should not be deleting the NOTE_INSN_BASIC_BLOCK or label. */ - if (insn == bb->head) + if (insn == BB_HEAD (bb)) abort (); /* Delete the insn. */ @@ -2480,10 +2312,7 @@ df_insn_delete (df, bb, insn) harm calling this function if the insn wasn't changed; it will just slow down the rescanning of refs. */ void -df_insn_modify (df, bb, insn) - struct df *df; - basic_block bb; - rtx insn; +df_insn_modify (struct df *df, basic_block bb, rtx insn) { unsigned int uid; @@ -2502,7 +2331,8 @@ df_insn_modify (df, bb, insn) } -typedef struct replace_args { +typedef struct replace_args +{ rtx match; rtx replacement; rtx insn; @@ -2515,9 +2345,7 @@ typedef struct replace_args { instruction currently being scanned and the MEM we are currently replacing. */ static int -df_rtx_mem_replace (px, data) - rtx *px; - void *data; +df_rtx_mem_replace (rtx *px, void *data) { replace_args *args = (replace_args *) data; rtx mem = *px; @@ -2553,12 +2381,7 @@ df_rtx_mem_replace (px, data) int -df_insn_mem_replace (df, bb, insn, mem, reg) - struct df *df; - basic_block bb; - rtx insn; - rtx mem; - rtx reg; +df_insn_mem_replace (struct df *df, basic_block bb, rtx insn, rtx mem, rtx reg) { replace_args args; @@ -2586,9 +2409,7 @@ df_insn_mem_replace (df, bb, insn, mem, reg) points to the rtx being scanned. DATA is actually a pointer to a structure of arguments. */ static int -df_rtx_reg_replace (px, data) - rtx *px; - void *data; +df_rtx_reg_replace (rtx *px, void *data) { rtx x = *px; replace_args *args = (replace_args *) data; @@ -2610,12 +2431,7 @@ df_rtx_reg_replace (px, data) BLOCKS of basic blocks with NEWREG. Also update the regs within REG_NOTES. */ void -df_refs_reg_replace (df, blocks, chain, oldreg, newreg) - struct df *df; - bitmap blocks; - struct df_link *chain; - rtx oldreg; - rtx newreg; +df_refs_reg_replace (struct df *df, bitmap blocks, struct df_link *chain, rtx oldreg, rtx newreg) { struct df_link *link; replace_args args; @@ -2663,11 +2479,7 @@ df_refs_reg_replace (df, blocks, chain, oldreg, newreg) OLDREG in the REG_NOTES but only for insns containing OLDREG. This routine expects the reg-use and reg-def chains to be valid. */ int -df_reg_replace (df, blocks, oldreg, newreg) - struct df *df; - bitmap blocks; - rtx oldreg; - rtx newreg; +df_reg_replace (struct df *df, bitmap blocks, rtx oldreg, rtx newreg) { unsigned int oldregno = REGNO (oldreg); @@ -2680,11 +2492,7 @@ df_reg_replace (df, blocks, oldreg, newreg) /* Try replacing the reg within REF with NEWREG. Do not modify def-use/use-def chains. */ int -df_ref_reg_replace (df, ref, oldreg, newreg) - struct df *df; - struct ref *ref; - rtx oldreg; - rtx newreg; +df_ref_reg_replace (struct df *df, struct ref *ref, rtx oldreg, rtx newreg) { /* Check that insn was deleted by being converted into a NOTE. If so ignore this insn. */ @@ -2703,12 +2511,7 @@ df_ref_reg_replace (df, ref, oldreg, newreg) struct ref* -df_bb_def_use_swap (df, bb, def_insn, use_insn, regno) - struct df * df; - basic_block bb; - rtx def_insn; - rtx use_insn; - unsigned int regno; +df_bb_def_use_swap (struct df *df, basic_block bb, rtx def_insn, rtx use_insn, unsigned int regno) { struct ref *def; struct ref *use; @@ -2752,11 +2555,7 @@ df_bb_def_use_swap (df, bb, def_insn, use_insn, regno) /* Record df between FIRST_INSN and LAST_INSN inclusive. All new insns must be processed by this routine. */ static void -df_insns_modify (df, bb, first_insn, last_insn) - struct df *df; - basic_block bb; - rtx first_insn; - rtx last_insn; +df_insns_modify (struct df *df, basic_block bb, rtx first_insn, rtx last_insn) { rtx insn; @@ -2787,17 +2586,13 @@ df_insns_modify (df, bb, first_insn, last_insn) /* Emit PATTERN before INSN within BB. */ rtx -df_pattern_emit_before (df, pattern, bb, insn) - struct df *df ATTRIBUTE_UNUSED; - rtx pattern; - basic_block bb; - rtx insn; +df_pattern_emit_before (struct df *df, rtx pattern, basic_block bb, rtx insn) { rtx ret_insn; rtx prev_insn = PREV_INSN (insn); /* We should not be inserting before the start of the block. */ - if (insn == bb->head) + if (insn == BB_HEAD (bb)) abort (); ret_insn = emit_insn_before (pattern, insn); if (ret_insn == insn) @@ -2810,11 +2605,7 @@ df_pattern_emit_before (df, pattern, bb, insn) /* Emit PATTERN after INSN within BB. */ rtx -df_pattern_emit_after (df, pattern, bb, insn) - struct df *df; - rtx pattern; - basic_block bb; - rtx insn; +df_pattern_emit_after (struct df *df, rtx pattern, basic_block bb, rtx insn) { rtx ret_insn; @@ -2829,11 +2620,7 @@ df_pattern_emit_after (df, pattern, bb, insn) /* Emit jump PATTERN after INSN within BB. */ rtx -df_jump_pattern_emit_after (df, pattern, bb, insn) - struct df *df; - rtx pattern; - basic_block bb; - rtx insn; +df_jump_pattern_emit_after (struct df *df, rtx pattern, basic_block bb, rtx insn) { rtx ret_insn; @@ -2852,12 +2639,7 @@ df_jump_pattern_emit_after (df, pattern, bb, insn) out of a loop where it has been proven that the def-use info will still be valid. */ rtx -df_insn_move_before (df, bb, insn, before_bb, before_insn) - struct df *df; - basic_block bb; - rtx insn; - basic_block before_bb; - rtx before_insn; +df_insn_move_before (struct df *df, basic_block bb, rtx insn, basic_block before_bb, rtx before_insn) { struct df_link *link; unsigned int uid; @@ -2887,11 +2669,8 @@ df_insn_move_before (df, bb, insn, before_bb, before_insn) int -df_insn_regno_def_p (df, bb, insn, regno) - struct df *df; - basic_block bb ATTRIBUTE_UNUSED; - rtx insn; - unsigned int regno; +df_insn_regno_def_p (struct df *df, basic_block bb ATTRIBUTE_UNUSED, + rtx insn, unsigned int regno) { unsigned int uid; struct df_link *link; @@ -2911,9 +2690,7 @@ df_insn_regno_def_p (df, bb, insn, regno) static int -df_def_dominates_all_uses_p (df, def) - struct df *df ATTRIBUTE_UNUSED; - struct ref *def; +df_def_dominates_all_uses_p (struct df *df ATTRIBUTE_UNUSED, struct ref *def) { struct df_link *du_link; @@ -2933,10 +2710,8 @@ df_def_dominates_all_uses_p (df, def) int -df_insn_dominates_all_uses_p (df, bb, insn) - struct df *df; - basic_block bb ATTRIBUTE_UNUSED; - rtx insn; +df_insn_dominates_all_uses_p (struct df *df, basic_block bb ATTRIBUTE_UNUSED, + rtx insn) { unsigned int uid; struct df_link *link; @@ -2958,10 +2733,8 @@ df_insn_dominates_all_uses_p (df, bb, insn) /* Return nonzero if all DF dominates all the uses within the bitmap BLOCKS. */ static int -df_def_dominates_uses_p (df, def, blocks) - struct df *df ATTRIBUTE_UNUSED; - struct ref *def; - bitmap blocks; +df_def_dominates_uses_p (struct df *df ATTRIBUTE_UNUSED, struct ref *def, + bitmap blocks) { struct df_link *du_link; @@ -2989,11 +2762,8 @@ df_def_dominates_uses_p (df, def, blocks) /* Return nonzero if all the defs of INSN within BB dominates all the corresponding uses. */ int -df_insn_dominates_uses_p (df, bb, insn, blocks) - struct df *df; - basic_block bb ATTRIBUTE_UNUSED; - rtx insn; - bitmap blocks; +df_insn_dominates_uses_p (struct df *df, basic_block bb ATTRIBUTE_UNUSED, + rtx insn, bitmap blocks) { unsigned int uid; struct df_link *link; @@ -3016,9 +2786,7 @@ df_insn_dominates_uses_p (df, bb, insn, blocks) /* Return the basic block that REG referenced in or NULL if referenced in multiple basic blocks. */ basic_block -df_regno_bb (df, regno) - struct df *df; - unsigned int regno; +df_regno_bb (struct df *df, unsigned int regno) { struct df_link *defs = df->regs[regno].defs; struct df_link *uses = df->regs[regno].uses; @@ -3035,9 +2803,7 @@ df_regno_bb (df, regno) /* Return nonzero if REG used in multiple basic blocks. */ int -df_reg_global_p (df, reg) - struct df *df; - rtx reg; +df_reg_global_p (struct df *df, rtx reg) { return df_regno_bb (df, REGNO (reg)) != 0; } @@ -3045,9 +2811,7 @@ df_reg_global_p (df, reg) /* Return total lifetime (in insns) of REG. */ int -df_reg_lifetime (df, reg) - struct df *df; - rtx reg; +df_reg_lifetime (struct df *df, rtx reg) { return df->regs[REGNO (reg)].lifetime; } @@ -3055,10 +2819,7 @@ df_reg_lifetime (df, reg) /* Return nonzero if REG live at start of BB. */ int -df_bb_reg_live_start_p (df, bb, reg) - struct df *df ATTRIBUTE_UNUSED; - basic_block bb; - rtx reg; +df_bb_reg_live_start_p (struct df *df, basic_block bb, rtx reg) { struct bb_info *bb_info = DF_BB_INFO (df, bb); @@ -3073,10 +2834,7 @@ df_bb_reg_live_start_p (df, bb, reg) /* Return nonzero if REG live at end of BB. */ int -df_bb_reg_live_end_p (df, bb, reg) - struct df *df ATTRIBUTE_UNUSED; - basic_block bb; - rtx reg; +df_bb_reg_live_end_p (struct df *df, basic_block bb, rtx reg) { struct bb_info *bb_info = DF_BB_INFO (df, bb); @@ -3092,11 +2850,7 @@ df_bb_reg_live_end_p (df, bb, reg) /* Return -1 if life of REG1 before life of REG2, 1 if life of REG1 after life of REG2, or 0, if the lives overlap. */ int -df_bb_regs_lives_compare (df, bb, reg1, reg2) - struct df *df; - basic_block bb; - rtx reg1; - rtx reg2; +df_bb_regs_lives_compare (struct df *df, basic_block bb, rtx reg1, rtx reg2) { unsigned int regno1 = REGNO (reg1); unsigned int regno2 = REGNO (reg2); @@ -3131,10 +2885,7 @@ df_bb_regs_lives_compare (df, bb, reg1, reg2) /* Return last use of REGNO within BB. */ static struct ref * -df_bb_regno_last_use_find (df, bb, regno) - struct df * df; - basic_block bb ATTRIBUTE_UNUSED; - unsigned int regno; +df_bb_regno_last_use_find (struct df *df, basic_block bb, unsigned int regno) { struct df_link *link; @@ -3155,10 +2906,7 @@ df_bb_regno_last_use_find (df, bb, regno) /* Return first def of REGNO within BB. */ static struct ref * -df_bb_regno_first_def_find (df, bb, regno) - struct df * df; - basic_block bb ATTRIBUTE_UNUSED; - unsigned int regno; +df_bb_regno_first_def_find (struct df *df, basic_block bb, unsigned int regno) { struct df_link *link; @@ -3179,11 +2927,9 @@ df_bb_regno_first_def_find (df, bb, regno) /* Return first use of REGNO inside INSN within BB. */ static struct ref * -df_bb_insn_regno_last_use_find (df, bb, insn, regno) - struct df * df; - basic_block bb ATTRIBUTE_UNUSED; - rtx insn; - unsigned int regno; +df_bb_insn_regno_last_use_find (struct df *df, + basic_block bb ATTRIBUTE_UNUSED, rtx insn, + unsigned int regno) { unsigned int uid; struct df_link *link; @@ -3204,11 +2950,9 @@ df_bb_insn_regno_last_use_find (df, bb, insn, regno) /* Return first def of REGNO inside INSN within BB. */ static struct ref * -df_bb_insn_regno_first_def_find (df, bb, insn, regno) - struct df * df; - basic_block bb ATTRIBUTE_UNUSED; - rtx insn; - unsigned int regno; +df_bb_insn_regno_first_def_find (struct df *df, + basic_block bb ATTRIBUTE_UNUSED, rtx insn, + unsigned int regno) { unsigned int uid; struct df_link *link; @@ -3230,11 +2974,7 @@ df_bb_insn_regno_first_def_find (df, bb, insn, regno) /* Return insn using REG if the BB contains only a single use and def of REG. */ rtx -df_bb_single_def_use_insn_find (df, bb, insn, reg) - struct df * df; - basic_block bb; - rtx insn; - rtx reg; +df_bb_single_def_use_insn_find (struct df *df, basic_block bb, rtx insn, rtx reg) { struct ref *def; struct ref *use; @@ -3268,9 +3008,7 @@ df_bb_single_def_use_insn_find (df, bb, insn, reg) /* Dump a def-use or use-def chain for REF to FILE. */ static void -df_chain_dump (link, file) - struct df_link *link; - FILE *file; +df_chain_dump (struct df_link *link, FILE *file) { fprintf (file, "{ "); for (; link; link = link->next) @@ -3282,10 +3020,10 @@ df_chain_dump (link, file) fprintf (file, "}"); } + +/* Dump a chain of refs with the associated regno. */ static void -df_chain_dump_regno (link, file) - struct df_link *link; - FILE *file; +df_chain_dump_regno (struct df_link *link, FILE *file) { fprintf (file, "{ "); for (; link; link = link->next) @@ -3298,12 +3036,10 @@ df_chain_dump_regno (link, file) fprintf (file, "}"); } + /* Dump dataflow info. */ void -df_dump (df, flags, file) - struct df *df; - int flags; - FILE *file; +df_dump (struct df *df, int flags, FILE *file) { unsigned int j; basic_block bb; @@ -3474,10 +3210,7 @@ df_dump (df, flags, file) void -df_insn_debug (df, insn, file) - struct df *df; - rtx insn; - FILE *file; +df_insn_debug (struct df *df, rtx insn, FILE *file) { unsigned int uid; int bbi; @@ -3501,11 +3234,9 @@ df_insn_debug (df, insn, file) fprintf (file, "\n"); } + void -df_insn_debug_regno (df, insn, file) - struct df *df; - rtx insn; - FILE *file; +df_insn_debug_regno (struct df *df, rtx insn, FILE *file) { unsigned int uid; int bbi; @@ -3529,11 +3260,9 @@ df_insn_debug_regno (df, insn, file) fprintf (file, "\n"); } + static void -df_regno_debug (df, regno, file) - struct df *df; - unsigned int regno; - FILE *file; +df_regno_debug (struct df *df, unsigned int regno, FILE *file) { if (regno >= df->reg_size) return; @@ -3548,10 +3277,7 @@ df_regno_debug (df, regno, file) static void -df_ref_debug (df, ref, file) - struct df *df; - struct ref *ref; - FILE *file; +df_ref_debug (struct df *df, struct ref *ref, FILE *file) { fprintf (file, "%c%d ", DF_REF_REG_DEF_P (ref) ? 'd' : 'u', @@ -3564,11 +3290,11 @@ df_ref_debug (df, ref, file) df_chain_dump (DF_REF_CHAIN (ref), file); fprintf (file, "\n"); } - + +/* Functions for debugging from GDB. */ void -debug_df_insn (insn) - rtx insn; +debug_df_insn (rtx insn) { df_insn_debug (ddf, insn, stderr); debug_rtx (insn); @@ -3576,78 +3302,68 @@ debug_df_insn (insn) void -debug_df_reg (reg) - rtx reg; +debug_df_reg (rtx reg) { df_regno_debug (ddf, REGNO (reg), stderr); } void -debug_df_regno (regno) - unsigned int regno; +debug_df_regno (unsigned int regno) { df_regno_debug (ddf, regno, stderr); } void -debug_df_ref (ref) - struct ref *ref; +debug_df_ref (struct ref *ref) { df_ref_debug (ddf, ref, stderr); } void -debug_df_defno (defno) - unsigned int defno; +debug_df_defno (unsigned int defno) { df_ref_debug (ddf, ddf->defs[defno], stderr); } void -debug_df_useno (defno) - unsigned int defno; +debug_df_useno (unsigned int defno) { df_ref_debug (ddf, ddf->uses[defno], stderr); } void -debug_df_chain (link) - struct df_link *link; +debug_df_chain (struct df_link *link) { df_chain_dump (link, stderr); fputc ('\n', stderr); } + /* Hybrid search algorithm from "Implementation Techniques for Efficient Data-Flow Analysis of Large Programs". */ static void -hybrid_search_bitmap (block, in, out, gen, kill, dir, - conf_op, transfun, visited, pending, - data) - basic_block block; - bitmap *in, *out, *gen, *kill; - enum df_flow_dir dir; - enum df_confluence_op conf_op; - transfer_function_bitmap transfun; - sbitmap visited; - sbitmap pending; - void *data; +hybrid_search_bitmap (basic_block block, bitmap *in, bitmap *out, bitmap *gen, + bitmap *kill, enum df_flow_dir dir, + enum df_confluence_op conf_op, + transfer_function_bitmap transfun, sbitmap visited, + sbitmap pending, void *data) { int changed; int i = block->index; edge e; basic_block bb = block; + SET_BIT (visited, block->index); if (TEST_BIT (pending, block->index)) { - if (dir == FORWARD) + if (dir == DF_FORWARD) { - /* Calculate <conf_op> of predecessor_outs */ + /* Calculate <conf_op> of predecessor_outs. */ bitmap_zero (in[i]); for (e = bb->pred; e != 0; e = e->pred_next) { @@ -3655,10 +3371,10 @@ hybrid_search_bitmap (block, in, out, gen, kill, dir, continue; switch (conf_op) { - case UNION: + case DF_UNION: bitmap_a_or_b (in[i], in[i], out[e->src->index]); break; - case INTERSECTION: + case DF_INTERSECTION: bitmap_a_and_b (in[i], in[i], out[e->src->index]); break; } @@ -3666,7 +3382,7 @@ hybrid_search_bitmap (block, in, out, gen, kill, dir, } else { - /* Calculate <conf_op> of successor ins */ + /* Calculate <conf_op> of successor ins. */ bitmap_zero (out[i]); for (e = bb->succ; e != 0; e = e->succ_next) { @@ -3674,10 +3390,10 @@ hybrid_search_bitmap (block, in, out, gen, kill, dir, continue; switch (conf_op) { - case UNION: + case DF_UNION: bitmap_a_or_b (out[i], out[i], in[e->dest->index]); break; - case INTERSECTION: + case DF_INTERSECTION: bitmap_a_and_b (out[i], out[i], in[e->dest->index]); break; } @@ -3688,7 +3404,7 @@ hybrid_search_bitmap (block, in, out, gen, kill, dir, RESET_BIT (pending, i); if (changed) { - if (dir == FORWARD) + if (dir == DF_FORWARD) { for (e = bb->succ; e != 0; e = e->succ_next) { @@ -3708,7 +3424,7 @@ hybrid_search_bitmap (block, in, out, gen, kill, dir, } } } - if (dir == FORWARD) + if (dir == DF_FORWARD) { for (e = bb->succ; e != 0; e = e->succ_next) { @@ -3737,28 +3453,23 @@ hybrid_search_bitmap (block, in, out, gen, kill, dir, /* Hybrid search for sbitmaps, rather than bitmaps. */ static void -hybrid_search_sbitmap (block, in, out, gen, kill, dir, - conf_op, transfun, visited, pending, - data) - basic_block block; - sbitmap *in, *out, *gen, *kill; - enum df_flow_dir dir; - enum df_confluence_op conf_op; - transfer_function_sbitmap transfun; - sbitmap visited; - sbitmap pending; - void *data; +hybrid_search_sbitmap (basic_block block, sbitmap *in, sbitmap *out, + sbitmap *gen, sbitmap *kill, enum df_flow_dir dir, + enum df_confluence_op conf_op, + transfer_function_sbitmap transfun, sbitmap visited, + sbitmap pending, void *data) { int changed; int i = block->index; edge e; basic_block bb = block; + SET_BIT (visited, block->index); if (TEST_BIT (pending, block->index)) { - if (dir == FORWARD) + if (dir == DF_FORWARD) { - /* Calculate <conf_op> of predecessor_outs */ + /* Calculate <conf_op> of predecessor_outs. */ sbitmap_zero (in[i]); for (e = bb->pred; e != 0; e = e->pred_next) { @@ -3766,10 +3477,10 @@ hybrid_search_sbitmap (block, in, out, gen, kill, dir, continue; switch (conf_op) { - case UNION: + case DF_UNION: sbitmap_a_or_b (in[i], in[i], out[e->src->index]); break; - case INTERSECTION: + case DF_INTERSECTION: sbitmap_a_and_b (in[i], in[i], out[e->src->index]); break; } @@ -3777,7 +3488,7 @@ hybrid_search_sbitmap (block, in, out, gen, kill, dir, } else { - /* Calculate <conf_op> of successor ins */ + /* Calculate <conf_op> of successor ins. */ sbitmap_zero (out[i]); for (e = bb->succ; e != 0; e = e->succ_next) { @@ -3785,21 +3496,21 @@ hybrid_search_sbitmap (block, in, out, gen, kill, dir, continue; switch (conf_op) { - case UNION: + case DF_UNION: sbitmap_a_or_b (out[i], out[i], in[e->dest->index]); break; - case INTERSECTION: + case DF_INTERSECTION: sbitmap_a_and_b (out[i], out[i], in[e->dest->index]); break; } } } - /* Common part */ + /* Common part. */ (*transfun)(i, &changed, in[i], out[i], gen[i], kill[i], data); RESET_BIT (pending, i); if (changed) { - if (dir == FORWARD) + if (dir == DF_FORWARD) { for (e = bb->succ; e != 0; e = e->succ_next) { @@ -3819,7 +3530,7 @@ hybrid_search_sbitmap (block, in, out, gen, kill, dir, } } } - if (dir == FORWARD) + if (dir == DF_FORWARD) { for (e = bb->succ; e != 0; e = e->succ_next) { @@ -3846,8 +3557,6 @@ hybrid_search_sbitmap (block, in, out, gen, kill, dir, } - - /* gen = GEN set. kill = KILL set. in, out = Filled in by function. @@ -3869,34 +3578,34 @@ hybrid_search_sbitmap (block, in, out, gen, kill, dir, block number to rc_order (like df->inverse_rc_map). */ void -iterative_dataflow_sbitmap (in, out, gen, kill, blocks, - dir, conf_op, transfun, order, data) - sbitmap *in, *out, *gen, *kill; - bitmap blocks; - enum df_flow_dir dir; - enum df_confluence_op conf_op; - transfer_function_sbitmap transfun; - int *order; - void *data; +iterative_dataflow_sbitmap (sbitmap *in, sbitmap *out, sbitmap *gen, + sbitmap *kill, bitmap blocks, + enum df_flow_dir dir, + enum df_confluence_op conf_op, + transfer_function_sbitmap transfun, int *order, + void *data) { int i; fibheap_t worklist; basic_block bb; sbitmap visited, pending; + pending = sbitmap_alloc (last_basic_block); visited = sbitmap_alloc (last_basic_block); sbitmap_zero (pending); sbitmap_zero (visited); worklist = fibheap_new (); + EXECUTE_IF_SET_IN_BITMAP (blocks, 0, i, { fibheap_insert (worklist, order[i], (void *) (size_t) i); SET_BIT (pending, i); - if (dir == FORWARD) + if (dir == DF_FORWARD) sbitmap_copy (out[i], gen[i]); else sbitmap_copy (in[i], gen[i]); }); + while (sbitmap_first_set_bit (pending) != -1) { while (!fibheap_empty (worklist)) @@ -3907,6 +3616,7 @@ iterative_dataflow_sbitmap (in, out, gen, kill, blocks, hybrid_search_sbitmap (bb, in, out, gen, kill, dir, conf_op, transfun, visited, pending, data); } + if (sbitmap_first_set_bit (pending) != -1) { EXECUTE_IF_SET_IN_BITMAP (blocks, 0, i, @@ -3920,42 +3630,43 @@ iterative_dataflow_sbitmap (in, out, gen, kill, blocks, break; } } + sbitmap_free (pending); sbitmap_free (visited); fibheap_delete (worklist); } + /* Exactly the same as iterative_dataflow_sbitmap, except it works on - bitmaps instead */ + bitmaps instead. */ void -iterative_dataflow_bitmap (in, out, gen, kill, blocks, - dir, conf_op, transfun, order, data) - bitmap *in, *out, *gen, *kill; - bitmap blocks; - enum df_flow_dir dir; - enum df_confluence_op conf_op; - transfer_function_bitmap transfun; - int *order; - void *data; +iterative_dataflow_bitmap (bitmap *in, bitmap *out, bitmap *gen, bitmap *kill, + bitmap blocks, enum df_flow_dir dir, + enum df_confluence_op conf_op, + transfer_function_bitmap transfun, int *order, + void *data) { int i; fibheap_t worklist; basic_block bb; sbitmap visited, pending; + pending = sbitmap_alloc (last_basic_block); visited = sbitmap_alloc (last_basic_block); sbitmap_zero (pending); sbitmap_zero (visited); worklist = fibheap_new (); + EXECUTE_IF_SET_IN_BITMAP (blocks, 0, i, { fibheap_insert (worklist, order[i], (void *) (size_t) i); SET_BIT (pending, i); - if (dir == FORWARD) + if (dir == DF_FORWARD) bitmap_copy (out[i], gen[i]); else bitmap_copy (in[i], gen[i]); }); + while (sbitmap_first_set_bit (pending) != -1) { while (!fibheap_empty (worklist)) @@ -3966,6 +3677,7 @@ iterative_dataflow_bitmap (in, out, gen, kill, blocks, hybrid_search_bitmap (bb, in, out, gen, kill, dir, conf_op, transfun, visited, pending, data); } + if (sbitmap_first_set_bit (pending) != -1) { EXECUTE_IF_SET_IN_BITMAP (blocks, 0, i, |