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