This changes gimple_build to follow fold_buildN behavior - combine stmts only from the sequence(s) we are currently building. This avoids possible issues with a straight-forward transitioning to gimple_build in passes if they do not keep SSA form up-to-date.
Bootstrap and regtest in progress on x86_64-unknown-linux-gnu. Richard. 2015-04-20 Richard Biener <rguent...@suse.de> * gimple-fold.h (gimple_build): Remove optional valueize arguments. * gimple-fold.c (gimple_build_valueize): New function. (gimple_build): Always use gimple_build_valueize as valueize hook. Index: gcc/gimple-fold.c =================================================================== *** gcc/gimple-fold.c (revision 222227) --- gcc/gimple-fold.c (working copy) *************** rewrite_to_defined_overflow (gimple stmt *** 6078,6095 **** } /* 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)) --- 6078,6105 ---- } + /* The valueization hook we use for the gimple_build API simplification. + This makes us match fold_buildN behavior by only combining with + statements in the sequence(s) we are currently building. */ + + static tree + gimple_build_valueize (tree op) + { + if (gimple_bb (SSA_NAME_DEF_STMT (op)) == NULL) + return op; + return NULL_TREE; + } + /* Build the expression CODE OP0 of type TYPE with location LOC, ! simplifying it first if possible. 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 res = gimple_simplify (code, type, op0, seq, gimple_build_valueize); if (!res) { if (gimple_in_ssa_p (cfun)) *************** gimple_build (gimple_seq *seq, location_ *** 6110,6126 **** } /* 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)) --- 6120,6134 ---- } /* Build the expression OP0 CODE OP1 of type TYPE with location LOC, ! simplifying it first if possible. 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 res = gimple_simplify (code, type, op0, op1, seq, gimple_build_valueize); if (!res) { if (gimple_in_ssa_p (cfun)) *************** gimple_build (gimple_seq *seq, location_ *** 6135,6152 **** } /* 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)) --- 6143,6158 ---- } /* Build the expression (CODE OP0 OP1 OP2) of type TYPE with location LOC, ! simplifying it first if possible. 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 res = gimple_simplify (code, type, op0, op1, op2, ! seq, gimple_build_valueize); if (!res) { if (gimple_in_ssa_p (cfun)) *************** gimple_build (gimple_seq *seq, location_ *** 6167,6183 **** /* 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); --- 6173,6187 ---- /* 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. 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 res = gimple_simplify (fn, type, arg0, seq, gimple_build_valueize); if (!res) { tree decl = builtin_decl_implicit (fn); *************** gimple_build (gimple_seq *seq, location_ *** 6198,6214 **** /* 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); --- 6202,6216 ---- /* 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. 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 res = gimple_simplify (fn, type, arg0, arg1, seq, gimple_build_valueize); if (!res) { tree decl = builtin_decl_implicit (fn); *************** gimple_build (gimple_seq *seq, location_ *** 6229,6246 **** /* 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); --- 6231,6247 ---- /* 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. 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 res = gimple_simplify (fn, type, arg0, arg1, arg2, ! seq, gimple_build_valueize); if (!res) { tree decl = builtin_decl_implicit (fn); Index: gcc/gimple-fold.h =================================================================== *** gcc/gimple-fold.h (revision 222227) --- gcc/gimple-fold.h (working copy) *************** extern gimple_seq rewrite_to_defined_ove *** 57,64 **** int the provided sequence, matching and simplifying them on-the-fly. Supposed to replace force_gimple_operand (fold_buildN (...), ...). */ extern tree gimple_build (gimple_seq *, location_t, ! enum tree_code, tree, tree, ! tree (*valueize) (tree) = NULL); inline tree gimple_build (gimple_seq *seq, enum tree_code code, tree type, tree op0) --- 57,63 ---- int the provided sequence, matching and simplifying them on-the-fly. Supposed to replace force_gimple_operand (fold_buildN (...), ...). */ extern tree gimple_build (gimple_seq *, location_t, ! enum tree_code, tree, tree); inline tree gimple_build (gimple_seq *seq, enum tree_code code, tree type, tree op0) *************** gimple_build (gimple_seq *seq, *** 66,73 **** return gimple_build (seq, UNKNOWN_LOCATION, code, type, op0); } extern tree gimple_build (gimple_seq *, location_t, ! enum tree_code, tree, tree, tree, ! tree (*valueize) (tree) = NULL); inline tree gimple_build (gimple_seq *seq, enum tree_code code, tree type, tree op0, tree op1) --- 65,71 ---- return gimple_build (seq, UNKNOWN_LOCATION, code, type, op0); } extern tree gimple_build (gimple_seq *, location_t, ! enum tree_code, tree, tree, tree); inline tree gimple_build (gimple_seq *seq, enum tree_code code, tree type, tree op0, tree op1) *************** gimple_build (gimple_seq *seq, *** 75,82 **** return gimple_build (seq, UNKNOWN_LOCATION, code, type, op0, op1); } extern tree gimple_build (gimple_seq *, location_t, ! enum tree_code, tree, tree, tree, tree, ! tree (*valueize) (tree) = NULL); inline tree gimple_build (gimple_seq *seq, enum tree_code code, tree type, tree op0, tree op1, tree op2) --- 73,79 ---- return gimple_build (seq, UNKNOWN_LOCATION, code, type, op0, op1); } extern tree gimple_build (gimple_seq *, location_t, ! enum tree_code, tree, tree, tree, tree); inline tree gimple_build (gimple_seq *seq, enum tree_code code, tree type, tree op0, tree op1, tree op2) *************** gimple_build (gimple_seq *seq, *** 84,91 **** return gimple_build (seq, UNKNOWN_LOCATION, code, type, op0, op1, op2); } extern tree gimple_build (gimple_seq *, location_t, ! enum built_in_function, tree, tree, ! tree (*valueize) (tree) = NULL); inline tree gimple_build (gimple_seq *seq, enum built_in_function fn, tree type, tree arg0) --- 81,87 ---- return gimple_build (seq, UNKNOWN_LOCATION, code, type, op0, op1, op2); } extern tree gimple_build (gimple_seq *, location_t, ! enum built_in_function, tree, tree); inline tree gimple_build (gimple_seq *seq, enum built_in_function fn, tree type, tree arg0) *************** gimple_build (gimple_seq *seq, *** 93,100 **** return gimple_build (seq, UNKNOWN_LOCATION, fn, type, arg0); } extern tree gimple_build (gimple_seq *, location_t, ! enum built_in_function, tree, tree, tree, ! tree (*valueize) (tree) = NULL); inline tree gimple_build (gimple_seq *seq, enum built_in_function fn, tree type, tree arg0, tree arg1) --- 89,95 ---- return gimple_build (seq, UNKNOWN_LOCATION, fn, type, arg0); } extern tree gimple_build (gimple_seq *, location_t, ! enum built_in_function, tree, tree, tree); inline tree gimple_build (gimple_seq *seq, enum built_in_function fn, tree type, tree arg0, tree arg1) *************** gimple_build (gimple_seq *seq, *** 102,109 **** return gimple_build (seq, UNKNOWN_LOCATION, fn, type, arg0, arg1); } extern tree gimple_build (gimple_seq *, location_t, ! enum built_in_function, tree, tree, tree, tree, ! tree (*valueize) (tree) = NULL); inline tree gimple_build (gimple_seq *seq, enum built_in_function fn, tree type, --- 97,103 ---- return gimple_build (seq, UNKNOWN_LOCATION, fn, type, arg0, arg1); } extern tree gimple_build (gimple_seq *, location_t, ! enum built_in_function, tree, tree, tree, tree); inline tree gimple_build (gimple_seq *seq, enum built_in_function fn, tree type,