Mercurial > hg > CbC > CbC_gcc
comparison gcc/tree-ssa-forwprop.c @ 63:b7f97abdc517 gcc-4.6-20100522
update gcc from gcc-4.5.0 to gcc-4.6
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 24 May 2010 12:47:05 +0900 |
parents | 77e2b8dfacca |
children | f6334be47118 |
comparison
equal
deleted
inserted
replaced
56:3c8a44c06a95 | 63:b7f97abdc517 |
---|---|
1 /* Forward propagation of expressions for single use variables. | 1 /* Forward propagation of expressions for single use variables. |
2 Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc. | 2 Copyright (C) 2004, 2005, 2007, 2008, 2009, 2010 |
3 Free Software Foundation, Inc. | |
3 | 4 |
4 This file is part of GCC. | 5 This file is part of GCC. |
5 | 6 |
6 GCC is free software; you can redistribute it and/or modify | 7 GCC is free software; you can redistribute it and/or modify |
7 it under the terms of the GNU General Public License as published by | 8 it under the terms of the GNU General Public License as published by |
19 | 20 |
20 #include "config.h" | 21 #include "config.h" |
21 #include "system.h" | 22 #include "system.h" |
22 #include "coretypes.h" | 23 #include "coretypes.h" |
23 #include "tm.h" | 24 #include "tm.h" |
24 #include "ggc.h" | |
25 #include "tree.h" | 25 #include "tree.h" |
26 #include "rtl.h" | |
27 #include "tm_p.h" | 26 #include "tm_p.h" |
28 #include "basic-block.h" | 27 #include "basic-block.h" |
29 #include "timevar.h" | 28 #include "timevar.h" |
30 #include "diagnostic.h" | 29 #include "diagnostic.h" |
30 #include "tree-pretty-print.h" | |
31 #include "tree-flow.h" | 31 #include "tree-flow.h" |
32 #include "tree-pass.h" | 32 #include "tree-pass.h" |
33 #include "tree-dump.h" | 33 #include "tree-dump.h" |
34 #include "langhooks.h" | 34 #include "langhooks.h" |
35 #include "flags.h" | 35 #include "flags.h" |
396 int did_something = 0; | 396 int did_something = 0; |
397 location_t loc = gimple_location (stmt); | 397 location_t loc = gimple_location (stmt); |
398 | 398 |
399 do { | 399 do { |
400 tree tmp = NULL_TREE; | 400 tree tmp = NULL_TREE; |
401 tree name, rhs0 = NULL_TREE, rhs1 = NULL_TREE; | 401 tree name = NULL_TREE, rhs0 = NULL_TREE, rhs1 = NULL_TREE; |
402 gimple def_stmt; | 402 gimple def_stmt; |
403 bool single_use0_p = false, single_use1_p = false; | 403 bool single_use0_p = false, single_use1_p = false; |
404 enum tree_code code = gimple_cond_code (stmt); | 404 enum tree_code code = gimple_cond_code (stmt); |
405 | 405 |
406 /* We can do tree combining on SSA_NAME and comparison expressions. */ | 406 /* We can do tree combining on SSA_NAME and comparison expressions. */ |
407 if (TREE_CODE_CLASS (gimple_cond_code (stmt)) == tcc_comparison | 407 if (TREE_CODE_CLASS (gimple_cond_code (stmt)) == tcc_comparison) |
408 && TREE_CODE (gimple_cond_lhs (stmt)) == SSA_NAME) | |
409 { | 408 { |
410 /* For comparisons use the first operand, that is likely to | 409 /* For comparisons use the first operand, that is likely to |
411 simplify comparisons against constants. */ | 410 simplify comparisons against constants. */ |
412 name = gimple_cond_lhs (stmt); | 411 if (TREE_CODE (gimple_cond_lhs (stmt)) == SSA_NAME) |
413 def_stmt = get_prop_source_stmt (name, false, &single_use0_p); | |
414 if (def_stmt && can_propagate_from (def_stmt)) | |
415 { | 412 { |
416 tree op1 = gimple_cond_rhs (stmt); | 413 name = gimple_cond_lhs (stmt); |
417 rhs0 = rhs_to_tree (TREE_TYPE (op1), def_stmt); | 414 def_stmt = get_prop_source_stmt (name, false, &single_use0_p); |
418 tmp = combine_cond_expr_cond (loc, code, boolean_type_node, rhs0, | 415 if (def_stmt && can_propagate_from (def_stmt)) |
419 op1, !single_use0_p); | 416 { |
417 tree op1 = gimple_cond_rhs (stmt); | |
418 rhs0 = rhs_to_tree (TREE_TYPE (op1), def_stmt); | |
419 tmp = combine_cond_expr_cond (loc, code, boolean_type_node, | |
420 rhs0, op1, !single_use0_p); | |
421 } | |
420 } | 422 } |
421 /* If that wasn't successful, try the second operand. */ | 423 /* If that wasn't successful, try the second operand. */ |
422 if (tmp == NULL_TREE | 424 if (tmp == NULL_TREE |
423 && TREE_CODE (gimple_cond_rhs (stmt)) == SSA_NAME) | 425 && TREE_CODE (gimple_cond_rhs (stmt)) == SSA_NAME) |
424 { | 426 { |
726 tree lhs, rhs, rhs2, array_ref; | 728 tree lhs, rhs, rhs2, array_ref; |
727 tree *rhsp, *lhsp; | 729 tree *rhsp, *lhsp; |
728 gimple use_stmt = gsi_stmt (*use_stmt_gsi); | 730 gimple use_stmt = gsi_stmt (*use_stmt_gsi); |
729 enum tree_code rhs_code; | 731 enum tree_code rhs_code; |
730 bool res = true; | 732 bool res = true; |
733 bool addr_p = false; | |
731 | 734 |
732 gcc_assert (TREE_CODE (def_rhs) == ADDR_EXPR); | 735 gcc_assert (TREE_CODE (def_rhs) == ADDR_EXPR); |
733 | 736 |
734 lhs = gimple_assign_lhs (use_stmt); | 737 lhs = gimple_assign_lhs (use_stmt); |
735 rhs_code = gimple_assign_rhs_code (use_stmt); | 738 rhs_code = gimple_assign_rhs_code (use_stmt); |
798 } | 801 } |
799 | 802 |
800 /* Strip away any outer COMPONENT_REF, ARRAY_REF or ADDR_EXPR | 803 /* Strip away any outer COMPONENT_REF, ARRAY_REF or ADDR_EXPR |
801 nodes from the RHS. */ | 804 nodes from the RHS. */ |
802 rhsp = gimple_assign_rhs1_ptr (use_stmt); | 805 rhsp = gimple_assign_rhs1_ptr (use_stmt); |
803 while (handled_component_p (*rhsp) | 806 if (TREE_CODE (*rhsp) == ADDR_EXPR) |
804 || TREE_CODE (*rhsp) == ADDR_EXPR) | 807 { |
808 rhsp = &TREE_OPERAND (*rhsp, 0); | |
809 addr_p = true; | |
810 } | |
811 while (handled_component_p (*rhsp)) | |
805 rhsp = &TREE_OPERAND (*rhsp, 0); | 812 rhsp = &TREE_OPERAND (*rhsp, 0); |
806 rhs = *rhsp; | 813 rhs = *rhsp; |
807 | 814 |
808 /* Now see if the RHS node is an INDIRECT_REF using NAME. If so, | 815 /* Now see if the RHS node is an INDIRECT_REF using NAME. If so, |
809 propagate the ADDR_EXPR into the use of NAME and fold the result. */ | 816 propagate the ADDR_EXPR into the use of NAME and fold the result. */ |
848 gimple_assign_set_rhs1 (use_stmt, new_rhs); | 855 gimple_assign_set_rhs1 (use_stmt, new_rhs); |
849 tidy_after_forward_propagate_addr (use_stmt); | 856 tidy_after_forward_propagate_addr (use_stmt); |
850 return res; | 857 return res; |
851 } | 858 } |
852 /* If the defining rhs comes from an indirect reference, then do not | 859 /* If the defining rhs comes from an indirect reference, then do not |
853 convert into a VIEW_CONVERT_EXPR. */ | 860 convert into a VIEW_CONVERT_EXPR. Likewise if we'll end up taking |
861 the address of a V_C_E of a constant. */ | |
854 def_rhs_base = TREE_OPERAND (def_rhs, 0); | 862 def_rhs_base = TREE_OPERAND (def_rhs, 0); |
855 while (handled_component_p (def_rhs_base)) | 863 while (handled_component_p (def_rhs_base)) |
856 def_rhs_base = TREE_OPERAND (def_rhs_base, 0); | 864 def_rhs_base = TREE_OPERAND (def_rhs_base, 0); |
857 if (!INDIRECT_REF_P (def_rhs_base)) | 865 if (!INDIRECT_REF_P (def_rhs_base) |
866 && (!addr_p | |
867 || !is_gimple_min_invariant (def_rhs))) | |
858 { | 868 { |
859 /* We may have arbitrary VIEW_CONVERT_EXPRs in a nested component | 869 /* We may have arbitrary VIEW_CONVERT_EXPRs in a nested component |
860 reference. Place it there and fold the thing. */ | 870 reference. Place it there and fold the thing. */ |
861 *rhsp = new_rhs; | 871 *rhsp = new_rhs; |
862 fold_stmt_inplace (use_stmt); | 872 fold_stmt_inplace (use_stmt); |
953 all = false; | 963 all = false; |
954 continue; | 964 continue; |
955 } | 965 } |
956 | 966 |
957 /* If the use is in a deeper loop nest, then we do not want | 967 /* If the use is in a deeper loop nest, then we do not want |
958 to propagate the ADDR_EXPR into the loop as that is likely | 968 to propagate non-invariant ADDR_EXPRs into the loop as that |
959 adding expression evaluations into the loop. */ | 969 is likely adding expression evaluations into the loop. */ |
960 if (gimple_bb (use_stmt)->loop_depth > stmt_loop_depth) | 970 if (gimple_bb (use_stmt)->loop_depth > stmt_loop_depth |
971 && !is_gimple_min_invariant (rhs)) | |
961 { | 972 { |
962 all = false; | 973 all = false; |
963 continue; | 974 continue; |
964 } | 975 } |
965 | 976 |