Message ID | 20120716131054.GA5416@adacore.com |
---|---|
State | New |
Headers | show |
Hi Arnaud, > The natural way to import a builtin that returns void * is to use > System.Address in Ada, which is in fact an integral type. how about doing this for formal arguments too and not just the return type? This would improve optimization by LLVM of calls to standard library functions since the optimizers bail out when they see an "int" parameter where normally there would be a void* (or other pointer type). Ciao, Duncan. > > Addressed by this patch, which makes it possible to e.g. compile: > > with System; > procedure Btins1 is > > function Frame_Address (Level : Integer) return System.Address; > pragma Import (Intrinsic, Frame_Address, "__builtin_frame_address"); > > Ptr : System.Address; > pragma Volatile (Ptr); > begin > Ptr := Frame_Address (0); > end; > > Tested on x86_64-pc-linux-gnu, committed on trunk > > 2012-07-16 Tristan Gingold <gingold@adacore.com> > > * gcc-interface/decl.c (intrin_return_compatible_p): Map Address to > void *. >
On Jul 16, 2012, at 3:16 PM, Duncan Sands wrote: > Hi Arnaud, > >> The natural way to import a builtin that returns void * is to use >> System.Address in Ada, which is in fact an integral type. > > how about doing this for formal arguments too and not just the return type? Formal arguments were already handled. Tristan. > This would improve optimization by LLVM of calls to standard library functions > since the optimizers bail out when they see an "int" parameter where normally > there would be a void* (or other pointer type). > > Ciao, Duncan. > >> >> Addressed by this patch, which makes it possible to e.g. compile: >> >> with System; >> procedure Btins1 is >> >> function Frame_Address (Level : Integer) return System.Address; >> pragma Import (Intrinsic, Frame_Address, "__builtin_frame_address"); >> >> Ptr : System.Address; >> pragma Volatile (Ptr); >> begin >> Ptr := Frame_Address (0); >> end; >> >> Tested on x86_64-pc-linux-gnu, committed on trunk >> >> 2012-07-16 Tristan Gingold <gingold@adacore.com> >> >> * gcc-interface/decl.c (intrin_return_compatible_p): Map Address to >> void *. >> > >
Hi Tristan, On 16/07/12 15:17, Tristan Gingold wrote: > > On Jul 16, 2012, at 3:16 PM, Duncan Sands wrote: > >> Hi Arnaud, >> >>> The natural way to import a builtin that returns void * is to use >>> System.Address in Ada, which is in fact an integral type. >> >> how about doing this for formal arguments too and not just the return type? > > Formal arguments were already handled. indeed, for two years already. Is there any reason not to do this for all functions, rather than just limiting it to builtins? Ciao, Duncan. > > Tristan. > >> This would improve optimization by LLVM of calls to standard library functions >> since the optimizers bail out when they see an "int" parameter where normally >> there would be a void* (or other pointer type). >> >> Ciao, Duncan. >> >>> >>> Addressed by this patch, which makes it possible to e.g. compile: >>> >>> with System; >>> procedure Btins1 is >>> >>> function Frame_Address (Level : Integer) return System.Address; >>> pragma Import (Intrinsic, Frame_Address, "__builtin_frame_address"); >>> >>> Ptr : System.Address; >>> pragma Volatile (Ptr); >>> begin >>> Ptr := Frame_Address (0); >>> end; >>> >>> Tested on x86_64-pc-linux-gnu, committed on trunk >>> >>> 2012-07-16 Tristan Gingold <gingold@adacore.com> >>> >>> * gcc-interface/decl.c (intrin_return_compatible_p): Map Address to >>> void *. >>> >> >> >
On Jul 16, 2012, at 3:24 PM, Duncan Sands wrote: > Hi Tristan, > > On 16/07/12 15:17, Tristan Gingold wrote: >> >> On Jul 16, 2012, at 3:16 PM, Duncan Sands wrote: >> >>> Hi Arnaud, >>> >>>> The natural way to import a builtin that returns void * is to use >>>> System.Address in Ada, which is in fact an integral type. >>> >>> how about doing this for formal arguments too and not just the return type? >> >> Formal arguments were already handled. > > indeed, for two years already. Is there any reason not to do this for all > functions, rather than just limiting it to builtins? I don't understand what do you mean. We need to do this implicit conversion for builtins because they are known by the compiler. Which other functions (that aren't builtins) are you referring to ? Tristan.
Hi Tristan, >> indeed, for two years already. Is there any reason not to do this for all >> functions, rather than just limiting it to builtins? > > I don't understand what do you mean. We need to do this implicit conversion for builtins because they are known by the compiler. Which other functions (that aren't builtins) are you referring to ? all of them! First off, the LLVM optimizers do a better job if an argument of a user defined function that is really a pointer is declared as such, rather than declared as an integer then cast to a pointer before being used. I don't know if the GCC optimizers are sensitive to this too. Also, the LLVM optimizers recognize some standard library functions that the gcc optimizers do not, but fail to recognize them when called from Ada because they have the wrong prototype: an integer rather than a pointer argument. Finally I would argue that as System.Address is really a pointer, playing pretty much exactly the same role as void* in C, it is more philosophically correct to express it as a void*. That said, it should probably just be declared as a pointer in the System package rather than doing all this mucking around in the gcc interface. Ciao, Duncan.
On Jul 16, 2012, at 3:58 PM, Duncan Sands wrote: > Hi Tristan, > >>> indeed, for two years already. Is there any reason not to do this for all >>> functions, rather than just limiting it to builtins? >> >> I don't understand what do you mean. We need to do this implicit conversion for builtins because they are known by the compiler. Which other functions (that aren't builtins) are you referring to ? > > all of them! First off, the LLVM optimizers do a better job if an argument of a > user defined function that is really a pointer is declared as such, rather than > declared as an integer then cast to a pointer before being used. I don't know > if the GCC optimizers are sensitive to this too. Also, the LLVM optimizers > recognize some standard library functions that the gcc optimizers do not, but > fail to recognize them when called from Ada because they have the wrong > prototype: an integer rather than a pointer argument. Finally I would argue > that as System.Address is really a pointer, playing pretty much exactly the > same role as void* in C, it is more philosophically correct to express it as a > void*. That said, it should probably just be declared as a pointer in the > System package rather than doing all this mucking around in the gcc interface. Ah, what you want is the use of 'void *' for System.Address. We didn't choose that because the semantic of System.Address (which includes arithmetic on the whole address space) doesn't match the void * one. But, you can try to implement this scheme by modifying the runtime. I don't know if this is a small work or not. Tristan.
Hi Tristan, > Ah, what you want is the use of 'void *' for System.Address. > We didn't choose that because the semantic of System.Address (which includes arithmetic on the whole address space) doesn't match the void * one. void* arithmetic of this kind exists, it's a gcc extension to C :) > But, you can try to implement this scheme by modifying the runtime. I don't know if this is a small work or not. It crashes the front-end, so it's not trivial. Ciao, Duncan.
On Jul 16, 2012, at 4:36 PM, Duncan Sands wrote: > Hi Tristan, > >> Ah, what you want is the use of 'void *' for System.Address. >> We didn't choose that because the semantic of System.Address (which includes arithmetic on the whole address space) doesn't match the void * one. > > void* arithmetic of this kind exists, it's a gcc extension to C :) The issue is not void * vs char *, but the fact that the C standard has restriction on pointer arithmetic. >> But, you can try to implement this scheme by modifying the runtime. I don't know if this is a small work or not. > > It crashes the front-end, so it's not trivial. :-)
Hi Tristan, >>> Ah, what you want is the use of 'void *' for System.Address. >>> We didn't choose that because the semantic of System.Address (which includes arithmetic on the whole address space) doesn't match the void * one. >> >> void* arithmetic of this kind exists, it's a gcc extension to C :) > > The issue is not void * vs char *, but the fact that the C standard has restriction on pointer arithmetic. I see, -fno-strict-overflow would be needed to get System.Address modulo arithmetic semantics if it was always turned into void*, which would then presumably pessimize other code. However this isn't really relevant to whether Address formal parameters should always be turned into void* or not. Ciao, Duncan. >>> But, you can try to implement this scheme by modifying the runtime. I don't know if this is a small work or not. >> >> It crashes the front-end, so it's not trivial. > > :-) >
PS: That said, I have to admit that using void* for builtins does cover the most important cases.
On Jul 16, 2012, at 5:16 PM, Duncan Sands wrote: > PS: That said, I have to admit that using void* for builtins does cover the > most important cases. Agreed. But I still think that these are two very different issues: * Doing implicit conversion to void * for builtins is just a convenient way for interfacing with builtins. * Using void * for System.Address shouldn't have any immediate advantage for users, but would be a better match for the representation. Tristan.
> Agreed. But I still think that these are two very different issues: > > * Doing implicit conversion to void * for builtins is just a convenient way > for interfacing with builtins. > > * Using void * for System.Address shouldn't have any immediate advantage > for users, but would be a better match for the representation. In fact the latter would unbreak the m68k port (this is PR ada/48835).
Index: gcc-interface/decl.c =================================================================== --- gcc-interface/decl.c (revision 189524) +++ gcc-interface/decl.c (working copy) @@ -8046,6 +8046,10 @@ && !VOID_TYPE_P (btin_return_type)) return true; + /* If return type is Address (integer type), map it to void *. */ + if (Is_Descendent_Of_Address (Etype (inb->gnat_entity))) + ada_return_type = ptr_void_type_node; + /* Check return types compatibility otherwise. Note that this handles void/void as well. */ if (intrin_types_incompatible_p (btin_return_type, ada_return_type))