OSDN Git Service

PR middle-end/47790
authorlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 18 Mar 2011 14:01:41 +0000 (14:01 +0000)
committerlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 18 Mar 2011 14:01:41 +0000 (14:01 +0000)
* expr.c (optimize_bitfield_assignment_op): Revamp to work
again after expansion changes.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@171139 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/expr.c

index 176a13a..cb69c8f 100644 (file)
@@ -1,3 +1,9 @@
+2011-03-16  Andrew Pinski  <pinskia@gmail.com>
+
+       PR middle-end/47790
+       * expr.c (optimize_bitfield_assignment_op): Revamp to work
+       again after expansion changes.
+
 2011-03-18  Chung-Lin Tang  <cltang@codesourcery.com>
 
        * combine.c (try_combine): Do simplification only call of
index 3295156..dc8366d 100644 (file)
@@ -3974,6 +3974,8 @@ optimize_bitfield_assignment_op (unsigned HOST_WIDE_INT bitsize,
   tree op0, op1;
   rtx value, result;
   optab binop;
+  gimple srcstmt;
+  enum tree_code code;
 
   if (mode1 != VOIDmode
       || bitsize >= BITS_PER_WORD
@@ -3983,13 +3985,37 @@ optimize_bitfield_assignment_op (unsigned HOST_WIDE_INT bitsize,
     return false;
 
   STRIP_NOPS (src);
-  if (!BINARY_CLASS_P (src)
-      || TREE_CODE (TREE_TYPE (src)) != INTEGER_TYPE)
+  if (TREE_CODE (src) != SSA_NAME)
+    return false;
+  if (TREE_CODE (TREE_TYPE (src)) != INTEGER_TYPE)
+    return false;
+
+  srcstmt = get_gimple_for_ssa_name (src);
+  if (!srcstmt
+      || TREE_CODE_CLASS (gimple_assign_rhs_code (srcstmt)) != tcc_binary)
     return false;
 
-  op0 = TREE_OPERAND (src, 0);
-  op1 = TREE_OPERAND (src, 1);
-  STRIP_NOPS (op0);
+  code = gimple_assign_rhs_code (srcstmt);
+
+  op0 = gimple_assign_rhs1 (srcstmt);
+
+  /* If OP0 is an SSA_NAME, then we want to walk the use-def chain
+     to find its initialization.  Hopefully the initialization will
+     be from a bitfield load.  */
+  if (TREE_CODE (op0) == SSA_NAME)
+    {
+      gimple op0stmt = get_gimple_for_ssa_name (op0);
+
+      /* We want to eventually have OP0 be the same as TO, which
+        should be a bitfield.  */
+      if (!op0stmt
+         || !is_gimple_assign (op0stmt)
+         || gimple_assign_rhs_code (op0stmt) != TREE_CODE (to))
+       return false;
+      op0 = gimple_assign_rhs1 (op0stmt);
+    }
+
+  op1 = gimple_assign_rhs2 (srcstmt);
 
   if (!operand_equal_p (to, op0, 0))
     return false;
@@ -4026,7 +4052,7 @@ optimize_bitfield_assignment_op (unsigned HOST_WIDE_INT bitsize,
   if (BYTES_BIG_ENDIAN)
     bitpos = str_bitsize - bitpos - bitsize;
 
-  switch (TREE_CODE (src))
+  switch (code)
     {
     case PLUS_EXPR:
     case MINUS_EXPR:
@@ -4054,7 +4080,7 @@ optimize_bitfield_assignment_op (unsigned HOST_WIDE_INT bitsize,
          set_mem_expr (str_rtx, 0);
        }
 
-      binop = TREE_CODE (src) == PLUS_EXPR ? add_optab : sub_optab;
+      binop = code == PLUS_EXPR ? add_optab : sub_optab;
       if (bitsize == 1 && bitpos + bitsize != str_bitsize)
        {
          value = expand_and (str_mode, value, const1_rtx, NULL);
@@ -4087,7 +4113,7 @@ optimize_bitfield_assignment_op (unsigned HOST_WIDE_INT bitsize,
          set_mem_expr (str_rtx, 0);
        }
 
-      binop = TREE_CODE (src) == BIT_IOR_EXPR ? ior_optab : xor_optab;
+      binop = code == BIT_IOR_EXPR ? ior_optab : xor_optab;
       if (bitpos + bitsize != GET_MODE_BITSIZE (GET_MODE (str_rtx)))
        {
          rtx mask = GEN_INT (((unsigned HOST_WIDE_INT) 1 << bitsize)