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 "flags.h"
00027 #include "function.h"
00028 #include "diagnostic.h"
00029 #include "tree-flow.h"
00030 #include "tree-inline.h"
00031 #include "tree-pass.h"
00032 #include "ggc.h"
00033 #include "timevar.h"
00034 #include "toplev.h"
00035 #include "langhooks.h"
00036 #include "ipa-reference.h"
00037
00038
00039
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
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082 #define opf_none 0
00083
00084
00085
00086 #define opf_is_def (1 << 0)
00087
00088
00089 #define opf_kill_def (1 << 1)
00090
00091
00092
00093
00094
00095
00096
00097 #define opf_no_vops (1 << 2)
00098
00099
00100
00101
00102 #define opf_non_specific (1 << 3)
00103
00104
00105 static VEC(tree,heap) *build_defs;
00106
00107
00108 static VEC(tree,heap) *build_uses;
00109
00110
00111 static VEC(tree,heap) *build_v_may_defs;
00112
00113
00114 static VEC(tree,heap) *build_vuses;
00115
00116
00117 static VEC(tree,heap) *build_v_must_defs;
00118
00119
00120 static bool ops_active = false;
00121
00122 static GTY (()) struct ssa_operand_memory_d *operand_memory = NULL;
00123 static unsigned operand_memory_index;
00124
00125 static void get_expr_operands (tree, tree *, int);
00126
00127 static def_optype_p free_defs = NULL;
00128 static use_optype_p free_uses = NULL;
00129 static vuse_optype_p free_vuses = NULL;
00130 static maydef_optype_p free_maydefs = NULL;
00131 static mustdef_optype_p free_mustdefs = NULL;
00132
00133
00134
00135
00136 #define ALLOC_OPTYPE(OP, TYPE) \
00137 do \
00138 { \
00139 TYPE##_optype_p ret = free_##TYPE##s; \
00140 if (ret) \
00141 free_##TYPE##s = ret->next; \
00142 else \
00143 ret = ssa_operand_alloc (sizeof (*ret)); \
00144 (OP) = ret; \
00145 } while (0)
00146
00147
00148
00149 static inline unsigned
00150 get_name_decl (tree t)
00151 {
00152 if (TREE_CODE (t) != SSA_NAME)
00153 return DECL_UID (t);
00154 else
00155 return DECL_UID (SSA_NAME_VAR (t));
00156 }
00157
00158
00159
00160
00161 static int
00162 operand_build_cmp (const void *p, const void *q)
00163 {
00164 tree e1 = *((const tree *)p);
00165 tree e2 = *((const tree *)q);
00166 unsigned int u1,u2;
00167
00168 u1 = get_name_decl (e1);
00169 u2 = get_name_decl (e2);
00170
00171
00172 #ifdef ENABLE_CHECKING
00173 gcc_assert (u1 != u2);
00174 #endif
00175 return (u1 > u2 ? 1 : -1);
00176 }
00177
00178
00179
00180
00181 static inline void
00182 operand_build_sort_virtual (VEC(tree,heap) *list)
00183 {
00184 int num = VEC_length (tree, list);
00185
00186 if (num < 2)
00187 return;
00188
00189 if (num == 2)
00190 {
00191 if (get_name_decl (VEC_index (tree, list, 0))
00192 > get_name_decl (VEC_index (tree, list, 1)))
00193 {
00194
00195 tree tmp = VEC_index (tree, list, 0);
00196 VEC_replace (tree, list, 0, VEC_index (tree, list, 1));
00197 VEC_replace (tree, list, 1, tmp);
00198 }
00199 return;
00200 }
00201
00202
00203 qsort (VEC_address (tree, list),
00204 VEC_length (tree, list),
00205 sizeof (tree),
00206 operand_build_cmp);
00207 }
00208
00209
00210
00211
00212 bool
00213 ssa_operands_active (void)
00214 {
00215 return ops_active;
00216 }
00217
00218
00219
00220
00221
00222 static struct
00223 {
00224
00225
00226 unsigned int clobbered_vars;
00227
00228
00229
00230 unsigned int static_write_clobbers_avoided;
00231
00232
00233 unsigned int static_read_clobbers_avoided;
00234
00235
00236
00237 unsigned int unescapable_clobbers_avoided;
00238
00239
00240
00241 unsigned int readonly_clobbers;
00242
00243
00244 unsigned int static_readonly_clobbers_avoided;
00245 } clobber_stats;
00246
00247
00248
00249
00250 void
00251 init_ssa_operands (void)
00252 {
00253 build_defs = VEC_alloc (tree, heap, 5);
00254 build_uses = VEC_alloc (tree, heap, 10);
00255 build_vuses = VEC_alloc (tree, heap, 25);
00256 build_v_may_defs = VEC_alloc (tree, heap, 25);
00257 build_v_must_defs = VEC_alloc (tree, heap, 25);
00258
00259 gcc_assert (operand_memory == NULL);
00260 operand_memory_index = SSA_OPERAND_MEMORY_SIZE;
00261 ops_active = true;
00262 memset (&clobber_stats, 0, sizeof (clobber_stats));
00263 }
00264
00265
00266
00267
00268 void
00269 fini_ssa_operands (void)
00270 {
00271 struct ssa_operand_memory_d *ptr;
00272 VEC_free (tree, heap, build_defs);
00273 VEC_free (tree, heap, build_uses);
00274 VEC_free (tree, heap, build_v_must_defs);
00275 VEC_free (tree, heap, build_v_may_defs);
00276 VEC_free (tree, heap, build_vuses);
00277 free_defs = NULL;
00278 free_uses = NULL;
00279 free_vuses = NULL;
00280 free_maydefs = NULL;
00281 free_mustdefs = NULL;
00282 while ((ptr = operand_memory) != NULL)
00283 {
00284 operand_memory = operand_memory->next;
00285 ggc_free (ptr);
00286 }
00287
00288 ops_active = false;
00289
00290 if (dump_file && (dump_flags & TDF_STATS))
00291 {
00292 fprintf (dump_file, "Original clobbered vars:%d\n",
00293 clobber_stats.clobbered_vars);
00294 fprintf (dump_file, "Static write clobbers avoided:%d\n",
00295 clobber_stats.static_write_clobbers_avoided);
00296 fprintf (dump_file, "Static read clobbers avoided:%d\n",
00297 clobber_stats.static_read_clobbers_avoided);
00298 fprintf (dump_file, "Unescapable clobbers avoided:%d\n",
00299 clobber_stats.unescapable_clobbers_avoided);
00300 fprintf (dump_file, "Original read-only clobbers:%d\n",
00301 clobber_stats.readonly_clobbers);
00302 fprintf (dump_file, "Static read-only clobbers avoided:%d\n",
00303 clobber_stats.static_readonly_clobbers_avoided);
00304 }
00305 }
00306
00307
00308
00309
00310 static inline void *
00311 ssa_operand_alloc (unsigned size)
00312 {
00313 char *ptr;
00314 if (operand_memory_index + size >= SSA_OPERAND_MEMORY_SIZE)
00315 {
00316 struct ssa_operand_memory_d *ptr;
00317 ptr = GGC_NEW (struct ssa_operand_memory_d);
00318 ptr->next = operand_memory;
00319 operand_memory = ptr;
00320 operand_memory_index = 0;
00321 }
00322 ptr = &(operand_memory->mem[operand_memory_index]);
00323 operand_memory_index += size;
00324 return ptr;
00325 }
00326
00327
00328
00329
00330
00331
00332 static inline void
00333 set_virtual_use_link (use_operand_p ptr, tree stmt)
00334 {
00335
00336 if (ptr->stmt != stmt)
00337 ptr->stmt = stmt;
00338
00339
00340 if (!ptr->prev)
00341 link_imm_use (ptr, *(ptr->use));
00342 }
00343
00344
00345
00346 #define APPEND_OP_AFTER(ELT, TO) \
00347 do \
00348 { \
00349 (TO)->next = (ELT); \
00350 (TO) = (ELT); \
00351 } while (0)
00352
00353
00354
00355
00356 #define MOVE_HEAD_AFTER(FROM, TO) \
00357 do \
00358 { \
00359 APPEND_OP_AFTER (FROM, TO); \
00360 (FROM) = (FROM)->next; \
00361 } while (0)
00362
00363
00364
00365 #define MOVE_HEAD_TO_FREELIST(OP, TYPE) \
00366 do \
00367 { \
00368 TYPE##_optype_p next = (OP)->next; \
00369 (OP)->next = free_##TYPE##s; \
00370 free_##TYPE##s = (OP); \
00371 (OP) = next; \
00372 } while (0)
00373
00374
00375
00376
00377 #define INITIALIZE_USE(USE_PTR, VAL, STMT) \
00378 do \
00379 { \
00380 (USE_PTR)->use = (VAL); \
00381 link_imm_use_stmt ((USE_PTR), *(VAL), (STMT)); \
00382 } while (0)
00383
00384
00385
00386
00387 static inline void
00388 add_def_op (tree *op, def_optype_p *last)
00389 {
00390 def_optype_p new;
00391
00392 ALLOC_OPTYPE (new, def);
00393 DEF_OP_PTR (new) = op;
00394 APPEND_OP_AFTER (new, *last);
00395 }
00396
00397
00398
00399
00400 static inline void
00401 add_use_op (tree stmt, tree *op, use_optype_p *last)
00402 {
00403 use_optype_p new;
00404
00405 ALLOC_OPTYPE (new, use);
00406 INITIALIZE_USE (USE_OP_PTR (new), op, stmt);
00407 APPEND_OP_AFTER (new, *last);
00408 }
00409
00410
00411
00412
00413 static inline void
00414 add_vuse_op (tree stmt, tree op, vuse_optype_p *last)
00415 {
00416 vuse_optype_p new;
00417
00418 ALLOC_OPTYPE (new, vuse);
00419 VUSE_OP (new) = op;
00420 INITIALIZE_USE (VUSE_OP_PTR (new), &VUSE_OP (new), stmt);
00421 APPEND_OP_AFTER (new, *last);
00422 }
00423
00424
00425
00426
00427 static inline void
00428 add_maydef_op (tree stmt, tree op, maydef_optype_p *last)
00429 {
00430 maydef_optype_p new;
00431
00432 ALLOC_OPTYPE (new, maydef);
00433 MAYDEF_RESULT (new) = op;
00434 MAYDEF_OP (new) = op;
00435 INITIALIZE_USE (MAYDEF_OP_PTR (new), &MAYDEF_OP (new), stmt);
00436 APPEND_OP_AFTER (new, *last);
00437 }
00438
00439
00440
00441
00442 static inline void
00443 add_mustdef_op (tree stmt, tree op, mustdef_optype_p *last)
00444 {
00445 mustdef_optype_p new;
00446
00447 ALLOC_OPTYPE (new, mustdef);
00448 MUSTDEF_RESULT (new) = op;
00449 MUSTDEF_KILL (new) = op;
00450 INITIALIZE_USE (MUSTDEF_KILL_PTR (new), &MUSTDEF_KILL (new), stmt);
00451 APPEND_OP_AFTER (new, *last);
00452 }
00453
00454
00455
00456
00457
00458
00459 static inline void
00460 finalize_ssa_def_ops (tree stmt)
00461 {
00462 unsigned new_i;
00463 struct def_optype_d new_list;
00464 def_optype_p old_ops, last;
00465 tree *old_base;
00466
00467 new_list.next = NULL;
00468 last = &new_list;
00469
00470 old_ops = DEF_OPS (stmt);
00471
00472 new_i = 0;
00473 while (old_ops && new_i < VEC_length (tree, build_defs))
00474 {
00475 tree *new_base = (tree *) VEC_index (tree, build_defs, new_i);
00476 old_base = DEF_OP_PTR (old_ops);
00477
00478 if (old_base == new_base)
00479 {
00480
00481 MOVE_HEAD_AFTER (old_ops, last);
00482 new_i++;
00483 }
00484 else if (old_base < new_base)
00485 {
00486
00487 MOVE_HEAD_TO_FREELIST (old_ops, def);
00488 }
00489 else
00490 {
00491
00492 add_def_op (new_base, &last);
00493 new_i++;
00494 }
00495 }
00496
00497
00498 for ( ; new_i < VEC_length (tree, build_defs); new_i++)
00499 add_def_op ((tree *) VEC_index (tree, build_defs, new_i), &last);
00500
00501 last->next = NULL;
00502
00503
00504 if (old_ops)
00505 {
00506 old_ops->next = free_defs;
00507 free_defs = old_ops;
00508 }
00509
00510
00511 DEF_OPS (stmt) = new_list.next;
00512
00513 #ifdef ENABLE_CHECKING
00514 {
00515 def_optype_p ptr;
00516 unsigned x = 0;
00517 for (ptr = DEF_OPS (stmt); ptr; ptr = ptr->next)
00518 x++;
00519
00520 gcc_assert (x == VEC_length (tree, build_defs));
00521 }
00522 #endif
00523 }
00524
00525
00526
00527 static void
00528 finalize_ssa_defs (tree stmt)
00529 {
00530 unsigned int num = VEC_length (tree, build_defs);
00531
00532
00533 gcc_assert ((stmt && TREE_CODE (stmt) != MODIFY_EXPR) || num <= 1);
00534
00535
00536
00537 finalize_ssa_def_ops (stmt);
00538 VEC_truncate (tree, build_defs, 0);
00539 }
00540
00541
00542
00543
00544 static inline void
00545 finalize_ssa_use_ops (tree stmt)
00546 {
00547 unsigned new_i;
00548 struct use_optype_d new_list;
00549 use_optype_p old_ops, ptr, last;
00550
00551 new_list.next = NULL;
00552 last = &new_list;
00553
00554 old_ops = USE_OPS (stmt);
00555
00556
00557 if (old_ops)
00558 {
00559 for (ptr = old_ops; ptr; ptr = ptr->next)
00560 delink_imm_use (USE_OP_PTR (ptr));
00561 old_ops->next = free_uses;
00562 free_uses = old_ops;
00563 }
00564
00565
00566 for (new_i = 0; new_i < VEC_length (tree, build_uses); new_i++)
00567 add_use_op (stmt, (tree *) VEC_index (tree, build_uses, new_i), &last);
00568
00569 last->next = NULL;
00570
00571
00572 USE_OPS (stmt) = new_list.next;
00573
00574 #ifdef ENABLE_CHECKING
00575 {
00576 unsigned x = 0;
00577 for (ptr = USE_OPS (stmt); ptr; ptr = ptr->next)
00578 x++;
00579
00580 gcc_assert (x == VEC_length (tree, build_uses));
00581 }
00582 #endif
00583 }
00584
00585
00586
00587 static void
00588 finalize_ssa_uses (tree stmt)
00589 {
00590 #ifdef ENABLE_CHECKING
00591 {
00592 unsigned x;
00593 unsigned num = VEC_length (tree, build_uses);
00594
00595
00596
00597
00598
00599 for (x = 0; x < num; x++)
00600 gcc_assert (*((tree *)VEC_index (tree, build_uses, x)) != stmt);
00601 }
00602 #endif
00603 finalize_ssa_use_ops (stmt);
00604 VEC_truncate (tree, build_uses, 0);
00605 }
00606
00607
00608
00609
00610
00611 static inline void
00612 finalize_ssa_v_may_def_ops (tree stmt)
00613 {
00614 unsigned new_i;
00615 struct maydef_optype_d new_list;
00616 maydef_optype_p old_ops, ptr, last;
00617 tree act;
00618 unsigned old_base, new_base;
00619
00620 new_list.next = NULL;
00621 last = &new_list;
00622
00623 old_ops = MAYDEF_OPS (stmt);
00624
00625 new_i = 0;
00626 while (old_ops && new_i < VEC_length (tree, build_v_may_defs))
00627 {
00628 act = VEC_index (tree, build_v_may_defs, new_i);
00629 new_base = get_name_decl (act);
00630 old_base = get_name_decl (MAYDEF_OP (old_ops));
00631
00632 if (old_base == new_base)
00633 {
00634
00635 MOVE_HEAD_AFTER (old_ops, last);
00636 set_virtual_use_link (MAYDEF_OP_PTR (last), stmt);
00637 new_i++;
00638 }
00639 else if (old_base < new_base)
00640 {
00641
00642 delink_imm_use (MAYDEF_OP_PTR (old_ops));
00643 MOVE_HEAD_TO_FREELIST (old_ops, maydef);
00644 }
00645 else
00646 {
00647
00648 add_maydef_op (stmt, act, &last);
00649 new_i++;
00650 }
00651 }
00652
00653
00654 for ( ; new_i < VEC_length (tree, build_v_may_defs); new_i++)
00655 add_maydef_op (stmt, VEC_index (tree, build_v_may_defs, new_i), &last);
00656
00657 last->next = NULL;
00658
00659
00660 if (old_ops)
00661 {
00662 for (ptr = old_ops; ptr; ptr = ptr->next)
00663 delink_imm_use (MAYDEF_OP_PTR (ptr));
00664 old_ops->next = free_maydefs;
00665 free_maydefs = old_ops;
00666 }
00667
00668
00669 MAYDEF_OPS (stmt) = new_list.next;
00670
00671 #ifdef ENABLE_CHECKING
00672 {
00673 unsigned x = 0;
00674 for (ptr = MAYDEF_OPS (stmt); ptr; ptr = ptr->next)
00675 x++;
00676
00677 gcc_assert (x == VEC_length (tree, build_v_may_defs));
00678 }
00679 #endif
00680 }
00681
00682 static void
00683 finalize_ssa_v_may_defs (tree stmt)
00684 {
00685 finalize_ssa_v_may_def_ops (stmt);
00686 }
00687
00688
00689
00690
00691 static inline void
00692 cleanup_v_may_defs (void)
00693 {
00694 unsigned x, num;
00695 num = VEC_length (tree, build_v_may_defs);
00696
00697 for (x = 0; x < num; x++)
00698 {
00699 tree t = VEC_index (tree, build_v_may_defs, x);
00700 if (TREE_CODE (t) != SSA_NAME)
00701 {
00702 var_ann_t ann = var_ann (t);
00703 ann->in_v_may_def_list = 0;
00704 }
00705 }
00706 VEC_truncate (tree, build_v_may_defs, 0);
00707 }
00708
00709
00710
00711
00712
00713 static inline void
00714 finalize_ssa_vuse_ops (tree stmt)
00715 {
00716 unsigned new_i;
00717 struct vuse_optype_d new_list;
00718 vuse_optype_p old_ops, ptr, last;
00719 tree act;
00720 unsigned old_base, new_base;
00721
00722 new_list.next = NULL;
00723 last = &new_list;
00724
00725 old_ops = VUSE_OPS (stmt);
00726
00727 new_i = 0;
00728 while (old_ops && new_i < VEC_length (tree, build_vuses))
00729 {
00730 act = VEC_index (tree, build_vuses, new_i);
00731 new_base = get_name_decl (act);
00732 old_base = get_name_decl (VUSE_OP (old_ops));
00733
00734 if (old_base == new_base)
00735 {
00736
00737 MOVE_HEAD_AFTER (old_ops, last);
00738 set_virtual_use_link (VUSE_OP_PTR (last), stmt);
00739 new_i++;
00740 }
00741 else if (old_base < new_base)
00742 {
00743
00744 delink_imm_use (USE_OP_PTR (old_ops));
00745 MOVE_HEAD_TO_FREELIST (old_ops, vuse);
00746 }
00747 else
00748 {
00749
00750 add_vuse_op (stmt, act, &last);
00751 new_i++;
00752 }
00753 }
00754
00755
00756 for ( ; new_i < VEC_length (tree, build_vuses); new_i++)
00757 add_vuse_op (stmt, VEC_index (tree, build_vuses, new_i), &last);
00758
00759 last->next = NULL;
00760
00761
00762 if (old_ops)
00763 {
00764 for (ptr = old_ops; ptr; ptr = ptr->next)
00765 delink_imm_use (VUSE_OP_PTR (ptr));
00766 old_ops->next = free_vuses;
00767 free_vuses = old_ops;
00768 }
00769
00770
00771 VUSE_OPS (stmt) = new_list.next;
00772
00773 #ifdef ENABLE_CHECKING
00774 {
00775 unsigned x = 0;
00776 for (ptr = VUSE_OPS (stmt); ptr; ptr = ptr->next)
00777 x++;
00778
00779 gcc_assert (x == VEC_length (tree, build_vuses));
00780 }
00781 #endif
00782 }
00783
00784
00785
00786 static void
00787 finalize_ssa_vuses (tree stmt)
00788 {
00789 unsigned num, num_v_may_defs;
00790 unsigned vuse_index;
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803 num = VEC_length (tree, build_vuses);
00804 num_v_may_defs = VEC_length (tree, build_v_may_defs);
00805
00806 if (num > 0 && num_v_may_defs > 0)
00807 {
00808 for (vuse_index = 0; vuse_index < VEC_length (tree, build_vuses); )
00809 {
00810 tree vuse;
00811 vuse = VEC_index (tree, build_vuses, vuse_index);
00812 if (TREE_CODE (vuse) != SSA_NAME)
00813 {
00814 var_ann_t ann = var_ann (vuse);
00815 ann->in_vuse_list = 0;
00816 if (ann->in_v_may_def_list)
00817 {
00818 VEC_ordered_remove (tree, build_vuses, vuse_index);
00819 continue;
00820 }
00821 }
00822 vuse_index++;
00823 }
00824 }
00825 else
00826 {
00827
00828 for (vuse_index = 0;
00829 vuse_index < VEC_length (tree, build_vuses);
00830 vuse_index++)
00831 {
00832 tree t = VEC_index (tree, build_vuses, vuse_index);
00833 if (TREE_CODE (t) != SSA_NAME)
00834 {
00835 var_ann_t ann = var_ann (t);
00836 ann->in_vuse_list = 0;
00837 }
00838 }
00839 }
00840
00841 finalize_ssa_vuse_ops (stmt);
00842
00843
00844 cleanup_v_may_defs ();
00845
00846
00847 VEC_truncate (tree, build_vuses, 0);
00848
00849 }
00850
00851
00852
00853
00854 static inline void
00855 finalize_ssa_v_must_def_ops (tree stmt)
00856 {
00857 unsigned new_i;
00858 struct mustdef_optype_d new_list;
00859 mustdef_optype_p old_ops, ptr, last;
00860 tree act;
00861 unsigned old_base, new_base;
00862
00863 new_list.next = NULL;
00864 last = &new_list;
00865
00866 old_ops = MUSTDEF_OPS (stmt);
00867
00868 new_i = 0;
00869 while (old_ops && new_i < VEC_length (tree, build_v_must_defs))
00870 {
00871 act = VEC_index (tree, build_v_must_defs, new_i);
00872 new_base = get_name_decl (act);
00873 old_base = get_name_decl (MUSTDEF_KILL (old_ops));
00874
00875 if (old_base == new_base)
00876 {
00877
00878 MOVE_HEAD_AFTER (old_ops, last);
00879 set_virtual_use_link (MUSTDEF_KILL_PTR (last), stmt);
00880 new_i++;
00881 }
00882 else if (old_base < new_base)
00883 {
00884
00885 delink_imm_use (MUSTDEF_KILL_PTR (old_ops));
00886 MOVE_HEAD_TO_FREELIST (old_ops, mustdef);
00887 }
00888 else
00889 {
00890
00891 add_mustdef_op (stmt, act, &last);
00892 new_i++;
00893 }
00894 }
00895
00896
00897 for ( ; new_i < VEC_length (tree, build_v_must_defs); new_i++)
00898 add_mustdef_op (stmt, VEC_index (tree, build_v_must_defs, new_i), &last);
00899
00900 last->next = NULL;
00901
00902
00903 if (old_ops)
00904 {
00905 for (ptr = old_ops; ptr; ptr = ptr->next)
00906 delink_imm_use (MUSTDEF_KILL_PTR (ptr));
00907 old_ops->next = free_mustdefs;
00908 free_mustdefs = old_ops;
00909 }
00910
00911
00912 MUSTDEF_OPS (stmt) = new_list.next;
00913
00914 #ifdef ENABLE_CHECKING
00915 {
00916 unsigned x = 0;
00917 for (ptr = MUSTDEF_OPS (stmt); ptr; ptr = ptr->next)
00918 x++;
00919
00920 gcc_assert (x == VEC_length (tree, build_v_must_defs));
00921 }
00922 #endif
00923 }
00924
00925 static void
00926 finalize_ssa_v_must_defs (tree stmt)
00927 {
00928
00929
00930
00931
00932
00933
00934 finalize_ssa_v_must_def_ops (stmt);
00935 VEC_truncate (tree, build_v_must_defs, 0);
00936 }
00937
00938
00939
00940
00941 static inline void
00942 finalize_ssa_stmt_operands (tree stmt)
00943 {
00944 finalize_ssa_defs (stmt);
00945 finalize_ssa_uses (stmt);
00946 finalize_ssa_v_must_defs (stmt);
00947 finalize_ssa_v_may_defs (stmt);
00948 finalize_ssa_vuses (stmt);
00949 }
00950
00951
00952
00953
00954 static inline void
00955 start_ssa_stmt_operands (void)
00956 {
00957 gcc_assert (VEC_length (tree, build_defs) == 0);
00958 gcc_assert (VEC_length (tree, build_uses) == 0);
00959 gcc_assert (VEC_length (tree, build_vuses) == 0);
00960 gcc_assert (VEC_length (tree, build_v_may_defs) == 0);
00961 gcc_assert (VEC_length (tree, build_v_must_defs) == 0);
00962 }
00963
00964
00965
00966
00967 static inline void
00968 append_def (tree *def_p)
00969 {
00970 VEC_safe_push (tree, heap, build_defs, (tree)def_p);
00971 }
00972
00973
00974
00975
00976 static inline void
00977 append_use (tree *use_p)
00978 {
00979 VEC_safe_push (tree, heap, build_uses, (tree)use_p);
00980 }
00981
00982
00983
00984
00985 static inline void
00986 append_v_may_def (tree var)
00987 {
00988 if (TREE_CODE (var) != SSA_NAME)
00989 {
00990 var_ann_t ann = get_var_ann (var);
00991
00992
00993 if (ann->in_v_may_def_list)
00994 return;
00995 ann->in_v_may_def_list = 1;
00996 }
00997
00998 VEC_safe_push (tree, heap, build_v_may_defs, (tree)var);
00999 }
01000
01001
01002
01003
01004 static inline void
01005 append_vuse (tree var)
01006 {
01007
01008 if (TREE_CODE (var) != SSA_NAME)
01009 {
01010 var_ann_t ann = get_var_ann (var);
01011
01012 if (ann->in_vuse_list || ann->in_v_may_def_list)
01013 return;
01014 ann->in_vuse_list = 1;
01015 }
01016
01017 VEC_safe_push (tree, heap, build_vuses, (tree)var);
01018 }
01019
01020
01021
01022
01023 static inline void
01024 append_v_must_def (tree var)
01025 {
01026 unsigned i;
01027
01028
01029 for (i = 0; i < VEC_length (tree, build_v_must_defs); i++)
01030 if (var == VEC_index (tree, build_v_must_defs, i))
01031 return;
01032
01033 VEC_safe_push (tree, heap, build_v_must_defs, (tree)var);
01034 }
01035
01036
01037
01038
01039
01040
01041
01042 static bool
01043 access_can_touch_variable (tree ref, tree alias, HOST_WIDE_INT offset,
01044 HOST_WIDE_INT size)
01045 {
01046 bool offsetgtz = offset > 0;
01047 unsigned HOST_WIDE_INT uoffset = (unsigned HOST_WIDE_INT) offset;
01048 tree base = ref ? get_base_address (ref) : NULL;
01049
01050
01051
01052
01053 if (alias == global_var)
01054 return true;
01055
01056
01057
01058 if (alias == nonlocal_all)
01059 return true;
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088 if (size != -1
01089 && TREE_CODE (alias) == STRUCT_FIELD_TAG
01090 && base
01091 && TREE_TYPE (base) == TREE_TYPE (SFT_PARENT_VAR (alias))
01092 && !overlap_subvar (offset, size, alias, NULL))
01093 {
01094 #ifdef ACCESS_DEBUGGING
01095 fprintf (stderr, "Access to ");
01096 print_generic_expr (stderr, ref, 0);
01097 fprintf (stderr, " may not touch ");
01098 print_generic_expr (stderr, alias, 0);
01099 fprintf (stderr, " in function %s\n", get_name (current_function_decl));
01100 #endif
01101 return false;
01102 }
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150 else if (ref
01151 && flag_strict_aliasing
01152 && TREE_CODE (ref) != INDIRECT_REF
01153 && !MTAG_P (alias)
01154 && (TREE_CODE (base) != INDIRECT_REF
01155 || TREE_CODE (TREE_TYPE (base)) != UNION_TYPE)
01156 && !AGGREGATE_TYPE_P (TREE_TYPE (alias))
01157 && TREE_CODE (TREE_TYPE (alias)) != COMPLEX_TYPE
01158 && !POINTER_TYPE_P (TREE_TYPE (alias))
01159
01160
01161 && get_alias_set (base))
01162 {
01163 #ifdef ACCESS_DEBUGGING
01164 fprintf (stderr, "Access to ");
01165 print_generic_expr (stderr, ref, 0);
01166 fprintf (stderr, " may not touch ");
01167 print_generic_expr (stderr, alias, 0);
01168 fprintf (stderr, " in function %s\n", get_name (current_function_decl));
01169 #endif
01170 return false;
01171 }
01172
01173
01174
01175
01176 else if (ref
01177 && flag_strict_aliasing
01178 && TREE_CODE (ref) != INDIRECT_REF
01179 && !MTAG_P (alias)
01180 && !POINTER_TYPE_P (TREE_TYPE (alias))
01181 && offsetgtz
01182 && DECL_SIZE (alias)
01183 && TREE_CODE (DECL_SIZE (alias)) == INTEGER_CST
01184 && uoffset > TREE_INT_CST_LOW (DECL_SIZE (alias)))
01185 {
01186 #ifdef ACCESS_DEBUGGING
01187 fprintf (stderr, "Access to ");
01188 print_generic_expr (stderr, ref, 0);
01189 fprintf (stderr, " may not touch ");
01190 print_generic_expr (stderr, alias, 0);
01191 fprintf (stderr, " in function %s\n", get_name (current_function_decl));
01192 #endif
01193 return false;
01194 }
01195
01196 return true;
01197 }
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207 static void
01208 add_virtual_operand (tree var, stmt_ann_t s_ann, int flags,
01209 tree full_ref, HOST_WIDE_INT offset,
01210 HOST_WIDE_INT size, bool for_clobber)
01211 {
01212 VEC(tree,gc) *aliases;
01213 tree sym;
01214 var_ann_t v_ann;
01215
01216 sym = (TREE_CODE (var) == SSA_NAME ? SSA_NAME_VAR (var) : var);
01217 v_ann = var_ann (sym);
01218
01219
01220
01221 if (TREE_THIS_VOLATILE (sym) && s_ann)
01222 s_ann->has_volatile_ops = true;
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237 if ((flags & opf_non_specific) && unmodifiable_var_p (var))
01238 flags &= ~(opf_is_def | opf_kill_def);
01239
01240
01241
01242
01243
01244 if (flags & opf_no_vops)
01245 return;
01246
01247 aliases = v_ann->may_aliases;
01248 if (aliases == NULL)
01249 {
01250
01251 if (flags & opf_is_def)
01252 {
01253 if (flags & opf_kill_def)
01254 {
01255
01256
01257 gcc_assert (!MTAG_P (var)
01258 || TREE_CODE (var) == STRUCT_FIELD_TAG);
01259 append_v_must_def (var);
01260 }
01261 else
01262 {
01263
01264
01265 append_v_may_def (var);
01266 }
01267 }
01268 else
01269 append_vuse (var);
01270 }
01271 else
01272 {
01273 unsigned i;
01274 tree al;
01275
01276
01277
01278 gcc_assert (VEC_length (tree, aliases) != 0);
01279
01280 if (flags & opf_is_def)
01281 {
01282
01283 bool none_added = true;
01284
01285 for (i = 0; VEC_iterate (tree, aliases, i, al); i++)
01286 {
01287 if (!access_can_touch_variable (full_ref, al, offset, size))
01288 continue;
01289
01290 none_added = false;
01291 append_v_may_def (al);
01292 }
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305 if (v_ann->is_aliased
01306 || none_added
01307 || (TREE_CODE (var) == SYMBOL_MEMORY_TAG
01308 && for_clobber
01309 && SMT_USED_ALONE (var)))
01310 {
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320 #ifdef ACCESS_DEBUGGING
01321 if (none_added
01322 && !updating_used_alone && aliases_computed_p
01323 && TREE_CODE (var) == SYMBOL_MEMORY_TAG)
01324 gcc_assert (SMT_USED_ALONE (var));
01325 #endif
01326 append_v_may_def (var);
01327 }
01328 }
01329 else
01330 {
01331 bool none_added = true;
01332 for (i = 0; VEC_iterate (tree, aliases, i, al); i++)
01333 {
01334 if (!access_can_touch_variable (full_ref, al, offset, size))
01335 continue;
01336 none_added = false;
01337 append_vuse (al);
01338 }
01339
01340
01341
01342 if (v_ann->is_aliased || none_added)
01343 append_vuse (var);
01344 }
01345 }
01346 }
01347
01348
01349
01350
01351
01352
01353
01354 static void
01355 add_stmt_operand (tree *var_p, stmt_ann_t s_ann, int flags)
01356 {
01357 bool is_real_op;
01358 tree var, sym;
01359 var_ann_t v_ann;
01360
01361 var = *var_p;
01362 gcc_assert (SSA_VAR_P (var));
01363
01364 is_real_op = is_gimple_reg (var);
01365
01366
01367
01368 gcc_assert (is_real_op || DECL_P (var));
01369
01370 sym = (TREE_CODE (var) == SSA_NAME ? SSA_NAME_VAR (var) : var);
01371 v_ann = var_ann (sym);
01372
01373
01374
01375 if (TREE_THIS_VOLATILE (sym) && s_ann)
01376 s_ann->has_volatile_ops = true;
01377
01378 if (is_real_op)
01379 {
01380
01381 if (flags & opf_is_def)
01382 append_def (var_p);
01383 else
01384 append_use (var_p);
01385 }
01386 else
01387 add_virtual_operand (var, s_ann, flags, NULL_TREE, 0, -1, false);
01388 }
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409 static void
01410 get_indirect_ref_operands (tree stmt, tree expr, int flags,
01411 tree full_ref,
01412 HOST_WIDE_INT offset, HOST_WIDE_INT size,
01413 bool recurse_on_base)
01414 {
01415 tree *pptr = &TREE_OPERAND (expr, 0);
01416 tree ptr = *pptr;
01417 stmt_ann_t s_ann = stmt_ann (stmt);
01418
01419
01420 flags &= ~opf_kill_def;
01421
01422 if (SSA_VAR_P (ptr))
01423 {
01424 struct ptr_info_def *pi = NULL;
01425
01426
01427 if (TREE_CODE (ptr) == SSA_NAME
01428 && (pi = SSA_NAME_PTR_INFO (ptr)) != NULL
01429 && pi->name_mem_tag)
01430 {
01431
01432 add_virtual_operand (pi->name_mem_tag, s_ann, flags,
01433 full_ref, offset, size, false);
01434 }
01435 else
01436 {
01437
01438
01439 var_ann_t v_ann;
01440
01441
01442
01443
01444
01445 if (dump_file
01446 && TREE_CODE (ptr) == SSA_NAME
01447 && pi == NULL)
01448 {
01449 fprintf (dump_file,
01450 "NOTE: no flow-sensitive alias info for ");
01451 print_generic_expr (dump_file, ptr, dump_flags);
01452 fprintf (dump_file, " in ");
01453 print_generic_stmt (dump_file, stmt, dump_flags);
01454 }
01455
01456 if (TREE_CODE (ptr) == SSA_NAME)
01457 ptr = SSA_NAME_VAR (ptr);
01458 v_ann = var_ann (ptr);
01459
01460 if (v_ann->symbol_mem_tag)
01461 add_virtual_operand (v_ann->symbol_mem_tag, s_ann, flags,
01462 full_ref, offset, size, false);
01463 }
01464 }
01465 else if (TREE_CODE (ptr) == INTEGER_CST)
01466 {
01467
01468
01469
01470 if (s_ann)
01471 s_ann->has_volatile_ops = true;
01472 return;
01473 }
01474 else
01475 {
01476
01477 gcc_unreachable ();
01478 }
01479
01480
01481 if (recurse_on_base)
01482 get_expr_operands (stmt, pptr, opf_none);
01483 }
01484
01485
01486
01487
01488 static void
01489 get_tmr_operands (tree stmt, tree expr, int flags)
01490 {
01491 tree tag = TMR_TAG (expr), ref;
01492 HOST_WIDE_INT offset, size, maxsize;
01493 subvar_t svars, sv;
01494 stmt_ann_t s_ann = stmt_ann (stmt);
01495
01496
01497 get_expr_operands (stmt, &TMR_BASE (expr), opf_none);
01498 get_expr_operands (stmt, &TMR_INDEX (expr), opf_none);
01499
01500
01501 flags &= ~opf_kill_def;
01502
01503 if (TMR_SYMBOL (expr))
01504 {
01505 stmt_ann_t ann = stmt_ann (stmt);
01506 add_to_addressable_set (TMR_SYMBOL (expr), &ann->addresses_taken);
01507 }
01508
01509 if (!tag)
01510 {
01511
01512 stmt_ann (stmt)->has_volatile_ops = true;
01513 return;
01514 }
01515
01516 if (DECL_P (tag))
01517 {
01518 get_expr_operands (stmt, &tag, flags);
01519 return;
01520 }
01521
01522 ref = get_ref_base_and_extent (tag, &offset, &size, &maxsize);
01523 gcc_assert (ref != NULL_TREE);
01524 svars = get_subvars_for_var (ref);
01525 for (sv = svars; sv; sv = sv->next)
01526 {
01527 bool exact;
01528 if (overlap_subvar (offset, maxsize, sv->var, &exact))
01529 {
01530 int subvar_flags = flags;
01531 if (!exact || size != maxsize)
01532 subvar_flags &= ~opf_kill_def;
01533 add_stmt_operand (&sv->var, s_ann, subvar_flags);
01534 }
01535 }
01536 }
01537
01538
01539
01540
01541
01542 static void
01543 add_call_clobber_ops (tree stmt, tree callee)
01544 {
01545 unsigned u;
01546 bitmap_iterator bi;
01547 stmt_ann_t s_ann = stmt_ann (stmt);
01548 bitmap not_read_b, not_written_b;
01549
01550
01551
01552 if (s_ann)
01553 s_ann->makes_clobbering_call = true;
01554
01555
01556
01557 if (global_var)
01558 {
01559 add_stmt_operand (&global_var, s_ann, opf_is_def);
01560 return;
01561 }
01562
01563
01564
01565
01566 not_read_b = callee ? ipa_reference_get_not_read_global (callee) : NULL;
01567 not_written_b = callee ? ipa_reference_get_not_written_global (callee) : NULL;
01568
01569 EXECUTE_IF_SET_IN_BITMAP (call_clobbered_vars, 0, u, bi)
01570 {
01571 tree var = referenced_var_lookup (u);
01572 unsigned int escape_mask = var_ann (var)->escape_mask;
01573 tree real_var = var;
01574 bool not_read;
01575 bool not_written;
01576
01577
01578
01579 if (TREE_CODE (var) == STRUCT_FIELD_TAG)
01580 real_var = SFT_PARENT_VAR (var);
01581
01582 not_read = not_read_b ? bitmap_bit_p (not_read_b,
01583 DECL_UID (real_var)) : false;
01584 not_written = not_written_b ? bitmap_bit_p (not_written_b,
01585 DECL_UID (real_var)) : false;
01586 gcc_assert (!unmodifiable_var_p (var));
01587
01588 clobber_stats.clobbered_vars++;
01589
01590
01591
01592
01593
01594 if ((escape_mask & ~(ESCAPE_TO_PURE_CONST)) == 0)
01595 {
01596 tree call = get_call_expr_in (stmt);
01597 if (call_expr_flags (call) & (ECF_CONST | ECF_PURE))
01598 {
01599 add_stmt_operand (&var, s_ann, opf_none);
01600 clobber_stats.unescapable_clobbers_avoided++;
01601 continue;
01602 }
01603 else
01604 {
01605 clobber_stats.unescapable_clobbers_avoided++;
01606 continue;
01607 }
01608 }
01609
01610 if (not_written)
01611 {
01612 clobber_stats.static_write_clobbers_avoided++;
01613 if (!not_read)
01614 add_stmt_operand (&var, s_ann, opf_none);
01615 else
01616 clobber_stats.static_read_clobbers_avoided++;
01617 }
01618 else
01619 add_virtual_operand (var, s_ann, opf_is_def, NULL, 0, -1, true);
01620 }
01621 }
01622
01623
01624
01625
01626
01627 static void
01628 add_call_read_ops (tree stmt, tree callee)
01629 {
01630 unsigned u;
01631 bitmap_iterator bi;
01632 stmt_ann_t s_ann = stmt_ann (stmt);
01633 bitmap not_read_b;
01634
01635
01636
01637
01638 if (global_var)
01639 {
01640 add_stmt_operand (&global_var, s_ann, opf_none);
01641 return;
01642 }
01643
01644 not_read_b = callee ? ipa_reference_get_not_read_global (callee) : NULL;
01645
01646
01647 EXECUTE_IF_SET_IN_BITMAP (call_clobbered_vars, 0, u, bi)
01648 {
01649 tree var = referenced_var (u);
01650 tree real_var = var;
01651 bool not_read;
01652
01653 clobber_stats.readonly_clobbers++;
01654
01655
01656
01657
01658 if (TREE_CODE (var) == STRUCT_FIELD_TAG)
01659 real_var = SFT_PARENT_VAR (var);
01660
01661 not_read = not_read_b ? bitmap_bit_p (not_read_b, DECL_UID (real_var))
01662 : false;
01663
01664 if (not_read)
01665 {
01666 clobber_stats.static_readonly_clobbers_avoided++;
01667 continue;
01668 }
01669
01670 add_stmt_operand (&var, s_ann, opf_none | opf_non_specific);
01671 }
01672 }
01673
01674
01675
01676
01677 static void
01678 get_call_expr_operands (tree stmt, tree expr)
01679 {
01680 tree op;
01681 int call_flags = call_expr_flags (expr);
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691
01692
01693 if (aliases_computed_p
01694 && !bitmap_empty_p (call_clobbered_vars)
01695 && !(call_flags & ECF_NOVOPS))
01696 {
01697
01698
01699
01700 if (TREE_SIDE_EFFECTS (expr)
01701 && !(call_flags & (ECF_PURE | ECF_CONST | ECF_NORETURN)))
01702 add_call_clobber_ops (stmt, get_callee_fndecl (expr));
01703 else if (!(call_flags & ECF_CONST))
01704 add_call_read_ops (stmt, get_callee_fndecl (expr));
01705 }
01706
01707
01708 get_expr_operands (stmt, &TREE_OPERAND (expr, 0), opf_none);
01709
01710 for (op = TREE_OPERAND (expr, 1); op; op = TREE_CHAIN (op))
01711 get_expr_operands (stmt, &TREE_VALUE (op), opf_none);
01712
01713 get_expr_operands (stmt, &TREE_OPERAND (expr, 2), opf_none);
01714 }
01715
01716
01717
01718
01719 static void
01720 get_asm_expr_operands (tree stmt)
01721 {
01722 stmt_ann_t s_ann = stmt_ann (stmt);
01723 int noutputs = list_length (ASM_OUTPUTS (stmt));
01724 const char **oconstraints
01725 = (const char **) alloca ((noutputs) * sizeof (const char *));
01726 int i;
01727 tree link;
01728 const char *constraint;
01729 bool allows_mem, allows_reg, is_inout;
01730
01731 for (i=0, link = ASM_OUTPUTS (stmt); link; ++i, link = TREE_CHAIN (link))
01732 {
01733 constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
01734 oconstraints[i] = constraint;
01735 parse_output_constraint (&constraint, i, 0, 0, &allows_mem,
01736 &allows_reg, &is_inout);
01737
01738
01739 gcc_assert (!allows_reg || !is_inout);
01740
01741
01742
01743 if (!allows_reg && allows_mem)
01744 {
01745 tree t = get_base_address (TREE_VALUE (link));
01746 if (t && DECL_P (t) && s_ann)
01747 add_to_addressable_set (t, &s_ann->addresses_taken);
01748 }
01749
01750 get_expr_operands (stmt, &TREE_VALUE (link), opf_is_def);
01751 }
01752
01753 for (link = ASM_INPUTS (stmt); link; link = TREE_CHAIN (link))
01754 {
01755 constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
01756 parse_input_constraint (&constraint, 0, 0, noutputs, 0,
01757 oconstraints, &allows_mem, &allows_reg);
01758
01759
01760
01761 if (!allows_reg && allows_mem)
01762 {
01763 tree t = get_base_address (TREE_VALUE (link));
01764 if (t && DECL_P (t) && s_ann)
01765 add_to_addressable_set (t, &s_ann->addresses_taken);
01766 }
01767
01768 get_expr_operands (stmt, &TREE_VALUE (link), 0);
01769 }
01770
01771
01772
01773 for (link = ASM_CLOBBERS (stmt); link; link = TREE_CHAIN (link))
01774 if (strcmp (TREE_STRING_POINTER (TREE_VALUE (link)), "memory") == 0)
01775 {
01776 unsigned i;
01777 bitmap_iterator bi;
01778
01779
01780
01781 if (global_var)
01782 add_stmt_operand (&global_var, s_ann, opf_is_def);
01783 else
01784 EXECUTE_IF_SET_IN_BITMAP (call_clobbered_vars, 0, i, bi)
01785 {
01786 tree var = referenced_var (i);
01787 add_stmt_operand (&var, s_ann, opf_is_def | opf_non_specific);
01788 }
01789
01790
01791 EXECUTE_IF_SET_IN_BITMAP (addressable_vars, 0, i, bi)
01792 {
01793 tree var = referenced_var (i);
01794
01795
01796
01797
01798
01799
01800
01801 if (var_can_have_subvars (var)
01802 && get_subvars_for_var (var) != NULL)
01803 continue;
01804
01805 add_stmt_operand (&var, s_ann, opf_is_def | opf_non_specific);
01806 }
01807
01808 break;
01809 }
01810 }
01811
01812
01813
01814
01815 static void
01816 get_modify_expr_operands (tree stmt, tree expr)
01817 {
01818
01819 get_expr_operands (stmt, &TREE_OPERAND (expr, 1), opf_none);
01820
01821
01822
01823
01824
01825
01826
01827
01828
01829
01830
01831
01832
01833
01834 get_expr_operands (stmt, &TREE_OPERAND (expr, 0), opf_is_def|opf_kill_def);
01835 }
01836
01837
01838
01839
01840
01841
01842 static void
01843 get_expr_operands (tree stmt, tree *expr_p, int flags)
01844 {
01845 enum tree_code code;
01846 enum tree_code_class class;
01847 tree expr = *expr_p;
01848 stmt_ann_t s_ann = stmt_ann (stmt);
01849
01850 if (expr == NULL)
01851 return;
01852
01853 code = TREE_CODE (expr);
01854 class = TREE_CODE_CLASS (code);
01855
01856 switch (code)
01857 {
01858 case ADDR_EXPR:
01859
01860
01861
01862
01863 add_to_addressable_set (TREE_OPERAND (expr, 0), &s_ann->addresses_taken);
01864
01865
01866
01867 if (is_gimple_min_invariant (expr))
01868 return;
01869
01870
01871
01872
01873
01874
01875 flags |= opf_no_vops;
01876 get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags);
01877 return;
01878
01879 case SSA_NAME:
01880 case STRUCT_FIELD_TAG:
01881 case SYMBOL_MEMORY_TAG:
01882 case NAME_MEMORY_TAG:
01883 add_stmt_operand (expr_p, s_ann, flags);
01884 return;
01885
01886 case VAR_DECL:
01887 case PARM_DECL:
01888 case RESULT_DECL:
01889 {
01890 subvar_t svars;
01891
01892
01893
01894
01895 if (var_can_have_subvars (expr)
01896 && (svars = get_subvars_for_var (expr)))
01897 {
01898 subvar_t sv;
01899 for (sv = svars; sv; sv = sv->next)
01900 add_stmt_operand (&sv->var, s_ann, flags);
01901 }
01902 else
01903 add_stmt_operand (expr_p, s_ann, flags);
01904
01905 return;
01906 }
01907
01908 case MISALIGNED_INDIRECT_REF:
01909 get_expr_operands (stmt, &TREE_OPERAND (expr, 1), flags);
01910
01911
01912 case ALIGN_INDIRECT_REF:
01913 case INDIRECT_REF:
01914 get_indirect_ref_operands (stmt, expr, flags, NULL_TREE, 0, -1, true);
01915 return;
01916
01917 case TARGET_MEM_REF:
01918 get_tmr_operands (stmt, expr, flags);
01919 return;
01920
01921 case ARRAY_REF:
01922 case ARRAY_RANGE_REF:
01923 case COMPONENT_REF:
01924 case REALPART_EXPR:
01925 case IMAGPART_EXPR:
01926 {
01927 tree ref;
01928 HOST_WIDE_INT offset, size, maxsize;
01929 bool none = true;
01930
01931
01932
01933
01934
01935
01936
01937 ref = get_ref_base_and_extent (expr, &offset, &size, &maxsize);
01938 if (SSA_VAR_P (ref) && get_subvars_for_var (ref))
01939 {
01940 subvar_t sv;
01941 subvar_t svars = get_subvars_for_var (ref);
01942
01943 for (sv = svars; sv; sv = sv->next)
01944 {
01945 bool exact;
01946
01947 if (overlap_subvar (offset, maxsize, sv->var, &exact))
01948 {
01949 int subvar_flags = flags;
01950 none = false;
01951 if (!exact || size != maxsize)
01952 subvar_flags &= ~opf_kill_def;
01953 add_stmt_operand (&sv->var, s_ann, subvar_flags);
01954 }
01955 }
01956
01957 if (!none)
01958 flags |= opf_no_vops;
01959 }
01960 else if (TREE_CODE (ref) == INDIRECT_REF)
01961 {
01962 get_indirect_ref_operands (stmt, ref, flags, expr, offset,
01963 maxsize, false);
01964 flags |= opf_no_vops;
01965 }
01966
01967
01968
01969
01970 get_expr_operands (stmt, &TREE_OPERAND (expr, 0),
01971 flags & ~opf_kill_def);
01972
01973 if (code == COMPONENT_REF)
01974 {
01975 if (s_ann && TREE_THIS_VOLATILE (TREE_OPERAND (expr, 1)))
01976 s_ann->has_volatile_ops = true;
01977 get_expr_operands (stmt, &TREE_OPERAND (expr, 2), opf_none);
01978 }
01979 else if (code == ARRAY_REF || code == ARRAY_RANGE_REF)
01980 {
01981 get_expr_operands (stmt, &TREE_OPERAND (expr, 1), opf_none);
01982 get_expr_operands (stmt, &TREE_OPERAND (expr, 2), opf_none);
01983 get_expr_operands (stmt, &TREE_OPERAND (expr, 3), opf_none);
01984 }
01985
01986 return;
01987 }
01988
01989 case WITH_SIZE_EXPR:
01990
01991
01992 get_expr_operands (stmt, &TREE_OPERAND (expr, 1), opf_none);
01993 get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags);
01994 return;
01995
01996 case CALL_EXPR:
01997 get_call_expr_operands (stmt, expr);
01998 return;
01999
02000 case COND_EXPR:
02001 case VEC_COND_EXPR:
02002 get_expr_operands (stmt, &TREE_OPERAND (expr, 0), opf_none);
02003 get_expr_operands (stmt, &TREE_OPERAND (expr, 1), opf_none);
02004 get_expr_operands (stmt, &TREE_OPERAND (expr, 2), opf_none);
02005 return;
02006
02007 case MODIFY_EXPR:
02008 get_modify_expr_operands (stmt, expr);
02009 return;
02010
02011 case CONSTRUCTOR:
02012 {
02013
02014
02015 constructor_elt *ce;
02016 unsigned HOST_WIDE_INT idx;
02017
02018 for (idx = 0;
02019 VEC_iterate (constructor_elt, CONSTRUCTOR_ELTS (expr), idx, ce);
02020 idx++)
02021 get_expr_operands (stmt, &ce->value, opf_none);
02022
02023 return;
02024 }
02025
02026 case BIT_FIELD_REF:
02027
02028 flags &= ~opf_kill_def;
02029
02030
02031
02032 case TRUTH_NOT_EXPR:
02033 case VIEW_CONVERT_EXPR:
02034 do_unary:
02035 get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags);
02036 return;
02037
02038 case TRUTH_AND_EXPR:
02039 case TRUTH_OR_EXPR:
02040 case TRUTH_XOR_EXPR:
02041 case COMPOUND_EXPR:
02042 case OBJ_TYPE_REF:
02043 case ASSERT_EXPR:
02044 do_binary:
02045 {
02046 get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags);
02047 get_expr_operands (stmt, &TREE_OPERAND (expr, 1), flags);
02048 return;
02049 }
02050
02051 case DOT_PROD_EXPR:
02052 case REALIGN_LOAD_EXPR:
02053 {
02054 get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags);
02055 get_expr_operands (stmt, &TREE_OPERAND (expr, 1), flags);
02056 get_expr_operands (stmt, &TREE_OPERAND (expr, 2), flags);
02057 return;
02058 }
02059
02060 case BLOCK:
02061 case FUNCTION_DECL:
02062 case EXC_PTR_EXPR:
02063 case FILTER_EXPR:
02064 case LABEL_DECL:
02065 case CONST_DECL:
02066 case OMP_PARALLEL:
02067 case OMP_SECTIONS:
02068 case OMP_FOR:
02069 case OMP_SINGLE:
02070 case OMP_MASTER:
02071 case OMP_ORDERED:
02072 case OMP_CRITICAL:
02073 case OMP_RETURN:
02074 case OMP_CONTINUE:
02075
02076 return;
02077
02078 default:
02079 if (class == tcc_unary)
02080 goto do_unary;
02081 if (class == tcc_binary || class == tcc_comparison)
02082 goto do_binary;
02083 if (class == tcc_constant || class == tcc_type)
02084 return;
02085 }
02086
02087
02088 #ifdef ENABLE_CHECKING
02089 fprintf (stderr, "unhandled expression in get_expr_operands():\n");
02090 debug_tree (expr);
02091 fputs ("\n", stderr);
02092 #endif
02093 gcc_unreachable ();
02094 }
02095
02096
02097
02098
02099
02100 static void
02101 parse_ssa_operands (tree stmt)
02102 {
02103 enum tree_code code;
02104
02105 code = TREE_CODE (stmt);
02106 switch (code)
02107 {
02108 case MODIFY_EXPR:
02109 get_modify_expr_operands (stmt, stmt);
02110 break;
02111
02112 case COND_EXPR:
02113 get_expr_operands (stmt, &COND_EXPR_COND (stmt), opf_none);
02114 break;
02115
02116 case SWITCH_EXPR:
02117 get_expr_operands (stmt, &SWITCH_COND (stmt), opf_none);
02118 break;
02119
02120 case ASM_EXPR:
02121 get_asm_expr_operands (stmt);
02122 break;
02123
02124 case RETURN_EXPR:
02125 get_expr_operands (stmt, &TREE_OPERAND (stmt, 0), opf_none);
02126 break;
02127
02128 case GOTO_EXPR:
02129 get_expr_operands (stmt, &GOTO_DESTINATION (stmt), opf_none);
02130 break;
02131
02132 case LABEL_EXPR:
02133 get_expr_operands (stmt, &LABEL_EXPR_LABEL (stmt), opf_none);
02134 break;
02135
02136 case BIND_EXPR:
02137 case CASE_LABEL_EXPR:
02138 case TRY_CATCH_EXPR:
02139 case TRY_FINALLY_EXPR:
02140 case EH_FILTER_EXPR:
02141 case CATCH_EXPR:
02142 case RESX_EXPR:
02143
02144 break;
02145
02146 default:
02147
02148
02149
02150
02151
02152 get_expr_operands (stmt, &stmt, opf_none);
02153 break;
02154 }
02155 }
02156
02157
02158
02159
02160 static void
02161 build_ssa_operands (tree stmt)
02162 {
02163 stmt_ann_t ann = get_stmt_ann (stmt);
02164
02165
02166 if (ann)
02167 ann->has_volatile_ops = false;
02168
02169 start_ssa_stmt_operands ();
02170
02171 parse_ssa_operands (stmt);
02172 operand_build_sort_virtual (build_vuses);
02173 operand_build_sort_virtual (build_v_may_defs);
02174 operand_build_sort_virtual (build_v_must_defs);
02175
02176 finalize_ssa_stmt_operands (stmt);
02177 }
02178
02179
02180
02181
02182 void
02183 free_ssa_operands (stmt_operands_p ops)
02184 {
02185 ops->def_ops = NULL;
02186 ops->use_ops = NULL;
02187 ops->maydef_ops = NULL;
02188 ops->mustdef_ops = NULL;
02189 ops->vuse_ops = NULL;
02190 }
02191
02192
02193
02194
02195 void
02196 update_stmt_operands (tree stmt)
02197 {
02198 stmt_ann_t ann = get_stmt_ann (stmt);
02199
02200
02201
02202 if (!ssa_operands_active ())
02203 return;
02204
02205
02206
02207 gcc_assert (!SSA_VAR_P (stmt));
02208
02209 gcc_assert (ann->modified);
02210
02211 timevar_push (TV_TREE_OPS);
02212
02213 build_ssa_operands (stmt);
02214
02215
02216 ann->modified = 0;
02217
02218 timevar_pop (TV_TREE_OPS);
02219 }
02220
02221
02222
02223
02224 void
02225 copy_virtual_operands (tree dest, tree src)
02226 {
02227 tree t;
02228 ssa_op_iter iter, old_iter;
02229 use_operand_p use_p, u2;
02230 def_operand_p def_p, d2;
02231
02232 build_ssa_operands (dest);
02233
02234
02235 FOR_EACH_SSA_TREE_OPERAND (t, src, iter, SSA_OP_VUSE)
02236 append_vuse (t);
02237 FOR_EACH_SSA_TREE_OPERAND (t, src, iter, SSA_OP_VMAYDEF)
02238 append_v_may_def (t);
02239 FOR_EACH_SSA_TREE_OPERAND (t, src, iter, SSA_OP_VMUSTDEF)
02240 append_v_must_def (t);
02241
02242 if (VEC_length (tree, build_vuses) == 0
02243 && VEC_length (tree, build_v_may_defs) == 0
02244 && VEC_length (tree, build_v_must_defs) == 0)
02245 return;
02246
02247
02248 finalize_ssa_v_must_defs (dest);
02249 finalize_ssa_v_may_defs (dest);
02250 finalize_ssa_vuses (dest);
02251
02252
02253 t = op_iter_init_tree (&old_iter, src, SSA_OP_VUSE);
02254 FOR_EACH_SSA_USE_OPERAND (use_p, dest, iter, SSA_OP_VUSE)
02255 {
02256 gcc_assert (!op_iter_done (&old_iter));
02257 SET_USE (use_p, t);
02258 t = op_iter_next_tree (&old_iter);
02259 }
02260 gcc_assert (op_iter_done (&old_iter));
02261
02262 op_iter_init_maydef (&old_iter, src, &u2, &d2);
02263 FOR_EACH_SSA_MAYDEF_OPERAND (def_p, use_p, dest, iter)
02264 {
02265 gcc_assert (!op_iter_done (&old_iter));
02266 SET_USE (use_p, USE_FROM_PTR (u2));
02267 SET_DEF (def_p, DEF_FROM_PTR (d2));
02268 op_iter_next_maymustdef (&u2, &d2, &old_iter);
02269 }
02270 gcc_assert (op_iter_done (&old_iter));
02271
02272 op_iter_init_mustdef (&old_iter, src, &u2, &d2);
02273 FOR_EACH_SSA_MUSTDEF_OPERAND (def_p, use_p, dest, iter)
02274 {
02275 gcc_assert (!op_iter_done (&old_iter));
02276 SET_USE (use_p, USE_FROM_PTR (u2));
02277 SET_DEF (def_p, DEF_FROM_PTR (d2));
02278 op_iter_next_maymustdef (&u2, &d2, &old_iter);
02279 }
02280 gcc_assert (op_iter_done (&old_iter));
02281
02282 }
02283
02284
02285
02286
02287
02288
02289
02290
02291 void
02292 create_ssa_artficial_load_stmt (tree new_stmt, tree old_stmt)
02293 {
02294 stmt_ann_t ann;
02295 tree op;
02296 ssa_op_iter iter;
02297 use_operand_p use_p;
02298 unsigned x;
02299
02300 ann = get_stmt_ann (new_stmt);
02301
02302
02303 start_ssa_stmt_operands ();
02304 parse_ssa_operands (new_stmt);
02305
02306 for (x = 0; x < VEC_length (tree, build_vuses); x++)
02307 {
02308 tree t = VEC_index (tree, build_vuses, x);
02309 if (TREE_CODE (t) != SSA_NAME)
02310 {
02311 var_ann_t ann = var_ann (t);
02312 ann->in_vuse_list = 0;
02313 }
02314 }
02315
02316 for (x = 0; x < VEC_length (tree, build_v_may_defs); x++)
02317 {
02318 tree t = VEC_index (tree, build_v_may_defs, x);
02319 if (TREE_CODE (t) != SSA_NAME)
02320 {
02321 var_ann_t ann = var_ann (t);
02322 ann->in_v_may_def_list = 0;
02323 }
02324 }
02325
02326
02327 VEC_truncate (tree, build_v_may_defs, 0);
02328 VEC_truncate (tree, build_v_must_defs, 0);
02329 VEC_truncate (tree, build_vuses, 0);
02330
02331
02332
02333
02334 FOR_EACH_SSA_TREE_OPERAND (op, old_stmt, iter,
02335 (SSA_OP_VMAYDEF | SSA_OP_VMUSTDEF))
02336 append_vuse (op);
02337
02338
02339 finalize_ssa_stmt_operands (new_stmt);
02340
02341
02342 FOR_EACH_SSA_USE_OPERAND (use_p, new_stmt, iter, SSA_OP_ALL_USES)
02343 delink_imm_use (use_p);
02344 }
02345
02346
02347
02348
02349
02350 void
02351 swap_tree_operands (tree stmt, tree *exp0, tree *exp1)
02352 {
02353 tree op0, op1;
02354 op0 = *exp0;
02355 op1 = *exp1;
02356
02357
02358
02359
02360 if (ssa_operands_active () && op0 != op1)
02361 {
02362 use_optype_p use0, use1, ptr;
02363 use0 = use1 = NULL;
02364
02365
02366 for (ptr = USE_OPS (stmt); ptr; ptr = ptr->next)
02367 if (USE_OP_PTR (ptr)->use == exp0)
02368 {
02369 use0 = ptr;
02370 break;
02371 }
02372
02373 for (ptr = USE_OPS (stmt); ptr; ptr = ptr->next)
02374 if (USE_OP_PTR (ptr)->use == exp1)
02375 {
02376 use1 = ptr;
02377 break;
02378 }
02379
02380
02381
02382 if (use0 && use1)
02383 {
02384 tree *tmp = USE_OP_PTR (use1)->use;
02385 USE_OP_PTR (use1)->use = USE_OP_PTR (use0)->use;
02386 USE_OP_PTR (use0)->use = tmp;
02387 }
02388 }
02389
02390
02391 *exp0 = op1;
02392 *exp1 = op0;
02393 }
02394
02395
02396
02397
02398
02399
02400
02401
02402
02403 void
02404 add_to_addressable_set (tree ref, bitmap *addresses_taken)
02405 {
02406 tree var;
02407 subvar_t svars;
02408
02409 gcc_assert (addresses_taken);
02410
02411
02412
02413
02414
02415
02416 var = get_base_address (ref);
02417 if (var && SSA_VAR_P (var))
02418 {
02419 if (*addresses_taken == NULL)
02420 *addresses_taken = BITMAP_GGC_ALLOC ();
02421
02422 if (var_can_have_subvars (var)
02423 && (svars = get_subvars_for_var (var)))
02424 {
02425 subvar_t sv;
02426 for (sv = svars; sv; sv = sv->next)
02427 {
02428 bitmap_set_bit (*addresses_taken, DECL_UID (sv->var));
02429 TREE_ADDRESSABLE (sv->var) = 1;
02430 }
02431 }
02432 else
02433 {
02434 bitmap_set_bit (*addresses_taken, DECL_UID (var));
02435 TREE_ADDRESSABLE (var) = 1;
02436 }
02437 }
02438 }
02439
02440
02441
02442
02443
02444 bool
02445 verify_imm_links (FILE *f, tree var)
02446 {
02447 use_operand_p ptr, prev, list;
02448 int count;
02449
02450 gcc_assert (TREE_CODE (var) == SSA_NAME);
02451
02452 list = &(SSA_NAME_IMM_USE_NODE (var));
02453 gcc_assert (list->use == NULL);
02454
02455 if (list->prev == NULL)
02456 {
02457 gcc_assert (list->next == NULL);
02458 return false;
02459 }
02460
02461 prev = list;
02462 count = 0;
02463 for (ptr = list->next; ptr != list; )
02464 {
02465 if (prev != ptr->prev)
02466 goto error;
02467
02468 if (ptr->use == NULL)
02469 goto error;
02470 else if (*(ptr->use) != var)
02471 goto error;
02472
02473 prev = ptr;
02474 ptr = ptr->next;
02475
02476
02477
02478 if (count++ > 50000000)
02479 goto error;
02480 }
02481
02482
02483 prev = list;
02484 for (ptr = list->prev; ptr != list; )
02485 {
02486 if (prev != ptr->next)
02487 goto error;
02488 prev = ptr;
02489 ptr = ptr->prev;
02490 if (count-- < 0)
02491 goto error;
02492 }
02493
02494 if (count != 0)
02495 goto error;
02496
02497 return false;
02498
02499 error:
02500 if (ptr->stmt && stmt_modified_p (ptr->stmt))
02501 {
02502 fprintf (f, " STMT MODIFIED. - <%p> ", (void *)ptr->stmt);
02503 print_generic_stmt (f, ptr->stmt, TDF_SLIM);
02504 }
02505 fprintf (f, " IMM ERROR : (use_p : tree - %p:%p)", (void *)ptr,
02506 (void *)ptr->use);
02507 print_generic_expr (f, USE_FROM_PTR (ptr), TDF_SLIM);
02508 fprintf(f, "\n");
02509 return true;
02510 }
02511
02512
02513
02514
02515 void
02516 dump_immediate_uses_for (FILE *file, tree var)
02517 {
02518 imm_use_iterator iter;
02519 use_operand_p use_p;
02520
02521 gcc_assert (var && TREE_CODE (var) == SSA_NAME);
02522
02523 print_generic_expr (file, var, TDF_SLIM);
02524 fprintf (file, " : -->");
02525 if (has_zero_uses (var))
02526 fprintf (file, " no uses.\n");
02527 else
02528 if (has_single_use (var))
02529 fprintf (file, " single use.\n");
02530 else
02531 fprintf (file, "%d uses.\n", num_imm_uses (var));
02532
02533 FOR_EACH_IMM_USE_FAST (use_p, iter, var)
02534 {
02535 if (use_p->stmt == NULL && use_p->use == NULL)
02536 fprintf (file, "***end of stmt iterator marker***\n");
02537 else
02538 if (!is_gimple_reg (USE_FROM_PTR (use_p)))
02539 print_generic_stmt (file, USE_STMT (use_p), TDF_VOPS);
02540 else
02541 print_generic_stmt (file, USE_STMT (use_p), TDF_SLIM);
02542 }
02543 fprintf(file, "\n");
02544 }
02545
02546
02547
02548
02549 void
02550 dump_immediate_uses (FILE *file)
02551 {
02552 tree var;
02553 unsigned int x;
02554
02555 fprintf (file, "Immediate_uses: \n\n");
02556 for (x = 1; x < num_ssa_names; x++)
02557 {
02558 var = ssa_name(x);
02559 if (!var)
02560 continue;
02561 dump_immediate_uses_for (file, var);
02562 }
02563 }
02564
02565
02566
02567
02568 void
02569 debug_immediate_uses (void)
02570 {
02571 dump_immediate_uses (stderr);
02572 }
02573
02574
02575
02576
02577 void
02578 debug_immediate_uses_for (tree var)
02579 {
02580 dump_immediate_uses_for (stderr, var);
02581 }
02582
02583 #include "gt-tree-ssa-operands.h"