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] |
[ Jeff & Richard -- there's an x86/gcse question buried in here so y'all might want to take a look, even though this is a C++ thing.] I noticed that our vbase initialization code was somewhat suboptimal. In C++, virtual bases are initialized from the most derived class. Therefore, we know the offsets of virtual bases at compile-time. (In general, the offset of a virtual base must be determined at run-time.) So, when we're constructing a virtual base, we don't need to look up its address dynamically. I've attached a test program and before-and-after x86 assembly to show how this makes an improvement. Look for how the arguments to __1Ai are constructed. BTW, I'm surprised that GCSE isn't able to eliminate the redundant test of edx. Any ideas? This is not an ABI change, but it will improve code generated by both the old and new ABIs. -- Mark Mitchell mark@codesourcery.com CodeSourcery, LLC http://www.codesourcery.com ==== test2.C ==== struct A { A (int); }; struct B : virtual public A { B (); }; B::B () : A (3) { } ==== test2.s ==== [old version] __1Bi: .LFB1: pushl %ebp .LCFI0: movl %esp, %ebp .LCFI1: subl $20, %esp .LCFI2: movl 12(%ebp), %edx pushl %ebx .LCFI3: movl 8(%ebp), %ebx testl %edx, %edx je .L3 leal 4(%ebx), %eax movl %eax, (%ebx) .L3: testl %edx, %edx je .L4 subl $8, %esp pushl $3 movl (%ebx), %edx pushl %edx .LCFI4: call __1Ai .L4: movl %ebx, %eax movl -24(%ebp), %ebx movl %ebp, %esp popl %ebp ret ==== test2.s ==== [new version] __1Bi: .LFB1: pushl %ebp .LCFI0: movl %esp, %ebp .LCFI1: subl $20, %esp .LCFI2: movl 12(%ebp), %edx pushl %ebx .LCFI3: movl 8(%ebp), %ebx testl %edx, %edx je .L3 leal 4(%ebx), %eax movl %eax, (%ebx) .L3: testl %edx, %edx je .L4 subl $8, %esp leal 4(%ebx), %eax pushl $3 pushl %eax .LCFI4: call __1Ai .L4: movl %ebx, %eax movl -24(%ebp), %ebx movl %ebp, %esp popl %ebp ret 2000-01-16 Mark Mitchell <mark@codesourcery.com> * init.c (construct_virtual_bases): Don't look up the addresses of virtual bases at run-time. Index: init.c =================================================================== RCS file: /cvs/gcc/egcs/gcc/cp/init.c,v retrieving revision 1.160 diff -c -p -r1.160 init.c *** init.c 2000/01/16 16:59:44 1.160 --- init.c 2000/01/16 20:13:31 *************** construct_virtual_bases (type, this_ref, *** 751,759 **** for (vbases = CLASSTYPE_VBASECLASSES (type); vbases; vbases = TREE_CHAIN (vbases)) { - tree tmp = purpose_member (vbases, result); tree inner_if_stmt; tree compound_stmt; /* If there are virtual base classes with destructors, we need to emit cleanups to destroy them if an exception is thrown during --- 751,759 ---- for (vbases = CLASSTYPE_VBASECLASSES (type); vbases; vbases = TREE_CHAIN (vbases)) { tree inner_if_stmt; tree compound_stmt; + tree exp; /* If there are virtual base classes with destructors, we need to emit cleanups to destroy them if an exception is thrown during *************** construct_virtual_bases (type, this_ref, *** 772,780 **** inner_if_stmt = begin_if_stmt (); finish_if_stmt_cond (flag, inner_if_stmt); compound_stmt = begin_compound_stmt (/*has_no_scope=*/1); ! expand_aggr_vbase_init_1 (vbases, this_ref, ! TREE_OPERAND (TREE_VALUE (tmp), 0), ! init_list); finish_compound_stmt (/*has_no_scope=*/1, compound_stmt); finish_then_clause (inner_if_stmt); finish_if_stmt (); --- 772,791 ---- inner_if_stmt = begin_if_stmt (); finish_if_stmt_cond (flag, inner_if_stmt); compound_stmt = begin_compound_stmt (/*has_no_scope=*/1); ! ! /* Compute the location of the virtual base. If we're ! constructing virtual bases, then we must be the most derived ! class. Therefore, we don't have to look up the virtual base; ! we already know where it is. */ ! exp = build (PLUS_EXPR, ! TREE_TYPE (this_ptr), ! this_ptr, ! BINFO_OFFSET (vbases)); ! exp = build1 (NOP_EXPR, ! build_pointer_type (BINFO_TYPE (vbases)), ! exp); ! ! expand_aggr_vbase_init_1 (vbases, this_ref, exp, init_list); finish_compound_stmt (/*has_no_scope=*/1, compound_stmt); finish_then_clause (inner_if_stmt); finish_if_stmt ();
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |