Index: tree-ssa-forwprop.c =================================================================== *** tree-ssa-forwprop.c (revision 107870) --- tree-ssa-forwprop.c (working copy) *************** forward_propagate_addr_into_variable_arr *** 528,563 **** /* STMT is a statement of the form SSA_NAME = ADDR_EXPR . ! Try to forward propagate the ADDR_EXPR into the uses of the SSA_NAME. Often this will allow for removal of an ADDR_EXPR and INDIRECT_REF ! node or for recovery of array indexing from pointer arithmetic. */ static bool ! forward_propagate_addr_expr (tree stmt) { - int stmt_loop_depth = bb_for_stmt (stmt)->loop_depth; tree name = TREE_OPERAND (stmt, 0); ! use_operand_p imm_use; ! tree use_stmt, lhs, rhs, array_ref; ! ! /* We require that the SSA_NAME holding the result of the ADDR_EXPR ! be used only once. That may be overly conservative in that we ! could propagate into multiple uses. However, that would effectively ! be un-cseing the ADDR_EXPR, which is probably not what we want. */ ! single_imm_use (name, &imm_use, &use_stmt); ! if (!use_stmt) ! return false; ! ! /* If the use is not in a simple assignment statement, then ! there is nothing we can do. */ ! if (TREE_CODE (use_stmt) != MODIFY_EXPR) ! return false; ! ! /* If the use is in a deeper loop nest, then we do not want ! to propagate the ADDR_EXPR into the loop as that is likely ! adding expression evaluations into the loop. */ ! if (bb_for_stmt (use_stmt)->loop_depth > stmt_loop_depth) ! return false; /* Strip away any outer COMPONENT_REF/ARRAY_REF nodes from the LHS. ADDR_EXPR will not appear on the LHS. */ --- 528,543 ---- /* STMT is a statement of the form SSA_NAME = ADDR_EXPR . ! Try to forward propagate the ADDR_EXPR into the use USE_STMT. Often this will allow for removal of an ADDR_EXPR and INDIRECT_REF ! node or for recovery of array indexing from pointer arithmetic. ! Return true, if the propagation was successful. */ static bool ! forward_propagate_addr_expr_1 (tree stmt, tree use_stmt) { tree name = TREE_OPERAND (stmt, 0); ! tree lhs, rhs, array_ref; /* Strip away any outer COMPONENT_REF/ARRAY_REF nodes from the LHS. ADDR_EXPR will not appear on the LHS. */ *************** forward_propagate_addr_expr (tree stmt) *** 680,685 **** --- 660,709 ---- return false; } + /* STMT is a statement of the form SSA_NAME = ADDR_EXPR . + + Try to forward propagate the ADDR_EXPR into all uses of the SSA_NAME. + Often this will allow for removal of an ADDR_EXPR and INDIRECT_REF + node or for recovery of array indexing from pointer arithmetic. + Returns true, if all uses have been propagated into. */ + + static bool + forward_propagate_addr_expr (tree stmt) + { + int stmt_loop_depth = bb_for_stmt (stmt)->loop_depth; + tree name = TREE_OPERAND (stmt, 0); + use_operand_p imm_use; + imm_use_iterator iter; + bool all = true; + + FOR_EACH_IMM_USE_SAFE (imm_use, iter, name) + { + tree use_stmt = USE_STMT (imm_use); + + /* If the use is not in a simple assignment statement, then + there is nothing we can do. */ + if (TREE_CODE (use_stmt) != MODIFY_EXPR) + { + all = false; + continue; + } + + /* If the use is in a deeper loop nest, then we do not want + to propagate the ADDR_EXPR into the loop as that is likely + adding expression evaluations into the loop. */ + if (bb_for_stmt (use_stmt)->loop_depth > stmt_loop_depth) + { + all = false; + continue; + } + + all = forward_propagate_addr_expr_1 (stmt, use_stmt) && all; + } + + return all; + } + + /* Main entry point for the forward propagation optimizer. */ static void