diff options
author | Richard Biener <rguenther@suse.de> | 2014-10-22 08:42:37 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2014-10-22 08:42:37 +0000 |
commit | 3d2cf79f8112e357327a1a8a1765ab1c6022244c (patch) | |
tree | b44c5fbbe45ceabde1404a524b10797087c153bb /gcc/gimple-fold.c | |
parent | 7d9f1cd276094689daa6451b7e24fe7bd683395f (diff) | |
download | gcc-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.c | 201 |
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); } |