This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Use get_call_expr_in more often
- From: Richard Henderson <rth at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 8 Jul 2004 09:21:02 -0700
- Subject: Use get_call_expr_in more often
This centralizes, a bit, knowledge of how call_expr appears in a
statement. Important, because fixing return of variable sized
types is going to require a change.
r~
* tree-cfg.c (make_exit_edges): Use get_call_expr_in.
(remove_useless_stmts_1, is_ctrl_altering_stmt): Likewise.
(tree_block_ends_with_call_p, need_fake_edge_p): Likewise.
* tree-eh.c (lower_eh_constructs_1): Likewise.
* tree-sra.c (sra_walk_modify_expr): Likewise.
* tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Likewise.
(eliminate_unnecessary_stmts): Likewise.
* tree-ssa-dse.c (dse_optimize_stmt): Likewise.
* tree-tailcall.c (optimize_tail_call): Likewise.
* tree-ssa-ccp.c (get_rhs, set_rhs): Reorg to use switch.
Index: gcc/tree-cfg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-cfg.c,v
retrieving revision 2.26
diff -c -p -d -r2.26 tree-cfg.c
*** gcc/tree-cfg.c 7 Jul 2004 22:19:41 -0000 2.26
--- gcc/tree-cfg.c 8 Jul 2004 16:07:39 -0000
*************** make_ctrl_stmt_edges (basic_block bb)
*** 510,516 ****
static void
make_exit_edges (basic_block bb)
{
! tree last = last_stmt (bb);
if (last == NULL_TREE)
abort ();
--- 510,516 ----
static void
make_exit_edges (basic_block bb)
{
! tree last = last_stmt (bb), op;
if (last == NULL_TREE)
abort ();
*************** make_exit_edges (basic_block bb)
*** 550,557 ****
/* A MODIFY_EXPR may have a CALL_EXPR on its RHS and the CALL_EXPR
may have an abnormal edge. Search the RHS for this case and
create any required edges. */
! if (TREE_CODE (TREE_OPERAND (last, 1)) == CALL_EXPR
! && TREE_SIDE_EFFECTS (TREE_OPERAND (last, 1))
&& current_function_has_nonlocal_label)
make_goto_expr_edges (bb);
--- 550,557 ----
/* A MODIFY_EXPR may have a CALL_EXPR on its RHS and the CALL_EXPR
may have an abnormal edge. Search the RHS for this case and
create any required edges. */
! op = get_call_expr_in (last);
! if (op && TREE_SIDE_EFFECTS (op)
&& current_function_has_nonlocal_label)
make_goto_expr_edges (bb);
*************** clear_special_calls (void)
*** 1520,1526 ****
static void
remove_useless_stmts_1 (tree *tp, struct rus_data *data)
{
! tree t = *tp;
switch (TREE_CODE (t))
{
--- 1520,1526 ----
static void
remove_useless_stmts_1 (tree *tp, struct rus_data *data)
{
! tree t = *tp, op;
switch (TREE_CODE (t))
{
*************** remove_useless_stmts_1 (tree *tp, struct
*** 1566,1575 ****
case MODIFY_EXPR:
data->last_goto = NULL;
fold_stmt (tp);
! if (TREE_CODE (TREE_OPERAND (t, 1)) == CALL_EXPR)
{
! update_call_expr_flags (TREE_OPERAND (t, 1));
! notice_special_calls (TREE_OPERAND (t, 1));
}
if (tree_could_throw_p (t))
data->may_throw = true;
--- 1566,1576 ----
case MODIFY_EXPR:
data->last_goto = NULL;
fold_stmt (tp);
! op = get_call_expr_in (t);
! if (op)
{
! update_call_expr_flags (op);
! notice_special_calls (op);
}
if (tree_could_throw_p (t))
data->may_throw = true;
*************** is_ctrl_stmt (tree t)
*** 2478,2514 ****
bool
is_ctrl_altering_stmt (tree t)
{
! tree call = t;
#if defined ENABLE_CHECKING
if (t == NULL)
abort ();
#endif
! switch (TREE_CODE (t))
{
- case MODIFY_EXPR:
- /* A MODIFY_EXPR with a rhs of a call has the characteristics
- of the call. */
- call = TREE_OPERAND (t, 1);
- if (TREE_CODE (call) != CALL_EXPR)
- break;
- /* FALLTHRU */
-
- case CALL_EXPR:
/* A non-pure/const CALL_EXPR alters flow control if the current
function has nonlocal labels. */
! if (TREE_SIDE_EFFECTS (t)
! && current_function_has_nonlocal_label)
return true;
/* A CALL_EXPR also alters control flow if it does not return. */
if (call_expr_flags (call) & (ECF_NORETURN | ECF_LONGJMP))
return true;
- break;
-
- default:
- return false;
}
/* If a statement can throw, it alters control flow. */
--- 2479,2502 ----
bool
is_ctrl_altering_stmt (tree t)
{
! tree call;
#if defined ENABLE_CHECKING
if (t == NULL)
abort ();
#endif
! call = get_call_expr_in (t);
! if (call)
{
/* A non-pure/const CALL_EXPR alters flow control if the current
function has nonlocal labels. */
! if (TREE_SIDE_EFFECTS (call) && current_function_has_nonlocal_label)
return true;
/* A CALL_EXPR also alters control flow if it does not return. */
if (call_expr_flags (call) & (ECF_NORETURN | ECF_LONGJMP))
return true;
}
/* If a statement can throw, it alters control flow. */
*************** static bool
*** 4509,4523 ****
tree_block_ends_with_call_p (basic_block bb)
{
block_stmt_iterator bsi = bsi_last (bb);
! tree t = tsi_stmt (bsi.tsi);
!
! if (TREE_CODE (t) == RETURN_EXPR && TREE_OPERAND (t, 0))
! t = TREE_OPERAND (t, 0);
!
! if (TREE_CODE (t) == MODIFY_EXPR)
! t = TREE_OPERAND (t, 1);
!
! return TREE_CODE (t) == CALL_EXPR;
}
--- 4497,4503 ----
tree_block_ends_with_call_p (basic_block bb)
{
block_stmt_iterator bsi = bsi_last (bb);
! return get_call_expr_in (bsi_stmt (bsi)) != NULL;
}
*************** tree_block_ends_with_condjump_p (basic_b
*** 4538,4548 ****
static bool
need_fake_edge_p (tree t)
{
! if (TREE_CODE (t) == RETURN_EXPR && TREE_OPERAND (t, 0))
! t = TREE_OPERAND (t, 0);
!
! if (TREE_CODE (t) == MODIFY_EXPR)
! t = TREE_OPERAND (t, 1);
/* NORETURN and LONGJMP calls already have an edge to exit.
CONST, PURE and ALWAYS_RETURN calls do not need one.
--- 4518,4524 ----
static bool
need_fake_edge_p (tree t)
{
! tree call;
/* NORETURN and LONGJMP calls already have an edge to exit.
CONST, PURE and ALWAYS_RETURN calls do not need one.
*************** need_fake_edge_p (tree t)
*** 4551,4559 ****
figured out from the RTL in mark_constant_function, and
the counter incrementation code from -fprofile-arcs
leads to different results from -fbranch-probabilities. */
! if (TREE_CODE (t) == CALL_EXPR
! && !(call_expr_flags (t) &
! (ECF_NORETURN | ECF_LONGJMP | ECF_ALWAYS_RETURN)))
return true;
if (TREE_CODE (t) == ASM_EXPR
--- 4527,4536 ----
figured out from the RTL in mark_constant_function, and
the counter incrementation code from -fprofile-arcs
leads to different results from -fbranch-probabilities. */
! call = get_call_expr_in (t);
! if (call
! && !(call_expr_flags (call) &
! (ECF_NORETURN | ECF_LONGJMP | ECF_ALWAYS_RETURN)))
return true;
if (TREE_CODE (t) == ASM_EXPR
Index: gcc/tree-eh.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-eh.c,v
retrieving revision 2.8
diff -c -p -d -r2.8 tree-eh.c
*** gcc/tree-eh.c 29 Jun 2004 06:59:34 -0000 2.8
--- gcc/tree-eh.c 8 Jul 2004 16:07:39 -0000
*************** lower_eh_constructs_1 (struct leh_state
*** 1552,1565 ****
/* Look for things that can throw exceptions, and record them. */
if (state->cur_region && tree_could_throw_p (t))
{
record_stmt_eh_region (state->cur_region, t);
note_eh_region_may_contain_throw (state->cur_region);
/* ??? For the benefit of calls.c, converting all this to rtl,
we need to record the call expression, not just the outer
modify statement. */
! if (TREE_CODE (TREE_OPERAND (t, 1)) == CALL_EXPR)
! record_stmt_eh_region (state->cur_region, TREE_OPERAND (t, 1));
}
break;
--- 1552,1568 ----
/* Look for things that can throw exceptions, and record them. */
if (state->cur_region && tree_could_throw_p (t))
{
+ tree op;
+
record_stmt_eh_region (state->cur_region, t);
note_eh_region_may_contain_throw (state->cur_region);
/* ??? For the benefit of calls.c, converting all this to rtl,
we need to record the call expression, not just the outer
modify statement. */
! op = get_call_expr_in (t);
! if (op)
! record_stmt_eh_region (state->cur_region, op);
}
break;
Index: gcc/tree-sra.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-sra.c,v
retrieving revision 2.17
diff -c -p -d -r2.17 tree-sra.c
*** gcc/tree-sra.c 6 Jul 2004 23:02:22 -0000 2.17
--- gcc/tree-sra.c 8 Jul 2004 16:07:39 -0000
*************** sra_walk_modify_expr (tree expr, block_s
*** 811,820 ****
else
fns->use (rhs_elt, &TREE_OPERAND (expr, 1), bsi, false);
}
- else if (TREE_CODE (rhs) == CALL_EXPR)
- sra_walk_call_expr (rhs, bsi, fns);
else
! sra_walk_expr (&TREE_OPERAND (expr, 1), bsi, false, fns);
}
/* Entry point to the walk functions. Search the entire function,
--- 811,824 ----
else
fns->use (rhs_elt, &TREE_OPERAND (expr, 1), bsi, false);
}
else
! {
! tree call = get_call_expr_in (rhs);
! if (call)
! sra_walk_call_expr (call, bsi, fns);
! else
! sra_walk_expr (&TREE_OPERAND (expr, 1), bsi, false, fns);
! }
}
/* Entry point to the walk functions. Search the entire function,
Index: gcc/tree-ssa-ccp.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-ccp.c,v
retrieving revision 2.17
diff -c -p -d -r2.17 tree-ssa-ccp.c
*** gcc/tree-ssa-ccp.c 8 Jul 2004 08:50:00 -0000 2.17
--- gcc/tree-ssa-ccp.c 8 Jul 2004 16:07:39 -0000
*************** get_rhs (tree stmt)
*** 2106,2132 ****
{
enum tree_code code = TREE_CODE (stmt);
! if (code == MODIFY_EXPR)
! return TREE_OPERAND (stmt, 1);
! if (code == COND_EXPR)
! return COND_EXPR_COND (stmt);
! else if (code == SWITCH_EXPR)
! return SWITCH_COND (stmt);
! else if (code == RETURN_EXPR)
{
! if (!TREE_OPERAND (stmt, 0))
! return NULL_TREE;
! if (TREE_CODE (TREE_OPERAND (stmt, 0)) == MODIFY_EXPR)
! return TREE_OPERAND (TREE_OPERAND (stmt, 0), 1);
else
! return TREE_OPERAND (stmt, 0);
}
- else if (code == GOTO_EXPR)
- return GOTO_DESTINATION (stmt);
- else if (code == LABEL_EXPR)
- return LABEL_EXPR_LABEL (stmt);
- else
- return stmt;
}
--- 2106,2135 ----
{
enum tree_code code = TREE_CODE (stmt);
! switch (code)
{
! case RETURN_EXPR:
! stmt = TREE_OPERAND (stmt, 0);
! if (stmt)
! return get_rhs (stmt);
else
! return NULL;
!
! case MODIFY_EXPR:
! return TREE_OPERAND (stmt, 1);
!
! case COND_EXPR:
! return COND_EXPR_COND (stmt);
! case SWITCH_EXPR:
! return SWITCH_COND (stmt);
! case GOTO_EXPR:
! return GOTO_DESTINATION (stmt);
! case LABEL_EXPR:
! return LABEL_EXPR_LABEL (stmt);
!
! default:
! return stmt;
}
}
*************** get_rhs (tree stmt)
*** 2135,2142 ****
static bool
set_rhs (tree *stmt_p, tree expr)
{
! tree stmt = *stmt_p;
enum tree_code code = TREE_CODE (expr);
/* Verify the constant folded result is valid gimple. */
if (TREE_CODE_CLASS (code) == '2')
--- 2138,2146 ----
static bool
set_rhs (tree *stmt_p, tree expr)
{
! tree stmt = *stmt_p, op;
enum tree_code code = TREE_CODE (expr);
+ stmt_ann_t ann;
/* Verify the constant folded result is valid gimple. */
if (TREE_CODE_CLASS (code) == '2')
*************** set_rhs (tree *stmt_p, tree expr)
*** 2151,2180 ****
return false;
}
! code = TREE_CODE (stmt);
! if (code == MODIFY_EXPR)
! TREE_OPERAND (stmt, 1) = expr;
! else if (code == COND_EXPR)
! COND_EXPR_COND (stmt) = expr;
! else if (code == SWITCH_EXPR)
! SWITCH_COND (stmt) = expr;
! else if (code == RETURN_EXPR)
! {
! if (TREE_OPERAND (stmt, 0)
! && TREE_CODE (TREE_OPERAND (stmt, 0)) == MODIFY_EXPR)
! TREE_OPERAND (TREE_OPERAND (stmt, 0), 1) = expr;
! else
! TREE_OPERAND (stmt, 0) = expr;
! }
! else if (code == GOTO_EXPR)
! GOTO_DESTINATION (stmt) = expr;
! else if (code == LABEL_EXPR)
! LABEL_EXPR_LABEL (stmt) = expr;
! else
{
/* Replace the whole statement with EXPR. If EXPR has no side
effects, then replace *STMT_P with an empty statement. */
! stmt_ann_t ann = stmt_ann (stmt);
*stmt_p = TREE_SIDE_EFFECTS (expr) ? expr : build_empty_stmt ();
(*stmt_p)->common.ann = (tree_ann_t) ann;
--- 2155,2193 ----
return false;
}
! switch (TREE_CODE (stmt))
{
+ case RETURN_EXPR:
+ op = TREE_OPERAND (stmt, 0);
+ if (TREE_CODE (op) != MODIFY_EXPR)
+ {
+ TREE_OPERAND (stmt, 0) = expr;
+ break;
+ }
+ stmt = op;
+ /* FALLTHRU */
+
+ case MODIFY_EXPR:
+ TREE_OPERAND (stmt, 1) = expr;
+ break;
+
+ case COND_EXPR:
+ COND_EXPR_COND (stmt) = expr;
+ break;
+ case SWITCH_EXPR:
+ SWITCH_COND (stmt) = expr;
+ break;
+ case GOTO_EXPR:
+ GOTO_DESTINATION (stmt) = expr;
+ break;
+ case LABEL_EXPR:
+ LABEL_EXPR_LABEL (stmt) = expr;
+ break;
+
+ default:
/* Replace the whole statement with EXPR. If EXPR has no side
effects, then replace *STMT_P with an empty statement. */
! ann = stmt_ann (stmt);
*stmt_p = TREE_SIDE_EFFECTS (expr) ? expr : build_empty_stmt ();
(*stmt_p)->common.ann = (tree_ann_t) ann;
*************** set_rhs (tree *stmt_p, tree expr)
*** 2211,2216 ****
--- 2224,2230 ----
SSA_NAME_DEF_STMT (var) = *stmt_p;
}
}
+ break;
}
return true;
Index: gcc/tree-ssa-dce.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-dce.c,v
retrieving revision 2.8
diff -c -p -d -r2.8 tree-ssa-dce.c
*** gcc/tree-ssa-dce.c 29 Jun 2004 06:59:35 -0000 2.8
--- gcc/tree-ssa-dce.c 8 Jul 2004 16:07:39 -0000
*************** mark_stmt_if_obviously_necessary (tree s
*** 290,295 ****
--- 290,296 ----
v_must_def_optype v_must_defs;
stmt_ann_t ann;
size_t i;
+ tree op;
/* Statements that are implicitly live. Most function calls, asm and return
statements are required. Labels and BIND_EXPR nodes are kept because
*************** mark_stmt_if_obviously_necessary (tree s
*** 319,326 ****
return;
case MODIFY_EXPR:
! if (TREE_CODE (TREE_OPERAND (stmt, 1)) == CALL_EXPR
! && TREE_SIDE_EFFECTS (TREE_OPERAND (stmt, 1)))
{
mark_stmt_necessary (stmt, true);
return;
--- 320,327 ----
return;
case MODIFY_EXPR:
! op = get_call_expr_in (stmt);
! if (op && TREE_SIDE_EFFECTS (op))
{
mark_stmt_necessary (stmt, true);
return;
*************** eliminate_unnecessary_stmts (void)
*** 638,648 ****
remove_dead_stmt (&i, bb);
else
{
! if (TREE_CODE (t) == CALL_EXPR)
! notice_special_calls (t);
! else if (TREE_CODE (t) == MODIFY_EXPR
! && TREE_CODE (TREE_OPERAND (t, 1)) == CALL_EXPR)
! notice_special_calls (TREE_OPERAND (t, 1));
bsi_next (&i);
}
}
--- 639,647 ----
remove_dead_stmt (&i, bb);
else
{
! tree call = get_call_expr_in (t);
! if (call)
! notice_special_calls (call);
bsi_next (&i);
}
}
Index: gcc/tree-ssa-dse.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-dse.c,v
retrieving revision 2.5
diff -c -p -d -r2.5 tree-ssa-dse.c
*** gcc/tree-ssa-dse.c 26 Jun 2004 05:03:54 -0000 2.5
--- gcc/tree-ssa-dse.c 8 Jul 2004 16:07:39 -0000
*************** dse_optimize_stmt (struct dom_walk_data
*** 244,253 ****
if (NUM_V_MAY_DEFS (v_may_defs) == 0)
return;
! /* We know we have virtual definitions. If this is a MODIFY_EXPR, then
! record it into our table. */
! if (TREE_CODE (stmt) == MODIFY_EXPR
! && TREE_CODE (TREE_OPERAND (stmt, 1)) != CALL_EXPR)
{
dataflow_t df = get_immediate_uses (stmt);
unsigned int num_uses = num_immediate_uses (df);
--- 244,254 ----
if (NUM_V_MAY_DEFS (v_may_defs) == 0)
return;
! /* We know we have virtual definitions. If this is a MODIFY_EXPR that's
! not also a function call, then record it into our table. */
! if (get_call_expr_in (stmt))
! return;
! if (TREE_CODE (stmt) == MODIFY_EXPR)
{
dataflow_t df = get_immediate_uses (stmt);
unsigned int num_uses = num_immediate_uses (df);
Index: gcc/tree-tailcall.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-tailcall.c,v
retrieving revision 2.13
diff -c -p -d -r2.13 tree-tailcall.c
*** gcc/tree-tailcall.c 26 Jun 2004 05:03:55 -0000 2.13
--- gcc/tree-tailcall.c 8 Jul 2004 16:07:39 -0000
*************** optimize_tail_call (struct tailcall *t,
*** 757,766 ****
{
tree stmt = bsi_stmt (t->call_bsi);
! if (TREE_CODE (stmt) == MODIFY_EXPR)
! stmt = TREE_OPERAND (stmt, 1);
! if (TREE_CODE (stmt) != CALL_EXPR)
! abort ();
CALL_EXPR_TAILCALL (stmt) = 1;
if (dump_file && (dump_flags & TDF_DETAILS))
{
--- 757,763 ----
{
tree stmt = bsi_stmt (t->call_bsi);
! stmt = get_call_expr_in (stmt);
CALL_EXPR_TAILCALL (stmt) = 1;
if (dump_file && (dump_flags & TDF_DETAILS))
{