Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers
- Original Message - > From: "H.J. Lu" > To: "Hal Finkel" > Cc: "GCC Development" , cfe-...@lists.llvm.org > Sent: Monday, September 21, 2015 7:17:20 PM > Subject: Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers > > On Mon, Sep 21, 2015 at 4:03 PM, Hal Finkel wrote: > > - Original Message - > >> From: "H.J. Lu" > >> To: "Hal Finkel" > >> Cc: "GCC Development" , cfe-...@lists.llvm.org > >> Sent: Monday, September 21, 2015 5:57:36 PM > >> Subject: Re: [cfe-dev] RFC: Support x86 interrupt and exception > >> handlers > >> > >> On Mon, Sep 21, 2015 at 3:40 PM, Hal Finkel > >> wrote: > >> > - Original Message - > >> >> From: "H.J. Lu via cfe-dev" > >> >> To: "GCC Development" , cfe-...@lists.llvm.org > >> >> Sent: Monday, September 21, 2015 11:27:18 AM > >> >> Subject: Re: [cfe-dev] RFC: Support x86 interrupt and exception > >> >> handlers > >> >> > >> >> On Thu, Sep 17, 2015 at 12:26 PM, H.J. Lu > >> >> wrote: > >> >> > On Tue, Sep 15, 2015 at 1:11 PM, H.J. Lu > >> >> > > >> >> > wrote: > >> >> >>> To implement interrupt and exception handlers for x86 > >> >> >>> processors, > >> >> >>> a > >> >> >>> compiler should support: > >> >> >>> > >> >> >>> 1. void * __builtin_ia32_interrupt_data (void) > >> >> >> > >> >> >> I got a feedback on the name of this builtin function. > >> >> >> Since > >> >> >> it also works for 64-bit, we should avoid ia32 in its name. > >> >> >> We'd like to change it to > >> >> >> > >> >> >> void * __builtin_interrupt_data (void) > >> >> >> > >> >> > > >> >> > Here is the updated spec. > >> >> > > >> >> > >> >> This updated spec adds > >> >> > >> >>unsigned int __builtin_exception_error (void) > >> >>unsigned long long int __builtin_exception_error (void) > >> >> > >> >> This function returns the exception error code pushed onto the > >> >> stack > >> >> by > >> >> processor. Its return value is 64 bits in 64-bit mode and 32 > >> >> bits > >> >> in > >> >> 32-bit mode. This function can only be used in exception > >> >> handler. > >> >> > >> >> It also changes the definition of > >> >> > >> >> void * __builtin_interrupt_data (void) > >> >> > >> >> so that it returns a pointer to the data layout pushed onto > >> >> stack > >> >> by processor for both interrupt and exception handlers. > >> >> > >> >> > >> >> -- > >> >> H.J. > >> >> --- > >> >> The interrupt and exception handlers are called by x86 > >> >> processors. > >> >> X86 > >> >> hardware pushes information onto stack and calls the handler. > >> >> The > >> >> requirements are > >> >> > >> >> 1. Both interrupt and exception handlers must use the 'IRET' > >> >> instruction, > >> >> instead of the 'RET' instruction, to return from the handlers. > >> >> 2. All registers are callee-saved in interrupt and exception > >> >> handlers. > >> >> 3. The difference between interrupt and exception handlers is > >> >> the > >> >> exception handler must pop 'ERROR_CODE' off the stack before > >> >> the > >> >> 'IRET' > >> >> instruction. > >> >> > >> >> The design goals of interrupt and exception handlers for x86 > >> >> processors > >> >> are: > >> >> > >> >> 1. No new calling convention in compiler. > >> >> 2. Support both 32-bit and 64-bit modes. > >> >> 3. Flexible for compilers to optimize. > >> >> 4. Easy to use by programmers. > >> >> > >> >> To implement interrupt and exception handlers for x86 > >> >> processors, > >> >> a > >> >> compiler should support: > >> >> > >> >> 1. void * __builtin_interrupt_data (void) > >> >> > >> >> This function returns a pointer to the return address pushed > >> >> onto > >> >> the > >> >> stack by processor. > >> >> > >> >> The __builtin_frame_address builtin isn't suitable for > >> >> interrupt > >> >> and > >> >> exception handlers since it returns the stack frame address on > >> >> the > >> >> callee side and compiler may generate a new stack frame for > >> >> stack > >> >> alignment. > >> >> > >> >> 2. unsigned int __builtin_exception_error (void) > >> >>unsigned long long int __builtin_exception_error (void) > >> >> > >> >> This function returns the exception error code pushed onto the > >> >> stack > >> >> by > >> >> processor. Its return value is 64 bits in 64-bit mode and 32 > >> >> bits > >> >> in > >> >> 32-bit mode. This function can only be used in exception > >> >> handler. > >> > > >> > Instead of adding more builtins for these, why not simply model > >> > this by giving the handler function a non-trivial signature? So, > >> > for example, the interrupt handler would be: > >> > > >> > void handler(void *); > >> > > >> > and the exception handler would be: > >> > > >> > void handler(size_t); > >> > > >> > >> Since x86 interrupt/exception handlers don't conform to any x86 > >> psABI, > >> you need to modify compiler to generate proper codes for > >> > >> void handler(void *); > >> > >> Please take a look at interrupt/exception handlers section in > >> Intel > >> SDM > >> vol 3. > > > > Yes, I understand that. But we already
Re: avoiding recursive calls of calloc due to optimization
On Mon, Sep 21, 2015 at 8:17 PM, Marc Glisse wrote: > On Mon, 21 Sep 2015, Daniel Gutson wrote: > >> This is derived from https://gcc.gnu.org/ml/gcc-help/2015-03/msg00091.html >> >> Currently, gcc provides an optimization that transforms a call to >> malloc and a call to memset into a call to calloc. >> This is fine except when it takes place within the calloc() function >> implementation itself, causing a recursive call. >> Two alternatives have been proposed: -fno-malloc-builtin and disable >> optimizations in calloc(). >> I think the former is suboptimal since it affects all the code just >> because of the implementation of one function (calloc()), >> whereas the latter is suboptimal too since it disables the >> optimizations in the whole function (calloc too). >> I think of two alternatives: either make -fno-calloc-builtin to >> disable the optimization, or make the optimization aware of the >> function context where it is operating and prevent it to do the >> transformation if the function is calloc(). >> >> Please help me to find the best alternative so we can implent it. > > > You may want to read this PR for more context > > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56888#c27 Yeah, I think the proper way is to add a helper to symtab to query whether the current function is BUILT_IN_XXX and use that to fend of most of the "obvious" cases. Richard. > -- > Marc Glisse
Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers
On 21 Sep 2015, at 21:45, H.J. Lu via cfe-dev wrote: > > The main purpose of x86 interrupt attribute is to allow programmers > to write x86 interrupt/exception handlers in C WITHOUT assembly > stubs to avoid extra branch from assembly stubs to C functions. I > want to keep the number of new intrinsics to minimum without sacrificing > handler performance. I leave faking error code in interrupt handler to > the programmer. The assembly stubs have to come from somewhere. You either put them in an assembly file (most people doing embedded x86 stuff steal the ones from NetBSD), or you put them in the compiler where they can be inlined. In terms of user interface, there’s not much difference in complexity. Having written this kind of code in the past, I can honestly say that using the assembly stubs was the least difficult part of getting them right. In terms of compiler complexity, there’s a big difference: in one case the compiler contains nothing, in the other it contains something special for a single use case. In terms of performance, the compiler version has the potential to be faster, but if we’re going to pay for the complexity then I think that we’d need to see some strong evidence that someone else is getting a noticeable benefit. David
RE: Predictive commoning leads to register to register moves through memory.
I took an attempt at addressing this through the RTL GCSE pass. This attempt tweaks mem_attrs_eq_p to return true if its comparing something like poly+8 and MEM [&poly + 8]. Is this a more suitable approach? Thanks, Simon +/* Return true if p and q reference the same location by the same name but + through VAR_DECL and MEM_REF. */ + +static bool +mem_locations_match_p (const struct mem_attrs *p, const struct mem_attrs *q) +{ + HOST_WIDE_INT var_offset; + tree var, memref; + + if (p->expr == NULL_TREE || q->expr == NULL_TREE) +return false; + + if (TREE_CODE (p->expr) == MEM_REF && TREE_CODE (q->expr) == VAR_DECL) +{ + var = q->expr; + var_offset = q->offset; + memref = p->expr; +} + else if (TREE_CODE (q->expr) == MEM_REF && TREE_CODE (p->expr) == VAR_DECL) +{ + var = p->expr; + var_offset = p->offset; + memref = q->expr; +} + else +return false; + + if (TREE_OPERAND (TREE_OPERAND (memref, 0), 0) != var) +return false; + + if (TREE_TYPE (TREE_TYPE (var)) != TREE_TYPE (memref)) +return false; + + tree offset = TREE_OPERAND (memref, 1); + if ((TREE_CODE (offset) == INTEGER_CST && tree_fits_shwi_p (offset) + && tree_to_shwi (offset) == var_offset) + || offset == NULL_TREE && var_offset == 0) +return true; + + return false; + +} + /* Return true if the given memory attributes are equal. */ bool @@ -254,16 +298,16 @@ mem_attrs_eq_p (const struct mem_attrs *p, const struct mem_attrs *q) return false; return (p->alias == q->alias && p->offset_known_p == q->offset_known_p - && (!p->offset_known_p || p->offset == q->offset) && p->size_known_p == q->size_known_p && (!p->size_known_p || p->size == q->size) && p->align == q->align && p->addrspace == q->addrspace - && (p->expr == q->expr - || (p->expr != NULL_TREE && q->expr != NULL_TREE - && operand_equal_p (p->expr, q->expr, 0; + && (mem_locations_match_p (p, q) +|| (!p->offset_known_p || p->offset == q->offset) +&& (p->expr == q->expr +|| (p->expr != NULL_TREE && q->expr != NULL_TREE +&& operand_equal_p (p->expr, q->expr, 0); }
Re: Predictive commoning leads to register to register moves through memory.
On Tue, Sep 22, 2015 at 12:45 PM, Simon Dardis wrote: > I took an attempt at addressing this through the RTL GCSE pass. This attempt > tweaks > mem_attrs_eq_p to return true if its comparing something like poly+8 and MEM > [&poly + 8]. > > Is this a more suitable approach? I actually recently modified stmt_kills_ref_p for a similar reason... not that I liked that vey much. I think the more suitable approach would be to not have both forms if they are actually equal. Of course that's way more work. So splitting out a function that handles sematic equality compare of MEM_EXPR sounds good to me. No comments on your actual implementation yet, but I think we should do it in a way to be re-usable by stmt_kills_ref_p. Richard. > Thanks, > Simon > > +/* Return true if p and q reference the same location by the same name but > + through VAR_DECL and MEM_REF. */ > + > +static bool > +mem_locations_match_p (const struct mem_attrs *p, const struct mem_attrs *q) > +{ > + HOST_WIDE_INT var_offset; > + tree var, memref; > + > + if (p->expr == NULL_TREE || q->expr == NULL_TREE) > +return false; > + > + if (TREE_CODE (p->expr) == MEM_REF && TREE_CODE (q->expr) == VAR_DECL) > +{ > + var = q->expr; > + var_offset = q->offset; > + memref = p->expr; > +} > + else if (TREE_CODE (q->expr) == MEM_REF && TREE_CODE (p->expr) == VAR_DECL) > +{ > + var = p->expr; > + var_offset = p->offset; > + memref = q->expr; > +} > + else > +return false; > + > + if (TREE_OPERAND (TREE_OPERAND (memref, 0), 0) != var) > +return false; > + > + if (TREE_TYPE (TREE_TYPE (var)) != TREE_TYPE (memref)) > +return false; > + > + tree offset = TREE_OPERAND (memref, 1); > + if ((TREE_CODE (offset) == INTEGER_CST && tree_fits_shwi_p (offset) > + && tree_to_shwi (offset) == var_offset) > + || offset == NULL_TREE && var_offset == 0) > +return true; > + > + return false; > + > +} > + > /* Return true if the given memory attributes are equal. */ > > bool > @@ -254,16 +298,16 @@ mem_attrs_eq_p (const struct mem_attrs *p, const struct > mem_attrs *q) > return false; >return (p->alias == q->alias > && p->offset_known_p == q->offset_known_p > - && (!p->offset_known_p || p->offset == q->offset) > && p->size_known_p == q->size_known_p > && (!p->size_known_p || p->size == q->size) > && p->align == q->align > && p->addrspace == q->addrspace > - && (p->expr == q->expr > - || (p->expr != NULL_TREE && q->expr != NULL_TREE > - && operand_equal_p (p->expr, q->expr, 0; > + && (mem_locations_match_p (p, q) > +|| (!p->offset_known_p || p->offset == q->offset) > +&& (p->expr == q->expr > +|| (p->expr != NULL_TREE && q->expr != NULL_TREE > +&& operand_equal_p (p->expr, q->expr, 0); > }
Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers
On Tue, Sep 22, 2015 at 1:11 AM, Hal Finkel wrote: > - Original Message - >> From: "H.J. Lu" >> To: "Hal Finkel" >> Cc: "GCC Development" , cfe-...@lists.llvm.org >> Sent: Monday, September 21, 2015 7:17:20 PM >> Subject: Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers >> >> On Mon, Sep 21, 2015 at 4:03 PM, Hal Finkel wrote: >> > - Original Message - >> >> From: "H.J. Lu" >> >> To: "Hal Finkel" >> >> Cc: "GCC Development" , cfe-...@lists.llvm.org >> >> Sent: Monday, September 21, 2015 5:57:36 PM >> >> Subject: Re: [cfe-dev] RFC: Support x86 interrupt and exception >> >> handlers >> >> >> >> On Mon, Sep 21, 2015 at 3:40 PM, Hal Finkel >> >> wrote: >> >> > - Original Message - >> >> >> From: "H.J. Lu via cfe-dev" >> >> >> To: "GCC Development" , cfe-...@lists.llvm.org >> >> >> Sent: Monday, September 21, 2015 11:27:18 AM >> >> >> Subject: Re: [cfe-dev] RFC: Support x86 interrupt and exception >> >> >> handlers >> >> >> >> >> >> On Thu, Sep 17, 2015 at 12:26 PM, H.J. Lu >> >> >> wrote: >> >> >> > On Tue, Sep 15, 2015 at 1:11 PM, H.J. Lu >> >> >> > >> >> >> > wrote: >> >> >> >>> To implement interrupt and exception handlers for x86 >> >> >> >>> processors, >> >> >> >>> a >> >> >> >>> compiler should support: >> >> >> >>> >> >> >> >>> 1. void * __builtin_ia32_interrupt_data (void) >> >> >> >> >> >> >> >> I got a feedback on the name of this builtin function. >> >> >> >> Since >> >> >> >> it also works for 64-bit, we should avoid ia32 in its name. >> >> >> >> We'd like to change it to >> >> >> >> >> >> >> >> void * __builtin_interrupt_data (void) >> >> >> >> >> >> >> > >> >> >> > Here is the updated spec. >> >> >> > >> >> >> >> >> >> This updated spec adds >> >> >> >> >> >>unsigned int __builtin_exception_error (void) >> >> >>unsigned long long int __builtin_exception_error (void) >> >> >> >> >> >> This function returns the exception error code pushed onto the >> >> >> stack >> >> >> by >> >> >> processor. Its return value is 64 bits in 64-bit mode and 32 >> >> >> bits >> >> >> in >> >> >> 32-bit mode. This function can only be used in exception >> >> >> handler. >> >> >> >> >> >> It also changes the definition of >> >> >> >> >> >> void * __builtin_interrupt_data (void) >> >> >> >> >> >> so that it returns a pointer to the data layout pushed onto >> >> >> stack >> >> >> by processor for both interrupt and exception handlers. >> >> >> >> >> >> >> >> >> -- >> >> >> H.J. >> >> >> --- >> >> >> The interrupt and exception handlers are called by x86 >> >> >> processors. >> >> >> X86 >> >> >> hardware pushes information onto stack and calls the handler. >> >> >> The >> >> >> requirements are >> >> >> >> >> >> 1. Both interrupt and exception handlers must use the 'IRET' >> >> >> instruction, >> >> >> instead of the 'RET' instruction, to return from the handlers. >> >> >> 2. All registers are callee-saved in interrupt and exception >> >> >> handlers. >> >> >> 3. The difference between interrupt and exception handlers is >> >> >> the >> >> >> exception handler must pop 'ERROR_CODE' off the stack before >> >> >> the >> >> >> 'IRET' >> >> >> instruction. >> >> >> >> >> >> The design goals of interrupt and exception handlers for x86 >> >> >> processors >> >> >> are: >> >> >> >> >> >> 1. No new calling convention in compiler. >> >> >> 2. Support both 32-bit and 64-bit modes. >> >> >> 3. Flexible for compilers to optimize. >> >> >> 4. Easy to use by programmers. >> >> >> >> >> >> To implement interrupt and exception handlers for x86 >> >> >> processors, >> >> >> a >> >> >> compiler should support: >> >> >> >> >> >> 1. void * __builtin_interrupt_data (void) >> >> >> >> >> >> This function returns a pointer to the return address pushed >> >> >> onto >> >> >> the >> >> >> stack by processor. >> >> >> >> >> >> The __builtin_frame_address builtin isn't suitable for >> >> >> interrupt >> >> >> and >> >> >> exception handlers since it returns the stack frame address on >> >> >> the >> >> >> callee side and compiler may generate a new stack frame for >> >> >> stack >> >> >> alignment. >> >> >> >> >> >> 2. unsigned int __builtin_exception_error (void) >> >> >>unsigned long long int __builtin_exception_error (void) >> >> >> >> >> >> This function returns the exception error code pushed onto the >> >> >> stack >> >> >> by >> >> >> processor. Its return value is 64 bits in 64-bit mode and 32 >> >> >> bits >> >> >> in >> >> >> 32-bit mode. This function can only be used in exception >> >> >> handler. >> >> > >> >> > Instead of adding more builtins for these, why not simply model >> >> > this by giving the handler function a non-trivial signature? So, >> >> > for example, the interrupt handler would be: >> >> > >> >> > void handler(void *); >> >> > >> >> > and the exception handler would be: >> >> > >> >> > void handler(size_t); >> >> > >> >> >> >> Since x86 interrupt/exception handlers don't conform to any x86 >> >> psABI, >> >> you need to modify compiler to generate
Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers
On 22 Sep 2015, at 12:39, H.J. Lu via cfe-dev wrote: > > The center piece of my proposal is not to change how parameters > are passed in compiler. As for user experience, the feedbacks on > my proposal from our users are very positive. Implementing the intrinsics for getting the current interrupt requires a lot of support code for it to actually be useful. For it to be useful, you are requiring all of the C code to be run with interrupts disabled (and even that doesn’t work if you get a NMI in the middle). Most implementations use a small amount of assembly to capture the interrupt cause and the register state on entry to the handler, then reenable interrupts while the C code runs. This means that any interrupts (e.g. page faults, illegal instruction traps, whatever) that happen while the C code is running do not mask the values. Accessing these values from *existing* C code is simply a matter of loading a field from a structure. I’m really unconvinced by something that something with such a narrow use case (and one that encourages writing bad code) belongs in the compiler. David
Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers
On Tue, Sep 22, 2015 at 1:41 AM, David Chisnall wrote: > On 21 Sep 2015, at 21:45, H.J. Lu via cfe-dev wrote: >> >> The main purpose of x86 interrupt attribute is to allow programmers >> to write x86 interrupt/exception handlers in C WITHOUT assembly >> stubs to avoid extra branch from assembly stubs to C functions. I >> want to keep the number of new intrinsics to minimum without sacrificing >> handler performance. I leave faking error code in interrupt handler to >> the programmer. > > The assembly stubs have to come from somewhere. You either put them in an > assembly file (most people doing embedded x86 stuff steal the ones from > NetBSD), or you put them in the compiler where they can be inlined. In terms > of user interface, there’s not much difference in complexity. Having written > this kind of code in the past, I can honestly say that using the assembly > stubs was the least difficult part of getting them right. In terms of > compiler complexity, there’s a big difference: in one case the compiler > contains nothing, in the other it contains something special for a single use > case. In terms of performance, the compiler version has the potential to be > faster, but if we’re going to pay for the complexity then I think that we’d > need to see some strong evidence that someone else is getting a noticeable > benefit. I understand your concern. IA MCU users want to write interrupt/exception handlers in C, just like many embedded processors. The goals are to save code space and improve performance. Using builtin functions, instead of adding a new way to pass parameters, makes compiler change much simpler, since __builtin_exception_error () is the same as __builtin_return_address (0) and __builtin_interrupt_data () is address of __builtin_exception_error () + size of register. -- H.J.
Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers
On Tue, Sep 22, 2015 at 4:44 AM, David Chisnall wrote: > On 22 Sep 2015, at 12:39, H.J. Lu via cfe-dev wrote: >> >> The center piece of my proposal is not to change how parameters >> are passed in compiler. As for user experience, the feedbacks on >> my proposal from our users are very positive. > > Implementing the intrinsics for getting the current interrupt requires a lot > of support code for it to actually be useful. For it to be useful, you are > requiring all of the C code to be run with interrupts disabled (and even that > doesn’t work if you get a NMI in the middle). Most implementations use a > small amount of assembly to capture the interrupt cause and the register > state on entry to the handler, then reenable interrupts while the C code > runs. This means that any interrupts (e.g. page faults, illegal instruction > traps, whatever) that happen while the C code is running do not mask the > values. Accessing these values from *existing* C code is simply a matter of > loading a field from a structure. The above applies to with and without intrinsics. > I’m really unconvinced by something that something with such a narrow use > case (and one that encourages writing bad code) belongs in the compiler. > > David -- H.J.
Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers
On 22 Sep 2015, at 12:47, H.J. Lu wrote: > > since __builtin_exception_error () is the same as > __builtin_return_address (0) and __builtin_interrupt_data () is > address of __builtin_exception_error () + size of register. Except that they’re *not*. __builtin_return_address(0) is guaranteed to be the same for the duration of the function. __builtin_exception_error() needs to either: 1) Fetch the values early with interrupts disabled, store them in a well-known location, and load them from this place when the intrinsic is called, or 2) Force any function that calls the intrinsic (and wants a meaningful result) to run with interrupts disabled, which is something that the compiler can’t verify without knowing the full chain of code from the interrupt handler to the current point (and therefore prone to error). It is trivial to write a little bit of inline assembly that reads these values from the CPU and expose that for C code. There is a good reason why no one does this. Without a better programmer model, you are not simplifying things, you are just providing more ways for introducing errors. David
Re: Compilers and RCU readers: Once more unto the breach!
On Mon, Jul 13, 2015 at 05:44:59PM -0700, Paul E. McKenney wrote: > On Tue, May 19, 2015 at 05:55:10PM -0700, Paul E. McKenney wrote: > > Hello! > > > > Following up on last year's discussion (https://lwn.net/Articles/586838/, > > https://lwn.net/Articles/588300/), I believe that we have a solution. If > > I am wrong, I am sure you all will let me know, and in great detail. ;-) > > > > The key simplification is to "just say no" to RCU-protected array indexes: > > https://lkml.org/lkml/2015/5/12/827, as was suggested by several people. > > This simplification means that rcu_dereference (AKA memory_order_consume) > > need only return pointers. This in ture avoids things like (x-x), > > (x*0), and (x%1) because if "x" is a pointer, these expressions either > > return non-pointers are compilation errors. With a very few exceptions, > > dependency chains can lead -to- non-pointers, but cannot pass -through- > > them. > > > > The result is that dependencies are carried only by operations for > > which the compiler cannot easily optimize the away those dependencies, > > these operations including simple assignment, integer offset (including > > indexing), dereferencing, casts, passing as a function argument, return > > values from functions and so on. A complete list with commentary starts > > on page 28 of: > > > > http://www.rdrop.com/users/paulmck/RCU/consume.2015.05.18a.pdf > > And an update is available here: > > http://www.rdrop.com/users/paulmck/RCU/consume.2015.07.13a.pdf > > Among other things, this update addresses the points about equality > comparisons introduced by the compiler, and outlines some of the > issues head-/tail-marked alternatives face with respect to abstraction. > The updated "Restricted Dependency Chains" section starts on page 28. > > Thoughts? This is updated based on many offline discussions. Section 7.9 has been updated accordingly, but still starts on page 28. This approach is again intended for large existing RCU code bases such as the Linux kernel. A new Section 7.10 starting on page 35 describes a possible longer-term solution for new-to-RCU code bases. This approach adds a storage class that indicates that the marked object carries dependencies. This allows better diagnostics (and arguably better code self-documentation) as well as providing something that formal-verification tools can handle while avoiding the need for compilers to trace dependency chains. http://www.rdrop.com/users/paulmck/submission/consume.2015.09.22a.pdf Thoughts? Thanx, Paul
ppc eabi float arguments
Hi, if been working with the windriver Diab c compiler for 32bit ppc for and encountered an incompatibly with the eabi version of the gcc 4.83. When calling functions with more than 8 float arguments the gcc stores the 9th float argument (and so on) as a float where as the diab compiler stores the argument as a double using 8 byte. I checked the EABI document and it seems to support the way the diab compiler passes the arguments: "Arguments not otherwise handled above [i.e. not passed in registers] are passed in the parameter words of the caller=E2=80=99s stack frame. [...= ] float, long long (where implemented), and double arguments are considered to have 8-byte size and alignment, *with float arguments converted to double representation*. " Does anyone know the reason why the gcc passes the argument as single float= ? Best Regards, -Bernhard
Re: ppc eabi float arguments
On Tue, Sep 22, 2015 at 1:39 PM, Bernhard Schommer wrote: > Hi, > > if been working with the windriver Diab c compiler for 32bit ppc for and > encountered an incompatibly with the eabi version of the gcc 4.83. When > calling functions with more than 8 float arguments the gcc stores the 9th > float argument (and so on) as a float where as the diab compiler stores the > argument as a double using 8 byte. > > I checked the EABI document and it seems to support the way the diab > compiler passes the arguments: > > "Arguments not otherwise handled above [i.e. not passed in registers] > are passed in the parameter words of the caller=E2=80=99s stack frame. [...= > ] > float, long long (where implemented), and double arguments are > considered to have 8-byte size and alignment, *with float arguments > converted to double representation*. " > > Does anyone know the reason why the gcc passes the argument as single float? Hi, Bernhard First, are you certain that you have the final version of the 32 bit PPC eABI? There were a few versions in circulation. Mike may remember the history of this. Thanks, David
Re: ppc eabi float arguments
Am 22.09.2015 um 19:43 schrieb David Edelsohn: On Tue, Sep 22, 2015 at 1:39 PM, Bernhard Schommer wrote: Hi, if been working with the windriver Diab c compiler for 32bit ppc for and encountered an incompatibly with the eabi version of the gcc 4.83. When calling functions with more than 8 float arguments the gcc stores the 9th float argument (and so on) as a float where as the diab compiler stores the argument as a double using 8 byte. I checked the EABI document and it seems to support the way the diab compiler passes the arguments: "Arguments not otherwise handled above [i.e. not passed in registers] are passed in the parameter words of the caller=E2=80=99s stack frame. [...= ] float, long long (where implemented), and double arguments are considered to have 8-byte size and alignment, *with float arguments converted to double representation*. " Does anyone know the reason why the gcc passes the argument as single float? Hi, Bernhard First, are you certain that you have the final version of the 32 bit PPC eABI? There were a few versions in circulation. Mike may remember the history of this. Thanks, David Hi, I'm referencing to the PPC SVR 4 Abi document, -Bernhard
Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers
On 09/21/2015 04:03 PM, Hal Finkel wrote: > - Original Message - >> From: "H.J. Lu" >> To: "Hal Finkel" >> Cc: "GCC Development" , cfe-...@lists.llvm.org >> Sent: Monday, September 21, 2015 5:57:36 PM >> Subject: Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers >> >> On Mon, Sep 21, 2015 at 3:40 PM, Hal Finkel wrote: >>> - Original Message - From: "H.J. Lu via cfe-dev" To: "GCC Development" , cfe-...@lists.llvm.org Sent: Monday, September 21, 2015 11:27:18 AM Subject: Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers On Thu, Sep 17, 2015 at 12:26 PM, H.J. Lu wrote: > On Tue, Sep 15, 2015 at 1:11 PM, H.J. Lu > wrote: >>> To implement interrupt and exception handlers for x86 >>> processors, >>> a >>> compiler should support: >>> >>> 1. void * __builtin_ia32_interrupt_data (void) >> >> I got a feedback on the name of this builtin function. Since >> it also works for 64-bit, we should avoid ia32 in its name. >> We'd like to change it to >> >> void * __builtin_interrupt_data (void) >> > > Here is the updated spec. > This updated spec adds unsigned int __builtin_exception_error (void) unsigned long long int __builtin_exception_error (void) This function returns the exception error code pushed onto the stack by processor. Its return value is 64 bits in 64-bit mode and 32 bits in 32-bit mode. This function can only be used in exception handler. It also changes the definition of void * __builtin_interrupt_data (void) so that it returns a pointer to the data layout pushed onto stack by processor for both interrupt and exception handlers. -- H.J. --- The interrupt and exception handlers are called by x86 processors. X86 hardware pushes information onto stack and calls the handler. The requirements are 1. Both interrupt and exception handlers must use the 'IRET' instruction, instead of the 'RET' instruction, to return from the handlers. 2. All registers are callee-saved in interrupt and exception handlers. 3. The difference between interrupt and exception handlers is the exception handler must pop 'ERROR_CODE' off the stack before the 'IRET' instruction. The design goals of interrupt and exception handlers for x86 processors are: 1. No new calling convention in compiler. 2. Support both 32-bit and 64-bit modes. 3. Flexible for compilers to optimize. 4. Easy to use by programmers. To implement interrupt and exception handlers for x86 processors, a compiler should support: 1. void * __builtin_interrupt_data (void) This function returns a pointer to the return address pushed onto the stack by processor. The __builtin_frame_address builtin isn't suitable for interrupt and exception handlers since it returns the stack frame address on the callee side and compiler may generate a new stack frame for stack alignment. 2. unsigned int __builtin_exception_error (void) unsigned long long int __builtin_exception_error (void) This function returns the exception error code pushed onto the stack by processor. Its return value is 64 bits in 64-bit mode and 32 bits in 32-bit mode. This function can only be used in exception handler. >>> >>> Instead of adding more builtins for these, why not simply model >>> this by giving the handler function a non-trivial signature? So, >>> for example, the interrupt handler would be: >>> >>> void handler(void *); >>> >>> and the exception handler would be: >>> >>> void handler(size_t); >>> >> >> Since x86 interrupt/exception handlers don't conform to any x86 >> psABI, >> you need to modify compiler to generate proper codes for >> >> void handler(void *); >> >> Please take a look at interrupt/exception handlers section in Intel >> SDM >> vol 3. > > Yes, I understand that. But we already would need to customize the > call-frame-lowering code for these functions, and since this already requires > customization, what's the advantage of the builtins over adding special logic > to make these parameters correspond to the appropriate stack locations and/or > registers? HJ, I think Hal is right. Providing the data via arguments is vastly superior to providing it via builtins. I had actually been thinking the same thing myself. It should be easy to check that the function has the correct signature in the hook adding the attribute. It should also be easy to check for the attribute at the beginning of ix86_function_arg et al, in order to handle these special cases. r~
Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers
On 09/22/15 01:41, David Chisnall wrote: > On 21 Sep 2015, at 21:45, H.J. Lu via cfe-dev wrote: >> >> The main purpose of x86 interrupt attribute is to allow programmers >> to write x86 interrupt/exception handlers in C WITHOUT assembly >> stubs to avoid extra branch from assembly stubs to C functions. I >> want to keep the number of new intrinsics to minimum without sacrificing >> handler performance. I leave faking error code in interrupt handler to >> the programmer. > > The assembly stubs have to come from somewhere. You either put them > in an assembly file (most people doing embedded x86 stuff steal the > ones from NetBSD), or you put them in the compiler where they can be > inlined. In terms of user interface, there’s not much difference in > complexity. Having written this kind of code in the past, I can > honestly say that using the assembly stubs was the least difficult > part of getting them right. In terms of compiler complexity, there’s > a big difference: in one case the compiler contains nothing, in the > other it contains something special for a single use case. In terms > of performance, the compiler version has the potential to be faster, > but if we’re going to pay for the complexity then I think that we’d > need to see some strong evidence that someone else is getting a > noticeable benefit. > It is worth noting that most architectures has this support for a reason. -hpa
Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers
On 09/22/15 04:44, David Chisnall wrote: > On 22 Sep 2015, at 12:39, H.J. Lu via cfe-dev wrote: >> >> The center piece of my proposal is not to change how parameters >> are passed in compiler. As for user experience, the feedbacks on >> my proposal from our users are very positive. > > Implementing the intrinsics for getting the current interrupt > requires a lot of support code for it to actually be useful. For it > to be useful, you are requiring all of the C code to be run with > interrupts disabled (and even that doesn’t work if you get a NMI in > the middle). Most implementations use a small amount of assembly to > capture the interrupt cause and the register state on entry to the > handler, then reenable interrupts while the C code runs. This means > that any interrupts (e.g. page faults, illegal instruction traps, > whatever) that happen while the C code is running do not mask the > values. Accessing these values from *existing* C code is simply a > matter of loading a field from a structure. > > I’m really unconvinced by something that something with such a narrow > use case (and one that encourages writing bad code) belongs in the > compiler. > You seem to not understand how x86 works, nor have noted how this is nearly universally supported by various architectures; x86 is the exception here. x86 stores its interrupt state on the stack, not in a register which can be clobbered. Also, a lot of your assertions about "most implementations" only apply to full-scale operating systems. -hpa
Re: [cfe-dev] RFC: Support x86 interrupt and exception handlers
On 09/22/15 04:52, David Chisnall wrote: > On 22 Sep 2015, at 12:47, H.J. Lu wrote: >> >> since __builtin_exception_error () is the same as >> __builtin_return_address (0) and __builtin_interrupt_data () is >> address of __builtin_exception_error () + size of register. > > Except that they’re *not*. __builtin_return_address(0) is guaranteed to be > the same for the duration of the function. __builtin_exception_error() needs > to either: > > 1) Fetch the values early with interrupts disabled, store them in a > well-known location, and load them from this place when the intrinsic > is called, or > > 2) Force any function that calls the intrinsic (and wants a > meaningful result) to run with interrupts disabled, which is > something that the compiler can’t verify without knowing the full > chain of code from the interrupt handler to the current point (and > therefore prone to error). > > It is trivial to write a little bit of inline assembly that reads > these values from the CPU and expose that for C code. There is a > good reason why no one does this. > This is why it makes no sense for the intrinsics to be callable from anywhere except inside the interrupt handler. It is really nothing other than a way to pass arguments -- whether or not it is simpler for the compilers to implement than supporting a different function signature is beyond my scope of expertise. -hpa
gcc-5-20150922 is now available
Snapshot gcc-5-20150922 is now available on ftp://gcc.gnu.org/pub/gcc/snapshots/5-20150922/ and on various mirrors, see http://gcc.gnu.org/mirrors.html for details. This snapshot has been generated from the GCC 5 SVN branch with the following options: svn://gcc.gnu.org/svn/gcc/branches/gcc-5-branch revision 228025 You'll find: gcc-5-20150922.tar.bz2 Complete GCC MD5=edd03b6569e7d9dbd33218b1b12ee8e4 SHA1=6562938fb3a8a172079067b06938bdec1b891e5d Diffs from 5-20150915 are available in the diffs/ subdirectory. When a particular snapshot is ready for public consumption the LATEST-5 link is updated and a message is sent to the gcc list. Please do not use a snapshot before it has been announced that way.
Re: ppc eabi float arguments
I advise looking at the "Power Architecture® 32-bit Application Binary Interface Supplement 1.0 - Embedded", not any older EABI documents. There may well be bugs in this ABI document (i.e. it may fail to reflect actual practice), but it's still more reliable as a guide to current practice than older documents. -- Joseph S. Myers jos...@codesourcery.com
Re: ppc eabi float arguments
On Tue, Sep 22, 2015 at 07:39:43PM +0200, Bernhard Schommer wrote: > Does anyone know the reason why the gcc passes the argument as single float? That's how the first powerpc gcc implementation behaved. Once gcc compiled code is out in the field, you need to ask everyone to recompile their code in order to fix an ABI problem. That may be more disrupting than just leaving gcc incompatible with other compilers. -- Alan Modra Australia Development Lab, IBM