GCC 5 Status Report (2014-11-17), Stage 3 in effect now
The trunk is in Stage 3 now, which means it is open for general bugfixing. Patches posted early enough during Stage 1 and not yet fully reviewed may still get in early in Stage 3. Please make sure to ping them soon enough. Still misleading quality data below - P3 bugs have not been re-prioritized. Quality Data Priority # Change from last report --- --- P1 15+ 5 P2 83+ 1 P3 132+ 40 --- --- Total 230+ 46 Previous Report === https://gcc.gnu.org/ml/gcc/2014-11/msg5.html
Re: [PATCH] Add gimple-compat.h (was Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign)
On Fri, Nov 14, 2014 at 4:27 PM, David Malcolm wrote: > On Thu, 2014-11-13 at 11:45 +0100, Richard Biener wrote: >> On Thu, Nov 13, 2014 at 2:41 AM, David Malcolm wrote: >> > On Tue, 2014-11-11 at 11:43 +0100, Richard Biener wrote: >> >> On Tue, Nov 11, 2014 at 8:26 AM, Jakub Jelinek wrote: >> >> > On Mon, Nov 10, 2014 at 05:27:50PM -0500, David Malcolm wrote: >> >> >> On Sat, 2014-11-08 at 14:56 +0100, Jakub Jelinek wrote: >> >> >> > On Sat, Nov 08, 2014 at 01:07:28PM +0100, Richard Biener wrote: >> >> >> > > To be constructive here - the above case is from within a >> >> >> > > GIMPLE_ASSIGN case label >> >> >> > > and thus I'd have expected >> >> >> > > >> >> >> > > case GIMPLE_ASSIGN: >> >> >> > > { >> >> >> > > gassign *a1 = as_a (s1); >> >> >> > > gassign *a2 = as_a (s2); >> >> >> > > lhs1 = gimple_assign_lhs (a1); >> >> >> > > lhs2 = gimple_assign_lhs (a2); >> >> >> > > if (TREE_CODE (lhs1) != SSA_NAME >> >> >> > > && TREE_CODE (lhs2) != SSA_NAME) >> >> >> > > return (operand_equal_p (lhs1, lhs2, 0) >> >> >> > > && gimple_operand_equal_value_p >> >> >> > > (gimple_assign_rhs1 (a1), >> >> >> > > >> >> >> > > gimple_assign_rhs1 (a2))); >> >> >> > > else if (TREE_CODE (lhs1) == SSA_NAME >> >> >> > >&& TREE_CODE (lhs2) == SSA_NAME) >> >> >> > > return vn_valueize (lhs1) == vn_valueize (lhs2); >> >> >> > > return false; >> >> >> > > } >> >> >> > > >> >> >> > > instead. That's the kind of changes I have expected and have >> >> >> > > approved of. >> >> >> > >> >> >> > But even that looks like just adding extra work for all developers, >> >> >> > with no >> >> >> > gain. You only have to add extra code and extra temporaries, in >> >> >> > switches >> >> >> > typically also have to add {} because of the temporaries and thus >> >> >> > extra >> >> >> > indentation level, and it doesn't simplify anything in the code. >> >> >> >> >> >> The branch attempts to use the C++ typesystem to capture information >> >> >> about the kinds of gimple statement we expect, both: >> >> >> (A) so that the compiler can detect type errors, and >> >> >> (B) as a comprehension aid to the human reader of the code >> >> >> >> >> >> The ideal here is when function params and struct field can be >> >> >> strengthened from "gimple" to a subclass ptr. This captures the >> >> >> knowledge that every use of a function or within a struct has a given >> >> >> gimple code. >> >> > >> >> > I just don't like all the as_a/is_a stuff enforced everywhere, >> >> > it means more typing, more temporaries, more indentation. >> >> > So, as I view it, instead of the checks being done cheaply (yes, I think >> >> > the gimple checking as we have right now is very cheap) under the >> >> > hood by the accessors (gimple_assign_{lhs,rhs1} etc.), those changes >> >> > put the burden on the developers, who has to check that manually through >> >> > the as_a/is_a stuff everywhere, more typing and uglier syntax. >> >> > I just don't see that as a step forward, instead a huge step backwards. >> >> > But perhaps I'm alone with this. >> >> > Can you e.g. compare the size of - lines in your patchset combined, and >> >> > size of + lines in your patchset? As in, if your changes lead to less >> >> > typing or more. >> >> >> >> I see two ways out here. One is to add overloads to all the functions >> >> taking the special types like >> >> >> >> tree >> >> gimple_assign_rhs1 (gimple *); >> >> >> >> or simply add >> >> >> >> gassign *operator ()(gimple *g) { return as_a (g); } >> >> >> >> into a gimple-compat.h header which you include in places that >> >> are not converted "nicely". >> > >> > Thanks for the suggestions. >> > >> > Am I missing something, or is the gimple-compat.h idea above not valid C >> > ++? >> > >> > Note that "gimple" is still a typedef to >> > gimple_statement_base * >> > (as noted before, the gimple -> gimple * change would break everyone >> > else's patches, so we talked about that as a followup patch for early >> > stage3). >> > >> > Given that, if I try to create an "operator ()" outside of a class, I >> > get this error: >> > >> > ‘gassign* operator()(gimple)’ must be a nonstatic member function >> > >> > which is emitted from cp/decl.c's grok_op_properties: >> > /* An operator function must either be a non-static member function >> > or have at least one parameter of a class, a reference to a class, >> > an enumeration, or a reference to an enumeration. 13.4.0.6 */ >> > >> > I tried making it a member function of gimple_statement_base, but that >> > doesn't work either: we want a conversion >> > from a gimple_statement_base * to a gassign *, not >> > from a gimple_statement_base to a gassign *. >> > >> > Is there some syntactic trick here that I'm missing? Sorry if I'm being >> > dumb (I can imagine there's a way of doing i
Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign
On Sat, Nov 15, 2014 at 12:00 PM, David Malcolm wrote: > On Thu, 2014-11-13 at 11:45 +0100, Richard Biener wrote: >> On Thu, Nov 13, 2014 at 2:41 AM, David Malcolm wrote: >> > On Tue, 2014-11-11 at 11:43 +0100, Richard Biener wrote: >> >> On Tue, Nov 11, 2014 at 8:26 AM, Jakub Jelinek wrote: >> >> > On Mon, Nov 10, 2014 at 05:27:50PM -0500, David Malcolm wrote: >> >> >> On Sat, 2014-11-08 at 14:56 +0100, Jakub Jelinek wrote: >> >> >> > On Sat, Nov 08, 2014 at 01:07:28PM +0100, Richard Biener wrote: >> >> >> > > To be constructive here - the above case is from within a >> >> >> > > GIMPLE_ASSIGN case label >> >> >> > > and thus I'd have expected >> >> >> > > >> >> >> > > case GIMPLE_ASSIGN: >> >> >> > > { >> >> >> > > gassign *a1 = as_a (s1); >> >> >> > > gassign *a2 = as_a (s2); >> >> >> > > lhs1 = gimple_assign_lhs (a1); >> >> >> > > lhs2 = gimple_assign_lhs (a2); >> >> >> > > if (TREE_CODE (lhs1) != SSA_NAME >> >> >> > > && TREE_CODE (lhs2) != SSA_NAME) >> >> >> > > return (operand_equal_p (lhs1, lhs2, 0) >> >> >> > > && gimple_operand_equal_value_p >> >> >> > > (gimple_assign_rhs1 (a1), >> >> >> > > >> >> >> > > gimple_assign_rhs1 (a2))); >> >> >> > > else if (TREE_CODE (lhs1) == SSA_NAME >> >> >> > >&& TREE_CODE (lhs2) == SSA_NAME) >> >> >> > > return vn_valueize (lhs1) == vn_valueize (lhs2); >> >> >> > > return false; >> >> >> > > } >> >> >> > > >> >> >> > > instead. That's the kind of changes I have expected and have >> >> >> > > approved of. >> >> >> > >> >> >> > But even that looks like just adding extra work for all developers, >> >> >> > with no >> >> >> > gain. You only have to add extra code and extra temporaries, in >> >> >> > switches >> >> >> > typically also have to add {} because of the temporaries and thus >> >> >> > extra >> >> >> > indentation level, and it doesn't simplify anything in the code. >> >> >> >> >> >> The branch attempts to use the C++ typesystem to capture information >> >> >> about the kinds of gimple statement we expect, both: >> >> >> (A) so that the compiler can detect type errors, and >> >> >> (B) as a comprehension aid to the human reader of the code >> >> >> >> >> >> The ideal here is when function params and struct field can be >> >> >> strengthened from "gimple" to a subclass ptr. This captures the >> >> >> knowledge that every use of a function or within a struct has a given >> >> >> gimple code. >> >> > >> >> > I just don't like all the as_a/is_a stuff enforced everywhere, >> >> > it means more typing, more temporaries, more indentation. >> >> > So, as I view it, instead of the checks being done cheaply (yes, I think >> >> > the gimple checking as we have right now is very cheap) under the >> >> > hood by the accessors (gimple_assign_{lhs,rhs1} etc.), those changes >> >> > put the burden on the developers, who has to check that manually through >> >> > the as_a/is_a stuff everywhere, more typing and uglier syntax. >> >> > I just don't see that as a step forward, instead a huge step backwards. >> >> > But perhaps I'm alone with this. >> >> > Can you e.g. compare the size of - lines in your patchset combined, and >> >> > size of + lines in your patchset? As in, if your changes lead to less >> >> > typing or more. >> >> >> >> I see two ways out here. One is to add overloads to all the functions >> >> taking the special types like >> >> >> >> tree >> >> gimple_assign_rhs1 (gimple *); >> >> >> >> or simply add >> >> >> >> gassign *operator ()(gimple *g) { return as_a (g); } >> >> >> >> into a gimple-compat.h header which you include in places that >> >> are not converted "nicely". >> > >> > Thanks for the suggestions. >> > >> > Am I missing something, or is the gimple-compat.h idea above not valid C >> > ++? >> > >> > Note that "gimple" is still a typedef to >> > gimple_statement_base * >> > (as noted before, the gimple -> gimple * change would break everyone >> > else's patches, so we talked about that as a followup patch for early >> > stage3). >> > >> > Given that, if I try to create an "operator ()" outside of a class, I >> > get this error: >> > >> > ‘gassign* operator()(gimple)’ must be a nonstatic member function >> > >> > which is emitted from cp/decl.c's grok_op_properties: >> > /* An operator function must either be a non-static member function >> > or have at least one parameter of a class, a reference to a class, >> > an enumeration, or a reference to an enumeration. 13.4.0.6 */ >> > >> > I tried making it a member function of gimple_statement_base, but that >> > doesn't work either: we want a conversion >> > from a gimple_statement_base * to a gassign *, not >> > from a gimple_statement_base to a gassign *. >> > >> > Is there some syntactic trick here that I'm missing? Sorry if I'm being >> > dumb (I can imagine there's a way of doing
Re: graphite in -O3
On Sun, Nov 16, 2014 at 10:08 PM, David Edelsohn wrote: > Because they have not shown general performance benefit. Also they very often cause very long compile-times. > I hope that the renewed attention and development effort will allow > them to be enabled by default eventually. Yeah - though I'd like to have a group flag that enables the mature ones. Mature here means transforms that guard themselves properly for long compile-time and ones that have a cost model (may be a runtime check even). Thanks, Richard. > Thanks, David > > On Sun, Nov 16, 2014 at 2:10 PM, Andi Kleen wrote: >> >> Is there any specific reason why none of the graphite loop optimizations >> (loop-block, loop-interchange, loop-strip-mine, loop-jam) >> are enabled with -O3 or -Ofast? >> >> I assume doing so would make them much more widely used. >> >> Perhaps would be something to consider for 5.0? >> >> -Andi >>
RE: Optimized Allocation of Argument registers
Hello All: I was looking at the optimized usage and allocation to argument registers. There are two aspects to it as follows. 1. We need to specify the argument registers as followed by ABI in the target specific code. Based on the function argument registers defined in the target dependent code the function argument registers are passed. If the number of argument registers defined in the Architecture is large say 6/8 function argument registers. Most of the time in the benchmarks we don't pass so many arguments and the number of arguments passed is quite less. Since we reserve the function arguments as specified in the target specific code for the given architecture, leads to unoptimized usage as this function argument registers will not be used in the function. Thus we need to steal some of the arguments registers and have the usage of those in the function depending on the support of the number of function argument registers. The stealing of function argument registers will lead more number of registers available that are to be used in the function and leading to less spill and fetch. 2. The other aspect of the function argument registers is not spill and fetch the argument registers as they are live across the function call. But the liveness is limited to certain point of the called function after that point the function argument registers are not live and can be used inside the called function. Other aspect is if there is a shortage of registers than can the function argument registers should be used as spill candidate? Will this lead to the optimized code. Please let me know what do you think. Thanks & Regards Ajit
Re: What is R_X86_64_GOTPLT64 used for?
Hi, On Thu, 13 Nov 2014, H.J. Lu wrote: > @GOTPLT will create a PLT entry, but it doesn't mean PLT entry will be > used. Correct. The compiler was supposed to somehow make a good decision (e.g. if there were calls and address-takings in the same unit). > Only @PLTOFF will use PLT entry. Linker should be smart enough to use > only one GOT slot, regardless if @GOTPLT or @GOT is used to take > function address and call via PLT. For @GOT the respective GOT slot needs to resolve to the final address (to provide stable function pointers). For @GOTPLT it could at first resolve to the PLT slot (which would be only a relative reloc, not a symbol based one), like Richard said. So there still would be a difference. Apart from that I agree that the linker should ideally only use one GOT slot, which would remove that particular advantage of @GOTPLT (note that it doesn't do so currently contrary to what you said downthread, I'll respond separately). > I'd like to propose > > 1. Update psABI to remove R_X86_64_GOTPLT64. I don't have much against this, but would like others to say something. Ciao, Michael.
Re: What is R_X86_64_GOTPLT64 used for?
Hi, On Thu, 13 Nov 2014, H.J. Lu wrote: > Linker does: > > ... code that looks like it might create just one GOT slot ... > > So if a symbol is accessed by both @GOT and @PLTOFF, its > needs_plt will be true and its got.plt entry will be used for > both @GOT and @GOTPLT. @GOTPLT has no advantage > over @GOT, but potentially wastes a PLT entry. The above is not correct. Had you tried you'd see this: % cat x.c extern void foo (void); void main (void) { void (*f)(void) = foo; f(); foo(); } % gcc -fPIE -mcmodel=large -S x.c; cat x.s ... movabsq $foo@GOT, %rax ... movabsq $foo@PLTOFF, %rax ... So, foo is access via @GOT offset and @PLTOFF. Then, % cat y.c void foo (void) {} % gcc -o liby.so -shared -fPIC y.c % gcc -fPIE -mcmodel=large x.s liby.so % readelf -r a.out ... 00600ff8 00040006 R_X86_64_GLOB_DAT foo + 0 ... 00601028 00040007 R_X86_64_JUMP_SLO foo + 0 ... The first one (to 600ff8) is the normal GOT slot, the second one the GOT slot for the PLT entry. Both are actually used: 004005f0 : 4005f0: ff 25 32 0a 20 00 jmpq *0x200a32(%rip)# 601028 <_GLOBAL_OFFSET_TABLE_+0x28> That uses the second GOT slot, and: 004006ec : 4006ec: 55 push %rbp 4006ed: 48 89 e5mov%rsp,%rbp 4006f0: 53 push %rbx 4006f1: 48 83 ec 18 sub$0x18,%rsp 4006f5: 48 8d 1d f9 ff ff fflea-0x7(%rip),%rbx# 4006f5 4006fc: 49 bb 0b 09 20 00 00movabs $0x20090b,%r11 400703: 00 00 00 400706: 4c 01 dbadd%r11,%rbx 400709: 48 b8 f8 ff ff ff ffmovabs $0xfff8,%rax 400710: ff ff ff 400713: 48 8b 04 03 mov(%rbx,%rax,1),%rax This uses the first slot at 0x600ff8. So, no, currently GOT and GOTPLT (at least how it's supposed to be implemented) are not equivalent. > Here is a patch to mark relocation 30 (R_X86_64_GOTPLT64) as reserved. > I pushed updated x86-64 psABI changes to > > https://github.com/hjl-tools/x86-64-psABI/tree/hjl/master > > I will update linker to keep accepting relocation 30 and treat it the > same as R_X86_64_GOT64. That seems a bit premature given the above. Ciao, Michael.
Re: Optimized Allocation of Argument registers
On 11/17/14 06:13, Ajit Kumar Agarwal wrote: Hello All: I was looking at the optimized usage and allocation to argument registers. There are two aspects to it as follows. 1. We need to specify the argument registers as followed by ABI in the target specific code. Based on the function argument registers defined in the target dependent code the function argument registers are passed. If the number of argument registers defined in the Architecture is large say 6/8 function argument registers. Most of the time in the benchmarks we don't pass so many arguments and the number of arguments passed is quite less. Since we reserve the function arguments as specified in the target specific code for the given architecture, leads to unoptimized usage as this function argument registers will not be used in the function. Thus we need to steal some of the arguments registers and have the usage of those in the function depending on the support of the number of function argument registers. The stealing of function argument registers will lead more number of registers available that are to be used in the function and leading to less spill and fetch. 2. The other aspect of the function argument registers is not spill and fetch the argument registers as they are live across the function call. But the liveness is limited to certain point of the called function after that point the function argument registers are not live and can be used inside the called function. Other aspect is if there is a shortage of registers than can the function argument registers should be used as spill candidate? Will this lead to the optimized code. Please let me know what do you think. Typically GCC ports do not reserve the function argument/return registers, they are allocatable just like any other call clobbered register. In essence arguments for function calls are set up at each call site by copying values out of pseudo registers, memory, constant initializations, etc to the appropriate outgoing argument register. The allocator will, when possible and profitable try to assign the pseudo register to the appropriate argument register to eliminate the copies. Similarly, GCC copies values out of the incoming argument registers and into pseudos at the start of a function. The allocator, again when possible and profitable, will try to allocate the pseudos to the incoming argument registers to avoid the copy. So in summary, there is no reason to reserve registers for argument passing in GCC and doing so would be wasteful. Treat the argument registers as any other call clobbered register and allow the register allocator to make appropriate decisions based on liveness, expected uses, call-crossing liveness, related copies, etc etc. jeff
Re: [PATCH] Add gimple-compat.h (was Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign)
On 11/14/14 08:27, David Malcolm wrote: I just don't like all the as_a/is_a stuff enforced everywhere, it means more typing, more temporaries, more indentation. So, as I view it, instead of the checks being done cheaply (yes, I think the gimple checking as we have right now is very cheap) under the hood by the accessors (gimple_assign_{lhs,rhs1} etc.), those changes put the burden on the developers, who has to check that manually through the as_a/is_a stuff everywhere, more typing and uglier syntax. I just don't see that as a step forward, instead a huge step backwards. But perhaps I'm alone with this. Can you e.g. compare the size of - lines in your patchset combined, and size of + lines in your patchset? As in, if your changes lead to less typing or more. So, I'm chiming in a bit late, but just want to touch on a few things. First, as I've stated before, I see as_a/is_a as generally a wart for things we still need to cleanup and redesign. I do not want to see them sprinkled throughout GCC. If we find ourselves adding a bunch of these, then we've got some redesign/rethinking that needs to be done. Yes, I know some will be necessary and some are more like markers for the limits of where we are with the gimple class work, particularly since we're trying to stage in this work rather than convert everything at once (which I believe, realistically, is impossible). I see two ways out here. One is to add overloads to all the functions taking the special types like IIRC Andrew was doing similar things as a temporary measure in the gimple/tree type work as well. Basically the overloads were to allow the two schemes to co-exist while conversions were done with the express intent that the overloads were to disappear when conversion is complete. I'd be comfortable with a similar mechanism for this work as well. Option 3: only convert the "easy" accessors: the ones I already did in the /89 patch kit, as reviewed by Jeff, and rebased by me recently, which is this 92-patch kit: "[gimple-classes, committed 00/92] Initial slew of commits": https://gcc.gnu.org/ml/gcc-patches/2014-10/msg02791.html Doing so converts about half of the gimple_foo_ accessors to taking a gfoo *, giving a mixture of GIMPLE_CHECK vs subclass use. I believe the quality of those patches was higher than the later ones on the branch: I was doing the places that didn't require the invasive/verbose changes seen in the later patches. Shelve the remaining ~80 increasingly ugly patches, starting a new branch to contain just the good ones. And this would be my preferred option for where we are today. That ~89 kit was a step in the right direction. I think going beyond that for the close of stage1 was ambitious :-) Works for me as well. The compat solution looks somewhat appealing as we can then incrementally fix up things rather than requiring to mass-convert everything. Exactly. And it's real easy to see what's depending on those overloads as one can simply remove them and try to build. In many ways, I'd prefer the temporary overload solution for the next round of work in this space so that conversions can occur piecemeal instead of in large series patchsets. I've got no objection if we have the compat hack in now. I haven't reviewed that work, just no philosophical objections :-) I would be opposed to pushing the gimple class work further than that prior to the next stage1 opening. jeff
Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign
On 11/17/14 03:06, Richard Biener wrote: Also, presumably if this were merged, it would require a followup with the gimple to gimple * fixup you wanted? (which we talked about doing as an early stage3 thing IIRC [1]). Yeah, that would be nice (to remind people - this is about getting rid of const_gimple and thus avoids introducing tons of new const_ for all the subclasses). Right. Mirrors what we've done for INSNs in RTL as well. jeff
Re: Optimized Allocation of Argument registers
On 2014-11-17 8:13 AM, Ajit Kumar Agarwal wrote: Hello All: I was looking at the optimized usage and allocation to argument registers. There are two aspects to it as follows. 1. We need to specify the argument registers as followed by ABI in the target specific code. Based on the function argument registers defined in the target dependent code the function argument registers are passed. If the number of argument registers defined in the Architecture is large say 6/8 function argument registers. Most of the time in the benchmarks we don't pass so many arguments and the number of arguments passed is quite less. Since we reserve the function arguments as specified in the target specific code for the given architecture, leads to unoptimized usage as this function argument registers will not be used in the function. Thus we need to steal some of the arguments registers and have the usage of those in the function depending on the support of the number of function argument registers. The stealing of function argument registers will lead more number of registers available that are to be used in the function and leading to less spill and fetch. The argument registers should be not reserved. They should be present in RTL and RA allocator will figure out itself when it can use them. That is how other ports work. 2. The other aspect of the function argument registers is not spill and fetch the argument registers as they are live across the function call. But the liveness is limited to certain point of the called function after that point the function argument registers are not live and can be used inside the called function. Other aspect is if there is a shortage of registers than can the function argument registers should be used as spill candidate? Will this lead to the optimized code. You can remove unnecessary code to save/restore arg registers around calls if you can figure out that they are not used in called functions. There is already code for this written by Tom de Vries. So you can use it.
Re: What is R_X86_64_GOTPLT64 used for?
On Mon, Nov 17, 2014 at 6:14 AM, Michael Matz wrote: > Hi, > > On Thu, 13 Nov 2014, H.J. Lu wrote: > >> Linker does: >> >> ... code that looks like it might create just one GOT slot ... >> >> So if a symbol is accessed by both @GOT and @PLTOFF, its >> needs_plt will be true and its got.plt entry will be used for >> both @GOT and @GOTPLT. @GOTPLT has no advantage >> over @GOT, but potentially wastes a PLT entry. > > The above is not correct. Had you tried you'd see this: > > % cat x.c > extern void foo (void); > void main (void) > { > void (*f)(void) = foo; > f(); > foo(); > } > % gcc -fPIE -mcmodel=large -S x.c; cat x.s > ... > movabsq $foo@GOT, %rax > ... > movabsq $foo@PLTOFF, %rax > ... > > So, foo is access via @GOT offset and @PLTOFF. Then, > > % cat y.c > void foo (void) {} > % gcc -o liby.so -shared -fPIC y.c > % gcc -fPIE -mcmodel=large x.s liby.so > % readelf -r a.out > ... > 00600ff8 00040006 R_X86_64_GLOB_DAT foo + 0 > ... > 00601028 00040007 R_X86_64_JUMP_SLO foo + 0 > ... > > The first one (to 600ff8) is the normal GOT slot, the second one the GOT > slot for the PLT entry. Both are actually used: > > 004005f0 : > 4005f0: ff 25 32 0a 20 00 jmpq *0x200a32(%rip)# > 601028 <_GLOBAL_OFFSET_TABLE_+0x28> > > That uses the second GOT slot, and: > > 004006ec : > 4006ec: 55 push %rbp > 4006ed: 48 89 e5mov%rsp,%rbp > 4006f0: 53 push %rbx > 4006f1: 48 83 ec 18 sub$0x18,%rsp > 4006f5: 48 8d 1d f9 ff ff fflea-0x7(%rip),%rbx# > 4006f5 > 4006fc: 49 bb 0b 09 20 00 00movabs $0x20090b,%r11 > 400703: 00 00 00 > 400706: 4c 01 dbadd%r11,%rbx > 400709: 48 b8 f8 ff ff ff ffmovabs $0xfff8,%rax > 400710: ff ff ff > 400713: 48 8b 04 03 mov(%rbx,%rax,1),%rax > > This uses the first slot at 0x600ff8. > > So, no, currently GOT and GOTPLT (at least how it's supposed to be > implemented) are not equivalent. It has nothing to do with large model. The same thing happens to small model.We may be to able optimize it, independent of GOTPLT. In any case, -mcmodel=large shouldn't change program behavior. -- H.J.
Re: [gimple-classes, committed 4/6] tree-ssa-tail-merge.c: Use gassign
On Mon, 2014-11-17 at 11:06 +0100, Richard Biener wrote: > On Sat, Nov 15, 2014 at 12:00 PM, David Malcolm wrote: > > On Thu, 2014-11-13 at 11:45 +0100, Richard Biener wrote: > >> On Thu, Nov 13, 2014 at 2:41 AM, David Malcolm wrote: > >> > On Tue, 2014-11-11 at 11:43 +0100, Richard Biener wrote: > >> >> On Tue, Nov 11, 2014 at 8:26 AM, Jakub Jelinek wrote: > >> >> > On Mon, Nov 10, 2014 at 05:27:50PM -0500, David Malcolm wrote: > >> >> >> On Sat, 2014-11-08 at 14:56 +0100, Jakub Jelinek wrote: > >> >> >> > On Sat, Nov 08, 2014 at 01:07:28PM +0100, Richard Biener wrote: > >> >> >> > > To be constructive here - the above case is from within a > >> >> >> > > GIMPLE_ASSIGN case label > >> >> >> > > and thus I'd have expected > >> >> >> > > > >> >> >> > > case GIMPLE_ASSIGN: > >> >> >> > > { > >> >> >> > > gassign *a1 = as_a (s1); > >> >> >> > > gassign *a2 = as_a (s2); > >> >> >> > > lhs1 = gimple_assign_lhs (a1); > >> >> >> > > lhs2 = gimple_assign_lhs (a2); > >> >> >> > > if (TREE_CODE (lhs1) != SSA_NAME > >> >> >> > > && TREE_CODE (lhs2) != SSA_NAME) > >> >> >> > > return (operand_equal_p (lhs1, lhs2, 0) > >> >> >> > > && gimple_operand_equal_value_p > >> >> >> > > (gimple_assign_rhs1 (a1), > >> >> >> > > > >> >> >> > > gimple_assign_rhs1 (a2))); > >> >> >> > > else if (TREE_CODE (lhs1) == SSA_NAME > >> >> >> > >&& TREE_CODE (lhs2) == SSA_NAME) > >> >> >> > > return vn_valueize (lhs1) == vn_valueize (lhs2); > >> >> >> > > return false; > >> >> >> > > } > >> >> >> > > > >> >> >> > > instead. That's the kind of changes I have expected and have > >> >> >> > > approved of. > >> >> >> > > >> >> >> > But even that looks like just adding extra work for all > >> >> >> > developers, with no > >> >> >> > gain. You only have to add extra code and extra temporaries, in > >> >> >> > switches > >> >> >> > typically also have to add {} because of the temporaries and thus > >> >> >> > extra > >> >> >> > indentation level, and it doesn't simplify anything in the code. > >> >> >> > >> >> >> The branch attempts to use the C++ typesystem to capture information > >> >> >> about the kinds of gimple statement we expect, both: > >> >> >> (A) so that the compiler can detect type errors, and > >> >> >> (B) as a comprehension aid to the human reader of the code > >> >> >> > >> >> >> The ideal here is when function params and struct field can be > >> >> >> strengthened from "gimple" to a subclass ptr. This captures the > >> >> >> knowledge that every use of a function or within a struct has a given > >> >> >> gimple code. > >> >> > > >> >> > I just don't like all the as_a/is_a stuff enforced everywhere, > >> >> > it means more typing, more temporaries, more indentation. > >> >> > So, as I view it, instead of the checks being done cheaply (yes, I > >> >> > think > >> >> > the gimple checking as we have right now is very cheap) under the > >> >> > hood by the accessors (gimple_assign_{lhs,rhs1} etc.), those changes > >> >> > put the burden on the developers, who has to check that manually > >> >> > through > >> >> > the as_a/is_a stuff everywhere, more typing and uglier syntax. > >> >> > I just don't see that as a step forward, instead a huge step > >> >> > backwards. > >> >> > But perhaps I'm alone with this. > >> >> > Can you e.g. compare the size of - lines in your patchset combined, > >> >> > and > >> >> > size of + lines in your patchset? As in, if your changes lead to less > >> >> > typing or more. > >> >> > >> >> I see two ways out here. One is to add overloads to all the functions > >> >> taking the special types like > >> >> > >> >> tree > >> >> gimple_assign_rhs1 (gimple *); > >> >> > >> >> or simply add > >> >> > >> >> gassign *operator ()(gimple *g) { return as_a (g); } > >> >> > >> >> into a gimple-compat.h header which you include in places that > >> >> are not converted "nicely". > >> > > >> > Thanks for the suggestions. > >> > > >> > Am I missing something, or is the gimple-compat.h idea above not valid C > >> > ++? > >> > > >> > Note that "gimple" is still a typedef to > >> > gimple_statement_base * > >> > (as noted before, the gimple -> gimple * change would break everyone > >> > else's patches, so we talked about that as a followup patch for early > >> > stage3). > >> > > >> > Given that, if I try to create an "operator ()" outside of a class, I > >> > get this error: > >> > > >> > ‘gassign* operator()(gimple)’ must be a nonstatic member function > >> > > >> > which is emitted from cp/decl.c's grok_op_properties: > >> > /* An operator function must either be a non-static member function > >> > or have at least one parameter of a class, a reference to a > >> > class, > >> > an enumeration, or a reference to an enumeration. 13.4.0.6 */ > >> > > >> > I tried making it a member function of gimple_statem