aboutsummaryrefslogtreecommitdiff
path: root/gcc/gimple-fold.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2014-10-22 08:42:37 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2014-10-22 08:42:37 +0000
commit3d2cf79f8112e357327a1a8a1765ab1c6022244c (patch)
treeb44c5fbbe45ceabde1404a524b10797087c153bb /gcc/gimple-fold.c
parent7d9f1cd276094689daa6451b7e24fe7bd683395f (diff)
downloadgcc-3d2cf79f8112e357327a1a8a1765ab1c6022244c.zip
gcc-3d2cf79f8112e357327a1a8a1765ab1c6022244c.tar.gz
gcc-3d2cf79f8112e357327a1a8a1765ab1c6022244c.tar.bz2
Makefile.in (OBJS): Add gimple-match.o and generic-match.o.
2014-10-22 Richard Biener <rguenther@suse.de> Prathamesh Kulkarni <bilbotheelffriend@gmail.com> * Makefile.in (OBJS): Add gimple-match.o and generic-match.o. (MOSTLYCLEANFILES): Add gimple-match.c and generic-match.c. (gimple-match.c): Generate by triggering s-match. (generic-match.c): Likewise. (s-match): Rule to build gimple-match.c and generic-match.c by running the genmatch generator program. (build/hash-table.o): Dependencies to build hash-table.c for the host. (build/genmatch.o): Dependencies to build genmatch. (genprog): Add match. (build/genmatch): Likewise. (TEXI_GCCINT_FILES): Add match-and-simplify.texi. * generic-match-head.c: New file. * gimple-match-head.c: Likewise. * gimple-match.h: Likewise. * genmatch.c: Likewise. * match.pd: Likewise. * builtins.h (fold_builtin_n): Export. * builtins.c (fold_builtin_n): Likewise. * gimple-fold.h (gimple_build): Declare various overloads. (gimple_simplify): Likewise. (gimple_convert): Re-implement in terms of gimple_build. * gimple-fold.c (gimple_convert): Remove. (gimple_build): New functions. * doc/match-and-simplify.texi: New file. * doc/gccint.texi: Add menu item Match and Simplify and include match-and-simplify.texi. Co-Authored-By: Prathamesh Kulkarni <bilbotheelffriend@gmail.com> From-SVN: r216542
Diffstat (limited to 'gcc/gimple-fold.c')
-rw-r--r--gcc/gimple-fold.c201
1 files changed, 192 insertions, 9 deletions
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 9344e0b..5b47cbc 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -5364,19 +5364,202 @@ rewrite_to_defined_overflow (gimple stmt)
return stmts;
}
-/* Return OP converted to TYPE by emitting a conversion statement on SEQ
- if required using location LOC. Note that OP will be returned
- unmodified if GIMPLE does not require an explicit conversion between
- its type and TYPE. */
+
+/* Build the expression CODE OP0 of type TYPE with location LOC,
+ simplifying it first if possible using VALUEIZE if not NULL.
+ OP0 is expected to be valueized already. Returns the built
+ expression value and appends statements possibly defining it
+ to SEQ. */
+
+tree
+gimple_build (gimple_seq *seq, location_t loc,
+ enum tree_code code, tree type, tree op0,
+ tree (*valueize)(tree))
+{
+ tree res = gimple_simplify (code, type, op0, seq, valueize);
+ if (!res)
+ {
+ if (gimple_in_ssa_p (cfun))
+ res = make_ssa_name (type, NULL);
+ else
+ res = create_tmp_reg (type, NULL);
+ gimple stmt;
+ if (code == REALPART_EXPR
+ || code == IMAGPART_EXPR
+ || code == VIEW_CONVERT_EXPR)
+ stmt = gimple_build_assign_with_ops (code, res,
+ build1 (code, type,
+ op0), NULL_TREE);
+ else
+ stmt = gimple_build_assign_with_ops (code, res, op0, NULL_TREE);
+ gimple_set_location (stmt, loc);
+ gimple_seq_add_stmt_without_update (seq, stmt);
+ }
+ return res;
+}
+
+/* Build the expression OP0 CODE OP1 of type TYPE with location LOC,
+ simplifying it first if possible using VALUEIZE if not NULL.
+ OP0 and OP1 are expected to be valueized already. Returns the built
+ expression value and appends statements possibly defining it
+ to SEQ. */
+
+tree
+gimple_build (gimple_seq *seq, location_t loc,
+ enum tree_code code, tree type, tree op0, tree op1,
+ tree (*valueize)(tree))
+{
+ tree res = gimple_simplify (code, type, op0, op1, seq, valueize);
+ if (!res)
+ {
+ if (gimple_in_ssa_p (cfun))
+ res = make_ssa_name (type, NULL);
+ else
+ res = create_tmp_reg (type, NULL);
+ gimple stmt = gimple_build_assign_with_ops (code, res, op0, op1);
+ gimple_set_location (stmt, loc);
+ gimple_seq_add_stmt_without_update (seq, stmt);
+ }
+ return res;
+}
+
+/* Build the expression (CODE OP0 OP1 OP2) of type TYPE with location LOC,
+ simplifying it first if possible using VALUEIZE if not NULL.
+ OP0, OP1 and OP2 are expected to be valueized already. Returns the built
+ expression value and appends statements possibly defining it
+ to SEQ. */
+
+tree
+gimple_build (gimple_seq *seq, location_t loc,
+ enum tree_code code, tree type, tree op0, tree op1, tree op2,
+ tree (*valueize)(tree))
+{
+ tree res = gimple_simplify (code, type, op0, op1, op2,
+ seq, valueize);
+ if (!res)
+ {
+ if (gimple_in_ssa_p (cfun))
+ res = make_ssa_name (type, NULL);
+ else
+ res = create_tmp_reg (type, NULL);
+ gimple stmt;
+ if (code == BIT_FIELD_REF)
+ stmt = gimple_build_assign_with_ops (code, res,
+ build3 (BIT_FIELD_REF, type,
+ op0, op1, op2),
+ NULL_TREE);
+ else
+ stmt = gimple_build_assign_with_ops (code, res, op0, op1, op2);
+ gimple_set_location (stmt, loc);
+ gimple_seq_add_stmt_without_update (seq, stmt);
+ }
+ return res;
+}
+
+/* Build the call FN (ARG0) with a result of type TYPE
+ (or no result if TYPE is void) with location LOC,
+ simplifying it first if possible using VALUEIZE if not NULL.
+ ARG0 is expected to be valueized already. Returns the built
+ expression value (or NULL_TREE if TYPE is void) and appends
+ statements possibly defining it to SEQ. */
+
+tree
+gimple_build (gimple_seq *seq, location_t loc,
+ enum built_in_function fn, tree type, tree arg0,
+ tree (*valueize)(tree))
+{
+ tree res = gimple_simplify (fn, type, arg0, seq, valueize);
+ if (!res)
+ {
+ tree decl = builtin_decl_implicit (fn);
+ gimple stmt = gimple_build_call (decl, 1, arg0);
+ if (!VOID_TYPE_P (type))
+ {
+ if (gimple_in_ssa_p (cfun))
+ res = make_ssa_name (type, NULL);
+ else
+ res = create_tmp_reg (type, NULL);
+ gimple_call_set_lhs (stmt, res);
+ }
+ gimple_set_location (stmt, loc);
+ gimple_seq_add_stmt_without_update (seq, stmt);
+ }
+ return res;
+}
+
+/* Build the call FN (ARG0, ARG1) with a result of type TYPE
+ (or no result if TYPE is void) with location LOC,
+ simplifying it first if possible using VALUEIZE if not NULL.
+ ARG0 is expected to be valueized already. Returns the built
+ expression value (or NULL_TREE if TYPE is void) and appends
+ statements possibly defining it to SEQ. */
+
+tree
+gimple_build (gimple_seq *seq, location_t loc,
+ enum built_in_function fn, tree type, tree arg0, tree arg1,
+ tree (*valueize)(tree))
+{
+ tree res = gimple_simplify (fn, type, arg0, arg1, seq, valueize);
+ if (!res)
+ {
+ tree decl = builtin_decl_implicit (fn);
+ gimple stmt = gimple_build_call (decl, 2, arg0, arg1);
+ if (!VOID_TYPE_P (type))
+ {
+ if (gimple_in_ssa_p (cfun))
+ res = make_ssa_name (type, NULL);
+ else
+ res = create_tmp_reg (type, NULL);
+ gimple_call_set_lhs (stmt, res);
+ }
+ gimple_set_location (stmt, loc);
+ gimple_seq_add_stmt_without_update (seq, stmt);
+ }
+ return res;
+}
+
+/* Build the call FN (ARG0, ARG1, ARG2) with a result of type TYPE
+ (or no result if TYPE is void) with location LOC,
+ simplifying it first if possible using VALUEIZE if not NULL.
+ ARG0 is expected to be valueized already. Returns the built
+ expression value (or NULL_TREE if TYPE is void) and appends
+ statements possibly defining it to SEQ. */
+
+tree
+gimple_build (gimple_seq *seq, location_t loc,
+ enum built_in_function fn, tree type,
+ tree arg0, tree arg1, tree arg2,
+ tree (*valueize)(tree))
+{
+ tree res = gimple_simplify (fn, type, arg0, arg1, arg2, seq, valueize);
+ if (!res)
+ {
+ tree decl = builtin_decl_implicit (fn);
+ gimple stmt = gimple_build_call (decl, 3, arg0, arg1, arg2);
+ if (!VOID_TYPE_P (type))
+ {
+ if (gimple_in_ssa_p (cfun))
+ res = make_ssa_name (type, NULL);
+ else
+ res = create_tmp_reg (type, NULL);
+ gimple_call_set_lhs (stmt, res);
+ }
+ gimple_set_location (stmt, loc);
+ gimple_seq_add_stmt_without_update (seq, stmt);
+ }
+ return res;
+}
+
+/* Build the conversion (TYPE) OP with a result of type TYPE
+ with location LOC if such conversion is neccesary in GIMPLE,
+ simplifying it first.
+ Returns the built expression value and appends
+ statements possibly defining it to SEQ. */
tree
gimple_convert (gimple_seq *seq, location_t loc, tree type, tree op)
{
if (useless_type_conversion_p (type, TREE_TYPE (op)))
return op;
- op = fold_convert_loc (loc, type, op);
- gimple_seq stmts = NULL;
- op = force_gimple_operand (op, &stmts, true, NULL_TREE);
- gimple_seq_add_seq_without_update (seq, stmts);
- return op;
+ return gimple_build (seq, loc, NOP_EXPR, type, op);
}