+/* STMT is a statement of the form SSA_NAME = ADDR_EXPR <whatever>.
+
+ 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 = all && forward_propagate_addr_expr_1 (stmt, use_stmt);
+ }
+
+ return all;
+}
+
+