Re: Turn check macros into functions. (issue6188088)
> "Mike" == Mike Stump writes: Mike> Yeah, I kinda think the gdb people are wimping out by not just Mike> implementing __extension__ and ({}), which, I think get us most of the Mike> way there. Shh, don't tell them I said that. We eagerly await your patch. Tom
Re: Turn check macros into functions. (issue6188088)
> "Lawrence" == Lawrence Crowl writes: Lawrence> Should I add that to my patch to gdbinit.in? I think it would be helpful. Tom
Re: Turn check macros into functions. (issue6188088)
On May 23, 2012, at 3:36 PM, Lawrence Crowl wrote: > For variables that are not optimized out of memory, I think this > can work. But if you need to go for registers, Also trivial... Just one has to generate the context correctly. One has to save off the registers and then in the context generator, synthesize them back up. So, take a context in which a is in register 5, one can generate something like: void eval() { register int a = __gdb_registers[5]; __gdb_registers[5] = a; } This preserves the value in register 5 from the gdb context at that point, and even allows the user to write to such variables, and have that reflected in the register file. > or undo a variable elimination, the effort gets harder. Yes, setting the value of a variable that has, for example, been removed due to dce, is annoying. But I'll note it is annoying in gdb currently. I'd be happy to introduce declarations that if used, lead to compile time errors. Darwin for example has an unavailable attribute one can attach to a decl to ensure an error is produced. gcc has deprecated, though, it is just a warning. Now, for variables that can be computed from variables that are present, I'd rather the optimizer explain how to produce the value given the state and for gdb to producea context with that value into a read only variable. This preserves for read access such variables that are gone. This is something that gcc and gdb should be doing anyway... but don't. > Yes, you essentially need to come close to sending the compiler's > symbol tables through the debug information. I don't know of any > compiler/debugger pair that is close to that capability. :-) Not yet... Maybe never. > I'm not saying that the task is impossible, only that there is a > lot of work to do before we get there. Yeah, I kinda think the gdb people are wimping out by not just implementing __extension__ and ({}), which, I think get us most of the way there. Shh, don't tell them I said that.
Re: Turn check macros into functions. (issue6188088)
On 5/21/12, Tom Tromey wrote: >> "Alexander" == Alexander Monakov writes: > > Alexander> Hm, isn't GDB's 'set unwindonsignal on' enough to fix it? > Alexander> It's useful to have that in your .gdbinit anyway, because the > Alexander> same issue arises when calling debug_* functions in cc1 from > Alexander> the debugger. > > Yeah, why didn't I remember that? I think it should suffice. > Thanks for the reminder. Should I add that to my patch to gdbinit.in? -- Lawrence Crowl
Re: Turn check macros into functions. (issue6188088)
On 5/21/12, Mike Stump wrote: > On May 18, 2012, at 7:48 PM, Lawrence Crowl wrote: >> On 5/17/12, Mike Stump wrote: >>> On May 17, 2012, at 2:41 PM, Lawrence Crowl wrote: > Reusing the compiler for this seems like the only way to go. > But, we did look at using g++ to parse C++ expressions from gdb, > and it was too slow :-(. We're going to look again, at least to > generate some bug reports if we can. It's a tough problem, particularly as C/C++ and their compilers were not designed for a read-eval-print-loop environment. >>> >>> This of course is trivial to do, >> >> I do not think that word means what you think it means. :-) > > Excellent reference... Yeah, well, just a little more work to do: > > $ ./eval > extern "C" int printf(const char *...); int &k2 = *(int*)4294971592; > void eval() { printf("k is %d\n", k2); } > about to run > k is 42 > done running, took 32540 usecs > > Notice, this sucked a int k2 = 42; that was a variable inside > the context in which I wanted a k2. The nature of the variable > is irrelevant, could be a stack variable, could be a global, > a static top-level, all I need to know, is where it is (the > address) and the type and I generate a binding stub for it into > the context, and presto, complete access to most all variables. > This does make use of C++ to manage the variables in a slightly > nicer way. One either has to inject all variables and functions > into the context into which the program fragment is compiled, > or notice which variables and function are or might be used and > inject just those. > > I've seen ptype foo print the types of variables, so, it isn't > far off, and certainly gdb knows about the symbol table and can > figure out the addresses of those variables, right?! For variables that are not optimized out of memory, I think this can work. But if you need to go for registers, or undo a variable elimination, the effort gets harder. > > Now, certainly one can find additional issues, and yes, there > is a bit of work to get 100% reliability that we'd like from > the scheme. For example, packed structures would need work, as > ptype isn't going to get that right from that start. I think the > functionality one would get would be good enough to start with, > and in time, better support for things ptype doesn't get right > would fix a certain class of problems. Agreed. > > So, what another 1000 lines to generate the context for the > fragment... I guess finding references could be annoying, and the > time required to generate and compile the entire context could > be annoying... > > Doing C++ would be harder, though, not quite for the reason > you gave. > >> I like the example, but it sidesteps the main problem, which is >> putting the expression in the context from which it was called. >> For instance if I stop in the middle of a function and type >> >> print foo->bar( a + b ) >> >> I need to find the find the variable names, lookup their types, > > ptype a does the lookup for a, and finds the type, so that isn't > hard, same with b and foo. Harder would be to synthesize the > context for the fragment to live in. To do this and work with > templates, you'd need the entire template bodies to be in the > debug information and to output them when generating the context > that might use them. Yes, you essentially need to come close to sending the compiler's symbol tables through the debug information. I don't know of any compiler/debugger pair that is close to that capability. That said, I don't know all such pairs either. > > class A { > foo() { } > } > > when stopped in foo, one needs to generate: > > class A { > foo(); > __eval() { fragment } > } > > and then call __eval(lookup("this"))... The compiler does > the overload resolution, the template instantiation and so on. > To ensure the compiler does name loookup right, one just needs > to generate the context for that fragment carefully. Agreed. >> do overload resolution, possibly do template instantiation, etc, >> all as if the compiler was in the scope defined for the line that >> the debugger is stopped at. That's the hard part. I'm not saying that the task is impossible, only that there is a lot of work to do before we get there. -- Lawrence Crowl
Re: Turn check macros into functions. (issue6188088)
> "Alexander" == Alexander Monakov writes: Alexander> Hm, isn't GDB's 'set unwindonsignal on' enough to fix it? Alexander> It's useful to have that in your .gdbinit anyway, because the Alexander> same issue arises when calling debug_* functions in cc1 from Alexander> the debugger. Yeah, why didn't I remember that? I think it should suffice. Thanks for the reminder. Tom
Re: Turn check macros into functions. (issue6188088)
On May 18, 2012, at 7:48 PM, Lawrence Crowl wrote: > On 5/17/12, Mike Stump wrote: >> On May 17, 2012, at 2:41 PM, Lawrence Crowl wrote: Reusing the compiler for this seems like the only way to go. But, we did look at using g++ to parse C++ expressions from gdb, and it was too slow :-(. We're going to look again, at least to generate some bug reports if we can. >>> >>> It's a tough problem, particularly as C/C++ and their compilers >>> were not designed for a read-eval-print-loop environment. >> >> This of course is trivial to do, > > I do not think that word means what you think it means. :-) Excellent reference... Yeah, well, just a little more work to do: $ ./eval extern "C" int printf(const char *...); int &k2 = *(int*)4294971592; void eval()\ { printf("k is %d\n", k2); } about to run k is 42 done running, took 32540 usecs Notice, this sucked a int k2 = 42; that was a variable inside the context in which I wanted a k2. The nature of the variable is irrelevant, could be a stack variable, could be a global, a static top-level, all I need to know, is where it is (the address) and the type and I generate a binding stub for it into the context, and presto, complete access to most all variables. This does make use of C++ to manage the variables in a slightly nicer way. One either has to inject all variables and functions into the context into which the program fragment is compiled, or notice which variables and function are or might be used and inject just those. I've seen ptype foo print the types of variables, so, it isn't far off, and certainly gdb knows about the symbol table and can figure out the addresses of those variables, right?! Now, certainly one can find additional issues, and yes, there is a bit of work to get 100% reliability that we'd like from the scheme. For example, packed structures would need work, as ptype isn't going to get that right from that start. I think the functionality one would get would be good enough to start with, and in time, better support for things ptype doesn't get right would fix a certain class of problems. So, what another 1000 lines to generate the context for the fragment... I guess finding references could be annoying, and the time required to generate and compile the entire context could be annoying... Doing C++ would be harder, though, not quite for the reason you gave. > I like the example, but it sidesteps the main problem, which is > putting the expression in the context from which it was called. > For instance if I stop in the middle of a function and type > > print foo->bar( a + b ) > > I need to find the find the variable names, lookup their types, ptype a does the lookup for a, and finds the type, so that isn't hard, same with b and foo. Harder would be to synthesize the context for the fragment to live in. To do this and work with templates, you'd need the entire template bodies to be in the debug information and to output them when generating the context that might use them. class A { foo() { } } when stopped in foo, one needs to generate: class A { foo(); __eval() { fragment } } and then call __eval(lookup("this"))... The compiler does the overload resolution, the template instantiation and so on. To ensure the compiler does name loookup right, one just needs to generate the context for that fragment carefully. > do overload resolution, possibly do template instantiation, etc, > all as if the compiler was in the scope defined for the line that > the debugger is stopped at. That's the hard part.
Re: Turn check macros into functions. (issue6188088)
On Thu, 17 May 2012, Tom Tromey wrote: > It would be nice if there were a way to make cc1 not crash due to user > error in the debugger. I think this kind of crash will be especially > crazy-making. Hm, isn't GDB's 'set unwindonsignal on' enough to fix it? It's useful to have that in your .gdbinit anyway, because the same issue arises when calling debug_* functions in cc1 from the debugger. Alexander
Re: Turn check macros into functions. (issue6188088)
On Mon, May 21, 2012 at 12:18 PM, Richard Guenther wrote: > On Sun, May 20, 2012 at 9:10 PM, Diego Novillo wrote: >> On 12-05-20 13:59 , Richard Henderson wrote: >>> >>> On 05/18/2012 04:48 PM, Diego Novillo wrote: We can do this in trunk today using a variant of Lawrence's original patch (http://gcc.gnu.org/ml/gcc-patches/2011-09/msg01649.html). This uses no C++ features, though it weakens type checking by removing away constness. In the cxx-conversion branch, we can use overloads, which will DTRT with const. My question is, what do folks prefer? a) The trunk patch today, using no C++ features. b) Wait for the cxx-conversion variant? >>> >>> >>> Surely (check(t), t) also works, and also strt wrt const. >> >> >> My concern with (check(t), t) is that it evaluates 't' twice. It may not be >> a big deal, however. In which case, I'm OK with that alternative. > > Hum. A source of possibly nasty errors. > > I'd like to avoid using templates here though. Going with two overloads > for each function sounds like the best solution to me, thus delay the > change to cxx-switch time. > > What's the effect on bootstrap times? Remember we build stage1 with -O0 > and checking enabled always ... Btw, as of doing this all for the sake of debuggability of GCC - for debugging you do _not_ want to have gdb invoke the checking functions, because then you ICE in the inferior if you mis-type. Instead ideally gdb would use the non-checking variant or even better, diagnose misuse itself (which means using a python implementation rather than the gcc macro or an inferior call). So - why not provide proper (python) implementations of the various accessors in .gdbinit? Richard. > Richard. > >> >> Diego. >>
Re: Turn check macros into functions. (issue6188088)
On Sun, May 20, 2012 at 9:10 PM, Diego Novillo wrote: > On 12-05-20 13:59 , Richard Henderson wrote: >> >> On 05/18/2012 04:48 PM, Diego Novillo wrote: >>> >>> We can do this in trunk today using a variant of Lawrence's original >>> patch (http://gcc.gnu.org/ml/gcc-patches/2011-09/msg01649.html). This >>> uses no C++ features, though it weakens type checking by removing away >>> constness. >>> >>> In the cxx-conversion branch, we can use overloads, which will DTRT >>> with const. >>> >>> My question is, what do folks prefer? >>> >>> a) The trunk patch today, using no C++ features. >>> b) Wait for the cxx-conversion variant? >> >> >> Surely (check(t), t) also works, and also strt wrt const. > > > My concern with (check(t), t) is that it evaluates 't' twice. It may not be > a big deal, however. In which case, I'm OK with that alternative. Hum. A source of possibly nasty errors. I'd like to avoid using templates here though. Going with two overloads for each function sounds like the best solution to me, thus delay the change to cxx-switch time. What's the effect on bootstrap times? Remember we build stage1 with -O0 and checking enabled always ... Richard. > > Diego. >
Re: Turn check macros into functions. (issue6188088)
On 12-05-20 13:59 , Richard Henderson wrote: On 05/18/2012 04:48 PM, Diego Novillo wrote: We can do this in trunk today using a variant of Lawrence's original patch (http://gcc.gnu.org/ml/gcc-patches/2011-09/msg01649.html). This uses no C++ features, though it weakens type checking by removing away constness. In the cxx-conversion branch, we can use overloads, which will DTRT with const. My question is, what do folks prefer? a) The trunk patch today, using no C++ features. b) Wait for the cxx-conversion variant? Surely (check(t), t) also works, and also strt wrt const. My concern with (check(t), t) is that it evaluates 't' twice. It may not be a big deal, however. In which case, I'm OK with that alternative. Diego.
Re: Turn check macros into functions. (issue6188088)
On 05/18/2012 04:48 PM, Diego Novillo wrote: We can do this in trunk today using a variant of Lawrence's original patch (http://gcc.gnu.org/ml/gcc-patches/2011-09/msg01649.html). This uses no C++ features, though it weakens type checking by removing away constness. In the cxx-conversion branch, we can use overloads, which will DTRT with const. My question is, what do folks prefer? a) The trunk patch today, using no C++ features. b) Wait for the cxx-conversion variant? Surely (check(t), t) also works, and also strt wrt const. r~
Re: Turn check macros into functions. (issue6188088)
On 5/18/12, Diego Novillo wrote: > So, I would like to figure out what to do with this. We have > a usability problem wrt deubgging that I would like to fix. > The only way we have of using all the tree accessor macros from > GDB is to convert the checks into functions (converting the actual > accessor macros would also work, but that's a different story). > > Now that we have the ability to skip functions in gdb, making tree > checking into functions should not be a problem. Additionally, we > can make gdb skip other common functions (like tree_code_length). > > We can do this in trunk today using a variant of Lawrence's original > patch (http://gcc.gnu.org/ml/gcc-patches/2011-09/msg01649.html). This > uses no C++ features, though it weakens type checking by removing away > constness. The difference between then and now is that we now have the gdb skip command, which fixes the problem of introducing another step point into debugging code using the macros. > In the cxx-conversion branch, we can use overloads, which will > DTRT with const. > > My question is, what do folks prefer? > > a) The trunk patch today, using no C++ features. > b) Wait for the cxx-conversion variant? > > Incidentally, making these expression statements into out-of-line > functions saves about 3% in the final binary size, but increases > compile time by about 10% (tested on several large .o files in > bld/gcc), so we likely want to keep them as inline functions. With the inline functions, if the compiler is doing no inlining, we should still get near to that 3% reduction in binary size. -- Lawrence Crowl
Re: Turn check macros into functions. (issue6188088)
On 5/17/12, Mike Stump wrote: > On May 17, 2012, at 2:41 PM, Lawrence Crowl wrote: >>> Reusing the compiler for this seems like the only way to go. >>> But, we did look at using g++ to parse C++ expressions from gdb, >>> and it was too slow :-(. We're going to look again, at least to >>> generate some bug reports if we can. >> >> It's a tough problem, particularly as C/C++ and their compilers >> were not designed for a read-eval-print-loop environment. > > This of course is trivial to do, I do not think that word means what you think it means. :-) > and reasonably fast as well. We have an existence proof that > they can generate a call on the target system, all one needs to > do would be to locate the target compiler, compile up a strapping > routine, push a dlopen of that routine onto the target system and > then call dlsym to grab a handle to it. The strapping routine > can set up an environment and communication channels as needed. > If could even allocate a thread and have it always be live > (non-stop), if one wanted. I agree that it is possible. > Oh, and the benefit, the language supported by the code closely > matches the compiler. Speed, 1/40 of a second, fast enough for > command like use. Want to evaluate it 100 times, sure, just > be sure to cache the dlopen/dlsym, and notice that you can do a > million invocations, well, I'd guess a million times faster than > gdb currently. Agree. > If gdb won't solve these problem, dump it, move to lldb, I can > assure you, they will not fail to solve the problem, just because > gdb can't or won't. The name of the game is compete or die. > > If you use the clang libraries, you can read eval, print... and > the performance would likely be even better. After all, it can > be used to do OpenCL style programming, and that certainly was > built for speed. So, I reject the idea this all isn't trivial. Yes, clang was designed to handle this use case. > > $ cat eval.c > #include > #include > #include > #include > > int main() { > char buf[4096]; > while (fgets (buf, sizeof (buf), stdin) != NULL) { > struct timeval tv1, tv2; > gettimeofday(&tv1, 0); > FILE *fp = popen ("gcc -w -xc - -shared -o test.so", "w"); > if (fputs (buf, fp) < 0) { > printf ("write fails\n"); > exit (1); > } > if (pclose (fp) != 0) { > printf ("compile fails\n"); > exit (1); > } > void *vp = dlopen("test.so", RTLD_NOW|RTLD_LOCAL|RTLD_FIRST); > void *fcn = dlsym (vp, "eval"); > if (fcn) { > void (*func)(); > func = fcn; > printf("about to run\n"); > func(); > gettimeofday(&tv2, 0); > printf("done running, took %ld usecs\n", tv2.tv_sec*100 > + tv2.tv_usec - tv1.tv_sec*100 - tv1.tv_usec); > } else { > printf ("eval not found\n"); > } > if (dlclose (vp) < 0) { > printf ("dlclose fails\n"); > exit (1); > } > } > } > $ gcc eval.c -o eval -O3 > $ ./eval > int eval () { printf ("hi\n"); } > about to run > hi > done running, took 28419 usecs > int eval () { printf ("hi\n"); } > about to run > hi > done running, took 29300 usecs > int eval () { printf ("hi\n"); } > about to run > hi > done running, took 25755 usecs > int eval () { printf ("hi\n"); } > about to run > hi > done running, took 28295 usecs I like the example, but it sidesteps the main problem, which is putting the expression in the context from which it was called. For instance if I stop in the middle of a function and type print foo->bar( a + b ) I need to find the find the variable names, lookup their types, do overload resolution, possibly do template instantiation, etc, all as if the compiler was in the scope defined for the line that the debugger is stopped at. That's the hard part. > Maybe your thinking of lisp, certainly that language makes > it hard. ;-P Actually, a read-eval-print loop in Lisp is easy. -- Lawrence Crowl
Re: Turn check macros into functions. (issue6188088)
On 12-05-18 08:23 , Jay Foad wrote: What's wrong with: (check_in_cxx(t), t) ? This evaluates 't' twice. Diego.
Re: Turn check macros into functions. (issue6188088)
On 12-05-18 18:14 , Richard Henderson wrote: On 05/18/12 05:06, Richard Guenther wrote: Can you locate those? I mean, most uses look like #define DECL_NONSHAREABLE(NODE) \ (TREE_CHECK2 (NODE, VAR_DECL, \ RESULT_DECL)->decl_common.decl_nonshareable_flag) thus they only dereference the result, not assign it anywhere. const_tree vs tree for NODE is the difference between the entire expression being writable, or read-only. DECL_NONSHARABLE (d) = true; Right. Returning a const_tree means that you can't write to anything in the resulting value. To answer richi's original question, this produces ~9,000 syntax errors in gcc/*.o. So, I would like to figure out what to do with this. We have a usability problem wrt deubgging that I would like to fix. The only way we have of using all the tree accessor macros from GDB is to convert the checks into functions (converting the actual accessor macros would also work, but that's a different story). Now that we have the ability to skip functions in gdb, making tree checking into functions should not be a problem. Additionally, we can make gdb skip other common functions (like tree_code_length). We can do this in trunk today using a variant of Lawrence's original patch (http://gcc.gnu.org/ml/gcc-patches/2011-09/msg01649.html). This uses no C++ features, though it weakens type checking by removing away constness. In the cxx-conversion branch, we can use overloads, which will DTRT with const. My question is, what do folks prefer? a) The trunk patch today, using no C++ features. b) Wait for the cxx-conversion variant? Incidentally, making these expression statements into out-of-line functions saves about 3% in the final binary size, but increases compile time by about 10% (tested on several large .o files in bld/gcc), so we likely want to keep them as inline functions. Diego.
Re: Turn check macros into functions. (issue6188088)
On 05/18/12 05:06, Richard Guenther wrote: > Can you locate those? I mean, most uses look like > > #define DECL_NONSHAREABLE(NODE) \ > (TREE_CHECK2 (NODE, VAR_DECL, \ > RESULT_DECL)->decl_common.decl_nonshareable_flag) > > thus they only dereference the result, not assign it anywhere. const_tree vs tree for NODE is the difference between the entire expression being writable, or read-only. DECL_NONSHARABLE (d) = true; r~
Re: Turn check macros into functions. (issue6188088)
On 18 May 2012 12:46, Diego Novillo wrote: > On 12-05-18 06:14 , Richard Guenther wrote: > >> As you retain the macros anyway you can simply not return anything >> from the C++ checking functions define to a stmt expression >> ({ check_in_cxx (t); t; }) > > > Sure, but that takes us back to the original gdb issue: it does not > understand statement expressions. What's wrong with: (check_in_cxx(t), t) ? Jay.
Re: Turn check macros into functions. (issue6188088)
On Fri, May 18, 2012 at 1:46 PM, Diego Novillo wrote: > On 12-05-18 06:14 , Richard Guenther wrote: > >> As you retain the macros anyway you can simply not return anything >> from the C++ checking functions define to a stmt expression >> ({ check_in_cxx (t); t; }) > > > Sure, but that takes us back to the original gdb issue: it does not > understand statement expressions. > > >> Btw, what breaks if the check functions always return a const_tree and >> take a const_tree? > > > You get a stream of "invalid conversion from 'tree_node* const*' to > 'tree_node**'". Can you locate those? I mean, most uses look like #define DECL_NONSHAREABLE(NODE) \ (TREE_CHECK2 (NODE, VAR_DECL, \ RESULT_DECL)->decl_common.decl_nonshareable_flag) thus they only dereference the result, not assign it anywhere. Richard. > > Diego.
Re: Turn check macros into functions. (issue6188088)
On 12-05-18 06:14 , Richard Guenther wrote: As you retain the macros anyway you can simply not return anything from the C++ checking functions define to a stmt expression ({ check_in_cxx (t); t; }) Sure, but that takes us back to the original gdb issue: it does not understand statement expressions. Btw, what breaks if the check functions always return a const_tree and take a const_tree? You get a stream of "invalid conversion from 'tree_node* const*' to 'tree_node**'". Diego.
Re: Turn check macros into functions. (issue6188088)
On Thu, May 17, 2012 at 8:36 PM, Diego Novillo wrote: > On 12-05-17 10:52 , Michael Matz wrote: > >> Cross the bridge when you reach it, not before. Not everybody agrees that >> the splitting of tree would be a good idea. Right now templates aren't >> necessary, so you shouldn't use them. (well, and an investigation why >> they come up with smaller .text would be in order anyway). > > > I've been playing around with this patch a little bit. The main motivation > for using templates here is to preserve the existing semantics. Note that > the return type from the function mimics the type of the argument passed in. > So, if the user passes a const_tree, the function returns a const_tree. > > The way to do this in C++ is to: (a) use templates (as in Lawrence's patch), > or (b) produce overloaded variants for tree and const_tree. > > For trunk, we have a third option: (c) make these functions out-of-line > functions that take const_tree and return tree. This slightly weakens the > semantics of the checks, but it does not rely on C++ features. > > Options (a) or (b) are the same to me. Option (b) has the slight advantage > that the code can be taken out of tree.h and buried in tree.c. > > The attached patch implements option (c). Should we consider this for trunk > now and then just replace the CONST_CAST_TREE into C++ overloads? As you retain the macros anyway you can simply not return anything from the C++ checking functions define to a stmt expression ({ check_in_cxx (t); t; }) Btw, what breaks if the check functions always return a const_tree and take a const_tree? Richard. > > Thanks. Diego. > > > 2012-05-17 Lawrence Crowl > > * tree.h (tree_check): Declare. > (TREE_CHECK): Use function above instead of __extension__. > (tree_not_check): Declare. > (TREE_NOT_CHECK): Use function above instead of __extension__. > (tree_check2): Declare. > (TREE_CHECK2): Use function above instead of __extension__. > (tree_not_check2): Declare. > (TREE_NOT_CHECK2): Use function above instead of __extension__. > (tree_check3): Declare. > (TREE_CHECK3): Use function above instead of __extension__. > (tree_not_check3): Declare. > (TREE_NOT_CHECK3): Use function above instead of __extension__. > (tree_check4): Declare. > (TREE_CHECK4): Use function above instead of __extension__. > (tree_not_check4): Declare. > (TREE_NOT_CHECK4): Use function above instead of __extension__. > (tree_check5): Declare. > (TREE_CHECK5): Use function above instead of __extension__. > (tree_not_check5): Declare. > (TREE_NOT_CHECK5): Use function above instead of __extension__. > (contains_struct_check): Declare. > (CONTAINS_STRUCT_CHECK): Use function above instead of > __extension__. > (tree_class_check): Declare. > (TREE_CLASS_CHECK): Use function above instead of __extension__. > (tree_range_check): Declare. > (TREE_RANGE_CHECK): Use function above instead of __extension__. > (omp_clause_subcode_check): Declare. > (OMP_CLAUSE_SUBCODE_CHECK): Use function above instead of > __extension__. > (omp_clause_range_check): Declare. > (OMP_CLAUSE_RANGE_CHECK): Use function above instead of > __extension__. > (expr_check): Declare. > (EXPR_CHECK): Use function above instead of __extension__. > (non_type_check): Declare. > (NON_TYPE_CHECK): Use function above instead of __extension__. > (tree_vec_elt_check): Declare. > (TREE_VEC_ELT_CHECK): Use function above instead of > __extension__. > (omp_clause_elt_check): Declare. > (OMP_CLAUSE_ELT_CHECK): Use function above instead of > __extension__. > (tree_operand_check): Declare. > (TREE_OPERAND_CHECK): Use function above instead of > __extension__. > (tree_operand_check_code): Declare. > (TREE_OPERAND_CHECK_CODE): Use function above instead of > > __extension__. > (TREE_CHAIN): Simplify implementation. > (TREE_TYPE): Simplify implementation. > (tree_operand_length): Move for compilation dependences. > * tree.c (tree_check): New. > (tree_not_check): New. > (tree_check2): New. > (tree_not_check2): New. > (tree_check3): New. > (tree_not_check3): New. > (tree_check4): New. > (tree_not_check4): New. > (tree_check5): New. > (tree_not_check5): New. > (contains_struct_check): New. > (tree_range_check): New. > (omp_clause_subcode_check): New. > (omp_clause_range_check): New. > (expr_check): New. > (non_type_check): New. > (tree_vec_elt_check): New. > (omp_clause_elt_check): New. > (tree_operand_check): New. > (tree_operand_check_code): New. > > * gdbinit.in: (macro define __FILE__): New. > (macro
Re: Turn check macros into functions. (issue6188088)
On May 17, 2012, at 2:41 PM, Lawrence Crowl wrote: >> Reusing the compiler for this seems like the only way to go. >> But, we did look at using g++ to parse C++ expressions from gdb, >> and it was too slow :-(. We're going to look again, at least to >> generate some bug reports if we can. > > It's a tough problem, particularly as C/C++ and their compilers > were not designed for a read-eval-print-loop environment. This of course is trivial to do, and reasonably fast as well. We have an existence proof that they can generate a call on the target system, all one needs to do would be to locate the target compiler, compile up a strapping routine, push a dlopen of that routine onto the target system and then call dlsym to grab a handle to it. The strapping routine can set up an environment and communication channels as needed. If could even allocate a thread and have it always be live (non-stop), if one wanted. Oh, and the benefit, the language supported by the code closely matches the compiler. Speed, 1/40 of a second, fast enough for command like use. Want to evaluate it 100 times, sure, just be sure to cache the dlopen/dlsym, and notice that you can do a million invocations, well, I'd guess a million times faster than gdb currently. If gdb won't solve these problem, dump it, move to lldb, I can assure you, they will not fail to solve the problem, just because gdb can't or won't. The name of the game is compete or die. If you use the clang libraries, you can read eval, print... and the performance would likely be even better. After all, it can be used to do OpenCL style programming, and that certainly was built for speed. So, I reject the idea this all isn't trivial. $ cat eval.c #include #include #include #include int main() { char buf[4096]; while (fgets (buf, sizeof (buf), stdin) != NULL) { struct timeval tv1, tv2; gettimeofday(&tv1, 0); FILE *fp = popen ("gcc -w -xc - -shared -o test.so", "w"); if (fputs (buf, fp) < 0) { printf ("write fails\n"); exit (1); } if (pclose (fp) != 0) { printf ("compile fails\n"); exit (1); } void *vp = dlopen("test.so", RTLD_NOW|RTLD_LOCAL|RTLD_FIRST); void *fcn = dlsym (vp, "eval"); if (fcn) { void (*func)(); func = fcn; printf("about to run\n"); func(); gettimeofday(&tv2, 0); printf("done running, took %ld usecs\n", tv2.tv_sec*100 + tv2.tv_usec - tv1.tv_sec*100 - tv1.tv_usec); } else { printf ("eval not found\n"); } if (dlclose (vp) < 0) { printf ("dlclose fails\n"); exit (1); } } } $ gcc eval.c -o eval -O3 $ ./eval int eval () { printf ("hi\n"); } about to run hi done running, took 28419 usecs int eval () { printf ("hi\n"); } about to run hi done running, took 29300 usecs int eval () { printf ("hi\n"); } about to run hi done running, took 25755 usecs int eval () { printf ("hi\n"); } about to run hi done running, took 28295 usecs Maybe your thinking of lisp, certainly that language makes it hard. ;-P
Re: Turn check macros into functions. (issue6188088)
On 5/17/12, Tom Tromey wrote: > > "Lawrence" == Lawrence Crowl writes: > > Tom> Doesn't this mean that if you have checking enabled, and you use > Tom> the wrong macro on some tree, cc1 will crash? That seems like > Tom> a distinct minus to me. > > Lawrence> Yes, it does mean that, but it is a net overall improvement. > > It is a net debugging improvement compared to trunk, but not > compared to using 'macro define's. If you know about them and your debuggers supports them. It was two years before I learned about those macros. By moving the source closer to standard code, we reduce the frustration for new developers. I was particularly frustrated by this problem. > It would be nice if there were a way to make cc1 not crash due > to user error in the debugger. I think this kind of crash will > be especially crazy-making. Agreed. Intercept abort in gdb? > Lawrence> These extensions are not on gdb's list of things to > Lawrence> implement. > > As a digression - I guess they could be. That would certainly help in several when using gdb. It would not help if someone needs or wants to use a different debugger. > Reusing the compiler for this seems like the only way to go. > But, we did look at using g++ to parse C++ expressions from gdb, > and it was too slow :-(. We're going to look again, at least to > generate some bug reports if we can. It's a tough problem, particularly as C/C++ and their compilers were not designed for a read-eval-print-loop environment. -- Lawrence Crowl
Re: Turn check macros into functions. (issue6188088)
On Thu, May 17, 2012 at 1:53 PM, Tom Tromey wrote: >> "Lawrence" == Lawrence Crowl writes: > > Tom> Doesn't this mean that if you have checking enabled, and you use the > Tom> wrong macro on some tree, cc1 will crash? That seems like a distinct > Tom> minus to me. > > Lawrence> Yes, it does mean that, but it is a net overall improvement. > > It is a net debugging improvement compared to trunk, but not compared to > using 'macro define's. > > It would be nice if there were a way to make cc1 not crash due to user > error in the debugger. I think this kind of crash will be especially > crazy-making. Then maybe someone should write some python scripts to do the extractions so that the debugger will not crash. Note I don't have enough experience with python or python scripting in gdb to do that. Thanks, Andrew > > Lawrence> These extensions are not on gdb's list of things to implement. > > As a digression - I guess they could be. > > Reusing the compiler for this seems like the only way to go. But, we > did look at using g++ to parse C++ expressions from gdb, and it was too > slow :-(. We're going to look again, at least to generate some bug > reports if we can. > > Tom
Re: Turn check macros into functions. (issue6188088)
> "Lawrence" == Lawrence Crowl writes: Tom> Doesn't this mean that if you have checking enabled, and you use the Tom> wrong macro on some tree, cc1 will crash? That seems like a distinct Tom> minus to me. Lawrence> Yes, it does mean that, but it is a net overall improvement. It is a net debugging improvement compared to trunk, but not compared to using 'macro define's. It would be nice if there were a way to make cc1 not crash due to user error in the debugger. I think this kind of crash will be especially crazy-making. Lawrence> These extensions are not on gdb's list of things to implement. As a digression - I guess they could be. Reusing the compiler for this seems like the only way to go. But, we did look at using g++ to parse C++ expressions from gdb, and it was too slow :-(. We're going to look again, at least to generate some bug reports if we can. Tom
Re: Turn check macros into functions. (issue6188088)
On 12-05-17 10:52 , Michael Matz wrote: Cross the bridge when you reach it, not before. Not everybody agrees that the splitting of tree would be a good idea. Right now templates aren't necessary, so you shouldn't use them. (well, and an investigation why they come up with smaller .text would be in order anyway). I've been playing around with this patch a little bit. The main motivation for using templates here is to preserve the existing semantics. Note that the return type from the function mimics the type of the argument passed in. So, if the user passes a const_tree, the function returns a const_tree. The way to do this in C++ is to: (a) use templates (as in Lawrence's patch), or (b) produce overloaded variants for tree and const_tree. For trunk, we have a third option: (c) make these functions out-of-line functions that take const_tree and return tree. This slightly weakens the semantics of the checks, but it does not rely on C++ features. Options (a) or (b) are the same to me. Option (b) has the slight advantage that the code can be taken out of tree.h and buried in tree.c. The attached patch implements option (c). Should we consider this for trunk now and then just replace the CONST_CAST_TREE into C++ overloads? Thanks. Diego. 2012-05-17 Lawrence Crowl * tree.h (tree_check): Declare. (TREE_CHECK): Use function above instead of __extension__. (tree_not_check): Declare. (TREE_NOT_CHECK): Use function above instead of __extension__. (tree_check2): Declare. (TREE_CHECK2): Use function above instead of __extension__. (tree_not_check2): Declare. (TREE_NOT_CHECK2): Use function above instead of __extension__. (tree_check3): Declare. (TREE_CHECK3): Use function above instead of __extension__. (tree_not_check3): Declare. (TREE_NOT_CHECK3): Use function above instead of __extension__. (tree_check4): Declare. (TREE_CHECK4): Use function above instead of __extension__. (tree_not_check4): Declare. (TREE_NOT_CHECK4): Use function above instead of __extension__. (tree_check5): Declare. (TREE_CHECK5): Use function above instead of __extension__. (tree_not_check5): Declare. (TREE_NOT_CHECK5): Use function above instead of __extension__. (contains_struct_check): Declare. (CONTAINS_STRUCT_CHECK): Use function above instead of __extension__. (tree_class_check): Declare. (TREE_CLASS_CHECK): Use function above instead of __extension__. (tree_range_check): Declare. (TREE_RANGE_CHECK): Use function above instead of __extension__. (omp_clause_subcode_check): Declare. (OMP_CLAUSE_SUBCODE_CHECK): Use function above instead of __extension__. (omp_clause_range_check): Declare. (OMP_CLAUSE_RANGE_CHECK): Use function above instead of __extension__. (expr_check): Declare. (EXPR_CHECK): Use function above instead of __extension__. (non_type_check): Declare. (NON_TYPE_CHECK): Use function above instead of __extension__. (tree_vec_elt_check): Declare. (TREE_VEC_ELT_CHECK): Use function above instead of __extension__. (omp_clause_elt_check): Declare. (OMP_CLAUSE_ELT_CHECK): Use function above instead of __extension__. (tree_operand_check): Declare. (TREE_OPERAND_CHECK): Use function above instead of __extension__. (tree_operand_check_code): Declare. (TREE_OPERAND_CHECK_CODE): Use function above instead of __extension__. (TREE_CHAIN): Simplify implementation. (TREE_TYPE): Simplify implementation. (tree_operand_length): Move for compilation dependences. * tree.c (tree_check): New. (tree_not_check): New. (tree_check2): New. (tree_not_check2): New. (tree_check3): New. (tree_not_check3): New. (tree_check4): New. (tree_not_check4): New. (tree_check5): New. (tree_not_check5): New. (contains_struct_check): New. (tree_range_check): New. (omp_clause_subcode_check): New. (omp_clause_range_check): New. (expr_check): New. (non_type_check): New. (tree_vec_elt_check): New. (omp_clause_elt_check): New. (tree_operand_check): New. (tree_operand_check_code): New. * gdbinit.in: (macro define __FILE__): New. (macro define __LINE__): New. (skip "tree.h"): New. 2012-05-17 Lawrence Crowl * tree.h (tree_check): Declare. (TREE_CHECK): Use function above instead of __extension__. (tree_not_check): Declare. (TREE_NOT_CHECK): Use function above instead of __extension__. (tree_check2): Declare. (TREE_CHECK2): Use function above instead of __extension__. (tree_not_check2): Decla
Re: Turn check macros into functions. (issue6188088)
Hi, On Wed, 16 May 2012, Lawrence Crowl wrote: > > Because it accepts any type as tree argument? It's of course not less > > type safety than using macros, but less type safety compared to not > > using templates. > > The overload works if the only types are tree and const_tree. In the > future, we may wish to refine the types so that, for example, we can > have a pointer to a decl and ask if it is a var decl. Cross the bridge when you reach it, not before. Not everybody agrees that the splitting of tree would be a good idea. Right now templates aren't necessary, so you shouldn't use them. (well, and an investigation why they come up with smaller .text would be in order anyway). Ciao, Michael.
Re: Turn check macros into functions. (issue6188088)
On 5/16/12, Tom Tromey wrote: >> "Lawrence" == Lawrence Crowl writes: > > Lawrence> The effect is that it now possible to get useful responses > Lawrence> to gdb command like > Lawrence> (gdb) print DECL_FUNCTION_CODE (decl) > > Doesn't this mean that if you have checking enabled, and you use the > wrong macro on some tree, cc1 will crash? That seems like a distinct > minus to me. Yes, it does mean that, but it is a net overall improvement. The use scenario is in copying an expression from the source to gdb to figure out its value. In this scenario, you typically are not going to have the wrong tree type. With the macro, gdb refuses to evaluate the print even when the code is correct. It complains about extensions or gets confused. These extensions are not on gdb's list of things to implement. The only way to "make it work" with the macro is to define overriding macros in gdb. If you do that, the patch introduces no behavioral change. So, the patch is a net positive. -- Lawrence Crowl
Re: Turn check macros into functions. (issue6188088)
On 5/16/12, Richard Guenther wrote: > On May 16, 2012 Diego Novillo wrote: > > On 12-05-16 09:00 , Richard Guenther wrote: > > > On May 16, 2012 Diego Novillo wrote: > > > > On 12-05-16 05:41 , Richard Guenther wrote: > > > > > What's the reason for templating these functions? > > > > > They all take trees as parameter!? The check templates replicate the behavior of the check macros, which carefully return the type of their argument. In essence, the check macros were templates. > > > > True. I don't recall what Lawrence had in mind, but I > > > > remember that by using templates here, you don't need to > > > > deal with the mess of distinguishing tree from const_tree, > > > > and having to force constness out with ugly casts. > > > > > > Well, but you get no typesafety for it in return. You can > > > simply provide a const_tree overload. > > > > There's less typing if you use the template variant. Not sure > > why you say there is less type safety with templates. > > Because it accepts any type as tree argument? It's of course not > less type safety than using macros, but less type safety compared > to not using templates. The overload works if the only types are tree and const_tree. In the future, we may wish to refine the types so that, for example, we can have a pointer to a decl and ask if it is a var decl. The implementation approach is to make small steps. It's a tradeoff between small steps that may show only incremental value, or big steps that risk rejection. In addition, merging is easier with small steps. > > > With using templates you are also forced to retain these > > > functions in the header file - another thing that I suppose > > > you guys were about to "fix"? It's after all debugging code. > > > > No, templated functions must always stay in the header file. > > There is no changing that. > > If they ain't templates they are not templates. And thus do not > need to stay in the header. Not sure what you are after here ;) Personally, I would like to get to the point where we take advantage of static typing and the vast bulk of these checks are eliminated. > > > > Additionally, templates are producing slightly smaller > > > > code than the non-template variant (about 0.2% smaller). > > > > I'm not actually sure why this happens, but it's consistent > > > > across all binaries. > > > > > > Well, what did you compare? Make sure to not have > > > -fkeep-inline-functions, otherwise you get all bodies as > > > compared to only the instantiated bodies. > > > > Two bootstrapped compilers built exactly the same, except one > > was using the template version, the other using the straight > > inline functions with const_tree parameters and CONST_CAST_TREE > > in return values. > > That's of course not exactly the same. The checking fns should > be able to unconditionally use const_tree anyway. The two versions are inline templates functions versus macros. I expect the non-template version would be roughly the same size as the template version. -- Lawrence Crowl
Re: Turn check macros into functions. (issue6188088)
> "Lawrence" == Lawrence Crowl writes: Lawrence> The effect is that it now possible to get useful responses to gdb Lawrence> command like Lawrence> (gdb) print DECL_FUNCTION_CODE (decl) Doesn't this mean that if you have checking enabled, and you use the wrong macro on some tree, cc1 will crash? That seems like a distinct minus to me. Tom
Re: Turn check macros into functions. (issue6188088)
Il 16/05/2012 15:27, Richard Guenther ha scritto: >> > >> > Two bootstrapped compilers built exactly the same, except one was using the >> > template version, the other using the straight inline functions with >> > const_tree parameters and CONST_CAST_TREE in return values. > That's of course not exactly the same. The checking fns should be able > to unconditionally use const_tree anyway. Take const_tree, yes. Return const_tree, no. So you need a tree->tree version and a const_tree->const_tree version, like the strchr overloads in the standard C++ library. Paolo
Re: Turn check macros into functions. (issue6188088)
On Wed, May 16, 2012 at 3:40 PM, Diego Novillo wrote: > On 12-05-16 09:27 , Richard Guenther wrote: > >>> There's less typing if you use the template variant. Not sure why >>> you say there is less type safety with templates. >> >> >> Because it accepts any type as tree argument? > > > Yes and no. It accepts any type that responds to tree > operations and has the same fields. > > >>> No, templated functions must always stay in the header file. >>> There is no changing that. >> >> >> If they ain't templates they are not templates. And thus do not >> need to stay in the header. Not sure what you are after here ;) > > > I think we are talking past each other. I simply stated that function > templates must stay in headers. There's no export template, after all. > > I'm not defending the choice of using templates for these particular > functions. That's something for Lawrence to argue. > > I am simply curious as to how using the template variant produces > slightly smaller code. > > >>> Two bootstrapped compilers built exactly the same, except one was >>> using the template version, the other using the straight inline >>> functions with const_tree parameters and CONST_CAST_TREE in return >>> values. >> >> >> That's of course not exactly the same. The checking fns should be >> able to unconditionally use const_tree anyway. > > > Sorry, I don't know what you are after. I was comparing two compilers > that only differ in how they implement the tree checking functions. One > uses templates, the other uses inline functions taking const_tree (not even > static inline, just inline). > > They are bootstrapped compilers, so -fkeep-inline-functions is not used. > What do you think I should have compared? Sounds like it should come out equally sized then. Possibly an instantiated template leads to different code from the frontend? Possibly we do not inline all calls in either case? Possibly because only instantiated templates count towards initial unit size (but all, even unused(?), inline functions count towards it)? Would be interesting to see preprocessed source for both cases for a single object files where the size difference appears. It might be artificial, too, caused by UID perturbations and random codegen difference due to that. Non-templates should use less memory (with templates you at least have a single instantiation and thus copy of the functions, with functions you just have one). That said - I see no technical reasons to use templates here and we should not use C++ just because we can ... (and not scare people off here if the technical reason is minor, such as an unknown size advantage). Richard. > > Diego.
Re: Turn check macros into functions. (issue6188088)
On 12-05-16 09:27 , Richard Guenther wrote: There's less typing if you use the template variant. Not sure why you say there is less type safety with templates. Because it accepts any type as tree argument? Yes and no. It accepts any type that responds to tree operations and has the same fields. No, templated functions must always stay in the header file. There is no changing that. If they ain't templates they are not templates. And thus do not need to stay in the header. Not sure what you are after here ;) I think we are talking past each other. I simply stated that function templates must stay in headers. There's no export template, after all. I'm not defending the choice of using templates for these particular functions. That's something for Lawrence to argue. I am simply curious as to how using the template variant produces slightly smaller code. Two bootstrapped compilers built exactly the same, except one was using the template version, the other using the straight inline functions with const_tree parameters and CONST_CAST_TREE in return values. That's of course not exactly the same. The checking fns should be able to unconditionally use const_tree anyway. Sorry, I don't know what you are after. I was comparing two compilers that only differ in how they implement the tree checking functions. One uses templates, the other uses inline functions taking const_tree (not even static inline, just inline). They are bootstrapped compilers, so -fkeep-inline-functions is not used. What do you think I should have compared? Diego.
Re: Turn check macros into functions. (issue6188088)
On Wed, May 16, 2012 at 3:16 PM, Diego Novillo wrote: > On 12-05-16 09:00 , Richard Guenther wrote: >> >> On Wed, May 16, 2012 at 2:43 PM, Diego Novillo >> wrote: >>> >>> On 12-05-16 05:41 , Richard Guenther wrote: >>> What's the reason for templating these functions? They all take trees as parameter!? >>> >>> >>> >>> True. I don't recall what Lawrence had in mind, but I remember that by >>> using templates here, you don't need to deal with the mess of >>> distinguishing >>> tree from const_tree, and having to force constness out with ugly casts. >> >> >> Well, but you get no typesafety for it in return. You can simply provide >> a const_tree overload. > > > There's less typing if you use the template variant. Not sure why you say > there is less type safety with templates. Because it accepts any type as tree argument? It's of course not less type safety than using macros, but less type safety compared to not using templates. >> With using templates you are also forced to retain >> these functions in the header file - another thing that I suppose you guys >> were about to "fix"? It's after all debugging code. > > > No, templated functions must always stay in the header file. There is no > changing that. If they ain't templates they are not templates. And thus do not need to stay in the header. Not sure what you are after here ;) >>> Additionally, templates are producing slightly smaller code than the >>> non-template variant (about 0.2% smaller). I'm not actually sure why >>> this >>> happens, but it's consistent across all binaries. >> >> >> Well, what did you compare? Make sure to not have >> -fkeep-inline-functions, >> otherwise you get all bodies as compared to only the instantiated bodies. > > > Two bootstrapped compilers built exactly the same, except one was using the > template version, the other using the straight inline functions with > const_tree parameters and CONST_CAST_TREE in return values. That's of course not exactly the same. The checking fns should be able to unconditionally use const_tree anyway. Richard. > > Diego.
Re: Turn check macros into functions. (issue6188088)
On 12-05-16 09:00 , Richard Guenther wrote: On Wed, May 16, 2012 at 2:43 PM, Diego Novillo wrote: On 12-05-16 05:41 , Richard Guenther wrote: What's the reason for templating these functions? They all take trees as parameter!? True. I don't recall what Lawrence had in mind, but I remember that by using templates here, you don't need to deal with the mess of distinguishing tree from const_tree, and having to force constness out with ugly casts. Well, but you get no typesafety for it in return. You can simply provide a const_tree overload. There's less typing if you use the template variant. Not sure why you say there is less type safety with templates. With using templates you are also forced to retain these functions in the header file - another thing that I suppose you guys were about to "fix"? It's after all debugging code. No, templated functions must always stay in the header file. There is no changing that. Additionally, templates are producing slightly smaller code than the non-template variant (about 0.2% smaller). I'm not actually sure why this happens, but it's consistent across all binaries. Well, what did you compare? Make sure to not have -fkeep-inline-functions, otherwise you get all bodies as compared to only the instantiated bodies. Two bootstrapped compilers built exactly the same, except one was using the template version, the other using the straight inline functions with const_tree parameters and CONST_CAST_TREE in return values. Diego.
Re: Turn check macros into functions. (issue6188088)
On Wed, May 16, 2012 at 2:43 PM, Diego Novillo wrote: > On 12-05-16 05:41 , Richard Guenther wrote: > >> What's the reason for templating these functions? They all take trees as >> parameter!? > > > True. I don't recall what Lawrence had in mind, but I remember that by > using templates here, you don't need to deal with the mess of distinguishing > tree from const_tree, and having to force constness out with ugly casts. Well, but you get no typesafety for it in return. You can simply provide a const_tree overload. With using templates you are also forced to retain these functions in the header file - another thing that I suppose you guys were about to "fix"? It's after all debugging code. > Additionally, templates are producing slightly smaller code than the > non-template variant (about 0.2% smaller). I'm not actually sure why this > happens, but it's consistent across all binaries. Well, what did you compare? Make sure to not have -fkeep-inline-functions, otherwise you get all bodies as compared to only the instantiated bodies. Richard. > > Diego.
Re: Turn check macros into functions. (issue6188088)
On 12-05-16 05:41 , Richard Guenther wrote: What's the reason for templating these functions? They all take trees as parameter!? True. I don't recall what Lawrence had in mind, but I remember that by using templates here, you don't need to deal with the mess of distinguishing tree from const_tree, and having to force constness out with ugly casts. Additionally, templates are producing slightly smaller code than the non-template variant (about 0.2% smaller). I'm not actually sure why this happens, but it's consistent across all binaries. Diego.
Re: Turn check macros into functions. (issue6188088)
On Tue, May 15, 2012 at 7:19 PM, Lawrence Crowl wrote: > The gcc source uses several constructs that GDB does not understand. > This patch corrects some of them. It affects only compilers built > with ENABLE_TREE_CHECKING, and hence release compilers are unaffected. > > In particular, I change the implementation of CHECK macros using > __extension__ into macros calling template inline functions. I do not > change the accessor macros themselves. > > The effect is that it now possible to get useful responses to gdb > command like > > (gdb) print DECL_FUNCTION_CODE (decl) > > To make the feature work, you must define two macros within gdb. > > (gdb) macro define __FILE__ "gdb" > (gdb) macro define __LINE__ 1 > > The reason for these definitions is that gdb does not expand the magic > preprocessor macros, and then cannot find what it thinks is a regular > symbol. (There is now a gdb issue for this problem.) I added these > definitions to gdbinit.in. > > The inline functions would normally introduce additional lines in a > sequence of gdb 'step' commands. To prevent that behavior, I have > added the new 'skip' command for the "tree.h" file to gdbinit.in. The > 'skip' command works with gdb 7.4 and later. > > (The better solution to the stepping behavior is a new gdb command. > See http://sourceware.org/bugzilla/show_bug.cgi?id=12940.) > > Tested on x86-64. What's the reason for templating these functions? They all take trees as parameter!? Richard. > Index: gcc/ChangeLog.cxx-conversion > > 2012-05-15 Lawrence Crowl > > * tree.h (tree_check): New. > (TREE_CHECK): Use inline function above instead of __extension__. > (tree_not_check): New. > (TREE_NOT_CHECK): Use inline function above instead of __extension__. > (tree_check2): New. > (TREE_CHECK2): Use inline function above instead of __extension__. > (tree_not_check2): New. > (TREE_NOT_CHECK2): Use inline function above instead of __extension__. > (tree_check3): New. > (TREE_CHECK3): Use inline function above instead of __extension__. > (tree_not_check3): New. > (TREE_NOT_CHECK3): Use inline function above instead of __extension__. > (tree_check4): New. > (TREE_CHECK4): Use inline function above instead of __extension__. > (tree_not_check4): New. > (TREE_NOT_CHECK4): Use inline function above instead of __extension__. > (tree_check5): New. > (TREE_CHECK5): Use inline function above instead of __extension__. > (tree_not_check5): New. > (TREE_NOT_CHECK5): Use inline function above instead of __extension__. > (contains_struct_check): New. > (CONTAINS_STRUCT_CHECK): Use inline function above instead of > __extension__. > (tree_class_check): New. > (TREE_CLASS_CHECK): Use inline function above instead of __extension__. > (tree_range_check): New. > (TREE_RANGE_CHECK): Use inline function above instead of __extension__. > (omp_clause_subcode_check): New. > (OMP_CLAUSE_SUBCODE_CHECK): Use inline function above instead of > __extension__. > (omp_clause_range_check): New. > (OMP_CLAUSE_RANGE_CHECK): Use inline function above instead of > __extension__. > (expr_check): New. > (EXPR_CHECK): Use inline function above instead of __extension__. > (non_type_check): New. > (NON_TYPE_CHECK): Use inline function above instead of __extension__. > (tree_vec_elt_check): New. > (TREE_VEC_ELT_CHECK): Use inline function above instead of > __extension__. > (omp_clause_elt_check): New. > (OMP_CLAUSE_ELT_CHECK): Use inline function above instead of > __extension__. > (tree_operand_check): New. > (TREE_OPERAND_CHECK): Use inline function above instead of > __extension__. > (tree_operand_check_code): New. > (TREE_OPERAND_CHECK_CODE): Use inline function above instead of > __extension__. > (TREE_CHAIN): Simplify implementation. > (TREE_TYPE): Simplify implementation. > (tree_operand_length): Move for compilation dependences. > * gdbinit.in: (macro define __FILE__): New. > (macro define __LINE__): New. > (skip "tree.h"): New. > > > Index: gcc/tree.h > === > --- gcc/tree.h (revision 187477) > +++ gcc/tree.h (working copy) > @@ -727,195 +727,80 @@ enum tree_node_structure_enum { > is accessed incorrectly. The macros die with a fatal error. */ > #if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007) > > -#define TREE_CHECK(T, CODE) __extension__ \ > -({ __typeof (T) const __t = (T); \ > - if (TREE_CODE (__t) != (CODE)) \ > - tree_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, \ > -
Re: Turn check macros into functions. (issue6188088)
On 12-05-15 13:19 , Lawrence Crowl wrote: The gcc source uses several constructs that GDB does not understand. This patch corrects some of them. It affects only compilers built with ENABLE_TREE_CHECKING, and hence release compilers are unaffected. In particular, I change the implementation of CHECK macros using __extension__ into macros calling template inline functions. I do not change the accessor macros themselves. I was going to ask you about effects on code size, but I had a clean build tree around so I could do some comparisons. Your patch reduces code size by about 1%. Before the patch: textdata bss dec hex filename 14,576,887 43008 1438432 16058327 f507d7 cc1 15,121,560 52048 1443504 16617112 fd8e98 f951 13,896,410 43760 1434640 15374810 ea99da jc1 13,673,077 42216 1435680 15150973 e72f7d lto1 After the patch: $ size *1 | grep -v libgcc textdata bss dec hex filename 14,390,489 43008 1438432 15871929 f22fb9 cc1 (-1.28%) 14,940,242 52048 1443504 16435794 faca52 f951 (-1.20%) 13,716,108 43760 1434640 15194508 e7d98c jc1 (-1.30%) 13,490,551 42216 1435680 14968447 e4667f lto1 (-1.33%) Clearly, this will only affect binaries built with --enable-checking. But this is a good result anyway. Thanks. Diego.
Re: Turn check macros into functions. (issue6188088)
On May 15, 2012, at 11:23 AM, Steven Bosscher wrote: > On Tue, May 15, 2012 at 7:19 PM, Lawrence Crowl wrote: >> The gcc source uses several constructs that GDB does not understand. >> This patch corrects some of them. It affects only compilers built >> with ENABLE_TREE_CHECKING, and hence release compilers are unaffected. >> Index: gcc/ChangeLog.cxx-conversion > (...) >> >> 2012-05-15 Lawrence Crowl >> > > Is this something you could do for the mainline instead? > > If not, then I hope it will land there some day. I now usually build > my debug compilers with checking disabled to work around this issue.. Gosh, we compile with -g3, and use: macro define TREE_CHECK(T, CODE) (T) macro define TREE_NOT_CHECK(T, CODE) (T) macro define TREE_CHECK2(T, CODE1, CODE2) (T) macro define TREE_NOT_CHECK2(T, CODE1, CODE2) (T) macro define TREE_CHECK3(T, CODE1, CODE2, CODE3) (T) macro define TREE_NOT_CHECK3(T, CODE1, CODE2, CODE3) (T) macro define TREE_CHECK4(T, CODE1, CODE2, CODE3, CODE4) (T) macro define NON_TREE_CHECK4(T, CODE1, CODE2, CODE3, CODE4) (T) macro define TREE_CHECK5(T, CODE1, CODE2, CODE3, CODE4, CODE5) (T) macro define TREE_NOT_CHECK5(T, CODE1, CODE2, CODE3, CODE4, CODE5) (T) macro define CONTAINS_STRUCT_CHECK(T, STRUCT) (T) macro define TREE_CLASS_CHECK(T, CLASS) (T) macro define TREE_RANGE_CHECK(T, CODE1, CODE2) (T) macro define OMP_CLAUSE_SUBCODE_CHECK(T, CODE) (T) macro define OMP_CLAUSE_RANGE_CHECK(T, CODE1, CODE2) (T) macro define EXPR_CHECK(T) (T) macro define NON_TYPE_CHECK(T) (T) macro define TREE_VEC_ELT_CHECK(T, I) ((T)->vec.a[I]) macro define OMP_CLAUSE_ELT_CHECK(T, I) ((T)->omp_clause.ops[I]) macro define TREE_OPERAND_CHECK(T, I) ((T)->exp.operands[I]) macro define TREE_OPERAND_CHECK_CODE(T, CODE, I) ((T)->exp.operands[I]) macro define TREE_CHAIN(T) ((T)->common.chain) macro define TREE_TYPE(T) ((T)->common.type) macro define RTL_FLAG_CHECK1(N, R, C1) (R) macro define RTL_FLAG_CHECK2(N, R, C1, C2) (R) macro define RTL_FLAG_CHECK3(N, R, C1, C2, C3) (R) macro define RTL_FLAG_CHECK4(N, R, C1, C2, C3, C4) (R) macro define RTL_FLAG_CHECK5(N, R, C1, C2, C3, C4, C5) (R) macro define RTL_FLAG_CHECK6(N, R, C1, C2, C3, C4, C5, C6) (R) macro define RTL_FLAG_CHECK7(N, R, C1, C2, C3, C4, C5, C6, C7) (R) macro define RTL_FLAG_CHECK8(N, R, C1, C2, C3, C4, C5, C6, C7, C8) (R) in gdbinit.in. This gets you 99% of the way there. The -g3 is annoying, as the sizes are large, fast machines, nice filesystems and ssd disks or better and help lesson the cost. This gives up checking during gdb usage, I've not found that to be a problem yet. I think this is fine for release branches and older software. For trunk, I do like a _better_ solution, like the first patch in this thread when it can go in. :-)
Re: Turn check macros into functions. (issue6188088)
On 12-05-15 14:23 , Steven Bosscher wrote: On Tue, May 15, 2012 at 7:19 PM, Lawrence Crowl wrote: The gcc source uses several constructs that GDB does not understand. This patch corrects some of them. It affects only compilers built with ENABLE_TREE_CHECKING, and hence release compilers are unaffected. Index: gcc/ChangeLog.cxx-conversion (...) 2012-05-15 Lawrence Crowl Is this something you could do for the mainline instead? The same patch applies to mainline. However, the patch makes use of template functions. So we can't put it in mainline until after mainline switches to C++. This will happen at some point in stage 1, but we agreed to have vec.[ch] converted before that happened. I'm working on the vec conversion, which I hope to have completed soon. Diego.
Re: Turn check macros into functions. (issue6188088)
On Tue, May 15, 2012 at 7:19 PM, Lawrence Crowl wrote: > The gcc source uses several constructs that GDB does not understand. > This patch corrects some of them. It affects only compilers built > with ENABLE_TREE_CHECKING, and hence release compilers are unaffected. > Index: gcc/ChangeLog.cxx-conversion (...) > > 2012-05-15 Lawrence Crowl > Is this something you could do for the mainline instead? If not, then I hope it will land there some day. I now usually build my debug compilers with checking disabled to work around this issue... Ciao! Steven