00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "config.h"
00022 #include "system.h"
00023 #include "coretypes.h"
00024 #include "tm.h"
00025 #include "tree.h"
00026 #include "rtl.h"
00027 #include "tm_p.h"
00028 #include "hard-reg-set.h"
00029 #include "basic-block.h"
00030 #include "output.h"
00031 #include "diagnostic.h"
00032 #include "tree-flow.h"
00033 #include "tree-dump.h"
00034 #include "timevar.h"
00035 #include "cfgloop.h"
00036 #include "domwalk.h"
00037 #include "params.h"
00038 #include "tree-pass.h"
00039 #include "flags.h"
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 struct depend
00067 {
00068 tree stmt;
00069 struct depend *next;
00070 };
00071
00072
00073
00074 struct lim_aux_data
00075 {
00076 struct loop *max_loop;
00077
00078
00079 struct loop *tgt_loop;
00080
00081
00082 struct loop *always_executed_in;
00083
00084
00085
00086
00087 bool sm_done;
00088
00089
00090
00091 unsigned cost;
00092
00093
00094 struct depend *depends;
00095
00096
00097
00098
00099 };
00100
00101 #define LIM_DATA(STMT) (TREE_CODE (STMT) == PHI_NODE \
00102 ? NULL \
00103 : (struct lim_aux_data *) (stmt_ann (STMT)->common.aux))
00104
00105
00106
00107 struct mem_ref
00108 {
00109 tree *ref;
00110 tree stmt;
00111 struct mem_ref *next;
00112 };
00113
00114
00115 #define LIM_EXPENSIVE ((unsigned) PARAM_VALUE (PARAM_LIM_EXPENSIVE))
00116
00117
00118
00119 #define ALWAYS_EXECUTED_IN(BB) ((struct loop *) (BB)->aux)
00120
00121 static unsigned max_stmt_uid;
00122
00123
00124
00125
00126
00127 static unsigned
00128 get_stmt_uid (tree stmt)
00129 {
00130 if (TREE_CODE (stmt) == PHI_NODE)
00131 return SSA_NAME_VERSION (PHI_RESULT (stmt)) + max_stmt_uid;
00132
00133 return stmt_ann (stmt)->uid;
00134 }
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150 bool
00151 for_each_index (tree *addr_p, bool (*cbck) (tree, tree *, void *), void *data)
00152 {
00153 tree *nxt, *idx;
00154
00155 for (; ; addr_p = nxt)
00156 {
00157 switch (TREE_CODE (*addr_p))
00158 {
00159 case SSA_NAME:
00160 return cbck (*addr_p, addr_p, data);
00161
00162 case MISALIGNED_INDIRECT_REF:
00163 case ALIGN_INDIRECT_REF:
00164 case INDIRECT_REF:
00165 nxt = &TREE_OPERAND (*addr_p, 0);
00166 return cbck (*addr_p, nxt, data);
00167
00168 case BIT_FIELD_REF:
00169 case VIEW_CONVERT_EXPR:
00170 case ARRAY_RANGE_REF:
00171 case REALPART_EXPR:
00172 case IMAGPART_EXPR:
00173 nxt = &TREE_OPERAND (*addr_p, 0);
00174 break;
00175
00176 case COMPONENT_REF:
00177
00178
00179 idx = &TREE_OPERAND (*addr_p, 2);
00180 if (*idx
00181 && !cbck (*addr_p, idx, data))
00182 return false;
00183
00184 nxt = &TREE_OPERAND (*addr_p, 0);
00185 break;
00186
00187 case ARRAY_REF:
00188 nxt = &TREE_OPERAND (*addr_p, 0);
00189 if (!cbck (*addr_p, &TREE_OPERAND (*addr_p, 1), data))
00190 return false;
00191 break;
00192
00193 case VAR_DECL:
00194 case PARM_DECL:
00195 case STRING_CST:
00196 case RESULT_DECL:
00197 case VECTOR_CST:
00198 case COMPLEX_CST:
00199 case INTEGER_CST:
00200 case REAL_CST:
00201 return true;
00202
00203 default:
00204 gcc_unreachable ();
00205 }
00206 }
00207 }
00208
00209
00210
00211
00212
00213
00214
00215
00216 enum move_pos
00217 movement_possibility (tree stmt)
00218 {
00219 tree lhs, rhs;
00220
00221 if (flag_unswitch_loops
00222 && TREE_CODE (stmt) == COND_EXPR)
00223 {
00224
00225
00226 get_stmt_operands (stmt);
00227
00228 return MOVE_POSSIBLE;
00229 }
00230
00231 if (TREE_CODE (stmt) != MODIFY_EXPR)
00232 return MOVE_IMPOSSIBLE;
00233
00234 if (stmt_ends_bb_p (stmt))
00235 return MOVE_IMPOSSIBLE;
00236
00237 get_stmt_operands (stmt);
00238
00239 if (stmt_ann (stmt)->has_volatile_ops)
00240 return MOVE_IMPOSSIBLE;
00241
00242 lhs = TREE_OPERAND (stmt, 0);
00243 if (TREE_CODE (lhs) == SSA_NAME
00244 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
00245 return MOVE_IMPOSSIBLE;
00246
00247 rhs = TREE_OPERAND (stmt, 1);
00248
00249 if (TREE_SIDE_EFFECTS (rhs))
00250 return MOVE_IMPOSSIBLE;
00251
00252 if (TREE_CODE (lhs) != SSA_NAME
00253 || tree_could_trap_p (rhs))
00254 return MOVE_PRESERVE_EXECUTION;
00255
00256 if (get_call_expr_in (stmt))
00257 {
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276 return MOVE_PRESERVE_EXECUTION;
00277 }
00278 return MOVE_POSSIBLE;
00279 }
00280
00281
00282
00283
00284
00285
00286 static struct loop *
00287 outermost_invariant_loop (tree def, struct loop *loop)
00288 {
00289 tree def_stmt;
00290 basic_block def_bb;
00291 struct loop *max_loop;
00292
00293 if (TREE_CODE (def) != SSA_NAME)
00294 return superloop_at_depth (loop, 1);
00295
00296 def_stmt = SSA_NAME_DEF_STMT (def);
00297 def_bb = bb_for_stmt (def_stmt);
00298 if (!def_bb)
00299 return superloop_at_depth (loop, 1);
00300
00301 max_loop = find_common_loop (loop, def_bb->loop_father);
00302
00303 if (LIM_DATA (def_stmt) && LIM_DATA (def_stmt)->max_loop)
00304 max_loop = find_common_loop (max_loop,
00305 LIM_DATA (def_stmt)->max_loop->outer);
00306 if (max_loop == loop)
00307 return NULL;
00308 max_loop = superloop_at_depth (loop, max_loop->depth + 1);
00309
00310 return max_loop;
00311 }
00312
00313
00314
00315
00316 static struct loop *
00317 outermost_invariant_loop_expr (tree expr, struct loop *loop)
00318 {
00319 enum tree_code_class class = TREE_CODE_CLASS (TREE_CODE (expr));
00320 unsigned i, nops;
00321 struct loop *max_loop = superloop_at_depth (loop, 1), *aloop;
00322
00323 if (TREE_CODE (expr) == SSA_NAME
00324 || TREE_CODE (expr) == INTEGER_CST
00325 || is_gimple_min_invariant (expr))
00326 return outermost_invariant_loop (expr, loop);
00327
00328 if (class != tcc_unary
00329 && class != tcc_binary
00330 && class != tcc_expression
00331 && class != tcc_comparison)
00332 return NULL;
00333
00334 nops = TREE_CODE_LENGTH (TREE_CODE (expr));
00335 for (i = 0; i < nops; i++)
00336 {
00337 aloop = outermost_invariant_loop_expr (TREE_OPERAND (expr, i), loop);
00338 if (!aloop)
00339 return NULL;
00340
00341 if (flow_loop_nested_p (max_loop, aloop))
00342 max_loop = aloop;
00343 }
00344
00345 return max_loop;
00346 }
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360 static bool
00361 add_dependency (tree def, struct lim_aux_data *data, struct loop *loop,
00362 bool add_cost)
00363 {
00364 tree def_stmt = SSA_NAME_DEF_STMT (def);
00365 basic_block def_bb = bb_for_stmt (def_stmt);
00366 struct loop *max_loop;
00367 struct depend *dep;
00368
00369 if (!def_bb)
00370 return true;
00371
00372 max_loop = outermost_invariant_loop (def, loop);
00373 if (!max_loop)
00374 return false;
00375
00376 if (flow_loop_nested_p (data->max_loop, max_loop))
00377 data->max_loop = max_loop;
00378
00379 if (!LIM_DATA (def_stmt))
00380 return true;
00381
00382 if (add_cost
00383
00384
00385
00386
00387 && def_bb->loop_father == loop)
00388 data->cost += LIM_DATA (def_stmt)->cost;
00389
00390 dep = xmalloc (sizeof (struct depend));
00391 dep->stmt = def_stmt;
00392 dep->next = data->depends;
00393 data->depends = dep;
00394
00395 return true;
00396 }
00397
00398
00399
00400
00401
00402 static unsigned
00403 stmt_cost (tree stmt)
00404 {
00405 tree lhs, rhs;
00406 unsigned cost = 1;
00407
00408
00409 if (TREE_CODE (stmt) == COND_EXPR)
00410 return LIM_EXPENSIVE;
00411
00412 lhs = TREE_OPERAND (stmt, 0);
00413 rhs = TREE_OPERAND (stmt, 1);
00414
00415
00416 if (stmt_references_memory_p (stmt))
00417 cost += 20;
00418
00419 switch (TREE_CODE (rhs))
00420 {
00421 case CALL_EXPR:
00422
00423
00424
00425
00426 rhs = get_callee_fndecl (rhs);
00427 if (DECL_BUILT_IN_CLASS (rhs) == BUILT_IN_NORMAL
00428 && DECL_FUNCTION_CODE (rhs) == BUILT_IN_CONSTANT_P)
00429 return 0;
00430
00431 cost += 20;
00432 break;
00433
00434 case MULT_EXPR:
00435 case TRUNC_DIV_EXPR:
00436 case CEIL_DIV_EXPR:
00437 case FLOOR_DIV_EXPR:
00438 case ROUND_DIV_EXPR:
00439 case EXACT_DIV_EXPR:
00440 case CEIL_MOD_EXPR:
00441 case FLOOR_MOD_EXPR:
00442 case ROUND_MOD_EXPR:
00443 case TRUNC_MOD_EXPR:
00444
00445 cost += 20;
00446 break;
00447
00448 default:
00449 break;
00450 }
00451
00452 return cost;
00453 }
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465 static bool
00466 determine_max_movement (tree stmt, bool must_preserve_exec)
00467 {
00468 basic_block bb = bb_for_stmt (stmt);
00469 struct loop *loop = bb->loop_father;
00470 struct loop *level;
00471 struct lim_aux_data *lim_data = LIM_DATA (stmt);
00472 tree val;
00473 ssa_op_iter iter;
00474
00475 if (must_preserve_exec)
00476 level = ALWAYS_EXECUTED_IN (bb);
00477 else
00478 level = superloop_at_depth (loop, 1);
00479 lim_data->max_loop = level;
00480
00481 FOR_EACH_SSA_TREE_OPERAND (val, stmt, iter, SSA_OP_USE)
00482 if (!add_dependency (val, lim_data, loop, true))
00483 return false;
00484
00485 FOR_EACH_SSA_TREE_OPERAND (val, stmt, iter, SSA_OP_VIRTUAL_USES | SSA_OP_VIRTUAL_KILLS)
00486 if (!add_dependency (val, lim_data, loop, false))
00487 return false;
00488
00489 lim_data->cost += stmt_cost (stmt);
00490
00491 return true;
00492 }
00493
00494
00495
00496
00497
00498
00499 static void
00500 set_level (tree stmt, struct loop *orig_loop, struct loop *level)
00501 {
00502 struct loop *stmt_loop = bb_for_stmt (stmt)->loop_father;
00503 struct depend *dep;
00504
00505 stmt_loop = find_common_loop (orig_loop, stmt_loop);
00506 if (LIM_DATA (stmt) && LIM_DATA (stmt)->tgt_loop)
00507 stmt_loop = find_common_loop (stmt_loop,
00508 LIM_DATA (stmt)->tgt_loop->outer);
00509 if (flow_loop_nested_p (stmt_loop, level))
00510 return;
00511
00512 gcc_assert (LIM_DATA (stmt));
00513 gcc_assert (level == LIM_DATA (stmt)->max_loop
00514 || flow_loop_nested_p (LIM_DATA (stmt)->max_loop, level));
00515
00516 LIM_DATA (stmt)->tgt_loop = level;
00517 for (dep = LIM_DATA (stmt)->depends; dep; dep = dep->next)
00518 set_level (dep->stmt, orig_loop, level);
00519 }
00520
00521
00522
00523
00524
00525 static void
00526 set_profitable_level (tree stmt)
00527 {
00528 set_level (stmt, bb_for_stmt (stmt)->loop_father, LIM_DATA (stmt)->max_loop);
00529 }
00530
00531
00532
00533 static bool
00534 nonpure_call_p (tree stmt)
00535 {
00536 tree call = get_call_expr_in (stmt);
00537
00538 if (!call)
00539 return false;
00540
00541 return TREE_SIDE_EFFECTS (call) != 0;
00542 }
00543
00544
00545
00546 static void
00547 free_lim_aux_data (struct lim_aux_data *data)
00548 {
00549 struct depend *dep, *next;
00550
00551 for (dep = data->depends; dep; dep = next)
00552 {
00553 next = dep->next;
00554 free (dep);
00555 }
00556 free (data);
00557 }
00558
00559
00560
00561
00562
00563 static void
00564 determine_invariantness_stmt (struct dom_walk_data *dw_data ATTRIBUTE_UNUSED,
00565 basic_block bb)
00566 {
00567 enum move_pos pos;
00568 block_stmt_iterator bsi;
00569 tree stmt;
00570 bool maybe_never = ALWAYS_EXECUTED_IN (bb) == NULL;
00571 struct loop *outermost = ALWAYS_EXECUTED_IN (bb);
00572
00573 if (!bb->loop_father->outer)
00574 return;
00575
00576 if (dump_file && (dump_flags & TDF_DETAILS))
00577 fprintf (dump_file, "Basic block %d (loop %d -- depth %d):\n\n",
00578 bb->index, bb->loop_father->num, bb->loop_father->depth);
00579
00580 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
00581 {
00582 stmt = bsi_stmt (bsi);
00583
00584 pos = movement_possibility (stmt);
00585 if (pos == MOVE_IMPOSSIBLE)
00586 {
00587 if (nonpure_call_p (stmt))
00588 {
00589 maybe_never = true;
00590 outermost = NULL;
00591 }
00592 continue;
00593 }
00594
00595 stmt_ann (stmt)->common.aux = xcalloc (1, sizeof (struct lim_aux_data));
00596 LIM_DATA (stmt)->always_executed_in = outermost;
00597
00598 if (maybe_never && pos == MOVE_PRESERVE_EXECUTION)
00599 continue;
00600
00601 if (!determine_max_movement (stmt, pos == MOVE_PRESERVE_EXECUTION))
00602 {
00603 LIM_DATA (stmt)->max_loop = NULL;
00604 continue;
00605 }
00606
00607 if (dump_file && (dump_flags & TDF_DETAILS))
00608 {
00609 print_generic_stmt_indented (dump_file, stmt, 0, 2);
00610 fprintf (dump_file, " invariant up to level %d, cost %d.\n\n",
00611 LIM_DATA (stmt)->max_loop->depth,
00612 LIM_DATA (stmt)->cost);
00613 }
00614
00615 if (LIM_DATA (stmt)->cost >= LIM_EXPENSIVE)
00616 set_profitable_level (stmt);
00617 }
00618 }
00619
00620
00621
00622
00623
00624
00625 static void
00626 determine_invariantness (void)
00627 {
00628 struct dom_walk_data walk_data;
00629
00630 memset (&walk_data, 0, sizeof (struct dom_walk_data));
00631 walk_data.before_dom_children_before_stmts = determine_invariantness_stmt;
00632
00633 init_walk_dominator_tree (&walk_data);
00634 walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
00635 fini_walk_dominator_tree (&walk_data);
00636 }
00637
00638
00639
00640 void
00641 loop_commit_inserts (void)
00642 {
00643 unsigned old_last_basic_block, i;
00644 basic_block bb;
00645
00646 old_last_basic_block = last_basic_block;
00647 bsi_commit_edge_inserts ();
00648 for (i = old_last_basic_block; i < (unsigned) last_basic_block; i++)
00649 {
00650 bb = BASIC_BLOCK (i);
00651 add_bb_to_loop (bb,
00652 find_common_loop (EDGE_SUCC (bb, 0)->dest->loop_father,
00653 EDGE_PRED (bb, 0)->src->loop_father));
00654 }
00655 }
00656
00657
00658
00659
00660
00661 static void
00662 move_computations_stmt (struct dom_walk_data *dw_data ATTRIBUTE_UNUSED,
00663 basic_block bb)
00664 {
00665 struct loop *level;
00666 block_stmt_iterator bsi;
00667 tree stmt;
00668 unsigned cost = 0;
00669
00670 if (!bb->loop_father->outer)
00671 return;
00672
00673 for (bsi = bsi_start (bb); !bsi_end_p (bsi); )
00674 {
00675 stmt = bsi_stmt (bsi);
00676
00677 if (!LIM_DATA (stmt))
00678 {
00679 bsi_next (&bsi);
00680 continue;
00681 }
00682
00683 cost = LIM_DATA (stmt)->cost;
00684 level = LIM_DATA (stmt)->tgt_loop;
00685 free_lim_aux_data (LIM_DATA (stmt));
00686 stmt_ann (stmt)->common.aux = NULL;
00687
00688 if (!level)
00689 {
00690 bsi_next (&bsi);
00691 continue;
00692 }
00693
00694
00695
00696 if (TREE_CODE (stmt) == COND_EXPR)
00697 continue;
00698
00699 if (dump_file && (dump_flags & TDF_DETAILS))
00700 {
00701 fprintf (dump_file, "Moving statement\n");
00702 print_generic_stmt (dump_file, stmt, 0);
00703 fprintf (dump_file, "(cost %u) out of loop %d.\n\n",
00704 cost, level->num);
00705 }
00706 bsi_insert_on_edge (loop_preheader_edge (level), stmt);
00707 bsi_remove (&bsi);
00708 }
00709 }
00710
00711
00712
00713
00714 static void
00715 move_computations (void)
00716 {
00717 struct dom_walk_data walk_data;
00718
00719 memset (&walk_data, 0, sizeof (struct dom_walk_data));
00720 walk_data.before_dom_children_before_stmts = move_computations_stmt;
00721
00722 init_walk_dominator_tree (&walk_data);
00723 walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
00724 fini_walk_dominator_tree (&walk_data);
00725
00726 loop_commit_inserts ();
00727 rewrite_into_ssa (false);
00728 if (!bitmap_empty_p (vars_to_rename))
00729 {
00730
00731
00732
00733 rewrite_into_loop_closed_ssa ();
00734 }
00735 bitmap_clear (vars_to_rename);
00736 }
00737
00738
00739
00740
00741 static bool
00742 may_move_till (tree ref, tree *index, void *data)
00743 {
00744 struct loop *loop = data, *max_loop;
00745
00746
00747
00748 if (TREE_CODE (ref) == ARRAY_REF)
00749 {
00750 tree step = array_ref_element_size (ref);
00751 tree lbound = array_ref_low_bound (ref);
00752
00753 max_loop = outermost_invariant_loop_expr (step, loop);
00754 if (!max_loop)
00755 return false;
00756
00757 max_loop = outermost_invariant_loop_expr (lbound, loop);
00758 if (!max_loop)
00759 return false;
00760 }
00761
00762 max_loop = outermost_invariant_loop (*index, loop);
00763 if (!max_loop)
00764 return false;
00765
00766 return true;
00767 }
00768
00769
00770
00771
00772 static void
00773 force_move_till_expr (tree expr, struct loop *orig_loop, struct loop *loop)
00774 {
00775 enum tree_code_class class = TREE_CODE_CLASS (TREE_CODE (expr));
00776 unsigned i, nops;
00777
00778 if (TREE_CODE (expr) == SSA_NAME)
00779 {
00780 tree stmt = SSA_NAME_DEF_STMT (expr);
00781 if (IS_EMPTY_STMT (stmt))
00782 return;
00783
00784 set_level (stmt, orig_loop, loop);
00785 return;
00786 }
00787
00788 if (class != tcc_unary
00789 && class != tcc_binary
00790 && class != tcc_expression
00791 && class != tcc_comparison)
00792 return;
00793
00794 nops = TREE_CODE_LENGTH (TREE_CODE (expr));
00795 for (i = 0; i < nops; i++)
00796 force_move_till_expr (TREE_OPERAND (expr, i), orig_loop, loop);
00797 }
00798
00799
00800
00801
00802
00803 struct fmt_data
00804 {
00805 struct loop *loop;
00806 struct loop *orig_loop;
00807 };
00808
00809 static bool
00810 force_move_till (tree ref, tree *index, void *data)
00811 {
00812 tree stmt;
00813 struct fmt_data *fmt_data = data;
00814
00815 if (TREE_CODE (ref) == ARRAY_REF)
00816 {
00817 tree step = array_ref_element_size (ref);
00818 tree lbound = array_ref_low_bound (ref);
00819
00820 force_move_till_expr (step, fmt_data->orig_loop, fmt_data->loop);
00821 force_move_till_expr (lbound, fmt_data->orig_loop, fmt_data->loop);
00822 }
00823
00824 if (TREE_CODE (*index) != SSA_NAME)
00825 return true;
00826
00827 stmt = SSA_NAME_DEF_STMT (*index);
00828 if (IS_EMPTY_STMT (stmt))
00829 return true;
00830
00831 set_level (stmt, fmt_data->orig_loop, fmt_data->loop);
00832
00833 return true;
00834 }
00835
00836
00837
00838
00839 static void
00840 record_mem_ref (struct mem_ref **mem_refs, tree stmt, tree *ref)
00841 {
00842 struct mem_ref *aref = xmalloc (sizeof (struct mem_ref));
00843
00844 aref->stmt = stmt;
00845 aref->ref = ref;
00846
00847 aref->next = *mem_refs;
00848 *mem_refs = aref;
00849 }
00850
00851
00852
00853 static void
00854 free_mem_refs (struct mem_ref *mem_refs)
00855 {
00856 struct mem_ref *act;
00857
00858 while (mem_refs)
00859 {
00860 act = mem_refs;
00861 mem_refs = mem_refs->next;
00862 free (act);
00863 }
00864 }
00865
00866
00867
00868
00869
00870 static void
00871 maybe_queue_var (tree var, struct loop *loop,
00872 sbitmap seen, tree *queue, unsigned *in_queue)
00873 {
00874 tree stmt = SSA_NAME_DEF_STMT (var);
00875 basic_block def_bb = bb_for_stmt (stmt);
00876
00877 if (!def_bb
00878 || !flow_bb_inside_loop_p (loop, def_bb)
00879 || TEST_BIT (seen, get_stmt_uid (stmt)))
00880 return;
00881
00882 SET_BIT (seen, get_stmt_uid (stmt));
00883 queue[(*in_queue)++] = stmt;
00884 }
00885
00886
00887
00888
00889
00890
00891 struct sra_data
00892 {
00893 struct mem_ref **mem_refs;
00894 tree common_ref;
00895 tree stmt;
00896 };
00897
00898 static bool
00899 fem_single_reachable_address (tree *op, void *data)
00900 {
00901 struct sra_data *sra_data = data;
00902
00903 if (sra_data->common_ref
00904 && !operand_equal_p (*op, sra_data->common_ref, 0))
00905 return false;
00906 sra_data->common_ref = *op;
00907
00908 record_mem_ref (sra_data->mem_refs, sra_data->stmt, op);
00909 return true;
00910 }
00911
00912
00913
00914
00915
00916
00917 static bool
00918 for_each_memref (tree stmt, bool (*callback)(tree *, void *), void *data)
00919 {
00920 tree *op;
00921
00922 if (TREE_CODE (stmt) == RETURN_EXPR)
00923 stmt = TREE_OPERAND (stmt, 1);
00924
00925 if (TREE_CODE (stmt) == MODIFY_EXPR)
00926 {
00927 op = &TREE_OPERAND (stmt, 0);
00928 if (TREE_CODE (*op) != SSA_NAME
00929 && !callback (op, data))
00930 return false;
00931
00932 op = &TREE_OPERAND (stmt, 1);
00933 if (TREE_CODE (*op) != SSA_NAME
00934 && is_gimple_lvalue (*op)
00935 && !callback (op, data))
00936 return false;
00937
00938 stmt = TREE_OPERAND (stmt, 1);
00939 }
00940
00941 if (TREE_CODE (stmt) == WITH_SIZE_EXPR)
00942 stmt = TREE_OPERAND (stmt, 0);
00943
00944 if (TREE_CODE (stmt) == CALL_EXPR)
00945 {
00946 tree args;
00947
00948 for (args = TREE_OPERAND (stmt, 1); args; args = TREE_CHAIN (args))
00949 {
00950 op = &TREE_VALUE (args);
00951
00952 if (TREE_CODE (*op) != SSA_NAME
00953 && is_gimple_lvalue (*op)
00954 && !callback (op, data))
00955 return false;
00956 }
00957 }
00958
00959 return true;
00960 }
00961
00962
00963
00964
00965
00966
00967
00968
00969 static tree
00970 single_reachable_address (struct loop *loop, tree stmt,
00971 struct mem_ref **mem_refs,
00972 bool *seen_call_stmt)
00973 {
00974 unsigned max_uid = max_stmt_uid + num_ssa_names;
00975 tree *queue = xmalloc (sizeof (tree) * max_uid);
00976 sbitmap seen = sbitmap_alloc (max_uid);
00977 unsigned in_queue = 1;
00978 dataflow_t df;
00979 unsigned i, n;
00980 struct sra_data sra_data;
00981 tree call;
00982 tree val;
00983 ssa_op_iter iter;
00984
00985 sbitmap_zero (seen);
00986
00987 *mem_refs = NULL;
00988 sra_data.mem_refs = mem_refs;
00989 sra_data.common_ref = NULL_TREE;
00990
00991 queue[0] = stmt;
00992 SET_BIT (seen, get_stmt_uid (stmt));
00993 *seen_call_stmt = false;
00994
00995 while (in_queue)
00996 {
00997 stmt = queue[--in_queue];
00998 sra_data.stmt = stmt;
00999
01000 if (LIM_DATA (stmt)
01001 && LIM_DATA (stmt)->sm_done)
01002 goto fail;
01003
01004 switch (TREE_CODE (stmt))
01005 {
01006 case MODIFY_EXPR:
01007 case CALL_EXPR:
01008 case RETURN_EXPR:
01009 if (!for_each_memref (stmt, fem_single_reachable_address,
01010 &sra_data))
01011 goto fail;
01012
01013
01014
01015
01016
01017 call = get_call_expr_in (stmt);
01018 if (call
01019 && !(call_expr_flags (call) & ECF_CONST))
01020 *seen_call_stmt = true;
01021
01022
01023
01024 FOR_EACH_SSA_TREE_OPERAND (val, stmt, iter, SSA_OP_VIRTUAL_USES)
01025 maybe_queue_var (val, loop, seen, queue, &in_queue);
01026
01027 break;
01028
01029 case PHI_NODE:
01030 for (i = 0; i < (unsigned) PHI_NUM_ARGS (stmt); i++)
01031 if (TREE_CODE (PHI_ARG_DEF (stmt, i)) == SSA_NAME)
01032 maybe_queue_var (PHI_ARG_DEF (stmt, i), loop,
01033 seen, queue, &in_queue);
01034 break;
01035
01036 default:
01037 goto fail;
01038 }
01039
01040
01041 df = get_immediate_uses (stmt);
01042 n = num_immediate_uses (df);
01043
01044 for (i = 0; i < n; i++)
01045 {
01046 stmt = immediate_use (df, i);
01047
01048 if (!flow_bb_inside_loop_p (loop, bb_for_stmt (stmt)))
01049 continue;
01050
01051 if (TEST_BIT (seen, get_stmt_uid (stmt)))
01052 continue;
01053 SET_BIT (seen, get_stmt_uid (stmt));
01054
01055 queue[in_queue++] = stmt;
01056 }
01057 }
01058
01059 free (queue);
01060 sbitmap_free (seen);
01061
01062 return sra_data.common_ref;
01063
01064 fail:
01065 free_mem_refs (*mem_refs);
01066 *mem_refs = NULL;
01067 free (queue);
01068 sbitmap_free (seen);
01069
01070 return NULL;
01071 }
01072
01073
01074
01075 static void
01076 rewrite_mem_refs (tree tmp_var, struct mem_ref *mem_refs)
01077 {
01078 tree var;
01079 ssa_op_iter iter;
01080
01081 for (; mem_refs; mem_refs = mem_refs->next)
01082 {
01083 FOR_EACH_SSA_TREE_OPERAND (var, mem_refs->stmt, iter, SSA_OP_ALL_VIRTUALS)
01084 {
01085 var = SSA_NAME_VAR (var);
01086 bitmap_set_bit (vars_to_rename, var_ann (var)->uid);
01087 }
01088
01089 *mem_refs->ref = tmp_var;
01090 modify_stmt (mem_refs->stmt);
01091 }
01092 }
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102 static void
01103 schedule_sm (struct loop *loop, edge *exits, unsigned n_exits, tree ref,
01104 struct mem_ref *mem_refs)
01105 {
01106 struct mem_ref *aref;
01107 tree tmp_var;
01108 unsigned i;
01109 tree load, store;
01110 struct fmt_data fmt_data;
01111
01112 if (dump_file && (dump_flags & TDF_DETAILS))
01113 {
01114 fprintf (dump_file, "Executing store motion of ");
01115 print_generic_expr (dump_file, ref, 0);
01116 fprintf (dump_file, " from loop %d\n", loop->num);
01117 }
01118
01119 tmp_var = make_rename_temp (TREE_TYPE (ref), "lsm_tmp");
01120
01121 fmt_data.loop = loop;
01122 fmt_data.orig_loop = loop;
01123 for_each_index (&ref, force_move_till, &fmt_data);
01124
01125 rewrite_mem_refs (tmp_var, mem_refs);
01126 for (aref = mem_refs; aref; aref = aref->next)
01127 if (LIM_DATA (aref->stmt))
01128 LIM_DATA (aref->stmt)->sm_done = true;
01129
01130
01131 load = build (MODIFY_EXPR, void_type_node, tmp_var, ref);
01132 get_stmt_ann (load)->common.aux = xcalloc (1, sizeof (struct lim_aux_data));
01133 LIM_DATA (load)->max_loop = loop;
01134 LIM_DATA (load)->tgt_loop = loop;
01135
01136
01137
01138 bsi_insert_on_edge (loop_latch_edge (loop), load);
01139
01140 for (i = 0; i < n_exits; i++)
01141 {
01142 store = build (MODIFY_EXPR, void_type_node,
01143 unshare_expr (ref), tmp_var);
01144 bsi_insert_on_edge (exits[i], store);
01145 }
01146 }
01147
01148
01149
01150 static bool
01151 is_call_clobbered_ref (tree ref)
01152 {
01153 tree base;
01154
01155 base = get_base_address (ref);
01156 if (!base)
01157 return true;
01158
01159 if (DECL_P (base))
01160 return is_call_clobbered (base);
01161
01162 if (INDIRECT_REF_P (base))
01163 {
01164
01165
01166 tree ptr = TREE_OPERAND (base, 0);
01167 struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr);
01168 tree nmt = (pi) ? pi->name_mem_tag : NULL_TREE;
01169 tree tmt = var_ann (SSA_NAME_VAR (ptr))->type_mem_tag;
01170
01171 if ((nmt && is_call_clobbered (nmt))
01172 || (tmt && is_call_clobbered (tmt)))
01173 return true;
01174
01175 return false;
01176 }
01177
01178 gcc_unreachable ();
01179 }
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189 static void
01190 determine_lsm_reg (struct loop *loop, edge *exits, unsigned n_exits, tree reg)
01191 {
01192 tree ref;
01193 struct mem_ref *mem_refs, *aref;
01194 struct loop *must_exec;
01195 bool sees_call;
01196
01197 if (is_gimple_reg (reg))
01198 return;
01199
01200 ref = single_reachable_address (loop, SSA_NAME_DEF_STMT (reg), &mem_refs,
01201 &sees_call);
01202 if (!ref)
01203 return;
01204
01205
01206 if (!is_gimple_reg_type (TREE_TYPE (ref))
01207 || TREE_THIS_VOLATILE (ref))
01208 goto fail;
01209
01210
01211 if (sees_call
01212 && is_call_clobbered_ref (ref))
01213 goto fail;
01214
01215 if (!for_each_index (&ref, may_move_till, loop))
01216 goto fail;
01217
01218 if (tree_could_trap_p (ref))
01219 {
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231 for (aref = mem_refs; aref; aref = aref->next)
01232 {
01233 if (!LIM_DATA (aref->stmt))
01234 continue;
01235
01236 must_exec = LIM_DATA (aref->stmt)->always_executed_in;
01237 if (!must_exec)
01238 continue;
01239
01240 if (must_exec == loop
01241 || flow_loop_nested_p (must_exec, loop))
01242 break;
01243 }
01244
01245 if (!aref)
01246 goto fail;
01247 }
01248
01249 schedule_sm (loop, exits, n_exits, ref, mem_refs);
01250
01251 fail: ;
01252 free_mem_refs (mem_refs);
01253 }
01254
01255
01256
01257
01258
01259 static bool
01260 loop_suitable_for_sm (struct loop *loop ATTRIBUTE_UNUSED, edge *exits,
01261 unsigned n_exits)
01262 {
01263 unsigned i;
01264
01265 for (i = 0; i < n_exits; i++)
01266 if (exits[i]->flags & EDGE_ABNORMAL)
01267 return false;
01268
01269 return true;
01270 }
01271
01272
01273
01274
01275 static void
01276 determine_lsm_loop (struct loop *loop)
01277 {
01278 tree phi;
01279 unsigned n_exits;
01280 edge *exits = get_loop_exit_edges (loop, &n_exits);
01281
01282 if (!loop_suitable_for_sm (loop, exits, n_exits))
01283 {
01284 free (exits);
01285 return;
01286 }
01287
01288 for (phi = phi_nodes (loop->header); phi; phi = PHI_CHAIN (phi))
01289 determine_lsm_reg (loop, exits, n_exits, PHI_RESULT (phi));
01290
01291 free (exits);
01292 }
01293
01294
01295
01296
01297 static void
01298 determine_lsm (struct loops *loops)
01299 {
01300 struct loop *loop;
01301 basic_block bb;
01302
01303 if (!loops->tree_root->inner)
01304 return;
01305
01306
01307
01308 max_stmt_uid = 0;
01309 FOR_EACH_BB (bb)
01310 {
01311 block_stmt_iterator bsi;
01312
01313 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
01314 stmt_ann (bsi_stmt (bsi))->uid = max_stmt_uid++;
01315 }
01316
01317 compute_immediate_uses (TDFA_USE_VOPS, NULL);
01318
01319
01320
01321
01322
01323 loop = loops->tree_root->inner;
01324 while (1)
01325 {
01326 determine_lsm_loop (loop);
01327
01328 if (loop->inner)
01329 {
01330 loop = loop->inner;
01331 continue;
01332 }
01333 while (!loop->next)
01334 {
01335 loop = loop->outer;
01336 if (loop == loops->tree_root)
01337 {
01338 free_df ();
01339 loop_commit_inserts ();
01340 return;
01341 }
01342 }
01343 loop = loop->next;
01344 }
01345 }
01346
01347
01348
01349
01350
01351
01352 static void
01353 fill_always_executed_in (struct loop *loop, sbitmap contains_call)
01354 {
01355 basic_block bb = NULL, *bbs, last = NULL;
01356 unsigned i;
01357 edge e;
01358 struct loop *inn_loop = loop;
01359
01360 if (!loop->header->aux)
01361 {
01362 bbs = get_loop_body_in_dom_order (loop);
01363
01364 for (i = 0; i < loop->num_nodes; i++)
01365 {
01366 edge_iterator ei;
01367 bb = bbs[i];
01368
01369 if (dominated_by_p (CDI_DOMINATORS, loop->latch, bb))
01370 last = bb;
01371
01372 if (TEST_BIT (contains_call, bb->index))
01373 break;
01374
01375 FOR_EACH_EDGE (e, ei, bb->succs)
01376 if (!flow_bb_inside_loop_p (loop, e->dest))
01377 break;
01378 if (e)
01379 break;
01380
01381
01382
01383 if (bb->flags & BB_IRREDUCIBLE_LOOP)
01384 break;
01385
01386 if (!flow_bb_inside_loop_p (inn_loop, bb))
01387 break;
01388
01389 if (bb->loop_father->header == bb)
01390 {
01391 if (!dominated_by_p (CDI_DOMINATORS, loop->latch, bb))
01392 break;
01393
01394
01395
01396 inn_loop = bb->loop_father;
01397 }
01398 }
01399
01400 while (1)
01401 {
01402 last->aux = loop;
01403 if (last == loop->header)
01404 break;
01405 last = get_immediate_dominator (CDI_DOMINATORS, last);
01406 }
01407
01408 free (bbs);
01409 }
01410
01411 for (loop = loop->inner; loop; loop = loop->next)
01412 fill_always_executed_in (loop, contains_call);
01413 }
01414
01415
01416
01417
01418 static void
01419 tree_ssa_lim_initialize (struct loops *loops)
01420 {
01421 sbitmap contains_call = sbitmap_alloc (last_basic_block);
01422 block_stmt_iterator bsi;
01423 struct loop *loop;
01424 basic_block bb;
01425
01426 sbitmap_zero (contains_call);
01427 FOR_EACH_BB (bb)
01428 {
01429 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
01430 {
01431 if (nonpure_call_p (bsi_stmt (bsi)))
01432 break;
01433 }
01434
01435 if (!bsi_end_p (bsi))
01436 SET_BIT (contains_call, bb->index);
01437 }
01438
01439 for (loop = loops->tree_root->inner; loop; loop = loop->next)
01440 fill_always_executed_in (loop, contains_call);
01441
01442 sbitmap_free (contains_call);
01443 }
01444
01445
01446
01447 static void
01448 tree_ssa_lim_finalize (void)
01449 {
01450 basic_block bb;
01451
01452 FOR_EACH_BB (bb)
01453 {
01454 bb->aux = NULL;
01455 }
01456 }
01457
01458
01459
01460
01461 void
01462 tree_ssa_lim (struct loops *loops)
01463 {
01464 tree_ssa_lim_initialize (loops);
01465
01466
01467
01468 determine_invariantness ();
01469
01470
01471
01472
01473 determine_lsm (loops);
01474
01475
01476 move_computations ();
01477
01478 tree_ssa_lim_finalize ();
01479 }