On Aug 7, 2009, at 6:41 PM, Douglas Gregor wrote:
> URL: http://llvm.org/viewvc/llvm-project?rev=78450&view=rev
> Log:
> Introduce reference counting for statements and expressions, using it
> to allow sharing of nodes. Simplifies some aspects of template
> instantiation, and fixes both PR3444 and <rdar://problem/6757457>.

Yay for progress :)

> +  /// \brief The statement class.
> +  const unsigned sClass : 8;
> +
> +  /// \brief The reference count for this statement.
> +  unsigned RefCount : 24;

Random thought, do you ever expect to need more than 65536 ref  
counts?  If not, shrinking the refcount to be an unsigned short would  
lead to slightly more efficient generated code for some operations. If  
you compare this:

struct x {
#ifdef BITFIELD
  unsigned int x : 8;
  unsigned int y : 24;
#else
  unsigned char x;
  unsigned short y;
#endif
};

void foo(struct x *P) {
  if (--P->y == 0)
    bar();
}

compiled with gcc 4.2, I get:

NONBITFIELD:  gcc t.c -S -o - -O3 -m32 -fomit-frame-pointer -fno- 
optimize-sibling-calls

_foo:
        subl    $12, %esp
        movl    16(%esp), %eax
        movzwl  2(%eax), %edx
        decl    %edx
        movw    %dx, 2(%eax)
        testw   %dx, %dx
        jne     L4
        call    _bar
L4:
        addl    $12, %esp
        ret

BITFIELD:  gcc t.c -S -o - -O3 -m32 -fomit-frame-pointer -fno-optimize- 
sibling-calls -DBITFIELD

_foo:
        pushl   %esi
        subl    $8, %esp
        movl    16(%esp), %esi
        movl    (%esi), %eax
        movl    %eax, %edx
        shrl    $8, %edx
        decl    %edx
        andl    $16777215, %edx
        movl    %edx, %ecx
        sall    $8, %ecx
        andl    $255, %eax
        orl     %ecx, %eax
        movl    %eax, (%esi)
        testl   %edx, %edx
        jne     L4
        call    _bar
L4:
        addl    $8, %esp
        popl    %esi
        ret

Clang does a better job than GCC, but still suffers:

NONBITFIELD:

_foo:
        subl    $12, %esp
        movl    16(%esp), %eax
        movw    2(%eax), %cx
        decw    %cx
        movw    %cx, 2(%eax)
        testw   %cx, %cx
        jne     LBB1_2
        call    _bar
LBB1_2:
        addl    $12, %esp
        ret


BITFIELD:  clang t.c -S -o - -O3 -m32 -fomit-frame-pointer -DBITFIELD

_foo:
        pushl   %esi
        subl    $8, %esp
        movl    16(%esp), %eax
        movl    (%eax), %ecx
        movzbl  %cl, %edx
        shrl    $8, %ecx
        addl    $16777215, %ecx
        movl    %ecx, %esi
        shll    $8, %esi
        orl     %edx, %esi
        movl    %esi, (%eax)
        testl   $16777215, %ecx
        jne     LBB1_2
        call    _bar
LBB1_2:
        addl    $8, %esp
        popl    %esi
        ret

Incidentally, llvm-gcc produces slightly code for the bitfield case  
than the non-bitfield case, and wipes the floor of either clang or gcc:

NONBITFIELD:

_foo:
        subl    $12, %esp
        movl    16(%esp), %eax
        movw    2(%eax), %cx
        movw    %cx, %dx
        decw    %dx
        movw    %dx, 2(%eax)
        cmpw    $1, %cx
        jne     LBB1_2
        call    _bar
LBB1_2:
        addl    $12, %esp
        ret

BITFIELD:

_foo:
        subl    $12, %esp
        movl    16(%esp), %eax
        movl    $4294967040, %ecx
        addl    (%eax), %ecx
        movl    %ecx, (%eax)
        cmpl    $255, %ecx
        ja      LBB1_2
        call    _bar
LBB1_2:
        addl    $12, %esp
        ret

-Chris

_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to