This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[tree-ssa] Fix for ASMs



Given this C++ code:

extern "C" {
typedef long int __fd_mask;
typedef struct
  {
    __fd_mask fds_bits[1024 / (8 * sizeof (__fd_mask))];
  } fd_set;
typedef __fd_mask fd_mask;
}
extern "Java"
{
  typedef __java_int jint;
  typedef jint jsize;
}
extern "Java" {
class __JArray
{
public:
  const jsize length;
};
template<class T>
class JArray;
}
typedef JArray<jint> *jintArray;
void
helper_put_filedescriptors (jintArray java_fd_array, fd_set& fds, int& max_fd)
{
  int counter;
  jint* java_fds;
  __asm__ __volatile__ ("btsl %1,%0" : "=m" (((&fds)->fds_bits)[((java_fds 
[coun
ter]) / (8 * sizeof (__fd_mask)))]) : "r" (((int) (java_fds [counter])) % (8 * 
s
izeof (__fd_mask))) : "cc","memory");
}

Compile with the tree-ssa compiler with -fdump-tree-all and look at the
.optimized dump.  You'll see something like this:

{
  unsigned int counter.1;
  unsigned int T.2;
  jint * T.3;
  jint * T.4;
  __java_int T.5;
  unsigned int T.6;
  unsigned int T.7;
  struct fd_set * fds.8;
  unsigned int counter.9;
  unsigned int T.10;
  jint * T.11;
  jint * T.12;
  __java_int T.13;
  unsigned int T.14;
  unsigned int T.15;

  {
    int counter;
    jint * java_fds;

    counter.1_2 = (unsigned int)counter_1;
    T.2_3 = counter.1_2 * 4;
    T.3_4 = (jint *)T.2_3;
    T.4_6 = java_fds_5 + T.3_4;
    T.5_9 = (*T.4)_8;
    T.6_10 = (unsigned int)T.5_9;
    T.7_11 = T.6_10 % 32;
    fds.8_13 = (struct fd_set *)fds_12;
    (void)0;
    (void)0;
    (void)0;
    (void)0;
    (void)0;
    (void)0;
    (void)0;
        __asm__("btsl %1,%0":"=m" fds.8->fds_bits[T.15]:"r" T.7:"memory", 
"cc");

  }
}

Note carefully how we have a use of T.15 in the asm statement, but
T.15 is never initialized.  Ouch!

FWIW, I found this with my code which zaps useless crud (such as unused
variables).  With those changes you'd get something like this:

{
  unsigned int counter.1;
  unsigned int T.2;
  jint * T.3;
  jint * T.4;
  __java_int T.5;
  unsigned int T.6;
  unsigned int T.7;
  struct fd_set * fds.8;
  jint * T.11;
  jint * T.12; 
  __java_int T.13;
  unsigned int T.14;
  unsigned int T.15;

  {
    int counter;
    jint * java_fds;

    counter.1 = (unsigned int)counter;
    T.2 = counter.1 * 4;
    T.3 = (jint *)T.2;
    T.4 = java_fds + T.3;
    T.5 = *T.4;
    T.6 = (unsigned int)T.5;
    T.7 = T.6 % 32;
    fds.8 = (struct fd_set *)fds;
    T.11 = T.3;
    T.12 = java_fds + T.11;
    T.13 = *T.12;
    T.14 = (unsigned int)T.13;
    T.15 = T.14 / 32;
        __asm__("btsl %1,%0":"=m" fds.8->fds_bits[T.15]:"r" T.7:"memory", 
"cc");

  }
}

As is obvious, the empty statements are gone.  What's less obvious is that
we also zapped T.10 out of the outer BIND_EXPR since it was never used :-)


Anyway, the fix for this little bug isn't terribly difficult.  Basically
when walking the list of operands to an ASM, we should be calling
back to get_expr_operands since the argument might be, well, something
like fds->fds_bits[index] :-)

	* tree-dfa.c (get_expr_operands): Look inside operands in
	a TREE_LIST.
	
Index: tree-dfa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-dfa.c,v
retrieving revision 1.1.4.101
diff -c -3 -p -r1.1.4.101 tree-dfa.c
*** tree-dfa.c	29 Apr 2003 21:26:13 -0000	1.1.4.101
--- tree-dfa.c	29 Apr 2003 22:22:34 -0000
*************** get_expr_operands (stmt, expr_p, flags, 
*** 492,498 ****
        tree op;
  
        for (op = expr; op; op = TREE_CHAIN (op))
! 	add_stmt_operand (&TREE_VALUE (op), stmt, flags, prev_vops);
  
        return;
      }
--- 492,498 ----
        tree op;
  
        for (op = expr; op; op = TREE_CHAIN (op))
!         get_expr_operands (stmt, &TREE_VALUE (op), flags, prev_vops);
  
        return;
      }






Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]