On 22 February 2016 at 17:36, Richard Biener <rguent...@suse.de> wrote: > On Mon, 22 Feb 2016, Prathamesh Kulkarni wrote: > >> Hi Richard, >> As discussed in private mail, this version of patch attempts to >> increase alignment >> of global struct decl if it contains an an array field(s) and array's >> offset is a multiple of the alignment of vector type corresponding to >> it's scalar type and recursively checks for nested structs. >> eg: >> static struct >> { >> int a, b, c, d; >> int k[4]; >> float f[10]; >> }; >> k is a candidate array since it's offset is 16 and alignment of >> "vector (4) int" is 8. >> Similarly for f. >> >> I haven't been able to create a test-case where there are >> multiple candidate arrays and vector alignment of arrays are different. >> I suppose in this case we will have to increase alignment >> of the struct by the max alignment ? >> eg: >> static struct >> { >> <fields> >> T1 k[S1] >> <fields> >> T2 f[S2] >> <fields> >> }; >> >> if V1 is vector type corresponding to T1, and V2 corresponding vector >> type to T2, >> offset (k) % align(V1) == 0 and offset (f) % align(V2) == 0 >> and align (V1) > align(V2) then we will increase alignment of struct >> by align(V1). >> >> Testing showed FAIL for g++.dg/torture/pr31863.C due to program timeout. >> Initially it appeared to me, it went in infinite loop. However >> on second thoughts I think it's probably not an infinite loop, rather >> taking (extraordinarily) large amount of time >> to compile the test-case with the patch. >> The test-case builds quickly for only 2 instantiations of ClassSpec >> (ClassSpec<Key, A001, 1>, >> ClassSpec<Key, A002, 2>) >> Building with 22 instantiations (upto ClassSpec<Key, A0023, 22>) takes up >> to ~1m to compile. >> with: >> 23 instantiations: ~2m >> 24 instantiations: ~5m >> For 30 instantiations I terminated cc1plus after 13m (by SIGKILL). >> >> I guess it shouldn't go in an infinite loop because: >> a) structs cannot have circular references. >> b) works for lower number of instantiations >> However I have no sound evidence that it cannot be in infinite loop. >> I don't understand why a decl node is getting visited more than once >> for that test-case. >> >> Using a hash_map to store alignments of decl's so that decl node gets visited >> only once prevents the issue. > > Maybe aliases. Try not walking vnode->alias == true vars. Hi, I have a hypothesis why decl node gets visited multiple times.
Consider the test-case: template <typename T, unsigned N> struct X { T a; virtual int foo() { return N; } }; typedef struct X<int, 1> x_1; typedef struct X<int ,2> x_2; static x_1 obj1 __attribute__((used)); static x_2 obj2 __attribute__((used)); Two additional structs are created by C++FE, c++filt shows: _ZTI1XIiLj1EE -> typeinfo for X<int, 1u> _ZTI1XIiLj2EE -> typeinfo for X<int, 2u> Both of these structs have only one field D.2991 and it appears it's *shared* between them: struct D.2991; const void * D.2980; const char * D.2981; Hence the decl node D.2991 and it's fields (D.2890, D.2981) get visited twice: once when walking _ZTI1XIiLj1EE and 2nd time when walking _ZTI1XIiLj2EE Dump of walking over the global structs for above test-case: http://pastebin.com/R5SABW0c So it appears to me to me a DAG (interior node == struct decl, leaf == non-struct field, edge from node1 -> node2 if node2 is field of node1) is getting created when struct decl is a type-info object. I am not really clear on how we should proceed: a) Keep using hash_map to store alignments so that every decl gets visited only once. b) Skip walking artificial record decls. I am not sure if skipping all artificial struct decls would be a good idea, but I don't think it's possible to identify if a struct-decl is typeinfo struct at middle-end ? Thanks, Prathamesh > > Richard.