diff options
author | rakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-02-17 16:41:44 +0000 |
---|---|---|
committer | rakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-02-17 16:41:44 +0000 |
commit | f9cce2dcaaf2f076df995c819b410d07d8636c04 (patch) | |
tree | 871928dcce64f79c8e877a86be241c2ed02c9cf3 /gcc/cfgloop.h | |
parent | d42ddab15e6682e46bbeb8f4dcdaac64868329e9 (diff) | |
download | gcc-f9cce2dcaaf2f076df995c819b410d07d8636c04.tar.gz |
* loop-iv.c: New file.
* Makefile.in (loop-iv.o): New.
* basic_block.h (FOR_BB_INSNS, FOR_BB_INSNS_REVERSE): New macros.
* cfgloop.c (fill_sons_in_loop, get_loop_body_in_dom_order,
num_loop_branches): New functions.
* cfgloop.h (get_loop_body_in_dom_order, num_loop_branches,
iv_analysis_loop_init, iv_get_reaching_def, iv_analyse, get_iv_value,
find_simple_exit, iv_number_of_iterations, iv_analysis_done,
get_simple_loop_desc, free_simple_loop_desc): Declare.
(simple_loop_desc): New inline function.
(struct rtx_iv, struct niter_desc): New.
* cfgloopmanip.c (loopify): Specify semantics more precisely.
* expr.c (force_operand): Handle subregs of expressions created by
loop unroller.
* loop-init.c (loop_optimizer_init, loop_optimizer_finalize): Move
parts of the initialization to toplev.c
* loop-unroll.c (loop_exit_at_end_p): New.
(unroll_and_peel_loops): Call iv_analysis_done.
(decide_peel_once_rolling, decide_peel_completely,
decide_unroll_stupid, decide_unroll_constant_iterations,
decide_unroll_runtime_iterations, decide_peel_simple,
peel_loop_simple, unroll_loop_stupid, unroll_loop_constant_iterations,
unroll_loop_runtime_iterations): Use new simple loop analysis.
* loop-unswitch.c (compare_and_jump_seq): New.
(may_unswitch_on_p): Renamed to ...
(may_unswitch_on): Use new iv analysis.
(reversed_condition): Export.
(unswitch_single_loop, unswitch_loop): Use new iv analysis.
* predict.c (estimate_probability): Use new simple loop analysis.
* rtl.h (get_mode_bounds, reversed_condition,compare_and_jump_seq,
canon_condition, simplify_using_condition): Declare.
* stor-layout.c (get_mode_bounds): New.
* toplev.c (rest_of_handle_loop2): Some parts of
initialization/finalization moved here from loop-init.c.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@77951 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cfgloop.h')
-rw-r--r-- | gcc/cfgloop.h | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h index 4d8c67dd35d..58184b5e29b 100644 --- a/gcc/cfgloop.h +++ b/gcc/cfgloop.h @@ -278,7 +278,9 @@ extern int average_num_loop_insns (struct loop *); /* Loops & cfg manipulation. */ extern basic_block *get_loop_body (const struct loop *); +extern basic_block *get_loop_body_in_dom_order (const struct loop *); extern edge *get_loop_exit_edges (const struct loop *, unsigned *); +extern unsigned num_loop_branches (const struct loop *); extern edge loop_preheader_edge (const struct loop *); extern edge loop_latch_edge (const struct loop *); @@ -322,6 +324,114 @@ extern void unloop (struct loops *, struct loop *); extern bool remove_path (struct loops *, edge); extern edge split_loop_bb (basic_block, rtx); +/* Induction variable analysis. */ + +/* The description of induction variable. The things are a bit complicated + due to need to handle subregs and extends. The value of the object described + by it can be obtained as follows (all computations are done in extend_mode): + + Value in i-th iteration is + delta + mult * extend_{extend_mode} (subreg_{mode} (base + i * step)). + + If first_special is true, the value in the first iteration is + delta + mult * base + + If extend = NIL, first_special must be false, delta 0, mult 1 and value is + subreg_{mode} (base + i * step) + + The get_iv_value function can be used to obtain these expressions. + + ??? Add a third mode field that would specify the mode in that inner + computation is done, which would enable it to be different from the + outer one? */ + +struct rtx_iv +{ + /* Its base and step (mode of base and step is supposed to be extend_mode, + see the description above). */ + rtx base, step; + + /* The type of extend applied to it (SIGN_EXTEND, ZERO_EXTEND or NIL). */ + enum rtx_code extend; + + /* Operations applied in the extended mode. */ + rtx delta, mult; + + /* The mode it is extended to. */ + enum machine_mode extend_mode; + + /* The mode the variable iterates in. */ + enum machine_mode mode; + + /* Whether we have already filled the remaining fields. */ + unsigned analysed : 1; + + /* Whether the first iteration needs to be handled specially. */ + unsigned first_special : 1; +}; + +/* This should replace struct loop_desc. We keep this just so that we are + able to compare the results. */ + +struct niter_desc +{ + /* The edge out of the loop. */ + edge out_edge; + + /* The other edge leading from the condition. */ + edge in_edge; + + /* True if we are able to say anything about number of iterations of the + loop. */ + bool simple_p; + + /* True if the loop iterates the constant number of times. */ + bool const_iter; + + /* Number of iterations if constant. */ + unsigned HOST_WIDEST_INT niter; + + /* Upper bound on the number of iterations. */ + unsigned HOST_WIDEST_INT niter_max; + + /* Assumptions under that the rest of the information is valid. */ + rtx assumptions; + + /* Assumptions under that the loop ends before reaching the latch, + even if value of niter_expr says otherwise. */ + rtx noloop_assumptions; + + /* Condition under that the loop is infinite. */ + rtx infinite; + + /* Whether the comparison is signed. */ + bool signed_p; + + /* The mode in that niter_expr should be computed. */ + enum machine_mode mode; + + /* The number of iterations of the loop. */ + rtx niter_expr; +}; + +extern void iv_analysis_loop_init (struct loop *); +extern rtx iv_get_reaching_def (rtx, rtx); +extern bool iv_analyse (rtx, rtx, struct rtx_iv *); +extern rtx get_iv_value (struct rtx_iv *, rtx); +extern void find_simple_exit (struct loop *, struct niter_desc *); +extern void iv_number_of_iterations (struct loop *, rtx, rtx, + struct niter_desc *); +extern void iv_analysis_done (void); + +extern struct niter_desc *get_simple_loop_desc (struct loop *loop); +extern void free_simple_loop_desc (struct loop *loop); + +static inline struct niter_desc * +simple_loop_desc (struct loop *loop) +{ + return loop->aux; +} + /* Loop optimizer initialization. */ extern struct loops *loop_optimizer_init (FILE *); extern void loop_optimizer_finalize (struct loops *, FILE *); |