OSDN Git Service

PR opt/13862
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 3 Mar 2004 18:31:36 +0000 (18:31 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 3 Mar 2004 18:31:36 +0000 (18:31 +0000)
        * cselib.c (cselib_record_sets): Don't record multiple sets in
        asm insns.

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

gcc/ChangeLog
gcc/cselib.c
gcc/testsuite/gcc.dg/i386-asm-2.c [new file with mode: 0644]

index 86c9d2e..814f285 100644 (file)
@@ -1,3 +1,9 @@
+2003-03-03  Richard Henderson  <rth@redhat.com>
+
+       PR opt/13862
+       * cselib.c (cselib_record_sets): Don't record multiple sets in
+       asm insns.
+
 2004-03-03  Mostafa Hagog  <mustafa@il.ibm.com>
 
        * common.opt: Add description of the new -fgcse-after-reload flag.
index 169b927..7cc37f1 100644 (file)
@@ -1293,6 +1293,29 @@ cselib_record_sets (rtx insn)
      locations may go away.  */
   note_stores (body, cselib_invalidate_rtx, NULL);
 
+  /* If this is an asm, look for duplicate sets.  This can happen when the
+     user uses the same value as an output multiple times.  This is valid
+     if the outputs are not actually used thereafter.  Treat this case as
+     if the value isn't actually set.  We do this by smashing the destination
+     to pc_rtx, so that we won't record the value later.  */
+  if (n_sets >= 2 && asm_noperands (body) >= 0)
+    {
+      for (i = 0; i < n_sets; i++)
+       {
+         rtx dest = sets[i].dest;
+         if (GET_CODE (dest) == REG || GET_CODE (dest) == MEM)
+           {
+             int j;
+             for (j = i + 1; j < n_sets; j++)
+               if (rtx_equal_p (dest, sets[j].dest))
+                 {
+                   sets[i].dest = pc_rtx;
+                   sets[j].dest = pc_rtx;
+                 }
+           }
+       }
+    }
+
   /* Now enter the equivalences in our tables.  */
   for (i = 0; i < n_sets; i++)
     {
diff --git a/gcc/testsuite/gcc.dg/i386-asm-2.c b/gcc/testsuite/gcc.dg/i386-asm-2.c
new file mode 100644 (file)
index 0000000..e143ea3
--- /dev/null
@@ -0,0 +1,61 @@
+/* PR opt/13862 */
+/* { dg-do compile { target i?86-*-* } } */
+/* { dg-options "-O" } */
+
+typedef struct _fame_syntax_t_ {
+} fame_syntax_t;
+
+typedef struct _fame_bitbuffer_t_
+{
+  unsigned char * base;
+  unsigned char * data;
+  unsigned long shift;
+} fame_bitbuffer_t;
+
+#define fast_bitbuffer_write(data, shift, c, l)                                \
+{                                                                      \
+  int d;                                                               \
+                                                                       \
+  asm("add %1, %%ecx\n"            /* ecx = shift + length */          \
+      "shrd %%cl, %2, %3\n"        /* adjust code to fit in */         \
+      "shr %%cl, %2\n"             /* adjust code to fit in */         \
+      "mov %%ecx, %1\n"            /* shift += length */               \
+      "bswap %2\n"                 /* reverse byte order of code */    \
+      "shr $5, %%ecx\n"            /* get dword increment */            \
+      "or %2, (%0)\n"              /* put first 32 bits */             \
+      "bswap %3\n"                 /* reverse byte order of code */    \
+      "lea   (%0, %%ecx, 4), %0\n" /* data += (ecx>32) */              \
+      "andl $31, %1\n"             /* mask shift */                    \
+      "orl %3, (%0)\n"             /* put last 32 bits */              \
+      : "=r"(data), "=r"(shift), "=a"(d), "=d"(d), "=c"(d)             \
+      : "0"(data), "1"(shift), "2"((unsigned long) c), "3"(0),         \
+       "c"((unsigned long) l)                                          \
+      : "memory");                                                     \
+}
+
+#define bitbuffer_write(bb, c, l) \
+  fast_bitbuffer_write((bb)->data, (bb)->shift, c, l)
+
+typedef enum { frame_type_I, frame_type_P } frame_type_t;
+
+typedef struct _fame_syntax_mpeg1_t_ {
+  fame_bitbuffer_t buffer;
+  frame_type_t frame_type;
+} fame_syntax_mpeg1_t;
+
+#define FAME_SYNTAX_MPEG1(x) ((fame_syntax_mpeg1_t *) x)
+
+void mpeg1_start_picture(fame_syntax_t *syntax)
+{
+  fame_syntax_mpeg1_t *syntax_mpeg1 = FAME_SYNTAX_MPEG1(syntax);
+  bitbuffer_write(&syntax_mpeg1->buffer, 0xFFFF, 16); 
+
+  switch(syntax_mpeg1->frame_type) {
+    case frame_type_I:
+      bitbuffer_write(&syntax_mpeg1->buffer, 0, 1);  
+    break;
+    case frame_type_P:
+      bitbuffer_write(&syntax_mpeg1->buffer, 0, 1);
+    break;
+  }
+}