This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Add utility functions to gimplify expressions
- From: Paolo Bonzini <bonzini at gnu dot org>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 13 Jul 2004 13:05:23 +0200
- Subject: [PATCH] Add utility functions to gimplify expressions
This moves some useful functions from tree-complex.c to tree-cfg.c,
renaming them to something clearer.
Paolo
2004-07-13 Paolo Bonzini <bonzini@gnu.org>
* tree-cfg.c (gimplify_val): Move from tree-complex.c.
(gimplify_build1): Move from tree-complex.c do_unop.
(gimplify_build2): Move from tree-complex.c do_binop.
(gimplify_build3): New.
* tree-complex.c (gimplify_val, do_unop, do_binop): Remove.
Adjust throughout to call the functions above.
* tree-flow.h: Declare the functions above.
* tree-nested.c (gimplify_val): Rename to...
(tsi_gimplify_val): ... this. Callers adjusted.
Index: gcc/tree-cfg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-cfg.c,v
retrieving revision 2.17
diff -u -r2.17 tree-cfg.c
--- gcc/tree-cfg.c 19 Jun 2004 18:52:04 -0000 2.17
+++ gcc/tree-cfg.c 21 Jun 2004 14:31:16 -0000
@@ -4654,6 +4654,79 @@
0, /* todo_flags_start */
TODO_dump_func, /* todo_flags_finish */
};
+
+
+/* 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 = make_rename_temp (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);
+}
+
+
/* Emit return warnings. */
Index: gcc/tree-complex.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-complex.c,v
retrieving revision 2.5
diff -u -r2.5 tree-complex.c
--- gcc/tree-complex.c 9 Jun 2004 15:07:01 -0000 2.5
+++ gcc/tree-complex.c 21 Jun 2004 14:31:16 -0000
@@ -30,28 +35,6 @@
#include "flags.h"
-/* 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_rename_temp (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;
-}
-
/* 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. */
@@ -85,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
@@ -142,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);
}
@@ -158,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);
}
@@ -187,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);
}
@@ -215,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);
@@ -292,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);
+ /* Result is now ((ar + ai*ratio)/div) + i((ai - ar*ratio)/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);
}
@@ -343,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);
}
@@ -359,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);
}
@@ -372,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-flow.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-flow.h,v
retrieving revision 2.12
diff -u -r2.12 tree-flow.h
--- gcc/tree-flow.h 19 Jun 2004 15:33:06 -0000 2.12
+++ gcc/tree-flow.h 21 Jun 2004 14:31:16 -0000
@@ -469,6 +469,15 @@
extern void verify_stmts (void);
extern tree tree_block_label (basic_block bb);
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/tree-nested.c,v
retrieving revision 2.4
diff -u -r2.4 tree-nested.c
--- gcc/tree-nested.c 30 May 2004 07:12:55 -0000 2.4
+++ gcc/tree-nested.c 21 Jun 2004 14:31:16 -0000
@@ -370,7 +370,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;
@@ -786,7 +786,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;
@@ -884,7 +884,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;
@@ -1005,7 +1005,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);
@@ -1103,7 +1103,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