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,

Reply via email to