On Tue, Apr 7, 2020 at 2:41 PM Erick Ochoa <erick.oc...@theobroma-systems.com> wrote: > > > > On 07/04/2020 14:34, Michael Matz wrote: > > Hello, > > > > On Tue, 7 Apr 2020, Erick Ochoa wrote: > > > >> Thanks for this lead! It is almost exactly what I need. I do have one more > >> question about this. It seems that the types obtained via > >> FOR_EACH_FUNCTION_ARGS and TREE_TYPE are different pointers when compiled > >> with > >> -flto. > >> > >> What do I mean by this? Consider the following code: > >> > >> #include <stdio.h> > >> int main(){ > >> FILE *f = fopen("hello.txt", "w"); > >> fclose(f); > >> return 0; > >> } > >> > >> The trees corresponding to types FILE* and FILE obtained via the variable f > >> are different from the trees obtained from the argument to fclose. > > > > Yes, quite possible. > > > >> However, when we are compiling the simple C program via > >> /path/to/gcc -flto a.c -fdump-ipa-hello-world -fipa-hello-world > >> /path/to/gcc -flto -flto-patition=none -fipa-hello-world a.c -o a.out > >> one can see that the pointers are different: > >> > >> pointers 0xffff79ee1c38 =?= 0xffff79ee0b28 > >> records 0xffff79ee1b90 =?= 0xffff79ee0a80 > >> > >> Do you, or anyone else for that matter, know if it would be possible to > >> keep the trees pointing to the same address? Or, in case it can be > >> possible with some modifications, where could I start looking to modify > >> the source code to make these addresses match? The other alternative for > >> me would be to make my own type comparison function, which is something > >> I can do. But I was wondering about this first. > > > > So, generally type equality can't be established by pointer equality in > > GCC, even more so with LTO; there are various reasons why the "same" type > > (same as in language equality) is represented by different trees, and > > those reasons are amplified with LTO. We try to unify some equal types to > > the same trees when reading in LTO bytecode, but that's only an > > optimization mostly. > > > > So, when you want to compare types use useless_type_conversion_p (for > > equivalence you need useless(a,b) && useless(b,a)). In particular, for > > record types T it's TYPE_CANONICAL(T) that needs to be pointer-equal. > > (I.e. you could hard-code that as well, but it's probably better to use > > the existing predicates we have). Note that useless_type_conversion_p is > > for the middle-end type system (it's actually one part of the definition > > of that type system), i.e. it's language agnostic. If you need language > > specific equality you would have to use a different approach, but given > > that you're adding IPA passes you probably don't worry about that. > > I've been using TYPE_MAIN_VARIANT(T) as opposed to TYPE_CANONICAL(T). > This was per the e-mail thread: > https://gcc.gnu.org/legacy-ml/gcc/2020-01/msg00077.html .
TYPE_CANONICAL (which might be NULL!) is conservative on the side of making types equal when they are not and used for type-based alias analysis where erroring so is conservatively correct but not optimal. TYPE_MAIN_VARIANT (which should never be NULL) is conservative on the side of makeing types distinct when they are not and is not really used in the middle-end but for means of caching variants of types (aka const qualified vs. unqualified). Erroring in making types distinct when they are not is then merely a missed caching opportunity. ISTR having said that being conservative on both sides is impossible. More so with LTO and absolutely when multiple source languages are involved. Which is why I chose to dismiss the idea of using "type escape". > I am not 100% sure what the differences are between these two yet, but I > think TYPE_CANONICAL(T) was not helpful because of typedefs? I might be > wrong here, it has been a while since I did the test to see what worked. > > Using TYPE_MAIN_VARIANT(T) has gotten us far in an optimization we are > working on, but I do think that a custom type comparison is needed now. > > I do not believe I can use useless_type_conversion_p because I need a > partial order in order to place types in a set. > > > > > > > Ciao, > > Michael. > >