------- Comment #16 from rguenth at gcc dot gnu dot org  2007-05-12 16:09 
-------
And it's update_stmt () that clears the flag.  It doesn't consider

(gdb) call debug_tree (stmt)
 <modify_expr 0xb7c6b384
    type <integer_type 0xb7c752e0 unsigned int public unsigned SI
        size <integer_cst 0xb7c643d8 constant invariant 32>
        unit size <integer_cst 0xb7c64168 constant invariant 4>
        align 32 symtab 0 alias set -1 precision 32 min <integer_cst 0xb7c64450
0> max <integer_cst 0xb7c64438 4294967295>>
    side-effects asm_written visited
    arg 0 <ssa_name 0xb7cf6d80 type <integer_type 0xb7c752e0 unsigned int>
        var <var_decl 0xb7c70420 D.1546> def_stmt <modify_expr 0xb7c6b384>
        version 8>
    arg 1 <component_ref 0xb7cf2168
        type <integer_type 0xb7cfa4ac unsigned int volatile unsigned SI size
<integer_cst 0xb7c643d8 32> unit size <integer_cst 0xb7c64168 4>
            align 32 symtab 0 alias set -1 precision 32 min <integer_cst
0xb7c64450 0> max <integer_cst 0xb7c64438 4294967295>>
        side-effects volatile
        arg 0 <array_ref 0xb7c715ac type <record_type 0xb7cfa3f4 GTeth_desc>

            arg 0 <component_ref 0xb7cf2870 type <array_type 0xb7cfa0b8>

                arg 0 <indirect_ref 0xb7cf3860 type <record_type 0xb7cfa000
GTeth_softc>

                    arg 0 <ssa_name 0xb7cf6c30 type <pointer_type 0xb7cfa284>
                        var <parm_decl 0xb7cfb0a0 sc> def_stmt <nop_expr
0xb7cf37a0>
                        version 1
                        ptr-info 0xb7cf0870>> arg 1 <field_decl 0xb7cfa170
txq_desc>>
            arg 1 <ssa_name 0xb7cf6cc0 type <integer_type 0xb7c752e0 unsigned
int>
                var <var_decl 0xb7c70318 D.1543> def_stmt <modify_expr
0xb7c6b318>
                version 4>
            arg 2 <integer_cst 0xb7c64180 constant invariant 0>
            arg 3 <integer_cst 0xb7c641f8 constant invariant 1>>
        arg 1 <field_decl 0xb7ceff74 ed_cmdsts type <integer_type 0xb7c752e0
unsigned int>
            unsigned SI file GT64260eth.c line 3 size <integer_cst 0xb7c643d8
32> unit size <integer_cst 0xb7c64168 4>
            align 32 offset_align 128 offset <integer_cst 0xb7c64180 0>
            bit offset <integer_cst 0xb7c64960 constant invariant 0> context
<record_type 0xb7ceff18 GTeth_desc>>>
    GT64260eth.c:24>

to have volatile ops just because the COMPONENT_REF has side-effects and wrong
types (the field_decl is non-volatile unsigned int while the component_ref
is volatile unsigned int).  So after update_stmt there is a mismatch.

Now what do we want here?  Clear the volatileness on the COMPONENT_REF?  Or
refrain from doing the propagation?  Or fix update_ssa?

Two of the solutions are like

Index: tree-ssa-operands.c
===================================================================
--- tree-ssa-operands.c (revision 124635)
+++ tree-ssa-operands.c (working copy)
@@ -2174,6 +2174,11 @@ build_ssa_operands (tree stmt)
   operand_build_sort_virtual (build_v_must_defs);

   finalize_ssa_stmt_operands (stmt);
+
+  /* If the RHS has side-effects, reset has_volatile_ops.  */
+  if (TREE_CODE (stmt) == MODIFY_EXPR
+      && TREE_SIDE_EFFECTS (TREE_OPERAND (stmt, 1)))
+    ann->has_volatile_ops = true;
 }

and

Index: tree-ssa-forwprop.c
===================================================================
--- tree-ssa-forwprop.c (revision 124635)
+++ tree-ssa-forwprop.c (working copy)
@@ -843,15 +843,22 @@ forward_propagate_addr_expr (tree stmt, 
          continue;
        }

-     /* If the use is in a deeper loop nest, then we do not want
-       to propagate the ADDR_EXPR into the loop as that is likely
-       adding expression evaluations into the loop.  */
+      /* If the use is in a deeper loop nest, then we do not want
+        to propagate the ADDR_EXPR into the loop as that is likely
+        adding expression evaluations into the loop.  */
       if (bb_for_stmt (use_stmt)->loop_depth > stmt_loop_depth)
        {
          all = false;
          continue;
        }
-      
+
+      /* If the use_stmt has side-effects, don't propagate into it.  */
+      if (stmt_ann (use_stmt)->has_volatile_ops)
+        {
+         all = false;
+         continue;
+       }
+ 
       result = forward_propagate_addr_expr_1 (stmt, use_stmt, some);
       *some |= result;
       all &= result;

where I prefer the first one.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31797

Reply via email to