On Fri, Nov 04, 2016 at 01:33:54PM +0100, Bernd Schmidt wrote:
> On 11/04/2016 01:26 PM, Jakub Jelinek wrote:
> >
> >The following patch avoids that.  Of course the question is if we want
> >to support something like:
> >char var[64];
> >...
> >var[0] = '0xe8';
> >var[1] = ...;
> >(void (*fn) (void) = (void (*) (void)) &var[0];
> >fn ();
> >without any kind of barrier, or not.
> 
> I was going to say no, but trampolines come to mind as a situation where we
> might come close to the above.

So then (untested so far) the following instead?
Indirect function calls will then be as non-efficient as in the past for DSE
and scheduling, but for direct calls, whether the target has a direct call
or only indirect call instruction, should be handled more efficiently.

2016-11-04  Jakub Jelinek  <ja...@redhat.com>

        PR target/77834
        * dse.c (check_mem_read_use): For CALL with MEM as first operand,
        ignore that MEM, but recurse on the MEM's operand if not SYMBOL_REF.
        (dse_step5): Call scan_reads even if just insn_info->frame_read.
        Improve and fix dump file messages.

--- gcc/dse.c.jj        2016-11-03 15:52:12.521965058 +0100
+++ gcc/dse.c   2016-11-04 09:42:27.640098125 +0100
@@ -2159,6 +2159,19 @@ check_mem_read_use (rtx *loc, void *data
       rtx *loc = *iter;
       if (MEM_P (*loc))
        check_mem_read_rtx (loc, (bb_info_t) data);
+      else if (GET_CODE (*loc) == CALL
+              && MEM_P (XEXP (*loc, 0))
+              && MEM_EXPR (XEXP (*loc, 0))
+              && TREE_CODE (MEM_EXPR (XEXP (*loc, 0))) == FUNCTION_DECL)
+       {
+         /* Ignore the MEM in first operand of CALL if it is
+            a direct call.  */
+         iter.skip_subrtxes ();
+         if (GET_CODE (XEXP (XEXP (*loc, 0), 0)) != SYMBOL_REF)
+           check_mem_read_use (&XEXP (XEXP (*loc, 0), 0), data);
+         if (!CONST_INT_P (XEXP (*loc, 1)))
+           check_mem_read_use (&XEXP (*loc, 1), data);
+       }
     }
 }
 
@@ -3298,12 +3311,19 @@ dse_step5 (void)
                  bitmap_clear (v);
                }
              else if (insn_info->read_rec
-                       || insn_info->non_frame_wild_read)
+                      || insn_info->non_frame_wild_read
+                      || insn_info->frame_read)
                {
-                 if (dump_file && !insn_info->non_frame_wild_read)
-                   fprintf (dump_file, "regular read\n");
-                  else if (dump_file && (dump_flags & TDF_DETAILS))
-                   fprintf (dump_file, "non-frame wild read\n");
+                 if (dump_file && (dump_flags & TDF_DETAILS))
+                   {
+                     if (!insn_info->non_frame_wild_read
+                         && !insn_info->frame_read)
+                       fprintf (dump_file, "regular read\n");
+                     if (insn_info->non_frame_wild_read)
+                       fprintf (dump_file, "non-frame wild read\n");
+                     if (insn_info->frame_read)
+                       fprintf (dump_file, "frame read\n");
+                   }
                  scan_reads (insn_info, v, NULL);
                }
            }


        Jakub

Reply via email to