Mercurial > hg > CbC > CbC_gcc
comparison gcc/tree-ssa-uninit.c @ 67:f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 22 Mar 2011 17:18:12 +0900 |
parents | b7f97abdc517 |
children | 04ced10e8804 |
comparison
equal
deleted
inserted
replaced
65:65488c3d617d | 67:f6334be47118 |
---|---|
27 #include "flags.h" | 27 #include "flags.h" |
28 #include "tm_p.h" | 28 #include "tm_p.h" |
29 #include "langhooks.h" | 29 #include "langhooks.h" |
30 #include "basic-block.h" | 30 #include "basic-block.h" |
31 #include "output.h" | 31 #include "output.h" |
32 #include "expr.h" | |
33 #include "function.h" | 32 #include "function.h" |
34 #include "diagnostic.h" | |
35 #include "gimple-pretty-print.h" | 33 #include "gimple-pretty-print.h" |
36 #include "bitmap.h" | 34 #include "bitmap.h" |
37 #include "pointer-set.h" | 35 #include "pointer-set.h" |
38 #include "tree-flow.h" | 36 #include "tree-flow.h" |
39 #include "gimple.h" | 37 #include "gimple.h" |
40 #include "tree-inline.h" | 38 #include "tree-inline.h" |
41 #include "timevar.h" | 39 #include "timevar.h" |
42 #include "hashtab.h" | 40 #include "hashtab.h" |
43 #include "tree-dump.h" | 41 #include "tree-dump.h" |
44 #include "tree-pass.h" | 42 #include "tree-pass.h" |
45 #include "toplev.h" | 43 #include "diagnostic-core.h" |
46 #include "timevar.h" | 44 #include "timevar.h" |
47 | 45 |
48 /* This implements the pass that does predicate aware warning on uses of | 46 /* This implements the pass that does predicate aware warning on uses of |
49 possibly uninitialized variables. The pass first collects the set of | 47 possibly uninitialized variables. The pass first collects the set of |
50 possibly uninitialized SSA names. For each such name, it walks through | 48 possibly uninitialized SSA names. For each such name, it walks through |
92 | 90 |
93 /* Parameters get their initial value from the function entry. */ | 91 /* Parameters get their initial value from the function entry. */ |
94 if (TREE_CODE (var) == PARM_DECL) | 92 if (TREE_CODE (var) == PARM_DECL) |
95 return false; | 93 return false; |
96 | 94 |
95 /* When returning by reference the return address is actually a hidden | |
96 parameter. */ | |
97 if (TREE_CODE (SSA_NAME_VAR (t)) == RESULT_DECL | |
98 && DECL_BY_REFERENCE (SSA_NAME_VAR (t))) | |
99 return false; | |
100 | |
97 /* Hard register variables get their initial value from the ether. */ | 101 /* Hard register variables get their initial value from the ether. */ |
98 if (TREE_CODE (var) == VAR_DECL && DECL_HARD_REGISTER (var)) | 102 if (TREE_CODE (var) == VAR_DECL && DECL_HARD_REGISTER (var)) |
99 return false; | 103 return false; |
100 | 104 |
101 /* The value is undefined iff its definition statement is empty. */ | 105 /* The value is undefined iff its definition statement is empty. */ |
142 { | 146 { |
143 size_t i, n; | 147 size_t i, n; |
144 unsigned uninit_opnds = 0; | 148 unsigned uninit_opnds = 0; |
145 | 149 |
146 n = gimple_phi_num_args (phi); | 150 n = gimple_phi_num_args (phi); |
151 /* Bail out for phi with too many args. */ | |
152 if (n > 32) | |
153 return 0; | |
147 | 154 |
148 for (i = 0; i < n; ++i) | 155 for (i = 0; i < n; ++i) |
149 { | 156 { |
150 tree op = gimple_phi_arg_def (phi, i); | 157 tree op = gimple_phi_arg_def (phi, i); |
151 if (TREE_CODE (op) == SSA_NAME | 158 if (TREE_CODE (op) == SSA_NAME |
483 for (i = 0; i < n; i++) | 490 for (i = 0; i < n; i++) |
484 { | 491 { |
485 opnd_edge = gimple_phi_arg_edge (phi, i); | 492 opnd_edge = gimple_phi_arg_edge (phi, i); |
486 opnd = gimple_phi_arg_def (phi, i); | 493 opnd = gimple_phi_arg_def (phi, i); |
487 | 494 |
488 if (TREE_CODE (opnd) != SSA_NAME | 495 if (TREE_CODE (opnd) != SSA_NAME) |
489 || !ssa_undefined_value_p (opnd)) | 496 { |
490 VEC_safe_push (edge, heap, *edges, opnd_edge); | 497 if (dump_file && (dump_flags & TDF_DETAILS)) |
498 { | |
499 fprintf (dump_file, "\n[CHECK] Found def edge %d in ", (int)i); | |
500 print_gimple_stmt (dump_file, phi, 0, 0); | |
501 } | |
502 VEC_safe_push (edge, heap, *edges, opnd_edge); | |
503 } | |
491 else | 504 else |
492 { | 505 { |
493 gimple def = SSA_NAME_DEF_STMT (opnd); | 506 gimple def = SSA_NAME_DEF_STMT (opnd); |
507 | |
494 if (gimple_code (def) == GIMPLE_PHI | 508 if (gimple_code (def) == GIMPLE_PHI |
495 && dominated_by_p (CDI_DOMINATORS, | 509 && dominated_by_p (CDI_DOMINATORS, |
496 gimple_bb (def), cd_root)) | 510 gimple_bb (def), cd_root)) |
497 collect_phi_def_edges (def, cd_root, edges, | 511 collect_phi_def_edges (def, cd_root, edges, |
498 visited_phis); | 512 visited_phis); |
513 else if (!ssa_undefined_value_p (opnd)) | |
514 { | |
515 if (dump_file && (dump_flags & TDF_DETAILS)) | |
516 { | |
517 fprintf (dump_file, "\n[CHECK] Found def edge %d in ", (int)i); | |
518 print_gimple_stmt (dump_file, phi, 0, 0); | |
519 } | |
520 VEC_safe_push (edge, heap, *edges, opnd_edge); | |
521 } | |
499 } | 522 } |
500 } | 523 } |
501 } | 524 } |
502 | 525 |
503 /* For each use edge of PHI, computes all control dependence chains. | 526 /* For each use edge of PHI, computes all control dependence chains. |
759 basic_block use_bb, | 782 basic_block use_bb, |
760 gimple phi, | 783 gimple phi, |
761 unsigned uninit_opnds, | 784 unsigned uninit_opnds, |
762 struct pointer_set_t *visited_phis); | 785 struct pointer_set_t *visited_phis); |
763 | 786 |
764 /* A helper function that determines if the predicate set | 787 /* Returns true if all uninitialized opnds are pruned. Returns false |
765 of the use is not overlapping with that of the uninit paths. | 788 otherwise. PHI is the phi node with uninitialized operands, |
766 The most common senario of guarded use is in Example 1: | 789 UNINIT_OPNDS is the bitmap of the uninitialize operand positions, |
767 Example 1: | 790 FLAG_DEF is the statement defining the flag guarding the use of the |
768 if (some_cond) | 791 PHI output, BOUNDARY_CST is the const value used in the predicate |
769 { | 792 associated with the flag, CMP_CODE is the comparison code used in |
770 x = ...; | 793 the predicate, VISITED_PHIS is the pointer set of phis visited, and |
771 flag = true; | 794 VISITED_FLAG_PHIS is the pointer to the pointer set of flag definitions |
772 } | 795 that are also phis. |
773 | 796 |
774 ... some code ... | 797 Example scenario: |
775 | 798 |
776 if (flag) | 799 BB1: |
777 use (x); | 800 flag_1 = phi <0, 1> // (1) |
778 | 801 var_1 = phi <undef, some_val> |
779 The real world examples are usually more complicated, but similar | 802 |
780 and usually result from inlining: | 803 |
781 | 804 BB2: |
782 bool init_func (int * x) | 805 flag_2 = phi <0, flag_1, flag_1> // (2) |
783 { | 806 var_2 = phi <undef, var_1, var_1> |
784 if (some_cond) | 807 if (flag_2 == 1) |
785 return false; | 808 goto BB3; |
786 *x = .. | 809 |
787 return true; | 810 BB3: |
788 } | 811 use of var_2 // (3) |
789 | 812 |
790 void foo(..) | 813 Because some flag arg in (1) is not constant, if we do not look into the |
791 { | 814 flag phis recursively, it is conservatively treated as unknown and var_1 |
792 int x; | 815 is thought to be flowed into use at (3). Since var_1 is potentially uninitialized |
793 | 816 a false warning will be emitted. Checking recursively into (1), the compiler can |
794 if (!init_func(&x)) | 817 find out that only some_val (which is defined) can flow into (3) which is OK. |
795 return; | 818 |
796 | 819 */ |
797 .. some_code ... | 820 |
798 use (x); | 821 static bool |
799 } | 822 prune_uninit_phi_opnds_in_unrealizable_paths ( |
800 | |
801 Another possible use scenario is in the following trivial example: | |
802 | |
803 Example 2: | |
804 if (n > 0) | |
805 x = 1; | |
806 ... | |
807 if (n > 0) | |
808 { | |
809 if (m < 2) | |
810 .. = x; | |
811 } | |
812 | |
813 Predicate analysis needs to compute the composite predicate: | |
814 | |
815 1) 'x' use predicate: (n > 0) .AND. (m < 2) | |
816 2) 'x' default value (non-def) predicate: .NOT. (n > 0) | |
817 (the predicate chain for phi operand defs can be computed | |
818 starting from a bb that is control equivalent to the phi's | |
819 bb and is dominating the operand def.) | |
820 | |
821 and check overlapping: | |
822 (n > 0) .AND. (m < 2) .AND. (.NOT. (n > 0)) | |
823 <==> false | |
824 | |
825 This implementation provides framework that can handle | |
826 scenarios. (Note that many simple cases are handled properly | |
827 without the predicate analysis -- this is due to jump threading | |
828 transformation which eliminates the merge point thus makes | |
829 path sensitive analysis unnecessary.) | |
830 | |
831 NUM_PREDS is the number is the number predicate chains, PREDS is | |
832 the array of chains, PHI is the phi node whose incoming (undefined) | |
833 paths need to be pruned, and UNINIT_OPNDS is the bitmap holding | |
834 uninit operand positions. VISITED_PHIS is the pointer set of phi | |
835 stmts being checked. */ | |
836 | |
837 | |
838 static bool | |
839 use_pred_not_overlap_with_undef_path_pred ( | |
840 size_t num_preds, | |
841 VEC(use_pred_info_t, heap) **preds, | |
842 gimple phi, unsigned uninit_opnds, | 823 gimple phi, unsigned uninit_opnds, |
843 struct pointer_set_t *visited_phis) | 824 gimple flag_def, tree boundary_cst, |
844 { | 825 enum tree_code cmp_code, |
845 unsigned int i, n; | 826 struct pointer_set_t *visited_phis, |
846 gimple flag_def = 0; | 827 bitmap *visited_flag_phis) |
847 tree boundary_cst = 0; | 828 { |
848 enum tree_code cmp_code; | 829 unsigned i; |
849 bool swap_cond = false; | 830 |
850 bool invert = false; | 831 for (i = 0; i < MIN (32, gimple_phi_num_args (flag_def)); i++) |
851 VEC(use_pred_info_t, heap) *the_pred_chain; | |
852 | |
853 gcc_assert (num_preds > 0); | |
854 /* Find within the common prefix of multiple predicate chains | |
855 a predicate that is a comparison of a flag variable against | |
856 a constant. */ | |
857 the_pred_chain = preds[0]; | |
858 n = VEC_length (use_pred_info_t, the_pred_chain); | |
859 for (i = 0; i < n; i++) | |
860 { | |
861 gimple cond; | |
862 tree cond_lhs, cond_rhs, flag = 0; | |
863 | |
864 use_pred_info_t the_pred | |
865 = VEC_index (use_pred_info_t, the_pred_chain, i); | |
866 | |
867 cond = the_pred->cond; | |
868 invert = the_pred->invert; | |
869 cond_lhs = gimple_cond_lhs (cond); | |
870 cond_rhs = gimple_cond_rhs (cond); | |
871 cmp_code = gimple_cond_code (cond); | |
872 | |
873 if (cond_lhs != NULL_TREE && TREE_CODE (cond_lhs) == SSA_NAME | |
874 && cond_rhs != NULL_TREE && is_gimple_constant (cond_rhs)) | |
875 { | |
876 boundary_cst = cond_rhs; | |
877 flag = cond_lhs; | |
878 } | |
879 else if (cond_rhs != NULL_TREE && TREE_CODE (cond_rhs) == SSA_NAME | |
880 && cond_lhs != NULL_TREE && is_gimple_constant (cond_lhs)) | |
881 { | |
882 boundary_cst = cond_lhs; | |
883 flag = cond_rhs; | |
884 swap_cond = true; | |
885 } | |
886 | |
887 if (!flag) | |
888 continue; | |
889 | |
890 flag_def = SSA_NAME_DEF_STMT (flag); | |
891 | |
892 if (!flag_def) | |
893 continue; | |
894 | |
895 if ((gimple_code (flag_def) == GIMPLE_PHI) | |
896 && (gimple_bb (flag_def) == gimple_bb (phi)) | |
897 && find_matching_predicate_in_rest_chains ( | |
898 the_pred, preds, num_preds)) | |
899 break; | |
900 | |
901 flag_def = 0; | |
902 } | |
903 | |
904 if (!flag_def) | |
905 return false; | |
906 | |
907 /* Now check all the uninit incoming edge has a constant flag value | |
908 that is in conflict with the use guard/predicate. */ | |
909 cmp_code = get_cmp_code (cmp_code, swap_cond, invert); | |
910 | |
911 if (cmp_code == ERROR_MARK) | |
912 return false; | |
913 | |
914 for (i = 0; i < sizeof (unsigned); i++) | |
915 { | 832 { |
916 tree flag_arg; | 833 tree flag_arg; |
917 | 834 |
918 if (!MASK_TEST_BIT (uninit_opnds, i)) | 835 if (!MASK_TEST_BIT (uninit_opnds, i)) |
919 continue; | 836 continue; |
920 | 837 |
921 flag_arg = gimple_phi_arg_def (flag_def, i); | 838 flag_arg = gimple_phi_arg_def (flag_def, i); |
922 if (!is_gimple_constant (flag_arg)) | 839 if (!is_gimple_constant (flag_arg)) |
923 return false; | 840 { |
841 gimple flag_arg_def, phi_arg_def; | |
842 tree phi_arg; | |
843 unsigned uninit_opnds_arg_phi; | |
844 | |
845 if (TREE_CODE (flag_arg) != SSA_NAME) | |
846 return false; | |
847 flag_arg_def = SSA_NAME_DEF_STMT (flag_arg); | |
848 if (gimple_code (flag_arg_def) != GIMPLE_PHI) | |
849 return false; | |
850 | |
851 phi_arg = gimple_phi_arg_def (phi, i); | |
852 if (TREE_CODE (phi_arg) != SSA_NAME) | |
853 return false; | |
854 | |
855 phi_arg_def = SSA_NAME_DEF_STMT (phi_arg); | |
856 if (gimple_code (phi_arg_def) != GIMPLE_PHI) | |
857 return false; | |
858 | |
859 if (gimple_bb (phi_arg_def) != gimple_bb (flag_arg_def)) | |
860 return false; | |
861 | |
862 if (!*visited_flag_phis) | |
863 *visited_flag_phis = BITMAP_ALLOC (NULL); | |
864 | |
865 if (bitmap_bit_p (*visited_flag_phis, | |
866 SSA_NAME_VERSION (gimple_phi_result (flag_arg_def)))) | |
867 return false; | |
868 | |
869 bitmap_set_bit (*visited_flag_phis, | |
870 SSA_NAME_VERSION (gimple_phi_result (flag_arg_def))); | |
871 | |
872 /* Now recursively prune the uninitialized phi args. */ | |
873 uninit_opnds_arg_phi = compute_uninit_opnds_pos (phi_arg_def); | |
874 if (!prune_uninit_phi_opnds_in_unrealizable_paths ( | |
875 phi_arg_def, uninit_opnds_arg_phi, | |
876 flag_arg_def, boundary_cst, cmp_code, | |
877 visited_phis, visited_flag_phis)) | |
878 return false; | |
879 | |
880 bitmap_clear_bit (*visited_flag_phis, | |
881 SSA_NAME_VERSION (gimple_phi_result (flag_arg_def))); | |
882 continue; | |
883 } | |
924 | 884 |
925 /* Now check if the constant is in the guarded range. */ | 885 /* Now check if the constant is in the guarded range. */ |
926 if (is_value_included_in (flag_arg, boundary_cst, cmp_code)) | 886 if (is_value_included_in (flag_arg, boundary_cst, cmp_code)) |
927 { | 887 { |
928 tree opnd; | 888 tree opnd; |
955 } | 915 } |
956 | 916 |
957 return true; | 917 return true; |
958 } | 918 } |
959 | 919 |
920 /* A helper function that determines if the predicate set | |
921 of the use is not overlapping with that of the uninit paths. | |
922 The most common senario of guarded use is in Example 1: | |
923 Example 1: | |
924 if (some_cond) | |
925 { | |
926 x = ...; | |
927 flag = true; | |
928 } | |
929 | |
930 ... some code ... | |
931 | |
932 if (flag) | |
933 use (x); | |
934 | |
935 The real world examples are usually more complicated, but similar | |
936 and usually result from inlining: | |
937 | |
938 bool init_func (int * x) | |
939 { | |
940 if (some_cond) | |
941 return false; | |
942 *x = .. | |
943 return true; | |
944 } | |
945 | |
946 void foo(..) | |
947 { | |
948 int x; | |
949 | |
950 if (!init_func(&x)) | |
951 return; | |
952 | |
953 .. some_code ... | |
954 use (x); | |
955 } | |
956 | |
957 Another possible use scenario is in the following trivial example: | |
958 | |
959 Example 2: | |
960 if (n > 0) | |
961 x = 1; | |
962 ... | |
963 if (n > 0) | |
964 { | |
965 if (m < 2) | |
966 .. = x; | |
967 } | |
968 | |
969 Predicate analysis needs to compute the composite predicate: | |
970 | |
971 1) 'x' use predicate: (n > 0) .AND. (m < 2) | |
972 2) 'x' default value (non-def) predicate: .NOT. (n > 0) | |
973 (the predicate chain for phi operand defs can be computed | |
974 starting from a bb that is control equivalent to the phi's | |
975 bb and is dominating the operand def.) | |
976 | |
977 and check overlapping: | |
978 (n > 0) .AND. (m < 2) .AND. (.NOT. (n > 0)) | |
979 <==> false | |
980 | |
981 This implementation provides framework that can handle | |
982 scenarios. (Note that many simple cases are handled properly | |
983 without the predicate analysis -- this is due to jump threading | |
984 transformation which eliminates the merge point thus makes | |
985 path sensitive analysis unnecessary.) | |
986 | |
987 NUM_PREDS is the number is the number predicate chains, PREDS is | |
988 the array of chains, PHI is the phi node whose incoming (undefined) | |
989 paths need to be pruned, and UNINIT_OPNDS is the bitmap holding | |
990 uninit operand positions. VISITED_PHIS is the pointer set of phi | |
991 stmts being checked. */ | |
992 | |
993 | |
994 static bool | |
995 use_pred_not_overlap_with_undef_path_pred ( | |
996 size_t num_preds, | |
997 VEC(use_pred_info_t, heap) **preds, | |
998 gimple phi, unsigned uninit_opnds, | |
999 struct pointer_set_t *visited_phis) | |
1000 { | |
1001 unsigned int i, n; | |
1002 gimple flag_def = 0; | |
1003 tree boundary_cst = 0; | |
1004 enum tree_code cmp_code; | |
1005 bool swap_cond = false; | |
1006 bool invert = false; | |
1007 VEC(use_pred_info_t, heap) *the_pred_chain; | |
1008 bitmap visited_flag_phis = NULL; | |
1009 bool all_pruned = false; | |
1010 | |
1011 gcc_assert (num_preds > 0); | |
1012 /* Find within the common prefix of multiple predicate chains | |
1013 a predicate that is a comparison of a flag variable against | |
1014 a constant. */ | |
1015 the_pred_chain = preds[0]; | |
1016 n = VEC_length (use_pred_info_t, the_pred_chain); | |
1017 for (i = 0; i < n; i++) | |
1018 { | |
1019 gimple cond; | |
1020 tree cond_lhs, cond_rhs, flag = 0; | |
1021 | |
1022 use_pred_info_t the_pred | |
1023 = VEC_index (use_pred_info_t, the_pred_chain, i); | |
1024 | |
1025 cond = the_pred->cond; | |
1026 invert = the_pred->invert; | |
1027 cond_lhs = gimple_cond_lhs (cond); | |
1028 cond_rhs = gimple_cond_rhs (cond); | |
1029 cmp_code = gimple_cond_code (cond); | |
1030 | |
1031 if (cond_lhs != NULL_TREE && TREE_CODE (cond_lhs) == SSA_NAME | |
1032 && cond_rhs != NULL_TREE && is_gimple_constant (cond_rhs)) | |
1033 { | |
1034 boundary_cst = cond_rhs; | |
1035 flag = cond_lhs; | |
1036 } | |
1037 else if (cond_rhs != NULL_TREE && TREE_CODE (cond_rhs) == SSA_NAME | |
1038 && cond_lhs != NULL_TREE && is_gimple_constant (cond_lhs)) | |
1039 { | |
1040 boundary_cst = cond_lhs; | |
1041 flag = cond_rhs; | |
1042 swap_cond = true; | |
1043 } | |
1044 | |
1045 if (!flag) | |
1046 continue; | |
1047 | |
1048 flag_def = SSA_NAME_DEF_STMT (flag); | |
1049 | |
1050 if (!flag_def) | |
1051 continue; | |
1052 | |
1053 if ((gimple_code (flag_def) == GIMPLE_PHI) | |
1054 && (gimple_bb (flag_def) == gimple_bb (phi)) | |
1055 && find_matching_predicate_in_rest_chains ( | |
1056 the_pred, preds, num_preds)) | |
1057 break; | |
1058 | |
1059 flag_def = 0; | |
1060 } | |
1061 | |
1062 if (!flag_def) | |
1063 return false; | |
1064 | |
1065 /* Now check all the uninit incoming edge has a constant flag value | |
1066 that is in conflict with the use guard/predicate. */ | |
1067 cmp_code = get_cmp_code (cmp_code, swap_cond, invert); | |
1068 | |
1069 if (cmp_code == ERROR_MARK) | |
1070 return false; | |
1071 | |
1072 all_pruned = prune_uninit_phi_opnds_in_unrealizable_paths (phi, | |
1073 uninit_opnds, | |
1074 flag_def, | |
1075 boundary_cst, | |
1076 cmp_code, | |
1077 visited_phis, | |
1078 &visited_flag_phis); | |
1079 | |
1080 if (visited_flag_phis) | |
1081 BITMAP_FREE (visited_flag_phis); | |
1082 | |
1083 return all_pruned; | |
1084 } | |
1085 | |
960 /* Returns true if TC is AND or OR */ | 1086 /* Returns true if TC is AND or OR */ |
961 | 1087 |
962 static inline bool | 1088 static inline bool |
963 is_and_or_or (enum tree_code tc, tree typ) | 1089 is_and_or_or (enum tree_code tc, tree typ) |
964 { | 1090 { |
1523 return false; | 1649 return false; |
1524 } | 1650 } |
1525 | 1651 |
1526 if (dump_file) | 1652 if (dump_file) |
1527 dump_predicates (use_stmt, num_preds, preds, | 1653 dump_predicates (use_stmt, num_preds, preds, |
1528 "Use in stmt "); | 1654 "\nUse in stmt "); |
1529 | 1655 |
1530 has_valid_preds = find_def_preds (&def_preds, | 1656 has_valid_preds = find_def_preds (&def_preds, |
1531 &num_def_preds, phi); | 1657 &num_def_preds, phi); |
1532 | 1658 |
1533 if (has_valid_preds) | 1659 if (has_valid_preds) |
1575 FOR_EACH_IMM_USE_FAST (use_p, iter, phi_result) | 1701 FOR_EACH_IMM_USE_FAST (use_p, iter, phi_result) |
1576 { | 1702 { |
1577 struct pointer_set_t *visited_phis; | 1703 struct pointer_set_t *visited_phis; |
1578 basic_block use_bb; | 1704 basic_block use_bb; |
1579 | 1705 |
1580 use_stmt = use_p->loc.stmt; | 1706 use_stmt = USE_STMT (use_p); |
1707 if (is_gimple_debug (use_stmt)) | |
1708 continue; | |
1581 | 1709 |
1582 visited_phis = pointer_set_create (); | 1710 visited_phis = pointer_set_create (); |
1583 | 1711 |
1584 use_bb = gimple_bb (use_stmt); | |
1585 if (gimple_code (use_stmt) == GIMPLE_PHI) | 1712 if (gimple_code (use_stmt) == GIMPLE_PHI) |
1586 { | 1713 use_bb = gimple_phi_arg_edge (use_stmt, |
1587 unsigned i, n; | 1714 PHI_ARG_INDEX_FROM_USE (use_p))->src; |
1588 n = gimple_phi_num_args (use_stmt); | 1715 else |
1589 | 1716 use_bb = gimple_bb (use_stmt); |
1590 /* Find the matching phi argument of the use. */ | |
1591 for (i = 0; i < n; ++i) | |
1592 { | |
1593 if (gimple_phi_arg_def_ptr (use_stmt, i) == use_p->use) | |
1594 { | |
1595 edge e = gimple_phi_arg_edge (use_stmt, i); | |
1596 use_bb = e->src; | |
1597 break; | |
1598 } | |
1599 } | |
1600 } | |
1601 | 1717 |
1602 if (is_use_properly_guarded (use_stmt, | 1718 if (is_use_properly_guarded (use_stmt, |
1603 use_bb, | 1719 use_bb, |
1604 phi, | 1720 phi, |
1605 uninit_opnds, | 1721 uninit_opnds, |
1608 pointer_set_destroy (visited_phis); | 1724 pointer_set_destroy (visited_phis); |
1609 continue; | 1725 continue; |
1610 } | 1726 } |
1611 pointer_set_destroy (visited_phis); | 1727 pointer_set_destroy (visited_phis); |
1612 | 1728 |
1729 if (dump_file && (dump_flags & TDF_DETAILS)) | |
1730 { | |
1731 fprintf (dump_file, "[CHECK]: Found unguarded use: "); | |
1732 print_gimple_stmt (dump_file, use_stmt, 0, 0); | |
1733 } | |
1613 /* Found one real use, return. */ | 1734 /* Found one real use, return. */ |
1614 if (gimple_code (use_stmt) != GIMPLE_PHI) | 1735 if (gimple_code (use_stmt) != GIMPLE_PHI) |
1615 return use_stmt; | 1736 return use_stmt; |
1616 | 1737 |
1617 /* Found a phi use that is not guarded, | 1738 /* Found a phi use that is not guarded, |
1618 add the phi to the worklist. */ | 1739 add the phi to the worklist. */ |
1619 if (!pointer_set_insert (added_to_worklist, | 1740 if (!pointer_set_insert (added_to_worklist, |
1620 use_stmt)) | 1741 use_stmt)) |
1621 { | 1742 { |
1743 if (dump_file && (dump_flags & TDF_DETAILS)) | |
1744 { | |
1745 fprintf (dump_file, "[WORKLIST]: Update worklist with phi: "); | |
1746 print_gimple_stmt (dump_file, use_stmt, 0, 0); | |
1747 } | |
1748 | |
1622 VEC_safe_push (gimple, heap, *worklist, use_stmt); | 1749 VEC_safe_push (gimple, heap, *worklist, use_stmt); |
1623 pointer_set_insert (possibly_undefined_names, | 1750 pointer_set_insert (possibly_undefined_names, |
1624 phi_result); | 1751 phi_result); |
1625 } | 1752 } |
1626 } | 1753 } |
1650 | 1777 |
1651 uninit_opnds = compute_uninit_opnds_pos (phi); | 1778 uninit_opnds = compute_uninit_opnds_pos (phi); |
1652 | 1779 |
1653 if (MASK_EMPTY (uninit_opnds)) | 1780 if (MASK_EMPTY (uninit_opnds)) |
1654 return; | 1781 return; |
1782 | |
1783 if (dump_file && (dump_flags & TDF_DETAILS)) | |
1784 { | |
1785 fprintf (dump_file, "[CHECK]: examining phi: "); | |
1786 print_gimple_stmt (dump_file, phi, 0, 0); | |
1787 } | |
1655 | 1788 |
1656 /* Now check if we have any use of the value without proper guard. */ | 1789 /* Now check if we have any use of the value without proper guard. */ |
1657 uninit_use_stmt = find_uninit_use (phi, uninit_opnds, | 1790 uninit_use_stmt = find_uninit_use (phi, uninit_opnds, |
1658 worklist, added_to_worklist); | 1791 worklist, added_to_worklist); |
1659 | 1792 |
1710 if (TREE_CODE (op) == SSA_NAME | 1843 if (TREE_CODE (op) == SSA_NAME |
1711 && ssa_undefined_value_p (op)) | 1844 && ssa_undefined_value_p (op)) |
1712 { | 1845 { |
1713 VEC_safe_push (gimple, heap, worklist, phi); | 1846 VEC_safe_push (gimple, heap, worklist, phi); |
1714 pointer_set_insert (added_to_worklist, phi); | 1847 pointer_set_insert (added_to_worklist, phi); |
1848 if (dump_file && (dump_flags & TDF_DETAILS)) | |
1849 { | |
1850 fprintf (dump_file, "[WORKLIST]: add to initial list: "); | |
1851 print_gimple_stmt (dump_file, phi, 0, 0); | |
1852 } | |
1715 break; | 1853 break; |
1716 } | 1854 } |
1717 } | 1855 } |
1718 } | 1856 } |
1719 | 1857 |
1721 { | 1859 { |
1722 gimple cur_phi = 0; | 1860 gimple cur_phi = 0; |
1723 cur_phi = VEC_pop (gimple, worklist); | 1861 cur_phi = VEC_pop (gimple, worklist); |
1724 warn_uninitialized_phi (cur_phi, &worklist, added_to_worklist); | 1862 warn_uninitialized_phi (cur_phi, &worklist, added_to_worklist); |
1725 } | 1863 } |
1726 | 1864 |
1727 VEC_free (gimple, heap, worklist); | 1865 VEC_free (gimple, heap, worklist); |
1728 pointer_set_destroy (added_to_worklist); | 1866 pointer_set_destroy (added_to_worklist); |
1729 pointer_set_destroy (possibly_undefined_names); | 1867 pointer_set_destroy (possibly_undefined_names); |
1730 possibly_undefined_names = NULL; | 1868 possibly_undefined_names = NULL; |
1731 free_dominance_info (CDI_POST_DOMINATORS); | 1869 free_dominance_info (CDI_POST_DOMINATORS); |