http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50430

             Bug #: 50430
           Summary: Constructors of static external vars are throwed away
                    leading to missed optimizations (and ipa-cp ICE).
    Classification: Unclassified
           Product: gcc
           Version: 4.7.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: lto
        AssignedTo: unassig...@gcc.gnu.org
        ReportedBy: hubi...@gcc.gnu.org


The LTO streaming code deals only with ctors of finalized variables, however
static external vars are useful for optimization. Vtables are common cases like
this.  Current mainline dies building libreoffice at:
(gdb) bt
#0  useless_type_conversion_p (outer_type=0x7ffff53501f8,
inner_type=0x66686e6973615f6e) at ../../gcc/tree-ssa.c:1292
#1  0x00000000005d77fc in fold_ctor_reference (type=0x7ffff53501f8,
ctor=0x7ffff7ec0b10, offset=1088, size=64) at ../../gcc/gimple-fold.c:2880
#2  0x00000000005d7e38 in gimple_get_virt_method_for_binfo (token=15,
known_binfo=0x7ffff2d39820) at ../../gcc/gimple-fold.c:3056
#3  0x0000000000ae6fde in devirtualization_time_bonus (node=<optimized out>,
known_csts=0x3625de0, known_binfos=0x3625d80) at ../../gcc/ipa-cp.c:1170
#4  0x0000000000aeae9c in estimate_local_effects (node=<optimized out>) at
../../gcc/ipa-cp.c:1401
#5  propagate_constants_topo (topo=<optimized out>) at ../../gcc/ipa-cp.c:1548
#6  ipcp_propagate_stage (topo=<optimized out>) at ../../gcc/ipa-cp.c:1631
#7  ipcp_driver () at ../../gcc/ipa-cp.c:2434
#8  0x00000000006733b7 in execute_one_pass (pass=0x10946e0) at
../../gcc/passes.c:2063
#9  0x0000000000673b86 in execute_ipa_pass_list (pass=0x10946e0) at
../../gcc/passes.c:2430
#10 0x00000000004ab3c4 in do_whole_program_analysis () at
../../gcc/lto/lto.c:2670
#11 0x00000000004adf6d in lto_main () at ../../gcc/lto/lto.c:2796
#12 0x0000000000706d42 in compile_file () at ../../gcc/toplev.c:548
#13 do_compile () at ../../gcc/toplev.c:1886
#14 toplev_main (argc=171, argv=0x1201290) at ../../gcc/toplev.c:1962
#15 0x00007ffff63efbc6 in __libc_start_main () from /lib64/libc.so.6
#16 0x00000000004909e9 in _start () at ../sysdeps/x86_64/elf/start.S:113

ctor passed to ctor_reference is error_mark indicating that the value has not
been streamed.

(gdb) p debug_tree (v)
 <var_decl 0x7fffe55dc140 _ZTV11SfxVoidItem
    type <array_type 0x7ffff5367e70
        type <pointer_type 0x7ffff53501f8 __vtbl_ptr_type type <function_type
0x7ffff53502a0>
            public unsigned DI
            size <integer_cst 0x7ffff7eb9ec0 constant 64>
            unit size <integer_cst 0x7ffff7eb9ee0 constant 8>
            align 64 symtab 0 alias set -1 canonical type 0x7ffff53591f8
            pointer_to_this <pointer_type 0x7ffff5350150>>
        BLK
        size <integer_cst 0x7ffff5366000 constant 1152>
        unit size <integer_cst 0x7ffff5366080 constant 144>
        align 64 symtab 0 alias set 2 canonical type 0x7ffff5367e70
        domain <integer_type 0x7ffff5367f18 type <integer_type 0x7ffff7ec9000
sizetype>
            DI size <integer_cst 0x7ffff7eb9ec0 64> unit size <integer_cst
0x7ffff7eb9ee0 8>
            align 64 symtab 0 alias set -1 canonical type 0x7ffff7ec9738
precision 64 min <integer_cst 0x7ffff7eb9f00 0> max <integer_cst 0x7ffff53660a0
17>>
        pointer_to_this <pointer_type 0x7ffff4f41738>>
    readonly public static ignored external virtual BLK file
/abuild/jh/libreoffice/core/solver/unxlngx6.pro/inc/svl/poolitem.hxx line 352
col 0 size <integer_cst 0x7ffff5366000 1152> unit size <integer_cst
0x7ffff5366080 144>
    align 64 context <record_type 0x7ffff53bb2a0 SfxVoidItem> initial
<error_mark 0x7ffff7ec0b10>>
$2 = void

I guess the following is correct fix for the ICE (to also avoid ICEs in case of
invalid programs etc.)

jan@linux-7ldc:~/trunk/gcc> svn diff gimple-fold.c
Index: gimple-fold.c
===================================================================
--- gimple-fold.c       (revision 178905)
+++ gimple-fold.c       (working copy)
@@ -3048,7 +3048,8 @@ gimple_get_virt_method_for_binfo (HOST_W

   if (TREE_CODE (v) != VAR_DECL
       || !DECL_VIRTUAL_P (v)
-      || !DECL_INITIAL (v))
+      || !DECL_INITIAL (v)
+      || DECL_INITIAL (v) == error_mark_node)
     return NULL_TREE;
   gcc_checking_assert (TREE_CODE (TREE_TYPE (v)) == ARRAY_TYPE);
   size = tree_low_cst (TYPE_SIZE (TREE_TYPE (TREE_TYPE (v))), 1);


but then we are missing optimization here.  I guess extern static vars should
go same way as extern inlines: i.e. be finalized to cgraph and then optimized
out after devirtualization.

Honza

Reply via email to