FOR_EACH_REFERENCED_VAR (var, rvi)
{
- if (!(TREE_STATIC (var) || DECL_EXTERNAL (var))
- && (var_ann (var)->mem_tag_kind == NOT_A_TAG
- || var_ann (var)->mem_tag_kind == STRUCT_FIELD)
+ if (!is_global_var (var)
+ && (!MTAG_P (var) || TREE_CODE (var) == STRUCT_FIELD_TAG)
&& is_call_clobbered (var))
return false;
}
}
/* Checks whether the expression EXPR in stmt AT is independent of the
- statement pointed by BSI (in a sense that we already know EXPR's value
+ statement pointed to by BSI (in a sense that we already know EXPR's value
at BSI). We use the fact that we are only called from the chain of
basic blocks that have only single successor. Returns the expression
containing the value of EXPR at BSI. */
var = m_acc;
else
{
- stmt = build (MODIFY_EXPR, ret_type, NULL_TREE,
- build (MULT_EXPR, ret_type, m_acc, a));
+ stmt = build2 (MODIFY_EXPR, ret_type, NULL_TREE,
+ build2 (MULT_EXPR, ret_type, m_acc, a));
tmp = create_tmp_var (ret_type, "acc_tmp");
add_referenced_tmp_var (tmp);
else
var = a;
- stmt = build (MODIFY_EXPR, ret_type, NULL_TREE,
- build (PLUS_EXPR, ret_type, a_acc, var));
+ stmt = build2 (MODIFY_EXPR, ret_type, NULL_TREE,
+ build2 (PLUS_EXPR, ret_type, a_acc, var));
var = make_ssa_name (SSA_NAME_VAR (a_acc), stmt);
TREE_OPERAND (stmt, 0) = var;
bsi_insert_after (&bsi, stmt, BSI_NEW_STMT);
if (m)
{
- stmt = build (MODIFY_EXPR, ret_type, NULL_TREE,
- build (MULT_EXPR, ret_type, m_acc, m));
+ stmt = build2 (MODIFY_EXPR, ret_type, NULL_TREE,
+ build2 (MULT_EXPR, ret_type, m_acc, m));
var = make_ssa_name (SSA_NAME_VAR (m_acc), stmt);
TREE_OPERAND (stmt, 0) = var;
bsi_insert_after (&bsi, stmt, BSI_NEW_STMT);
if (m)
{
- stmt = build (MODIFY_EXPR, ret_type, NULL_TREE,
- build (MULT_EXPR, ret_type, m_acc, ret_var));
+ stmt = build2 (MODIFY_EXPR, ret_type, NULL_TREE,
+ build2 (MULT_EXPR, ret_type, m_acc, ret_var));
tmp = create_tmp_var (ret_type, "acc_tmp");
add_referenced_tmp_var (tmp);
if (a)
{
- stmt = build (MODIFY_EXPR, ret_type, NULL_TREE,
- build (PLUS_EXPR, ret_type, a_acc, var));
+ stmt = build2 (MODIFY_EXPR, ret_type, NULL_TREE,
+ build2 (PLUS_EXPR, ret_type, a_acc, var));
tmp = create_tmp_var (ret_type, "acc_tmp");
add_referenced_tmp_var (tmp);
update_stmt (ret_stmt);
}
+/* Subtract COUNT and FREQUENCY from the basic block and it's
+ outgoing edge. */
+static void
+decrease_profile (basic_block bb, gcov_type count, int frequency)
+{
+ edge e;
+ bb->count -= count;
+ if (bb->count < 0)
+ bb->count = 0;
+ bb->frequency -= frequency;
+ if (bb->frequency < 0)
+ bb->frequency = 0;
+ if (!single_succ_p (bb))
+ {
+ gcc_assert (!EDGE_COUNT (bb->succs));
+ return;
+ }
+ e = single_succ_edge (bb);
+ e->count -= count;
+ if (e->count < 0)
+ e->count = 0;
+}
+
/* Eliminates tail call described by T. TMP_VARS is a list of
temporary variables used to copy the function arguments. */
release_defs (t);
}
+ /* Number of executions of function has reduced by the tailcall. */
+ e = single_succ_edge (t->call_block);
+ decrease_profile (EXIT_BLOCK_PTR, e->count, EDGE_FREQUENCY (e));
+ decrease_profile (ENTRY_BLOCK_PTR, e->count, EDGE_FREQUENCY (e));
+ if (e->dest != EXIT_BLOCK_PTR)
+ decrease_profile (e->dest, e->count, EDGE_FREQUENCY (e));
+
/* Replace the call by a jump to the start of function. */
e = redirect_edge_and_branch (single_succ_edge (t->call_block), first);
gcc_assert (e);