This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[tree-ssa] Provide some utility functions
- From: Bonzini <bonzini at gnu dot org>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 22 Mar 2004 10:13:24 -0500
- Subject: [tree-ssa] Provide some utility functions
I noted that some improvements in lno branch (notably phiopt)
introduced code duplication in the form of static functions
that are the same in tree-complex.c and tree-ssa-phiopt.c.
These are easy enough that I think it is easier to apply
them to tree-ssa directly.
Paolo
2004-03-22 Paolo Bonzini <bonzini@gnu.org>
* tree-cfg.c (create_renamed_tmp_var, gimplify_val,
gimplify_build1, gimplify_build2, gimplify_build3): New
functions.
* tree-flow.h: Declare them.
* tree-complex.c: Replace do_unop with gimplify_build1,
do_binop with gimplify_build2, make_temp with
create_renamed_tmp_var.
(make_temp, gimplify_val, do_unop, do_binop): Remove.
* tree-nested.c (tsi_gimplify_val): New name of...
(gimplify_val): ... this function.
Index: gcc/tree-cfg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-cfg.c,v
retrieving revision 1.1.4.278
diff -u -r1.1.4.278 tree-cfg.c
--- gcc/tree-cfg.c 16 Mar 2004 22:31:55 -0000 1.1.4.278
+++ gcc/tree-cfg.c 22 Mar 2004 14:49:34 -0000
@@ -4361,6 +4361,94 @@
0, /* todo_flags_start */
0, /* todo_flags_finish */
};
+
+
+/* Build a temporary like create_tmp_var. If necessary, make sure
+ and register it to be renamed. */
+
+tree
+create_renamed_tmp_var (tree type, const char *prefix)
+{
+ tree t = create_tmp_var (type, prefix);
+ if (vars_to_rename)
+ {
+ add_referenced_tmp_var (t);
+ bitmap_set_bit (vars_to_rename, var_ann (t)->uid);
+ }
+ return t;
+}
+
+/* Return EXP if it is a valid GIMPLE rvalue, else gimplify it into
+ a temporary, make sure and register it to be renamed if necessary,
+ and finally return the temporary. Put the statements to compute
+ EXP before the current statement in BSI. */
+
+tree
+gimplify_val (block_stmt_iterator *bsi, tree type, tree exp)
+{
+ tree t, new_stmt, orig_stmt;
+
+ if (is_gimple_val (exp))
+ return exp;
+
+ t = create_renamed_tmp_var (type, NULL);
+ new_stmt = build (MODIFY_EXPR, type, t, exp);
+
+ orig_stmt = bsi_stmt (*bsi);
+ SET_EXPR_LOCUS (new_stmt, EXPR_LOCUS (orig_stmt));
+ TREE_BLOCK (new_stmt) = TREE_BLOCK (orig_stmt);
+
+ bsi_insert_before (bsi, new_stmt, BSI_SAME_STMT);
+
+ return t;
+}
+
+/* Build a ternary operation and gimplify it. Emit code before BSI.
+ Return the gimple_val holding the result. */
+
+tree
+gimplify_build3 (block_stmt_iterator *bsi, enum tree_code code,
+ tree type, tree a, tree b, tree c)
+{
+ tree ret;
+
+ ret = fold (build3 (code, type, a, b, c));
+ STRIP_NOPS (ret);
+
+ return gimplify_val (bsi, type, ret);
+}
+
+/* Build a binary operation and gimplify it. Emit code before BSI.
+ Return the gimple_val holding the result. */
+
+tree
+gimplify_build2 (block_stmt_iterator *bsi, enum tree_code code,
+ tree type, tree a, tree b)
+{
+ tree ret;
+
+ ret = fold (build2 (code, type, a, b));
+ STRIP_NOPS (ret);
+
+ return gimplify_val (bsi, type, ret);
+}
+
+/* Build a unary operation and gimplify it. Emit code before BSI.
+ Return the gimple_val holding the result. */
+
+tree
+gimplify_build1 (block_stmt_iterator *bsi, enum tree_code code, tree type,
+ tree a)
+{
+ tree ret;
+
+ ret = fold (build1 (code, type, a));
+ STRIP_NOPS (ret);
+
+ return gimplify_val (bsi, type, ret);
+}
+
+
static void
execute_warn_function_return (void)
Index: gcc/tree-complex.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-complex.c,v
retrieving revision 1.1.2.6
diff -u -r1.1.2.6 tree-complex.c
--- gcc/tree-complex.c 18 Jan 2004 07:23:21 -0000 1.1.2.6
+++ gcc/tree-complex.c 22 Mar 2004 14:49:34 -0000
@@ -30,39 +35,6 @@
#include "flags.h"
-/* Build a temporary. Make sure and register it to be renamed. */
-
-static tree
-make_temp (tree type)
-{
- tree t = create_tmp_var (type, NULL);
- add_referenced_tmp_var (t);
- bitmap_set_bit (vars_to_rename, var_ann (t)->uid);
- return t;
-}
-
-/* Force EXP to be a gimple_val. */
-
-static tree
-gimplify_val (block_stmt_iterator *bsi, tree type, tree exp)
-{
- tree t, new_stmt, orig_stmt;
-
- if (is_gimple_val (exp))
- return exp;
-
- t = make_temp (type);
- new_stmt = build (MODIFY_EXPR, type, t, exp);
-
- orig_stmt = bsi_stmt (*bsi);
- SET_EXPR_LOCUS (new_stmt, EXPR_LOCUS (orig_stmt));
- TREE_BLOCK (new_stmt) = TREE_BLOCK (orig_stmt);
-
- bsi_insert_before (bsi, new_stmt, BSI_SAME_STMT);
-
- return t;
-}
-
/* Extract the real or imaginary part of a complex variable or constant.
Make sure that it's a proper gimple_val and gimplify it if not.
Emit any new code before BSI. */
@@ -96,35 +68,6 @@
return gimplify_val (bsi, inner_type, ret);
}
-/* Build a binary operation and gimplify it. Emit code before BSI.
- Return the gimple_val holding the result. */
-
-static tree
-do_binop (block_stmt_iterator *bsi, enum tree_code code,
- tree type, tree a, tree b)
-{
- tree ret;
-
- ret = fold (build (code, type, a, b));
- STRIP_NOPS (ret);
-
- return gimplify_val (bsi, type, ret);
-}
-
-/* Build a unary operation and gimplify it. Emit code before BSI.
- Return the gimple_val holding the result. */
-
-static tree
-do_unop (block_stmt_iterator *bsi, enum tree_code code, tree type, tree a)
-{
- tree ret;
-
- ret = fold (build1 (code, type, a));
- STRIP_NOPS (ret);
-
- return gimplify_val (bsi, type, ret);
-}
-
/* Update an assignment to a complex variable in place. */
static void
@@ -153,8 +96,8 @@
{
tree rr, ri;
- rr = do_binop (bsi, code, inner_type, ar, br);
- ri = do_binop (bsi, code, inner_type, ai, bi);
+ rr = gimplify_build2 (bsi, code, inner_type, ar, br);
+ ri = gimplify_build2 (bsi, code, inner_type, ai, bi);
update_complex_assignment (bsi, rr, ri);
}
@@ -169,19 +112,19 @@
{
tree t1, t2, t3, t4, rr, ri;
- t1 = do_binop (bsi, MULT_EXPR, inner_type, ar, br);
- t2 = do_binop (bsi, MULT_EXPR, inner_type, ai, bi);
- t3 = do_binop (bsi, MULT_EXPR, inner_type, ar, bi);
+ t1 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ar, br);
+ t2 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ai, bi);
+ t3 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ar, bi);
/* Avoid expanding redundant multiplication for the common
case of squaring a complex number. */
if (ar == br && ai == bi)
t4 = t3;
else
- t4 = do_binop (bsi, MULT_EXPR, inner_type, ai, br);
+ t4 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ai, br);
- rr = do_binop (bsi, MINUS_EXPR, inner_type, t1, t2);
- ri = do_binop (bsi, PLUS_EXPR, inner_type, t3, t4);
+ rr = gimplify_build2 (bsi, MINUS_EXPR, inner_type, t1, t2);
+ ri = gimplify_build2 (bsi, PLUS_EXPR, inner_type, t3, t4);
update_complex_assignment (bsi, rr, ri);
}
@@ -198,19 +141,19 @@
{
tree rr, ri, div, t1, t2, t3;
- t1 = do_binop (bsi, MULT_EXPR, inner_type, br, br);
- t2 = do_binop (bsi, MULT_EXPR, inner_type, bi, bi);
- div = do_binop (bsi, PLUS_EXPR, inner_type, t1, t2);
-
- t1 = do_binop (bsi, MULT_EXPR, inner_type, ar, br);
- t2 = do_binop (bsi, MULT_EXPR, inner_type, ai, bi);
- t3 = do_binop (bsi, PLUS_EXPR, inner_type, t1, t2);
- rr = do_binop (bsi, code, inner_type, t3, div);
-
- t1 = do_binop (bsi, MULT_EXPR, inner_type, ai, br);
- t2 = do_binop (bsi, MULT_EXPR, inner_type, ar, bi);
- t3 = do_binop (bsi, MINUS_EXPR, inner_type, t1, t2);
- ri = do_binop (bsi, code, inner_type, t3, div);
+ t1 = gimplify_build2 (bsi, MULT_EXPR, inner_type, br, br);
+ t2 = gimplify_build2 (bsi, MULT_EXPR, inner_type, bi, bi);
+ div = gimplify_build2 (bsi, PLUS_EXPR, inner_type, t1, t2);
+
+ t1 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ar, br);
+ t2 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ai, bi);
+ t3 = gimplify_build2 (bsi, PLUS_EXPR, inner_type, t1, t2);
+ rr = gimplify_build2 (bsi, code, inner_type, t3, div);
+
+ t1 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ai, br);
+ t2 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ar, bi);
+ t3 = gimplify_build2 (bsi, MINUS_EXPR, inner_type, t1, t2);
+ ri = gimplify_build2 (bsi, code, inner_type, t3, div);
update_complex_assignment (bsi, rr, ri);
}
@@ -226,8 +169,8 @@
tree rr, ri, ratio, div, t1, t2, min, max, cond;
/* Examine |br| < |bi|, and branch. */
- t1 = do_unop (bsi, ABS_EXPR, inner_type, br);
- t2 = do_unop (bsi, ABS_EXPR, inner_type, bi);
+ t1 = gimplify_build1 (bsi, ABS_EXPR, inner_type, br);
+ t2 = gimplify_build1 (bsi, ABS_EXPR, inner_type, bi);
cond = fold (build (LT_EXPR, boolean_type_node, t1, t2));
STRIP_NOPS (cond);
@@ -251,8 +194,8 @@
cond = build (COND_EXPR, void_type_node, cond, t1, t2);
bsi_insert_before (bsi, cond, BSI_SAME_STMT);
- min = make_temp (inner_type);
- max = make_temp (inner_type);
+ min = create_renamed_tmp_var (inner_type, NULL);
+ max = create_renamed_tmp_var (inner_type, NULL);
l3 = create_artificial_label ();
/* Split the original block, and create the TRUE and FALSE blocks. */
@@ -303,20 +246,20 @@
/* Now we have MIN(|br|, |bi|) and MAX(|br|, |bi|). We now use the
ratio min/max to scale both the dividend and divisor. */
- ratio = do_binop (bsi, code, inner_type, min, max);
+ ratio = gimplify_build2 (bsi, code, inner_type, min, max);
/* Calculate the divisor: min*ratio + max. */
- t1 = do_binop (bsi, MULT_EXPR, inner_type, min, ratio);
- div = do_binop (bsi, PLUS_EXPR, inner_type, t1, max);
+ t1 = gimplify_build2 (bsi, MULT_EXPR, inner_type, min, ratio);
+ div = gimplify_build2 (bsi, PLUS_EXPR, inner_type, t1, max);
/* Result is now ((ar + ai*ratio)/div) + i((ai - ar*ratio)/div). */
- t1 = do_binop (bsi, MULT_EXPR, inner_type, ai, ratio);
- t2 = do_binop (bsi, PLUS_EXPR, inner_type, ar, t1);
- rr = do_binop (bsi, code, inner_type, t2, div);
-
- t1 = do_binop (bsi, MULT_EXPR, inner_type, ar, ratio);
- t2 = do_binop (bsi, MINUS_EXPR, inner_type, ai, t1);
- ri = do_binop (bsi, code, inner_type, t2, div);
+ t1 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ai, ratio);
+ t2 = gimplify_build2 (bsi, PLUS_EXPR, inner_type, ar, t1);
+ rr = gimplify_build2 (bsi, code, inner_type, t2, div);
+
+ t1 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ar, ratio);
+ t2 = gimplify_build2 (bsi, MINUS_EXPR, inner_type, ai, t1);
+ ri = gimplify_build2 (bsi, code, inner_type, t2, div);
update_complex_assignment (bsi, rr, ri);
}
@@ -354,8 +297,8 @@
{
tree rr, ri;
- rr = do_unop (bsi, NEGATE_EXPR, inner_type, ar);
- ri = do_unop (bsi, NEGATE_EXPR, inner_type, ai);
+ rr = gimplify_build1 (bsi, NEGATE_EXPR, inner_type, ar);
+ ri = gimplify_build1 (bsi, NEGATE_EXPR, inner_type, ai);
update_complex_assignment (bsi, rr, ri);
}
@@ -370,7 +313,7 @@
{
tree ri;
- ri = do_unop (bsi, NEGATE_EXPR, inner_type, ai);
+ ri = gimplify_build1 (bsi, NEGATE_EXPR, inner_type, ai);
update_complex_assignment (bsi, ar, ri);
}
@@ -383,10 +326,11 @@
{
tree cr, ci, cc, stmt, type;
- cr = do_binop (bsi, code, boolean_type_node, ar, br);
- ci = do_binop (bsi, code, boolean_type_node, ai, bi);
- cc = do_binop (bsi, (code == EQ_EXPR ? TRUTH_AND_EXPR : TRUTH_OR_EXPR),
- boolean_type_node, cr, ci);
+ cr = gimplify_build2 (bsi, code, boolean_type_node, ar, br);
+ ci = gimplify_build2 (bsi, code, boolean_type_node, ai, bi);
+ cc = gimplify_build2 (bsi,
+ (code == EQ_EXPR ? TRUTH_AND_EXPR : TRUTH_OR_EXPR),
+ boolean_type_node, cr, ci);
stmt = bsi_stmt (*bsi);
modify_stmt (stmt);
Index: gcc/tree-dfa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-dfa.c,v
retrieving revision 1.1.4.222
diff -u -r1.1.4.222 tree-dfa.c
--- gcc/tree-dfa.c 19 Mar 2004 17:51:45 -0000 1.1.4.222
+++ gcc/tree-dfa.c 22 Mar 2004 14:49:35 -0000
@@ -983,6 +983,7 @@
while (code == ARRAY_REF
|| code == COMPONENT_REF
+ || code == BIT_FIELD_REF
|| code == REALPART_EXPR
|| code == IMAGPART_EXPR)
{
@@ -1222,6 +1223,7 @@
while ((TREE_CODE (t) == ARRAY_REF
&& is_gimple_min_invariant (TREE_OPERAND (t, 1)))
|| (TREE_CODE (t) == COMPONENT_REF
+ || TREE_CODE (t) == BIT_FIELD_REF
|| TREE_CODE (t) == REALPART_EXPR
|| TREE_CODE (t) == IMAGPART_EXPR))
t = TREE_OPERAND (t, 0);
Index: gcc/tree-flow.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-flow.h,v
retrieving revision 1.1.4.197
diff -u -r1.1.4.197 tree-flow.h
--- gcc/tree-flow.h 19 Mar 2004 02:07:25 -0000 1.1.4.197
+++ gcc/tree-flow.h 22 Mar 2004 14:49:35 -0000
@@ -474,6 +474,15 @@
extern bool verify_stmt (tree);
extern void verify_stmts (void);
extern void extract_true_false_edges_from_block (basic_block, edge *, edge *);
+extern tree create_renamed_tmp_var (tree, const char *);
+extern tree gimplify_val (block_stmt_iterator *, tree, tree);
+extern tree gimplify_build1 (block_stmt_iterator *, enum tree_code,
+ tree, tree);
+extern tree gimplify_build2 (block_stmt_iterator *, enum tree_code,
+ tree, tree, tree);
+extern tree gimplify_build3 (block_stmt_iterator *, enum tree_code,
+ tree, tree, tree, tree);
+
/* In tree-pretty-print.c. */
extern void dump_generic_bb (FILE *, basic_block, int, int);
Index: gcc/tree-nested.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-nested.c,v
retrieving revision 1.1.2.4
diff -u -r1.1.2.4 tree-nested.c
--- gcc/tree-nested.c 18 Mar 2004 22:43:56 -0000 1.1.2.4
+++ gcc/tree-nested.c 22 Mar 2004 14:49:35 -0000
@@ -365,7 +365,7 @@
/* Similarly, but only do so to force EXP to satisfy is_gimple_val. */
static tree
-gimplify_val (struct nesting_info *info, tree exp, tree_stmt_iterator *tsi)
+tsi_gimplify_val (struct nesting_info *info, tree exp, tree_stmt_iterator *tsi)
{
if (is_gimple_val (exp))
return exp;
@@ -778,7 +778,7 @@
where we only accept variables (and min_invariant, presumably),
then compute the address into a temporary. */
if (save_val_only)
- *tp = gimplify_val (wi->info, t, &wi->tsi);
+ *tp = tsi_gimplify_val (wi->info, t, &wi->tsi);
}
}
break;
@@ -850,7 +850,7 @@
/* If we are in a context where we only accept values, then
compute the address into a temporary. */
if (save_val_only)
- *tp = gimplify_val (wi->info, t, &wi->tsi);
+ *tp = tsi_gimplify_val (wi->info, t, &wi->tsi);
}
}
break;
@@ -945,7 +945,7 @@
field = get_nl_goto_field (i);
x = get_frame_field (info, target_context, field, &wi->tsi);
x = build_addr (x);
- x = gimplify_val (info, x, &wi->tsi);
+ x = tsi_gimplify_val (info, x, &wi->tsi);
arg = tree_cons (NULL, x, NULL);
x = build_addr (new_label);
arg = tree_cons (NULL, x, arg);
@@ -1043,7 +1043,7 @@
/* Compute the address of the field holding the trampoline. */
x = get_frame_field (info, target_context, x, &wi->tsi);
x = build_addr (x);
- x = gimplify_val (info, x, &wi->tsi);
+ x = tsi_gimplify_val (info, x, &wi->tsi);
arg = tree_cons (NULL, x, NULL);
/* Do machine-specific ugliness. Normally this will involve