+ 0 /* todo_flags_finish */
+ }
+};
+
+/* Compute TREE_ADDRESSABLE for local variables. */
+
+static unsigned int
+execute_update_addresses_taken (void)
+{
+ tree var;
+ referenced_var_iterator rvi;
+ gimple_stmt_iterator gsi;
+ basic_block bb;
+ bitmap addresses_taken = BITMAP_ALLOC (NULL);
+ bitmap vars_updated = BITMAP_ALLOC (NULL);
+ bool update_vops = false;
+
+ /* Collect into ADDRESSES_TAKEN all variables whose address is taken within
+ the function body. */
+ FOR_EACH_BB (bb)
+ {
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ bitmap taken = gimple_addresses_taken (gsi_stmt (gsi));
+ if (taken)
+ bitmap_ior_into (addresses_taken, taken);
+ }
+
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ size_t i;
+ gimple phi = gsi_stmt (gsi);
+
+ for (i = 0; i < gimple_phi_num_args (phi); i++)
+ {
+ tree op = PHI_ARG_DEF (phi, i), var;
+ if (TREE_CODE (op) == ADDR_EXPR
+ && (var = get_base_address (TREE_OPERAND (op, 0))) != NULL
+ && DECL_P (var))
+ bitmap_set_bit (addresses_taken, DECL_UID (var));
+ }
+ }
+ }
+
+ /* When possible, clear ADDRESSABLE bit and mark variable for conversion into
+ SSA. */
+ FOR_EACH_REFERENCED_VAR (var, rvi)
+ if (!is_global_var (var)
+ && TREE_CODE (var) != RESULT_DECL
+ && TREE_ADDRESSABLE (var)
+ && !bitmap_bit_p (addresses_taken, DECL_UID (var)))
+ {
+ TREE_ADDRESSABLE (var) = 0;
+ if (is_gimple_reg (var))
+ mark_sym_for_renaming (var);
+ update_vops = true;
+ bitmap_set_bit (vars_updated, DECL_UID (var));
+ if (dump_file)
+ {
+ fprintf (dump_file, "No longer having address taken ");
+ print_generic_expr (dump_file, var, 0);
+ fprintf (dump_file, "\n");
+ }
+ }
+
+ /* Operand caches needs to be recomputed for operands referencing the updated
+ variables. */
+ if (update_vops)
+ FOR_EACH_BB (bb)
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple stmt = gsi_stmt (gsi);
+
+ if ((gimple_loaded_syms (stmt)
+ && bitmap_intersect_p (gimple_loaded_syms (stmt), vars_updated))
+ || (gimple_stored_syms (stmt)
+ && bitmap_intersect_p (gimple_stored_syms (stmt), vars_updated)))
+ update_stmt (stmt);
+ }
+ BITMAP_FREE (addresses_taken);
+ BITMAP_FREE (vars_updated);
+ return 0;
+}
+
+struct gimple_opt_pass pass_update_address_taken =
+{
+ {
+ GIMPLE_PASS,
+ "addressables", /* name */
+ NULL, /* gate */
+ execute_update_addresses_taken, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ 0, /* tv_id */
+ PROP_ssa, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_update_ssa /* todo_flags_finish */
+ }