static void execute_return_slot_opt (void) { basic_block bb; FOR_EACH_BB (bb) { block_stmt_iterator i; for (i = bsi_start (bb); !bsi_end_p (i); bsi_next (&i)) { tree stmt = bsi_stmt (i); tree call; if (TREE_CODE (stmt) == MODIFY_EXPR && (call = TREE_OPERAND (stmt, 1), TREE_CODE (call) == CALL_EXPR) && !CALL_EXPR_RETURN_SLOT_OPT (call) && aggregate_value_p (call, call)) { def_operand_p def_p; ssa_op_iter op_iter; /* We determine whether or not the LHS address escapes by asking whether it is call clobbered. When the LHS isn't a simple decl, we need to check the VDEFs, so it's simplest to just loop through all the DEFs. */ FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, op_iter, SSA_OP_ALL_DEFS) { tree def = DEF_FROM_PTR (def_p); if (TREE_CODE (def) == SSA_NAME) def = SSA_NAME_VAR (def); if (is_call_clobbered (def)) goto unsafe; } /* No defs are call clobbered, so the optimization is safe. */ CALL_EXPR_RETURN_SLOT_OPT (call) = 1; /* This is too late to mark the target addressable like we do in gimplify_modify_expr_rhs, but that's OK; anything that wasn't already addressable was handled there. */ unsafe:; } }
static bool all_immediate_uses_same_place (def_operand_p def_p) { tree var = DEF_FROM_PTR (def_p); imm_use_iterator imm_iter; use_operand_p use_p; gimple *firstuse = NULL; FOR_EACH_IMM_USE_FAST (use_p, imm_iter, var) { if (is_gimple_debug (USE_STMT (use_p))) continue; if (firstuse == NULL) firstuse = USE_STMT (use_p); else if (firstuse != USE_STMT (use_p)) return false; } return true; }
static basic_block nearest_common_dominator_of_uses (def_operand_p def_p, bool *debug_stmts) { tree var = DEF_FROM_PTR (def_p); bitmap blocks = BITMAP_ALLOC (NULL); basic_block commondom; unsigned int j; bitmap_iterator bi; imm_use_iterator imm_iter; use_operand_p use_p; FOR_EACH_IMM_USE_FAST (use_p, imm_iter, var) { gimple *usestmt = USE_STMT (use_p); basic_block useblock; if (gphi *phi = dyn_cast <gphi *> (usestmt)) { int idx = PHI_ARG_INDEX_FROM_USE (use_p); useblock = gimple_phi_arg_edge (phi, idx)->src; } else if (is_gimple_debug (usestmt)) { *debug_stmts = true; continue; } else { useblock = gimple_bb (usestmt); } /* Short circuit. Nothing dominates the entry block. */ if (useblock == ENTRY_BLOCK_PTR_FOR_FN (cfun)) { BITMAP_FREE (blocks); return NULL; } bitmap_set_bit (blocks, useblock->index); }