Re: [gimple-ssa] result_decl and ssa_name
On 06/04/2024 14:53, Richard Biener wrote: > On Fri, Apr 5, 2024 at 3:44 PM Pierrick Philippe > wrote: >> On 05/04/2024 14:46, Richard Biener wrote: >> >> On Fri, Apr 5, 2024 at 1:59 PM Pierrick Philippe >> wrote: >> >> Hi all, >> >> I do have a question regarding ssa_name and result_decl. >> >> For example on the following gimple function: >> >> int f () >> { >> int x; >> int D.2747; >> int _2; >> >>: >> x_1 = 42; >> _2 = x_1; >> >>: >> : >> return _2; >> >> } >> >> On the above example, using the macro SSA_NAME_VAR() on _2 does not >> yield anything usable. >> Neither to call ssa_default_def() on the result of the result_decl >> obtain through macro DECL_RESULT(). >> >> Is there a way to get the ssa_name corresponding to the result_decl of a >> function obtained through the use of macro DECL_RESULT() on a fn_decl? >> And/or the other way around? I.e., from the returned ssa_name of a >> function to the result_decl of that function? >> >> I totally might be missing something here, but I cannot figure out what. >> >> DECL_RESULT isn't always used (as in your example). Not all SSA names >> have corresponding declarations, we have "anonymous" SSA names which >> have a NULL_TREE SSA_NAME_VAR (such as the _2 in your example). >> >> I see, that makes so much more sense to me now. >> >> What do you try to find in the end? If you want to find all returns you can >> walk predecessors of EXIT_BLOCK and look at their last stmt whether they >> are greturn statements. >> >> I am implementing a state_machine within the analyzer, and I am trying to >> understand where would be the best place to propagate the state of the >> return value. >> I intuitively thought it would be best to do so in the >> state_machine::on_pop_frame() method, which is called by the analyzer >> between the two frames of the caller and the callee. What I do have access >> to is the struct function of the callee/caller, the gcall instruction in the >> caller and the callee have been processed by my analysis. > It might make sense to record the analysis of the return value in > meta-data that the analyzer keeps and access it that way. > Other than that you'd have to do it the way I said with finding the > greturn stmts again and look at what is returned there. That is what I had in mind, thanks for answering me. I do have another question though, how do you obtain the decl_context of such an ssa_name? The DECL_CONTEXT macro is failing during the tree check and I ha ve no idea how to know where a given ssa_name is declared without accessing its inner var (through SSA_NAME_VAR). And this operation is failing on _i ssa_name trees. >> And to illustrate, here I do have the _2 ssa_name and its state which I know >> in that case should be propagate to the lhs of the caller gcall instruction. >> >> Again I might be taking this in a wrong way. >> >> Richard. >> >> Thanks for your time, >> >> Pierrick
Re: [gimple-ssa] result_decl and ssa_name
On Mon, Apr 8, 2024 at 10:47 AM Pierrick Philippe wrote: > > On 06/04/2024 14:53, Richard Biener wrote: > > On Fri, Apr 5, 2024 at 3:44 PM Pierrick Philippe > wrote: > > On 05/04/2024 14:46, Richard Biener wrote: > > On Fri, Apr 5, 2024 at 1:59 PM Pierrick Philippe > wrote: > > Hi all, > > I do have a question regarding ssa_name and result_decl. > > For example on the following gimple function: > > int f () > { > int x; > int D.2747; > int _2; > >: > x_1 = 42; > _2 = x_1; > >: > : > return _2; > > } > > On the above example, using the macro SSA_NAME_VAR() on _2 does not > yield anything usable. > Neither to call ssa_default_def() on the result of the result_decl > obtain through macro DECL_RESULT(). > > Is there a way to get the ssa_name corresponding to the result_decl of a > function obtained through the use of macro DECL_RESULT() on a fn_decl? > And/or the other way around? I.e., from the returned ssa_name of a > function to the result_decl of that function? > > I totally might be missing something here, but I cannot figure out what. > > DECL_RESULT isn't always used (as in your example). Not all SSA names > have corresponding declarations, we have "anonymous" SSA names which > have a NULL_TREE SSA_NAME_VAR (such as the _2 in your example). > > I see, that makes so much more sense to me now. > > What do you try to find in the end? If you want to find all returns you can > walk predecessors of EXIT_BLOCK and look at their last stmt whether they > are greturn statements. > > I am implementing a state_machine within the analyzer, and I am trying to > understand where would be the best place to propagate the state of the return > value. > I intuitively thought it would be best to do so in the > state_machine::on_pop_frame() method, which is called by the analyzer between > the two frames of the caller and the callee. What I do have access to is the > struct function of the callee/caller, the gcall instruction in the caller and > the callee have been processed by my analysis. > > It might make sense to record the analysis of the return value in > meta-data that the analyzer keeps and access it that way. > Other than that you'd have to do it the way I said with finding the > greturn stmts again and look at what is returned there. > > That is what I had in mind, thanks for answering me. > > I do have another question though, how do you obtain the decl_context of such > an ssa_name? The DECL_CONTEXT macro is failing during the tree check and I ha > ve no idea how to know where a given ssa_name is declared without accessing > its inner var (through SSA_NAME_VAR). And this operation is failing on _i > ssa_name trees. There is no DECL_CONTEXT for SSA names, if the name is anonymous (no SSA_NAME_VAR) then the context is implicityly the whole function, thus the FUNCTION_DECL. > > And to illustrate, here I do have the _2 ssa_name and its state which I know > in that case should be propagate to the lhs of the caller gcall instruction. > > Again I might be taking this in a wrong way. > > Richard. > > Thanks for your time, > > Pierrick
[RFC] Linux system call builtins
Hello! I'm a beginner when it comes to GCC development. I want to learn how it works and start contributing. Decided to start by implementing something relatively simple but which would still be very useful for me: Linux builtins. I sought help in the OFTC IRC channel and it was suggested that I discuss it here first and obtain consensus before spending more time on it since it might not be acceptable. I'd like to add GCC builtins for generating Linux system call code for all architectures supported by Linux. They would look like this: __builtin_linux_system_call(long n, ...) __builtin_linux_system_call_1(long n, long _1) __builtin_linux_system_call_2(long n, long _1, long _2) /* More definitions, all the way up to 6 arguments */ Calling these builtins will make GCC place all the parameters in the correct registers for the system call, emit the appropriate instruction for the target architecture and return the result. In other words, they would implement the calling convention[1] of the Linux system calls. I'm often asked why anyone should care about this system call stuff, and I've been asked why I want this added to GCC in particular. My rationale is as follows: + It's stable This is one of the things which makes Linux unique in the operating system landscape: applications can target the kernel directly. Unlike in virtually every other operating system out there, the Linux kernel to user space binary interface is documented[2] as stable. Breaking it is considered a regression in the kernel. Therefore it makes sense for a compiler to target it. The same is not true for any other operating system. + It's a calling convention GCC already supports many calling conventions via function attributes. On x86 alone[3] there's cdecl, fastcall, thiscall, stdcall, ms_abi, sysv_abi, Win32 specific hot patching hooks. So I believe this would not at all be a strange addition to the compiler. + It's becoming common Despite being specific to the Linux kernel, support for it is showing up in other systems. FreeBSD implements limited support[4] for Linux ABIs. Windows Subsystem for Linux started out[5] similarly, as an implementation of this system call ABI. Apparently it's becoming something of a lingua franca. Maybe one day Linux programs will actually become portable by virtue of this stable binary interface. + It doesn't make sense for libraries to support it There are libraries out there that provide system call functionality. The various libcs do. However they usually don't support the full set of Linux system calls. Using certain system calls could invalidate global state in these libraries which leads to them not being supported. Clone is the quintessential example. So I think libraries are not the proper place for this functionality. + It allows freestanding software to easily target Linux Freestanding code usually refers to bare metal targets but Linux is also a viable target. This will make it much easier for developers to create freestanding nolibc no dependency software targeting Linux without having to write any assembly code at all, making GCC ever more useful. + It centralizes functionality in the compiler Currently every programmer who wants to use these system calls must rely on libraries with incomplete support or recreate the system call machinery via inline assembly. Even the Linux kernel ended up doing it[6]. It would be so much nicer if the compiler simply had support for it. I'm a huge fan of builtins like __builtin_frame_address, they make it very easy to solve difficult problems which would otherwise require tons of target specific assembly code. Getting the compiler to do that for Linux system calls is what this proposal is for. + It allows other languages to easily target Linux GCC is a compiler collection and has support for numerous languages. These builtins should allow all of them to target Linux directly in one fell swoop. + Compilers seem like the proper place for it The compiler knows everything about registers and instructions and calling conventions. It just seems like the right place for it. A just in time compiler could also generate this code instead of calling native functions. I really have no idea why they don't do that. Maybe this will prove that it's viable. Implementation wise, I have managed to define the above builtins in my GCC branch and compile it successfully. I have not yet figured out how or even where to implement the code generation. I was hopin
Re: [RFC] add regenerate Makefile target
Hi, On Mon, 25 Mar 2024 at 15:19, Christophe Lyon wrote: > > On Thu, 21 Mar 2024 at 15:32, Christophe Lyon > wrote: > > > > On Wed, 20 Mar 2024 at 16:34, Simon Marchi wrote: > > > > > > On 3/18/24 13:25, Christophe Lyon wrote: > > > > Well the rule to regenerate Makefile.in (eg in in opcodes/) is a bit > > > > more complex > > > > than just calling automake. IIUC it calls automake --foreign it any of > > > > *.m4 file from $(am__configure_deps) that is newer than Makefile.in > > > > (with an early exit in the loop), does nothing if Makefile.am or > > > > doc/local.mk are newer than Makefile.in, and then calls 'automake > > > > --foreign Makefile' > > > > > > The rules looks complex because they've been generated by automake, this > > > Makefile.in is not written by hand. And I guess automake has put > > > `--foreign` there because foreign is used in Makefile.am: > > Yes, I know :-) > > > > > > > > AUTOMAKE_OPTIONS = foreign no-dist > > > > > > But a simple call so `automake -f` (or `autoreconf -f`) just works, as > > > automake picks up the foreign option from AUTOMAKE_OPTIONS, so a human > > > or an external script who wants to regenerate things would probably just > > > use that. > > > > Indeed. I guess my concern is: if some change happens to > > Makefile.am/Makefile.in which would imply that 'autoreconf -f' would > > not work, how do we make sure autoregen.py (or whatever script) is > > updated accordingly? Or maybe whatever change is made to > > Makefile.am/Makefile.in, 'autoreconf -f' is supposed to handle it > > without additional flag? > > > I think I've just noticed a variant of this: if you look at > opcodes/Makefile.in, you can see that aclocal.m4 depends on > configure.ac (among others). So if configure.ac is updated, a > maintainer-mode rule in Makefile.in will call aclocal and regenerate > aclocal.m4. > > However, autoregen.py calls aclocal only if configure.ac contains > AC_CONFIG_MACRO_DIRS, which is not the case here. > > That's probably a bug in opcode/configure.ac, but still the current > Makefile.in machinery would update aclocal.m4 as needed when > autoregen.py will not. > > I haven't audited all configure.ac but there are probably other > occurrences of this. > Another discrepancy I've just noticed: if you look at libsframe/Makefile.am, you can see that ACLOCAL_AMFLAGS = -I .. -I ../config -I ../bfd, so if you run autoreconf -f, it will invoke aclocal with these flags (the same is performed by the aclocal.m4 regeneration rule in the Makefile), but autoregen.py won't run aclocal because configure.ac does not define AC_CONFIG_MACRO_DIRS, and even if it did, it would only use -I../config I guess the same applies for several other subdirs. So in general how do we make sure autoregen.py uses the right flags? Or what prevents us from just using autoreconf -f? If that does not work because configure.ac/Makeline.am and others have bugs, maybe we should fix those bugs instead? which makes me think about Eric's reply: > `autoreconf -f` works fine in individual subdirectories, the problem > is that the top-level configure.ac doesn't use the AC_CONFIG_SUBDIRS > macro to specify its subdirectories, but rather uses its own > hand-rolled method of specifying subdirectories that autoreconf > doesn't know about. This means that autoreconf won't automatically > recurse into all the necessary subdirectories by itself automatically, > and instead has to be run manually in each subdirectory separately. It's not clear to me if that "problem" is a bug, or a design decision we must take into account when writing tools to help regeneration? > Also the various subdirectories are inconsistent about whether they > have a rule for running it (autoreconf) from the Makefile or not, should that be considered a bug, and fixed? > which usually comes down to whether the subdirectory uses automake for > its Makefile or not (the top-level Makefile doesn't; it uses its own > weird autogen-based regeneration method instead, which means that it > misses out on all the built-in rules that automake would implicitly > generate, including ones related to build system regeneration). Thanks, Christophe > Christophe > > > > > > > > The bot I want to put in place would regenerate things as they are > > > > supposed to be, then build and run the testsuite to make sure that > > > > what is supposed to be committed would work (if the committer > > > > regenerates everything correctly) > > > > > > For your job, would it be fine to just force-regenerate everything and > > > ignore timestamps (just like the buildbot's autoregen job wants to do)? > > > It would waste a few cycles, but it would be much simpler. > > > > > Yes, that would achieve the purpose: be able to handle as many patches > > as possible in precommit-CI. > > And as described earlier, for binutils this currently means: > > autoregen > > confgure --enable-maintainer-mode > > make all (with a low -j value otherwise we have random build failures) > > and
Re: [RFC] Linux system call builtins
Hello, On Mon, 8 Apr 2024 at 10:20, Matheus Afonso Martins Moreira via Gcc wrote: > > I'd like to add GCC builtins for generating Linux system call > code for all architectures supported by Linux. > > They would look like this: > > __builtin_linux_system_call(long n, ...) > __builtin_linux_system_call_1(long n, long _1) > __builtin_linux_system_call_2(long n, long _1, long _2) > /* More definitions, all the way up to 6 arguments */ What's the advantage of the _1, _2 etc. forms? The compiler knows how many arguments you're passing, why can't there just be one built-in handling all cases? > > + It doesn't make sense for libraries to support it > > There are libraries out there that provide > system call functionality. The various libcs do. > However they usually don't support the full set > of Linux system calls. Using certain system calls > could invalidate global state in these libraries > which leads to them not being supported. Clone is > the quintessential example. So I think libraries > are not the proper place for this functionality. Your proposal doesn't seem to actually address the problem. If using the clone syscall causes problems for glibc by not giving glibc a chance to set up TLS etc for the new thread, how does making it easier to use the clone syscall help?
Re: [RFC] Linux system call builtins
* Matheus Afonso Martins Moreira via Gcc: > + It's stable > > This is one of the things which makes Linux unique > in the operating system landscape: applications > can target the kernel directly. Unlike in virtually > every other operating system out there, the Linux kernel > to user space binary interface is documented[2] as stable. > Breaking it is considered a regression in the kernel. > Therefore it makes sense for a compiler to target it. > The same is not true for any other operating system. There is quite a bit of variance in how the kernel is entered. On x86-64, one once popular mechanism is longer present in widely-used kernels. For POWER, the preferred way changed over time. Likewise for i386. > + It's a calling convention > > GCC already supports many calling conventions > via function attributes. On x86 alone[3] there's > cdecl, fastcall, thiscall, stdcall, ms_abi, sysv_abi, > Win32 specific hot patching hooks. So I believe this > would not at all be a strange addition to the compiler. But using a builtin obfuscates that relationship. There is no __builtin_call_ms_abi, is there? Thanks, Florian
Re: [RFC] Linux system call builtins
On Mon, 8 Apr 2024, Florian Weimer via Gcc wrote: > * Matheus Afonso Martins Moreira via Gcc: > > > + It's stable > > > > This is one of the things which makes Linux unique > > in the operating system landscape: applications > > can target the kernel directly. Unlike in virtually > > every other operating system out there, the Linux kernel > > to user space binary interface is documented[2] as stable. > > Breaking it is considered a regression in the kernel. > > Therefore it makes sense for a compiler to target it. > > The same is not true for any other operating system. > > There is quite a bit of variance in how the kernel is entered. On > x86-64, one once popular mechanism is longer present in widely-used > kernels. I assume you're implicitly referencing the vsyscall mechanism, but on amd64 it's not useful to *enter the kernel*, right? It was useful for obtaining the result of certain syscalls without actually entering the kernel, like with vdso. Unlike i386, where the vdso (as well as vsyscall I guess) provides the __kernel_vsyscall entrypoint, which provides whichever of { int 0x80, sysenter, syscall } methods is available and fastest. Or am I missing something? Alexander
Re: [RFC] Linux system call builtins
* Alexander Monakov: > On Mon, 8 Apr 2024, Florian Weimer via Gcc wrote: > >> * Matheus Afonso Martins Moreira via Gcc: >> >> > + It's stable >> > >> > This is one of the things which makes Linux unique >> > in the operating system landscape: applications >> > can target the kernel directly. Unlike in virtually >> > every other operating system out there, the Linux kernel >> > to user space binary interface is documented[2] as stable. >> > Breaking it is considered a regression in the kernel. >> > Therefore it makes sense for a compiler to target it. >> > The same is not true for any other operating system. >> >> There is quite a bit of variance in how the kernel is entered. On >> x86-64, one once popular mechanism is longer present in widely-used >> kernels. > > I assume you're implicitly referencing the vsyscall mechanism, but on > amd64 it's not useful to *enter the kernel*, right? It was useful for > obtaining the result of certain syscalls without actually entering > the kernel, like with vdso. The implementation performed a standard system call if a pure userspace implementation wasn't possible. It wasn't intended as a general-purpose way to enter the kernel (although it could be used as such, hence the desire to remove it in some cases). Thanks, Florian
Re: Re: [RFC] Linux system call builtins
> What's the advantage of the _1, _2 etc. forms? Now that you mention it... I don't believe there are any. > The compiler knows how many arguments you're passing, > why can't there just be one built-in handling all cases? You're right about that. When I started working on this I just mirrored the existing APIs which consist of one function for each possible arity. I have always wanted a variadic system call function though so when I saw that GCC had variadic builtins I threw one in. A builtin doesn't have the overhead of variadic C functions though. The compiler should be able to generate optimal code depending on how many arguments it's called with. It's the best possible interface and strictly superior to anything libraries can offer. Would other languages supported by GCC benefit from the other forms? Perhaps variadic builtins are incompatible with them for some reason? I can't think of any reason to keep the numbered forms otherwise. > Your proposal doesn't seem to actually address the problem. > If using the clone syscall causes problems for glibc by not > giving glibc a chance to set up TLS etc for the new thread, > how does making it easier to use the clone syscall help? I think that problem can never be fully addressed, only worked around. It seems to be inherent to how standard C libraries are implemented. The C standards apparently make it impossible to avoid either global or thread local state. Locales come to mind... Compiler support for system calls help by eliminating the need for the system call stub functions traditionally provided by these C libraries. There's no need to link against the C libraries just for that anymore and there's also no need to implement it ourselves since the compiler provides it. The result is it makes it easier to develop freestanding software targeting Linux.
Re: [RFC] Linux system call builtins
On Mon, 8 Apr 2024, Florian Weimer wrote: > * Alexander Monakov: > > >> There is quite a bit of variance in how the kernel is entered. On > >> x86-64, one once popular mechanism is longer present in widely-used > >> kernels. > > > > I assume you're implicitly referencing the vsyscall mechanism, but on > > amd64 it's not useful to *enter the kernel*, right? It was useful for > > obtaining the result of certain syscalls without actually entering > > the kernel, like with vdso. > > The implementation performed a standard system call if a pure userspace > implementation wasn't possible. It wasn't intended as a general-purpose > way to enter the kernel (although it could be used as such, hence the > desire to remove it in some cases). I guess you meant it was "popular" only for the specific syscalls it provided acceleration for. I'm not sure how that is relevant to the current discussion. Alexander
Question about constructing vector types in GIMPLE pass
Hi, I've been working on strengthening auto-vectorization on intel CPUs recently. I tried to do it in the GIMPLE pass. And I noticed that some vector types in the GIMPLE code are confusing to me. The example code is here: _1 = MEM[(const __m256i_u * {ref-all})_2]; I wondered how I could construct or get the type `(const __m256i_u * {ref-all})` in the GIMPLE pass. If you have any ideas that can help me. I'll be so grateful! :) Thanks Hanke Zhang
Re: Re: [RFC] Linux system call builtins
> There is quite a bit of variance in how the kernel is entered. I assume you mean the vDSO. It is also documented and stable. https://www.kernel.org/doc/html/latest/admin-guide/abi-stable.html#vdso > Unless otherwise noted, the set of symbols with any given version > and the ABI of those symbols is considered stable. > It may vary across architectures, though. > As of this writing, this ABI documentation as been confirmed > for x86_64. The maintainers of the other vDSO-using architectures > should confirm that it is correct for their architecture. It is an also entirely optional. The architecture specific system call entry point is always available. The vDSO exists to provide much more efficient ways to access frequently queried system information such as the current time. While the optimized approaches are preferable, the slower system call entry points are still available and stable. > On x86-64, one once popular mechanism > is longer present in widely-used kernels. Please elaborate. Do you mean the vDSO? Linux places a pointer to the vDSO in the auxiliary vector, and a pointer to that vector is located immediately after the program's environment. The program will have to walk that vector in order to find the vDSO. If the vDSO is missing, then the program will fail to find that pointer and hopefully fall back to traditional system call entry points. Perhaps GCC could also have builtins for accessing things like argc, argv, envp and auxvec. They are part of the ABI too. This would allow programs to access the vDSO via the auxvec. It'd also allow implementation of ELF entry points entirely in C. > But using a builtin obfuscates that relationship. > There is no __builtin_call_ms_abi, is there? That's true but that's because there's no need for those builtins. Functions which conform to specific ABIs will have been marked with the relevant attribute so GCC will know how what to do when it is called. Linux system calls do not actually exist as functions so they can't be marked that way. It could be implemented that way by having a naked system call function whose entire body is just the syscall instruction. Then it could be marked with a linux_syscall_abi attribute and the compiler would know to where to put the arguments and from where to obtain the return value. That just replicates what the builtin is supposed to do though. The builtin would not need any declarations or attributes. It would just work.
Re: Re: [RFC] Linux system call builtins
On Mon, 8 Apr 2024, 13:00 Matheus Afonso Martins Moreira via Gcc, < gcc@gcc.gnu.org> wrote: > > Compiler support for system calls help by eliminating the need for the > system call stub functions traditionally provided by these C libraries. > There's no need to link against the C libraries just for that anymore > and there's also no need to implement it ourselves since the compiler > provides it. The result is it makes it easier to develop freestanding > software targeting Linux. > It means you don't need newlib just for the syscall function, but then you would also need to implement memcpy, etc. for yourself. Obviously some bare metal code needs to do that anyway, but that wouldn't be using syscalls either. This isn't my field so maybe I'm totally wrong, but the use case seems like a niche within a niche, but with a non-zero maintenance burden for GCC.
Re: Patches submission policy change
On 03/04/2024 14:23, Christophe Lyon via Gcc wrote: > On Wed, 3 Apr 2024 at 14:59, Joel Sherrill wrote: >> >> Another possible issue which may be better now than in years past >> is that the versions of autoconf/automake required often had to be >> installed by hand. I think newlib has gotten better but before the >> rework on its Makefile/configure, I had a special install of autotools >> which precisely matched what it required. >> >> And that led to very few people being able to successfully regenerate. >> >> Is that avoidable? >> >> OTOH the set of people touching these files may be small enough that >> pain isn't an issue. >> > > For binutils/gcc/gdb we still have to use specific versions which are > generally not the distro's ones. That's because at least some distros modify autoconf to their own taste/needs, so that it does not generate the same output as the officially released version. Furthermore, they provide no mechanism to make their version revert back to the original behaviour. R.
Re: [RFC] Linux system call builtins
Hi, On Mon, Apr 08, 2024 at 06:19:14AM -0300, Matheus Afonso Martins Moreira via Gcc wrote: > Hello! I'm a beginner when it comes to GCC development. > I want to learn how it works and start contributing. > Decided to start by implementing something relatively simple > but which would still be very useful for me: Linux builtins. > I sought help in the OFTC IRC channel and it was suggested > that I discuss it here first and obtain consensus before > spending more time on it since it might not be acceptable. > > I'd like to add GCC builtins for generating Linux system call > code for all architectures supported by Linux. > > They would look like this: > > __builtin_linux_system_call(long n, ...) > __builtin_linux_system_call_1(long n, long _1) > __builtin_linux_system_call_2(long n, long _1, long _2) > /* More definitions, all the way up to 6 arguments */ > As noted by J. Wakely, you don't need to have one variant for each number of arguments. By the way, even if you have multiple variants you could unify them all under a macro __builtin_linux_system_call by means such as "overloading macros based on the argument count." [1] > Calling these builtins will make GCC place all the parameters > in the correct registers for the system call, emit the appropriate > instruction for the target architecture and return the result. > In other words, they would implement the calling convention[1] of > the Linux system calls. > > I'm often asked why anyone should care about this system call stuff, > and I've been asked why I want this added to GCC in particular. > My rationale is as follows: > > + It's stable > [snip] I assume you're talking about the interface which is often abstracted by functions such as the following which are often found in libcs or freestanding libraries. The musl is a typical example (cf syscall_arch.h) for each architecture ( https://git.musl-libc.org/cgit/musl/tree/arch ) long linux_system_call_1(long number, long _1) { register long rax __asm__("rax") = number; register long rdi __asm__("rdi") = _1; __asm__ volatile ("syscall" : "+r" (rax) : "r" (rdi) : "rcx", "r11", "cc", "memory"); return rax; } > > + It's a calling convention > > GCC already supports many calling conventions > via function attributes. On x86 alone[3] there's > cdecl, fastcall, thiscall, stdcall, ms_abi, sysv_abi, > Win32 specific hot patching hooks. So I believe this > would not at all be a strange addition to the compiler. I may be wrong, but I think that at least on sysv x86_64, syscalls have the same calling conventions as regular functions. However, the function descriptor is not an address (or a symbol reference) but a number. > > + It's becoming common > [snip] > > + It doesn't make sense for libraries to support it > [snip] At least, it would be nice if not all freestanding libraries had to reimplement those syscalls stubs. > > + It allows freestanding software to easily target Linux > > + It centralizes functionality in the compiler > > + It allows other languages to easily target Linux > > + Compilers seem like the proper place for it I tend to agree with those points. > Implementation wise, I have managed to define the above builtins > in my GCC branch and compile it successfully. I have not yet > figured out how or even where to implement the code generation. > I was hoping to show up here with patches ready for review > but it really is a complex project. That's why I would like to > to see what the community thinks before proceeding. > I think you could have a look at the function 'expand_call' in calls.cc to see how regular calls are expanded to RTL and see what you would need to do to support calls which use a number rather than an address. Cheers, Paul [1]: https://jadlevesque.github.io/PPMP-Iceberg/explanations#overloading-macros-based-on-argument-count
Re: [RFC] Linux system call builtins
On Mon, Apr 8, 2024 at 11:20 AM Paul Iannetta via Gcc wrote: > > Hi, > > On Mon, Apr 08, 2024 at 06:19:14AM -0300, Matheus Afonso Martins Moreira via > Gcc wrote: > > Hello! I'm a beginner when it comes to GCC development. > > I want to learn how it works and start contributing. > > Decided to start by implementing something relatively simple > > but which would still be very useful for me: Linux builtins. > > I sought help in the OFTC IRC channel and it was suggested > > that I discuss it here first and obtain consensus before > > spending more time on it since it might not be acceptable. > > > > I'd like to add GCC builtins for generating Linux system call > > code for all architectures supported by Linux. > > > > They would look like this: > > > > __builtin_linux_system_call(long n, ...) > > __builtin_linux_system_call_1(long n, long _1) > > __builtin_linux_system_call_2(long n, long _1, long _2) > > /* More definitions, all the way up to 6 arguments */ > > > > As noted by J. Wakely, you don't need to have one variant for each > number of arguments. By the way, even if you have multiple variants > you could unify them all under a macro __builtin_linux_system_call by > means such as "overloading macros based on the argument count." [1] Actually you don't need a macro if implemented inside GCC. Can you can count the number of arguments and expand it based on that. No reason for macros. Now the question comes is the argument long or some other type? E.g. for some 32bit ABIs built on top of 64bit ISA might always just pass 32bits or they might allow passing the full 64bits. (x32 might fall under this and MIPS n32). Or do you split a 64bit argument into the lower and upper half registers. Maybe you should warn/error out if not passed the correct sized argument. Also do you sign or zero extend a 32bit argument for LP64 targets? Right now it is not obvious nor documented in your examples. Thanks, Andrew Pinski > > > Calling these builtins will make GCC place all the parameters > > in the correct registers for the system call, emit the appropriate > > instruction for the target architecture and return the result. > > In other words, they would implement the calling convention[1] of > > the Linux system calls. > > > > I'm often asked why anyone should care about this system call stuff, > > and I've been asked why I want this added to GCC in particular. > > My rationale is as follows: > > > > + It's stable > > [snip] > > I assume you're talking about the interface which is often abstracted > by functions such as the following which are often found in libcs or > freestanding libraries. The musl is a typical example (cf syscall_arch.h) > for each architecture ( https://git.musl-libc.org/cgit/musl/tree/arch ) > > long linux_system_call_1(long number, long _1) > { > register long rax __asm__("rax") = number; > register long rdi __asm__("rdi") = _1; > > __asm__ volatile > ("syscall" > > : "+r" (rax) > : "r" (rdi) > : "rcx", "r11", "cc", "memory"); > > return rax; > } > > > > > + It's a calling convention > > > > GCC already supports many calling conventions > > via function attributes. On x86 alone[3] there's > > cdecl, fastcall, thiscall, stdcall, ms_abi, sysv_abi, > > Win32 specific hot patching hooks. So I believe this > > would not at all be a strange addition to the compiler. > > I may be wrong, but I think that at least on sysv x86_64, syscalls have > the same calling conventions as regular functions. However, the > function descriptor is not an address (or a symbol reference) but a > number. > > > > > + It's becoming common > > [snip] > > > > + It doesn't make sense for libraries to support it > > [snip] > > At least, it would be nice if not all freestanding libraries had to > reimplement those syscalls stubs. > > > > > + It allows freestanding software to easily target Linux > > > > + It centralizes functionality in the compiler > > > > + It allows other languages to easily target Linux > > > > + Compilers seem like the proper place for it > > I tend to agree with those points. > > > Implementation wise, I have managed to define the above builtins > > in my GCC branch and compile it successfully. I have not yet > > figured out how or even where to implement the code generation. > > I was hoping to show up here with patches ready for review > > but it really is a complex project. That's why I would like to > > to see what the community thinks before proceeding. > > > > I think you could have a look at the function 'expand_call' in > calls.cc to see how regular calls are expanded to RTL and see what you > would need to do to support calls which use a number rather than an > address. > > Cheers, > Paul > > [1]: > https://jadlevesque.github.io/PPMP-Iceberg/explanations#overloading-macros-based-on-argument-count > > > >
Re: Question about constructing vector types in GIMPLE pass
On Mon, 8 Apr 2024, Hanke Zhang via Gcc wrote: Hi, I've been working on strengthening auto-vectorization on intel CPUs recently. I tried to do it in the GIMPLE pass. And I noticed that some vector types in the GIMPLE code are confusing to me. The example code is here: _1 = MEM[(const __m256i_u * {ref-all})_2]; I wondered how I could construct or get the type `(const __m256i_u * {ref-all})` in the GIMPLE pass. If you have any ideas that can help me. I'll be so grateful! :) I am not sure what you are asking exactly. If you already have access to such a MEM_REF, then the doc tells you where to look for this type: "The first operand is the pointer being dereferenced; it will always have pointer or reference type. The second operand is a pointer constant serving as constant offset applied to the pointer being dereferenced with its type specifying the type to be used for type-based alias analysis. The type of the node specifies the alignment of the access." If you want to create a new type similar to this one, you can build it with various tools: build_vector_type or build_vector_type_for_mode build_pointer_type_for_mode(*, VOIDmode, true) to build a pointer that can alias anything build_qualified_type to add const (probably useless) build_aligned_type to specify that it is unaligned -- Marc Glisse
Re: [RFC] Linux system call builtins
On Mon, Apr 08, 2024 at 11:26:40AM -0700, Andrew Pinski wrote: > On Mon, Apr 8, 2024 at 11:20 AM Paul Iannetta via Gcc wrote: > > > > Hi, > > > > On Mon, Apr 08, 2024 at 06:19:14AM -0300, Matheus Afonso Martins Moreira > > via Gcc wrote: > > > Hello! I'm a beginner when it comes to GCC development. > > > I want to learn how it works and start contributing. > > > Decided to start by implementing something relatively simple > > > but which would still be very useful for me: Linux builtins. > > > I sought help in the OFTC IRC channel and it was suggested > > > that I discuss it here first and obtain consensus before > > > spending more time on it since it might not be acceptable. > > > > > > I'd like to add GCC builtins for generating Linux system call > > > code for all architectures supported by Linux. > > > > > > They would look like this: > > > > > > __builtin_linux_system_call(long n, ...) > > > __builtin_linux_system_call_1(long n, long _1) > > > __builtin_linux_system_call_2(long n, long _1, long _2) > > > /* More definitions, all the way up to 6 arguments */ > > > > > > > As noted by J. Wakely, you don't need to have one variant for each > > number of arguments. By the way, even if you have multiple variants > > you could unify them all under a macro __builtin_linux_system_call by > > means such as "overloading macros based on the argument count." [1] > > Actually you don't need a macro if implemented inside GCC. Can you can > count the number of arguments and expand it based on that. No reason > for macros. I fully agree here. I was mentioning the macro solution in the case where it is supported outside the compiler. > Now the question comes is the argument long or some other > type? E.g. for some 32bit ABIs built on top of 64bit ISA might always > just pass 32bits or they might allow passing the full 64bits. (x32 > might fall under this and MIPS n32). Or do you split a 64bit argument > into the lower and upper half registers. Maybe you should warn/error > out if not passed the correct sized argument. > Also do you sign or zero extend a 32bit argument for LP64 targets? > Right now it is not obvious nor documented in your examples. > Another case would be targets allowing an immediate argument for their syscall instruction. Sign extend is probably always an error, zero extend may give the expected results. Emitting an error or a warning seems a very good idea if the size does not match. Syscalls can receive both values or pointers (which may not have the same size as regular values) which may complicate the handling and the types of the arguments. However, for most complex ABIs, all the cases you mentioned should be addressed by each target backend by specializing the call/call_value SPNs in their machine description files, and specifying the right constraints. > > Thanks, > Andrew Pinski > > > > > > Calling these builtins will make GCC place all the parameters > > > in the correct registers for the system call, emit the appropriate > > > instruction for the target architecture and return the result. > > > In other words, they would implement the calling convention[1] of > > > the Linux system calls. > > > > > > I'm often asked why anyone should care about this system call stuff, > > > and I've been asked why I want this added to GCC in particular. > > > My rationale is as follows: > > > > > > + It's stable > > > [snip] > > > > I assume you're talking about the interface which is often abstracted > > by functions such as the following which are often found in libcs or > > freestanding libraries. The musl is a typical example (cf syscall_arch.h) > > for each architecture ( https://git.musl-libc.org/cgit/musl/tree/arch ) > > > > long linux_system_call_1(long number, long _1) > > { > > register long rax __asm__("rax") = number; > > register long rdi __asm__("rdi") = _1; > > > > __asm__ volatile > > ("syscall" > > > > : "+r" (rax) > > : "r" (rdi) > > : "rcx", "r11", "cc", "memory"); > > > > return rax; > > } > > > > > > > > + It's a calling convention > > > > > > GCC already supports many calling conventions > > > via function attributes. On x86 alone[3] there's > > > cdecl, fastcall, thiscall, stdcall, ms_abi, sysv_abi, > > > Win32 specific hot patching hooks. So I believe this > > > would not at all be a strange addition to the compiler. > > > > I may be wrong, but I think that at least on sysv x86_64, syscalls have > > the same calling conventions as regular functions. However, the > > function descriptor is not an address (or a symbol reference) but a > > number. > > > > > > > > + It's becoming common > > > [snip] > > > > > > + It doesn't make sense for libraries to support it > > > [snip] > > > > At least, it would be nice if not all freestanding libraries had to > > reimplement those syscalls stubs. > > > > > > > > + It allows fr
Re: [RFC] Linux system call builtins
> On Apr 8, 2024, at 4:01 PM, Paul Iannetta via Gcc wrote: > > On Mon, Apr 08, 2024 at 11:26:40AM -0700, Andrew Pinski wrote: >> On Mon, Apr 8, 2024 at 11:20 AM Paul Iannetta via Gcc >> wrote: >>> ... >> Also do you sign or zero extend a 32bit argument for LP64 targets? >> Right now it is not obvious nor documented in your examples. >> > > Another case would be targets allowing an immediate argument for their > syscall instruction. Sign extend is probably always an error, zero > extend may give the expected results. It depends on the ABI. For example, on MIPS, pointers are treated as signed when extending from 32 to 64 bits. paul
typo on homepage
Hello, on https://gcc.gnu.org/onlinedocs/gfortran/Code-Gen-Options.html there is at the end the part -ffrontend-optimize This option performs front-end optimization, based on manipulating parts the Fortran parse tree. Might it be that it should say "... manipulating parts _of_ the Fortran parse tree."? Greets, John
Re: [RFC] Linux system call builtins
On 08-04-24 09:19, Matheus Afonso Martins Moreira via Gcc wrote: + It's becoming common Despite being specific to the Linux kernel, support for it is showing up in other systems. FreeBSD implements limited support[4] for Linux ABIs. Windows Subsystem for Linux started out[5] similarly, as an implementation of this system call ABI. Apparently it's becoming something of a lingua franca. Maybe one day Linux programs will actually become portable by virtue of this stable binary interface. I don't really buy your portability argument. FreeBSD implements this as a syscall (two actually). syscall 0: int syscall(int number, ...); syscall 198: int __syscall(int64_t number, ...); (I've never seen the second one used in anger, it's supposed to be for systems that have unusual argument padding). The argument shuffling gets done in the kernel, not libc. In fact FreeBSD 15 just moved all syscall wrappers to a separate library, libsys, so it's there now. Over in OpenBSD they are going to removing 'syscall' from libc. https://lwn.net/Articles/949078/ From what I've seen it has also been removed by Apple. Whilst you aren't proposing the same thing, I see systems making it more difficult for code to make syscalls, not easier. I also think that this could be misleading. There are sometimes subtle differences between the syscall interface and the interface exported by libc. A+ Paul
Re: Question about constructing vector types in GIMPLE pass
Hi Marc, Thanks for your reply. I want to create a new type similar to this one `(const __m256i_u * {ref-all})` indeed. And I try to create it via these calls: tree type = build_vector_type_for_mode (intDI_type_node, V4DImode); tree type_p = build_pointer_type_for_mode(type, VOIDmode, true); But when I print the `type_p`, it shows `vector(4) long int * {ref-all}`. So I'm confused if they are the same type or can be transferred to each other. And I'm stucked with another problem that, I want to call `__builtin_ia32_pmovmskb256` in the GIMPLE pass. But I found that this function is defined in `config/i386/i386-builtins.h`. And when I try to include this header file, the error will occur during the compilation. If you know any way to solve this problem, I would be very grateful. :) Thanks Hanke Zhang Marc Glisse 于2024年4月9日周二 03:01写道: > > On Mon, 8 Apr 2024, Hanke Zhang via Gcc wrote: > > > Hi, > > I've been working on strengthening auto-vectorization on intel CPUs > > recently. I tried to do it in the GIMPLE pass. And I noticed that some > > vector types in the GIMPLE code are confusing to me. The example code > > is here: > > > > _1 = MEM[(const __m256i_u * {ref-all})_2]; > > > > I wondered how I could construct or get the type `(const __m256i_u * > > {ref-all})` in the GIMPLE pass. > > > > If you have any ideas that can help me. I'll be so grateful! :) > > I am not sure what you are asking exactly. If you already have access to > such a MEM_REF, then the doc tells you where to look for this type: > > "The first operand is the pointer being dereferenced; it will always have > pointer or reference type. The second operand is a pointer constant > serving as constant offset applied to the pointer being dereferenced > with its type specifying the type to be used for type-based alias > analysis. > The type of the node specifies the alignment of the access." > > If you want to create a new type similar to this one, you can build it > with various tools: > > build_vector_type or build_vector_type_for_mode > build_pointer_type_for_mode(*, VOIDmode, true) to build a pointer that can > alias anything > build_qualified_type to add const (probably useless) > build_aligned_type to specify that it is unaligned > > -- > Marc Glisse
Re: Question about constructing vector types in GIMPLE pass
On Tue, Apr 9, 2024 at 4:42 AM Hanke Zhang via Gcc wrote: > > Hi Marc, > > Thanks for your reply. > > I want to create a new type similar to this one `(const __m256i_u * > {ref-all})` indeed. And I try to create it via these calls: > > tree type = build_vector_type_for_mode (intDI_type_node, V4DImode); > tree type_p = build_pointer_type_for_mode(type, VOIDmode, true); > > But when I print the `type_p`, it shows `vector(4) long int * > {ref-all}`. So I'm confused if they are the same type or can be > transferred to each other. > > And I'm stucked with another problem that, I want to call > `__builtin_ia32_pmovmskb256` in the GIMPLE pass. But I found that this > function is defined in `config/i386/i386-builtins.h`. And when I try > to include this header file, the error will occur during the > compilation. If you know any way to solve this problem, I would be > very grateful. :) The type being dumped in the "cast" is the type of the constant offset operand which is used to determine the type effective for TBAA. I'll suggest you use -fdump-tree-XXX-gimple which dumps the MEM_REFs in a more complete way (yeah, should make that default ... but need to adjust all testcases that scan for them). You can't call __builtin_ia32_pmovmskb256, you instead should emit .MASK_LOAD or .MASK_STORE internal function calls. Richard. > Thanks > Hanke Zhang > > Marc Glisse 于2024年4月9日周二 03:01写道: > > > > On Mon, 8 Apr 2024, Hanke Zhang via Gcc wrote: > > > > > Hi, > > > I've been working on strengthening auto-vectorization on intel CPUs > > > recently. I tried to do it in the GIMPLE pass. And I noticed that some > > > vector types in the GIMPLE code are confusing to me. The example code > > > is here: > > > > > > _1 = MEM[(const __m256i_u * {ref-all})_2]; > > > > > > I wondered how I could construct or get the type `(const __m256i_u * > > > {ref-all})` in the GIMPLE pass. > > > > > > If you have any ideas that can help me. I'll be so grateful! :) > > > > I am not sure what you are asking exactly. If you already have access to > > such a MEM_REF, then the doc tells you where to look for this type: > > > > "The first operand is the pointer being dereferenced; it will always have > > pointer or reference type. The second operand is a pointer constant > > serving as constant offset applied to the pointer being dereferenced > > with its type specifying the type to be used for type-based alias > > analysis. > > The type of the node specifies the alignment of the access." > > > > If you want to create a new type similar to this one, you can build it > > with various tools: > > > > build_vector_type or build_vector_type_for_mode > > build_pointer_type_for_mode(*, VOIDmode, true) to build a pointer that can > > alias anything > > build_qualified_type to add const (probably useless) > > build_aligned_type to specify that it is unaligned > > > > -- > > Marc Glisse