[cfe-commits] r78450 - in /cfe/trunk: include/clang/AST/Expr.h include/clang/AST/Stmt.h lib/AST/Stmt.cpp lib/Frontend/PCHReaderStmt.cpp lib/Sema/Sema.h lib/Sema/SemaTemplateInstantiateDecl.cpp lib/Sema/SemaTemplateInstantiateExpr.cpp

Chris Lattner sabre at nondot.org
Wed Aug 19 23:42:51 PDT 2009


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




More information about the cfe-commits mailing list