On Thu, 2 Apr 2015, Richard Biener wrote:

> 
> The following makes CCP track copies which avoids pass ordering
> issues between CCP and copyprop as seen from the testcase.
> 
> Bootstrapped and tested on x86_64-unknown-linux-gnu, queued for stage1.
> 
> For stage1 I'd like to get rid of copyprop completely, a 2nd patch
> in the series will remove the copyprop instances immediately
> preceeding/following CCP.
> 
> CCP needs some TLC and I'm going to apply that during stage1.

With the propagator engine improvement this need some extra
testcase adjustments.

Re-bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Note that the "obvious" improvement of ccp_lattice_meet to

  if (val1->lattice_val == UNDEFINED
      /* For UNDEFINED M SSA we can't always SSA because its definition
         may not dominate the PHI node.  */
      && (val2->lattice_val != CONSTANT
          || TREE_CODE (val2->value) != SSA_NAME
          || SSA_NAME_IS_DEFAULT_DEF (val2->value)
          || (gimple_bb (SSA_NAME_DEF_STMT (val2->value)) != where
              && dominated_by_p (CDI_DOMINATORS, where,
                                 gimple_bb (SSA_NAME_DEF_STMT 
(val2->value))))))

to enable optimistic copy propagation (yes, copyprop doesn't do that)
regresses quite some gcc.dg/uninit-pred*.c testcases, so I'm at least
not enabling this with this patch.  For example in
gcc.dg/uninit-pred-2_a.c:

int foo (int n, int m, int r)
{
  int flag = 0;
  int v;

  if (n)
    {
      v = r;
      flag = 1;
    }

  if (m)
    g++;
  else
    bar();

  /* Wrong guard */
  if (!flag)
    blah(v); /* { dg-warning "uninitialized" "real uninitialized var 
warning" } */

we see that we can optimistically propagate r into v for the call
due to the PHI

 v_3 = PHI <v_1(D)(2), v_2(3)>

and v being uninitialized on one path.  We have similar missed
uninit warnings for optimistic constant propagations already
so I think optimistically propagating copies isn't wrong.
We might want to provide a flag to turn both off, of course.

I'll send a followup enabling optimistic copyprop once I get
my mind around on how to fix the testcases.

Richard.

2015-04-16  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/65650
        * tree-ssa-ccp.c (valid_lattice_transition): Allow lattice
        transitions involving copies.
        (set_lattice_value): Adjust for copy lattice state.
        (ccp_lattice_meet): Do not merge UNDEFINED and a copy to the copy
        if that doesn't dominate the merge point.
        (bit_value_unop): Adjust what we treat as varying mask.
        (bit_value_binop): Likewise.
        (bit_value_assume_aligned): Likewise.
        (evaluate_stmt): When we simplified to a SSA name record a copy
        instead of dropping to varying.
        (visit_assignment): Simplify.

        * gimple-match.h (gimple_simplify): Add another callback.
        * gimple-fold.c (fold_stmt_1): Adjust caller.
        (gimple_fold_stmt_to_constant_1): Likewise - pass valueize
        for the 2nd callback.
        * gimple-match-head.c (gimple_simplify): Add a callback that is
        used to valueize the stmt operands and use it that way.

        * gcc.dg/tree-ssa/ssa-ccp-37.c: New testcase.
        * gcc.dg/tree-ssa/forwprop-11.c: Adjust.
        * gcc.dg/tree-ssa/ssa-fre-3.c: Likewise.
        * gcc.dg/tree-ssa/ssa-fre-4.c: Likewise.
        * gcc.dg/tree-ssa/ssa-fre-5.c: Likewise.
        * gcc.dg/tree-ssa/ssa-fre-32.c: Likewise.


Index: gcc/gimple-fold.c
===================================================================
*** gcc/gimple-fold.c   (revision 222266)
--- gcc/gimple-fold.c   (working copy)
*************** fold_stmt_1 (gimple_stmt_iterator *gsi,
*** 3621,3627 ****
        gimple_seq seq = NULL;
        code_helper rcode;
        tree ops[3] = {};
!       if (gimple_simplify (stmt, &rcode, ops, inplace ? NULL : &seq, 
valueize))
        {
          if (replace_stmt_with_simplification (gsi, rcode, ops, &seq, inplace))
            changed = true;
--- 3621,3628 ----
        gimple_seq seq = NULL;
        code_helper rcode;
        tree ops[3] = {};
!       if (gimple_simplify (stmt, &rcode, ops, inplace ? NULL : &seq,
!                          valueize, valueize))
        {
          if (replace_stmt_with_simplification (gsi, rcode, ops, &seq, inplace))
            changed = true;
*************** gimple_fold_stmt_to_constant_1 (gimple s
*** 4928,4934 ****
       edges if there are intermediate VARYING defs.  For this reason
       do not follow SSA edges here even though SCCVN can technically
       just deal fine with that.  */
!   if (gimple_simplify (stmt, &rcode, ops, NULL, gvalueize)
        && rcode.is_tree_code ()
        && (TREE_CODE_LENGTH ((tree_code) rcode) == 0
          || ((tree_code) rcode) == ADDR_EXPR)
--- 4929,4935 ----
       edges if there are intermediate VARYING defs.  For this reason
       do not follow SSA edges here even though SCCVN can technically
       just deal fine with that.  */
!   if (gimple_simplify (stmt, &rcode, ops, NULL, gvalueize, valueize)
        && rcode.is_tree_code ()
        && (TREE_CODE_LENGTH ((tree_code) rcode) == 0
          || ((tree_code) rcode) == ADDR_EXPR)
Index: gcc/gimple-match-head.c
===================================================================
*** gcc/gimple-match-head.c     (revision 222266)
--- gcc/gimple-match-head.c     (working copy)
*************** gimple_simplify (enum built_in_function
*** 601,607 ****
  bool
  gimple_simplify (gimple stmt,
                 code_helper *rcode, tree *ops,
!                gimple_seq *seq, tree (*valueize)(tree))
  {
    switch (gimple_code (stmt))
      {
--- 601,608 ----
  bool
  gimple_simplify (gimple stmt,
                 code_helper *rcode, tree *ops,
!                gimple_seq *seq,
!                tree (*valueize)(tree), tree (*top_valueize)(tree))
  {
    switch (gimple_code (stmt))
      {
*************** gimple_simplify (gimple stmt,
*** 617,625 ****
                || code == VIEW_CONVERT_EXPR)
              {
                tree op0 = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
!               if (valueize && TREE_CODE (op0) == SSA_NAME)
                  {
!                   tree tem = valueize (op0);
                    if (tem)
                      op0 = tem;
                  }
--- 618,626 ----
                || code == VIEW_CONVERT_EXPR)
              {
                tree op0 = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
!               if (top_valueize && TREE_CODE (op0) == SSA_NAME)
                  {
!                   tree tem = top_valueize (op0);
                    if (tem)
                      op0 = tem;
                  }
*************** gimple_simplify (gimple stmt,
*** 631,639 ****
              {
                tree rhs1 = gimple_assign_rhs1 (stmt);
                tree op0 = TREE_OPERAND (rhs1, 0);
!               if (valueize && TREE_CODE (op0) == SSA_NAME)
                  {
!                   tree tem = valueize (op0);
                    if (tem)
                      op0 = tem;
                  }
--- 632,640 ----
              {
                tree rhs1 = gimple_assign_rhs1 (stmt);
                tree op0 = TREE_OPERAND (rhs1, 0);
!               if (top_valueize && TREE_CODE (op0) == SSA_NAME)
                  {
!                   tree tem = top_valueize (op0);
                    if (tem)
                      op0 = tem;
                  }
*************** gimple_simplify (gimple stmt,
*** 644,653 ****
                return gimple_resimplify3 (seq, rcode, type, ops, valueize);
              }
            else if (code == SSA_NAME
!                    && valueize)
              {
                tree op0 = gimple_assign_rhs1 (stmt);
!               tree valueized = valueize (op0);
                if (!valueized || op0 == valueized)
                  return false;
                ops[0] = valueized;
--- 645,654 ----
                return gimple_resimplify3 (seq, rcode, type, ops, valueize);
              }
            else if (code == SSA_NAME
!                    && top_valueize)
              {
                tree op0 = gimple_assign_rhs1 (stmt);
!               tree valueized = top_valueize (op0);
                if (!valueized || op0 == valueized)
                  return false;
                ops[0] = valueized;
*************** gimple_simplify (gimple stmt,
*** 658,666 ****
          case GIMPLE_UNARY_RHS:
            {
              tree rhs1 = gimple_assign_rhs1 (stmt);
!             if (valueize && TREE_CODE (rhs1) == SSA_NAME)
                {
!                 tree tem = valueize (rhs1);
                  if (tem)
                    rhs1 = tem;
                }
--- 659,667 ----
          case GIMPLE_UNARY_RHS:
            {
              tree rhs1 = gimple_assign_rhs1 (stmt);
!             if (top_valueize && TREE_CODE (rhs1) == SSA_NAME)
                {
!                 tree tem = top_valueize (rhs1);
                  if (tem)
                    rhs1 = tem;
                }
*************** gimple_simplify (gimple stmt,
*** 671,686 ****
          case GIMPLE_BINARY_RHS:
            {
              tree rhs1 = gimple_assign_rhs1 (stmt);
!             if (valueize && TREE_CODE (rhs1) == SSA_NAME)
                {
!                 tree tem = valueize (rhs1);
                  if (tem)
                    rhs1 = tem;
                }
              tree rhs2 = gimple_assign_rhs2 (stmt);
!             if (valueize && TREE_CODE (rhs2) == SSA_NAME)
                {
!                 tree tem = valueize (rhs2);
                  if (tem)
                    rhs2 = tem;
                }
--- 672,687 ----
          case GIMPLE_BINARY_RHS:
            {
              tree rhs1 = gimple_assign_rhs1 (stmt);
!             if (top_valueize && TREE_CODE (rhs1) == SSA_NAME)
                {
!                 tree tem = top_valueize (rhs1);
                  if (tem)
                    rhs1 = tem;
                }
              tree rhs2 = gimple_assign_rhs2 (stmt);
!             if (top_valueize && TREE_CODE (rhs2) == SSA_NAME)
                {
!                 tree tem = top_valueize (rhs2);
                  if (tem)
                    rhs2 = tem;
                }
*************** gimple_simplify (gimple stmt,
*** 692,714 ****
          case GIMPLE_TERNARY_RHS:
            {
              tree rhs1 = gimple_assign_rhs1 (stmt);
!             if (valueize && TREE_CODE (rhs1) == SSA_NAME)
                {
!                 tree tem = valueize (rhs1);
                  if (tem)
                    rhs1 = tem;
                }
              tree rhs2 = gimple_assign_rhs2 (stmt);
!             if (valueize && TREE_CODE (rhs2) == SSA_NAME)
                {
!                 tree tem = valueize (rhs2);
                  if (tem)
                    rhs2 = tem;
                }
              tree rhs3 = gimple_assign_rhs3 (stmt);
!             if (valueize && TREE_CODE (rhs3) == SSA_NAME)
                {
!                 tree tem = valueize (rhs3);
                  if (tem)
                    rhs3 = tem;
                }
--- 693,715 ----
          case GIMPLE_TERNARY_RHS:
            {
              tree rhs1 = gimple_assign_rhs1 (stmt);
!             if (top_valueize && TREE_CODE (rhs1) == SSA_NAME)
                {
!                 tree tem = top_valueize (rhs1);
                  if (tem)
                    rhs1 = tem;
                }
              tree rhs2 = gimple_assign_rhs2 (stmt);
!             if (top_valueize && TREE_CODE (rhs2) == SSA_NAME)
                {
!                 tree tem = top_valueize (rhs2);
                  if (tem)
                    rhs2 = tem;
                }
              tree rhs3 = gimple_assign_rhs3 (stmt);
!             if (top_valueize && TREE_CODE (rhs3) == SSA_NAME)
                {
!                 tree tem = top_valueize (rhs3);
                  if (tem)
                    rhs3 = tem;
                }
*************** gimple_simplify (gimple stmt,
*** 732,740 ****
          /* ???  Internal function support missing.  */
          if (!fn)
            return false;
!         if (valueize && TREE_CODE (fn) == SSA_NAME)
            {
!             tree tem = valueize (fn);
              if (tem)
                fn = tem;
            }
--- 733,741 ----
          /* ???  Internal function support missing.  */
          if (!fn)
            return false;
!         if (top_valueize && TREE_CODE (fn) == SSA_NAME)
            {
!             tree tem = top_valueize (fn);
              if (tem)
                fn = tem;
            }
*************** gimple_simplify (gimple stmt,
*** 754,762 ****
            case 1:
              {
                tree arg1 = gimple_call_arg (stmt, 0);
!               if (valueize && TREE_CODE (arg1) == SSA_NAME)
                  {
!                   tree tem = valueize (arg1);
                    if (tem)
                      arg1 = tem;
                  }
--- 755,763 ----
            case 1:
              {
                tree arg1 = gimple_call_arg (stmt, 0);
!               if (top_valueize && TREE_CODE (arg1) == SSA_NAME)
                  {
!                   tree tem = top_valueize (arg1);
                    if (tem)
                      arg1 = tem;
                  }
*************** gimple_simplify (gimple stmt,
*** 767,782 ****
            case 2:
              {
                tree arg1 = gimple_call_arg (stmt, 0);
!               if (valueize && TREE_CODE (arg1) == SSA_NAME)
                  {
!                   tree tem = valueize (arg1);
                    if (tem)
                      arg1 = tem;
                  }
                tree arg2 = gimple_call_arg (stmt, 1);
!               if (valueize && TREE_CODE (arg2) == SSA_NAME)
                  {
!                   tree tem = valueize (arg2);
                    if (tem)
                      arg2 = tem;
                  }
--- 768,783 ----
            case 2:
              {
                tree arg1 = gimple_call_arg (stmt, 0);
!               if (top_valueize && TREE_CODE (arg1) == SSA_NAME)
                  {
!                   tree tem = top_valueize (arg1);
                    if (tem)
                      arg1 = tem;
                  }
                tree arg2 = gimple_call_arg (stmt, 1);
!               if (top_valueize && TREE_CODE (arg2) == SSA_NAME)
                  {
!                   tree tem = top_valueize (arg2);
                    if (tem)
                      arg2 = tem;
                  }
*************** gimple_simplify (gimple stmt,
*** 788,810 ****
            case 3:
              {
                tree arg1 = gimple_call_arg (stmt, 0);
!               if (valueize && TREE_CODE (arg1) == SSA_NAME)
                  {
!                   tree tem = valueize (arg1);
                    if (tem)
                      arg1 = tem;
                  }
                tree arg2 = gimple_call_arg (stmt, 1);
!               if (valueize && TREE_CODE (arg2) == SSA_NAME)
                  {
!                   tree tem = valueize (arg2);
                    if (tem)
                      arg2 = tem;
                  }
                tree arg3 = gimple_call_arg (stmt, 2);
!               if (valueize && TREE_CODE (arg3) == SSA_NAME)
                  {
!                   tree tem = valueize (arg3);
                    if (tem)
                      arg3 = tem;
                  }
--- 789,811 ----
            case 3:
              {
                tree arg1 = gimple_call_arg (stmt, 0);
!               if (top_valueize && TREE_CODE (arg1) == SSA_NAME)
                  {
!                   tree tem = top_valueize (arg1);
                    if (tem)
                      arg1 = tem;
                  }
                tree arg2 = gimple_call_arg (stmt, 1);
!               if (top_valueize && TREE_CODE (arg2) == SSA_NAME)
                  {
!                   tree tem = top_valueize (arg2);
                    if (tem)
                      arg2 = tem;
                  }
                tree arg3 = gimple_call_arg (stmt, 2);
!               if (top_valueize && TREE_CODE (arg3) == SSA_NAME)
                  {
!                   tree tem = top_valueize (arg3);
                    if (tem)
                      arg3 = tem;
                  }
*************** gimple_simplify (gimple stmt,
*** 823,838 ****
      case GIMPLE_COND:
        {
        tree lhs = gimple_cond_lhs (stmt);
!       if (valueize && TREE_CODE (lhs) == SSA_NAME)
          {
!           tree tem = valueize (lhs);
            if (tem)
              lhs = tem;
          }
        tree rhs = gimple_cond_rhs (stmt);
!       if (valueize && TREE_CODE (rhs) == SSA_NAME)
          {
!           tree tem = valueize (rhs);
            if (tem)
              rhs = tem;
          }
--- 824,839 ----
      case GIMPLE_COND:
        {
        tree lhs = gimple_cond_lhs (stmt);
!       if (top_valueize && TREE_CODE (lhs) == SSA_NAME)
          {
!           tree tem = top_valueize (lhs);
            if (tem)
              lhs = tem;
          }
        tree rhs = gimple_cond_rhs (stmt);
!       if (top_valueize && TREE_CODE (rhs) == SSA_NAME)
          {
!           tree tem = top_valueize (rhs);
            if (tem)
              rhs = tem;
          }
Index: gcc/gimple-match.h
===================================================================
*** gcc/gimple-match.h  (revision 222266)
--- gcc/gimple-match.h  (working copy)
*************** private:
*** 41,47 ****
  };
  
  bool gimple_simplify (gimple, code_helper *, tree *, gimple_seq *,
!                     tree (*)(tree));
  tree maybe_push_res_to_seq (code_helper, tree, tree *,
                            gimple_seq *, tree res = NULL_TREE);
  void maybe_build_generic_op (enum tree_code, tree, tree *, tree, tree);
--- 41,47 ----
  };
  
  bool gimple_simplify (gimple, code_helper *, tree *, gimple_seq *,
!                     tree (*)(tree), tree (*)(tree));
  tree maybe_push_res_to_seq (code_helper, tree, tree *,
                            gimple_seq *, tree res = NULL_TREE);
  void maybe_build_generic_op (enum tree_code, tree, tree *, tree, tree);
Index: gcc/testsuite/gcc.dg/tree-ssa/forwprop-11.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/forwprop-11.c (revision 222266)
--- gcc/testsuite/gcc.dg/tree-ssa/forwprop-11.c (working copy)
*************** int g(int *p, int n)
*** 16,20 ****
    return q[-1];
  }
  
! /* { dg-final { scan-tree-dump-times "= MEM\\\[\\\(int \\\*\\\)\[ap\]_.. \\\+ 
4B\\\];" 2 "forwprop1" } } */
  /* { dg-final { cleanup-tree-dump "forwprop1" } } */
--- 16,20 ----
    return q[-1];
  }
  
! /* { dg-final { scan-tree-dump-times "= MEM\\\[\\\(int 
\\\*\\\)\[ap\]_\[0-9\]+(?:\\(D\\))? \\\+ 4B\\\];" 2 "forwprop1" } } */
  /* { dg-final { cleanup-tree-dump "forwprop1" } } */
Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-37.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-37.c  (revision 0)
--- gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-37.c  (working copy)
***************
*** 0 ****
--- 1,14 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O -fdump-tree-ccp1" } */
+ 
+ int foo (int i)
+ {
+   int j = i;
+   int k = 0;
+   int l = j + k;
+   int m = l - j;
+   return m;
+ }
+ 
+ /* { dg-final { scan-tree-dump "return 0;" "ccp1" } } */
+ /* { dg-final { cleanup-tree-dump "ccp1" } } */
Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-3.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-3.c   (revision 222266)
--- gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-3.c   (working copy)
***************
*** 6,12 ****
     When the condition is true, we distribute "(int) (a + b)" as
     "(int) a + (int) b", otherwise we keep the original.  */
  /* { dg-do compile { target { { ! mips64 } && { ! spu-*-* } } } } */
! /* { dg-options "-O -fno-tree-forwprop -fwrapv -fdump-tree-fre1-details" } */
  
  /* From PR14844.  */
  
--- 6,12 ----
     When the condition is true, we distribute "(int) (a + b)" as
     "(int) a + (int) b", otherwise we keep the original.  */
  /* { dg-do compile { target { { ! mips64 } && { ! spu-*-* } } } } */
! /* { dg-options "-O -fno-tree-forwprop -fno-tree-ccp -fwrapv 
-fdump-tree-fre1-details" } */
  
  /* From PR14844.  */
  
Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-32.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-32.c  (revision 222266)
--- gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-32.c  (working copy)
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O -fno-tree-forwprop -fdump-tree-fre1-details" } */
  
  _Complex float m;
  
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O -fno-tree-forwprop -fno-tree-ccp 
-fdump-tree-fre1-details" } */
  
  _Complex float m;
  
Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-4.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-4.c   (revision 222266)
--- gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-4.c   (working copy)
***************
*** 1,7 ****
  /* If the target returns false for TARGET_PROMOTE_PROTOTYPES, then there
     will be no casts for FRE to eliminate and the test will fail.  */
  /* { dg-do compile { target i?86-*-* x86_64-*-* hppa*-*-* mips*-*-* m68k*-*-* 
} } */
! /* { dg-options "-O -fno-tree-forwprop -fdump-tree-fre1-details" } */
  
  /* From PR21608.  */
  
--- 1,7 ----
  /* If the target returns false for TARGET_PROMOTE_PROTOTYPES, then there
     will be no casts for FRE to eliminate and the test will fail.  */
  /* { dg-do compile { target i?86-*-* x86_64-*-* hppa*-*-* mips*-*-* m68k*-*-* 
} } */
! /* { dg-options "-O -fno-tree-ccp -fno-tree-forwprop 
-fdump-tree-fre1-details" } */
  
  /* From PR21608.  */
  
Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-5.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-5.c   (revision 222266)
--- gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-5.c   (working copy)
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O -fno-tree-forwprop -fdump-tree-fre1-details" } */
  
  /* From PR19792.  */
  
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O -fno-tree-ccp -fno-tree-forwprop 
-fdump-tree-fre1-details" } */
  
  /* From PR19792.  */
  
Index: gcc/tree-ssa-ccp.c
===================================================================
*** gcc/tree-ssa-ccp.c  (revision 222266)
--- gcc/tree-ssa-ccp.c  (working copy)
*************** valid_lattice_transition (ccp_prop_value
*** 439,444 ****
--- 439,455 ----
  
    /* Now both lattice values are CONSTANT.  */
  
+   /* Allow arbitrary copy changes as we might look through PHI <a_1, ...>
+      when only a single copy edge is executable.  */
+   if (TREE_CODE (old_val.value) == SSA_NAME
+       && TREE_CODE (new_val.value) == SSA_NAME)
+     return true;
+ 
+   /* Allow transitioning from a constant to a copy.  */
+   if (is_gimple_min_invariant (old_val.value)
+       && TREE_CODE (new_val.value) == SSA_NAME)
+     return true;
+ 
    /* Allow transitioning from PHI <&x, not executable> == &x
       to PHI <&x, &y> == common alignment.  */
    if (TREE_CODE (old_val.value) != INTEGER_CST
*************** set_lattice_value (tree var, ccp_prop_va
*** 527,535 ****
       caller that this was a non-transition.  */
    if (old_val->lattice_val != new_val.lattice_val
        || (new_val.lattice_val == CONSTANT
!         && TREE_CODE (new_val.value) == INTEGER_CST
!         && (TREE_CODE (old_val->value) != INTEGER_CST
!             || new_val.mask != old_val->mask)))
      {
        /* ???  We would like to delay creation of INTEGER_CSTs from
         partially constants here.  */
--- 538,547 ----
       caller that this was a non-transition.  */
    if (old_val->lattice_val != new_val.lattice_val
        || (new_val.lattice_val == CONSTANT
!         && (TREE_CODE (new_val.value) != TREE_CODE (old_val->value)
!             || simple_cst_equal (new_val.value, old_val->value) != 1
!             || (TREE_CODE (new_val.value) == INTEGER_CST
!                 && new_val.mask != old_val->mask))))
      {
        /* ???  We would like to delay creation of INTEGER_CSTs from
         partially constants here.  */
*************** ccp_finalize (void)
*** 965,978 ****
     */
  
  static void
! ccp_lattice_meet (ccp_prop_value_t *val1, ccp_prop_value_t *val2)
  {
!   if (val1->lattice_val == UNDEFINED)
      {
        /* UNDEFINED M any = any   */
        *val1 = *val2;
      }
!   else if (val2->lattice_val == UNDEFINED)
      {
        /* any M UNDEFINED = any
           Nothing to do.  VAL1 already contains the value we want.  */
--- 977,999 ----
     */
  
  static void
! ccp_lattice_meet (basic_block where,
!                 ccp_prop_value_t *val1, ccp_prop_value_t *val2)
  {
!   if (val1->lattice_val == UNDEFINED
!       /* For UNDEFINED M SSA we can't always SSA because its definition
!          may not dominate the PHI node.  Doing optimistic copy propagation
!        also causes a lot of gcc.dg/uninit-pred*.c FAILs.  */
!       && (val2->lattice_val != CONSTANT
!         || TREE_CODE (val2->value) != SSA_NAME))
      {
        /* UNDEFINED M any = any   */
        *val1 = *val2;
      }
!   else if (val2->lattice_val == UNDEFINED
!          /* See above.  */
!          && (val1->lattice_val != CONSTANT
!              || TREE_CODE (val1->value) != SSA_NAME))
      {
        /* any M UNDEFINED = any
           Nothing to do.  VAL1 already contains the value we want.  */
*************** ccp_lattice_meet (ccp_prop_value_t *val1
*** 1026,1032 ****
        *val1 = get_value_for_expr (val1->value, true);
        if (TREE_CODE (val2->value) == ADDR_EXPR)
        tem = get_value_for_expr (val2->value, true);
!       ccp_lattice_meet (val1, &tem);
      }
    else
      {
--- 1047,1053 ----
        *val1 = get_value_for_expr (val1->value, true);
        if (TREE_CODE (val2->value) == ADDR_EXPR)
        tem = get_value_for_expr (val2->value, true);
!       ccp_lattice_meet (where, val1, &tem);
      }
    else
      {
*************** ccp_visit_phi_node (gphi *phi)
*** 1095,1101 ****
          tree arg = gimple_phi_arg (phi, i)->def;
          ccp_prop_value_t arg_val = get_value_for_expr (arg, false);
  
!         ccp_lattice_meet (&new_val, &arg_val);
  
          if (dump_file && (dump_flags & TDF_DETAILS))
            {
--- 1116,1122 ----
          tree arg = gimple_phi_arg (phi, i)->def;
          ccp_prop_value_t arg_val = get_value_for_expr (arg, false);
  
!         ccp_lattice_meet (gimple_bb (phi), &new_val, &arg_val);
  
          if (dump_file && (dump_flags & TDF_DETAILS))
            {
*************** evaluate_stmt (gimple stmt)
*** 1929,1937 ****
    /* The statement produced a nonconstant value.  */
    if (!is_constant)
      {
!       val.lattice_val = VARYING;
!       val.mask = -1;
!       val.value = NULL_TREE;
      }
  
    return val;
--- 1950,1970 ----
    /* The statement produced a nonconstant value.  */
    if (!is_constant)
      {
!       /* The statement produced a copy.  */
!       if (simplified && TREE_CODE (simplified) == SSA_NAME
!         && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (simplified))
!       {
!         val.lattice_val = CONSTANT;
!         val.value = simplified;
!         val.mask = -1;
!       }
!       /* The statement is VARYING.  */
!       else
!       {
!         val.lattice_val = VARYING;
!         val.value = NULL_TREE;
!         val.mask = -1;
!       }
      }
  
    return val;
*************** static enum ssa_prop_result
*** 2243,2269 ****
  visit_assignment (gimple stmt, tree *output_p)
  {
    ccp_prop_value_t val;
!   enum ssa_prop_result retval;
  
    tree lhs = gimple_get_lhs (stmt);
- 
-   gcc_assert (gimple_code (stmt) != GIMPLE_CALL
-               || gimple_call_lhs (stmt) != NULL_TREE);
- 
-   if (gimple_assign_single_p (stmt)
-       && gimple_assign_rhs_code (stmt) == SSA_NAME)
-     /* For a simple copy operation, we copy the lattice values.  */
-     val = *get_value (gimple_assign_rhs1 (stmt));
-   else
-     /* Evaluate the statement, which could be
-        either a GIMPLE_ASSIGN or a GIMPLE_CALL.  */
-     val = evaluate_stmt (stmt);
- 
-   retval = SSA_PROP_NOT_INTERESTING;
- 
-   /* Set the lattice value of the statement's output.  */
    if (TREE_CODE (lhs) == SSA_NAME)
      {
        /* If STMT is an assignment to an SSA_NAME, we only have one
         value to set.  */
        if (set_lattice_value (lhs, val))
--- 2276,2290 ----
  visit_assignment (gimple stmt, tree *output_p)
  {
    ccp_prop_value_t val;
!   enum ssa_prop_result retval = SSA_PROP_NOT_INTERESTING;
  
    tree lhs = gimple_get_lhs (stmt);
    if (TREE_CODE (lhs) == SSA_NAME)
      {
+       /* Evaluate the statement, which could be
+        either a GIMPLE_ASSIGN or a GIMPLE_CALL.  */
+       val = evaluate_stmt (stmt);
+ 
        /* If STMT is an assignment to an SSA_NAME, we only have one
         value to set.  */
        if (set_lattice_value (lhs, val))

Reply via email to