+
+/* Remove local variables that are not referenced in the IL. */
+
+void
+remove_unused_locals (void)
+{
+ basic_block bb;
+ tree t, *cell;
+
+ /* Assume all locals are unused. */
+ for (t = cfun->unexpanded_var_list; t; t = TREE_CHAIN (t))
+ {
+ tree var = TREE_VALUE (t);
+ if (TREE_CODE (var) != FUNCTION_DECL
+ && var_ann (var))
+ var_ann (var)->used = false;
+ }
+
+ /* Walk the CFG marking all referenced symbols. */
+ FOR_EACH_BB (bb)
+ {
+ block_stmt_iterator bsi;
+ tree phi, def;
+
+ /* Walk the statements. */
+ for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ mark_all_vars_used (bsi_stmt_ptr (bsi));
+
+ for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ {
+ use_operand_p arg_p;
+ ssa_op_iter i;
+
+ /* No point processing globals. */
+ if (is_global_var (SSA_NAME_VAR (PHI_RESULT (phi))))
+ continue;
+
+ def = PHI_RESULT (phi);
+ mark_all_vars_used (&def);
+
+ FOR_EACH_PHI_ARG (arg_p, phi, i, SSA_OP_ALL_USES)
+ {
+ tree arg = USE_FROM_PTR (arg_p);
+ mark_all_vars_used (&arg);
+ }
+ }
+ }
+
+ /* Remove unmarked vars and clear used flag. */
+ for (cell = &cfun->unexpanded_var_list; *cell; )
+ {
+ tree var = TREE_VALUE (*cell);
+ var_ann_t ann;
+
+ if (TREE_CODE (var) != FUNCTION_DECL
+ && (!(ann = var_ann (var))
+ || !ann->used))
+ {
+ *cell = TREE_CHAIN (*cell);
+ continue;
+ }
+
+ cell = &TREE_CHAIN (*cell);
+ }
+}
+