irange best practices document
Below is a documented we have drafted to provide guidance on using irange's and converting passes to it. This will future proof any such passes so that they will work with the ranger, or any other mechanism using multiple sub-ranges (as opposed to the more limited value_range). The official document will live here, but is included below for discussion: https://gcc.gnu.org/wiki/irange-best-practices Feel free to respond to this post with any questions or comments. Aldy & Andrew INTRODUCTION irange is a class for storing and manipulating multi-ranges of integers. It is meant to be a replacement for value_range's, and can currently inter-operate seamlessly with them. Original value_range's can contain a range of integers, say from 10 to 20 inclusive, represented as [10, 20]. It also has a way of representing an anti-range, which is the inverse of a range. For example, everything except 10 to 20 is represented as an anti-range of ~[10, 20]. This is really, shorthand for the union of [MIN_INT, 9] U [21, MAX_INT]. The value_range representation has the limitation that higher granularity is not representable without losing precision. For example, you cannot specify the range of [10, 15] U [20, 30], instead it is represented ambiguously with with a range of [10, 30]. On the other hand, multi-ranges with the irange class, can represent an arbitrary number of sub-ranges. More formally, multi-ranges have 0 or more non-intersecting sub-ranges with integral bounds. For example, you can specify a range containing the numbers of [10, 15] and [20, 30] with an irange of [10, 15][20, 30]. With irange, instead of using anti-ranges for ~[10, 20] the underlying number of ranges can be represented accurately with [MIN_INT, 9][21, MAX_INT]. Multi-ranges are not limited to 1 or 2 sub-ranges. Instead, you can specify any number of sub-ranges. For example: int_range<5> five_pairs; int_range<2> two_pairs; int_range<1> legacy_value_range; widest_irange huge_irange; // currently 255 sub-ranges. The special case of int_range<1> provides legacy support for value_range. Currently, value_range is just a typedef for int_range<1>. The specially named widest_irange is used for "unlimited" sub-ranges, and is meant to be used when calculating intermediate results. Currently it is a large number (255), but could be changed without prior notice. Note that "widest" does not have anything to do with the range of the underlying integers, but the maximum amount of sub-range pairs available for calculation. Here are some examples of calculations with different sub-range granularity: // Assume: tree n10 = build_int_cst (integer_type_node, 10); tree n20 = build_int_cst (integer_type_node, 20); tree n30 = build_int_cst (integer_type_node, 30); tree n40 = build_int_cst (integer_type_node, 40); tree n50 = build_int_cst (integer_type_node, 50); tree n60 = build_int_cst (integer_type_node, 60); int_range<1> (aka value_range): int_range<1> r1 (n10, n20); int_range<1> r2 (n30, n40); r1.union_ (r2); r1.dump (); // Outputs: [10, 40] // Note: Since result doesn't fit in an int_range<1>, it is // conservatively truncated. int_range<2>: int_range<2> r1 (n10, n20); int_range<2> r2 (n30, n40); r1.union_ (r2); r1.dump (); // Outputs: [10, 20][30, 40] int_range<2> r3 (n50, n60); r1.union_ (r3); r1.dump (); // Outputs: [10, 20][30, 60] // Note: Unioning [10, 20][30, 40] and [50, 60] doesn't fit // into an int_range<2>, so it is truncated. int_range<1> small; small = r1; // r1 is [10,20][30,60] as above. small.dump (); // Outputs: [10, 60] // Note: Copying a larger range into a smaller range will // result in truncating the result. widest_irange: widest_irange r; for (i = 0; i <= 40; i += 10) { tree low = build_int_cst (integer_type_node, i); tree high = build_int_cst (integer_type_node, i + 1); int_range<2> tmp (low, high); r.union_ (tmp); } r.dump (); // Outputs: [0, 1][10, 11][20, 21][30, 31][40, 41] WRITE YOUR CODE FOR INFINITE SUB-RANGES --- Your code should be agnostic to the sub-ranges there-in. For example, if you wanted to check if the numbers 5 through 10 are in a range R, avoid looking at min/max/kind and having to special case VR_RANGE, VR_ANTI_RANGE, and VR_VARYING. Instead do something like this: widest_irange my_range (build_int_cst (5, integer_type_node), build_int_cst (10, integer_type_node)); my_range.intersect (R); if (R == my_range) return goodness; If on the other hand, if you want to check if there is ANY o
Is there a way to look for a tree by its UID?
I think every SSA_NAME variable has a: * ptr_info_def* * which points to a pt_solution * which points to a bitmap field vars and I think this bitmap vars is set with 1 in the UID location of variables/references that an SSA_NAME variable might point to it. So, I am just wondering is there an interface where I could do something like: ``` // vars is the field in pt_solution of type bitmap EXECUTE_IF_SET_IN_BITMAP (vars, 0, uid, bi) { // uid is set tree pointed_to = get_tree_with_uid(uid); } ``` Thanks!
Re: Is there a way to look for a tree by its UID?
On Thu, Sep 03, 2020 at 10:22:52AM +0200, Erick Ochoa wrote: > So, I am just wondering is there an interface where I could do something > like: > > ``` > // vars is the field in pt_solution of type bitmap > EXECUTE_IF_SET_IN_BITMAP (vars, 0, uid, bi) > { >// uid is set >tree pointed_to = get_tree_with_uid(uid); > } > ``` There is not. Jakub
Re: Is there a way to look for a tree by its UID?
On Thu, Sep 3, 2020 at 10:58 AM Jakub Jelinek via Gcc wrote: > > On Thu, Sep 03, 2020 at 10:22:52AM +0200, Erick Ochoa wrote: > > So, I am just wondering is there an interface where I could do something > > like: > > > > ``` > > // vars is the field in pt_solution of type bitmap > > EXECUTE_IF_SET_IN_BITMAP (vars, 0, uid, bi) > > { > >// uid is set > >tree pointed_to = get_tree_with_uid(uid); > > } > > ``` > > There is not. And there cannot be since the solution includes UIDs of decls that are "fake" and thus never really existed. I think you need to first get a set of candidates you want to transform (to limit the work done below), then use the internal points-to solutions and compute alias sets for this set plus the points-to solution this alias-set aliases. You can then keep the candidate -> alias-set ID -> points-to relation (thus candidates should not be "all variables" for efficiency reasons). Richard. > Jakub >
Re: Types are confused in inlining
>This is absolutely not enough information to guess at the >issue ;) That's fair, I was hoping some mad genius out there would confess to a fubar_adjustment phase that was probably at fault. 😉 >I suggest you break at the return stmt of make_ssa_name_fn >looking for t->base.u.version == 101 to see where and with >which type _101 is created, from there watch *&t->typed.type >in case something adjusts the type. I did the former but I used ssa_name_nodes_created instead. Which though harder to get at, is unique. Regarding the later... I guess... But, at various times (on certain OS versions of certain machines) watch points have been at bit dubious. I assume on a recent Ubuntu release on an Intel I7 core this wouldn't be the case??? Thanks, Gary From: Richard Biener Sent: Wednesday, September 2, 2020 11:31 PM To: Gary Oblock Cc: gcc@gcc.gnu.org Subject: Re: Types are confused in inlining [EXTERNAL EMAIL NOTICE: This email originated from an external sender. Please be mindful of safe email handling and proprietary information protection practices.] On Wed, Sep 2, 2020 at 10:19 PM Gary Oblock via Gcc wrote: > > I'm not accusing inlining of having problems but I really > need to understand what's going on in this situation so I can > fix my optimization. > > The error given is: > main.c: In function ‘main’: > main.c:5:1: error: non-trivial conversion in ‘ssa_name’ > 5 | main(void) > | ^ > struct type_t * > unsigned long > _101 = dedangled_97; > during GIMPLE pass: fixup_cfg > etc. > etc. > > I put a conditional breakpoint in gdb where both > _101 and dedangled_97 were created and low > and behold they were both set to "unsigned long". > Does anybody have a clue as to how "_101" got > changed from "unsigned long" to "struct type_t *"? > Note, the later is a meaningful type in my program. > I'm trying to replace all instances of the former as > part of structure reorganization optimization.) I should > mention that this GIMPLE stmt is the one that moves > the value computed in an inlined function into the body > of code where the inling took place. This is absolutely not enough information to guess at the issue ;) I suggest you break at the return stmt of make_ssa_name_fn looking for t->base.u.version == 101 to see where and with which type _101 is created, from there watch *&t->typed.type in case something adjusts the type. > Thanks, > > Gary Oblock > > > > > > CONFIDENTIALITY NOTICE: This e-mail message, including any attachments, is > for the sole use of the intended recipient(s) and contains information that > is confidential and proprietary to Ampere Computing or its subsidiaries. It > is to be used solely for the purpose of furthering the parties' business > relationship. Any unauthorized review, copying, or distribution of this email > (or any attachments thereto) is strictly prohibited. If you are not the > intended recipient, please contact the sender immediately and permanently > delete the original and any copies of this email and any attachments thereto.
Re: Types are confused in inlining
On September 3, 2020 7:59:12 PM GMT+02:00, Gary Oblock wrote: >>This is absolutely not enough information to guess at the >>issue ;) > >That's fair, I was hoping some mad genius out there would confess to a >fubar_adjustment phase that was probably at fault. 😉 Ah, well. It's probably your own code that is at fault ;) >>I suggest you break at the return stmt of make_ssa_name_fn >>looking for t->base.u.version == 101 to see where and with >>which type _101 is created, from there watch *&t->typed.type >>in case something adjusts the type. > >I did the former but I used ssa_name_nodes_created >instead. Which though harder to get at, is unique. >Regarding the later... I guess... But, at various times (on certain >OS versions of certain machines) watch points have been >at bit dubious. I assume on a recent Ubuntu release >on an Intel I7 core this wouldn't be the case??? I never had an issue with watch points. Richard. >Thanks, > >Gary > >From: Richard Biener >Sent: Wednesday, September 2, 2020 11:31 PM >To: Gary Oblock >Cc: gcc@gcc.gnu.org >Subject: Re: Types are confused in inlining > >[EXTERNAL EMAIL NOTICE: This email originated from an external sender. >Please be mindful of safe email handling and proprietary information >protection practices.] > > >On Wed, Sep 2, 2020 at 10:19 PM Gary Oblock via Gcc >wrote: >> >> I'm not accusing inlining of having problems but I really >> need to understand what's going on in this situation so I can >> fix my optimization. >> >> The error given is: >> main.c: In function ‘main’: >> main.c:5:1: error: non-trivial conversion in ‘ssa_name’ >> 5 | main(void) >> | ^ >> struct type_t * >> unsigned long >> _101 = dedangled_97; >> during GIMPLE pass: fixup_cfg >> etc. >> etc. >> >> I put a conditional breakpoint in gdb where both >> _101 and dedangled_97 were created and low >> and behold they were both set to "unsigned long". >> Does anybody have a clue as to how "_101" got >> changed from "unsigned long" to "struct type_t *"? >> Note, the later is a meaningful type in my program. >> I'm trying to replace all instances of the former as >> part of structure reorganization optimization.) I should >> mention that this GIMPLE stmt is the one that moves >> the value computed in an inlined function into the body >> of code where the inling took place. > >This is absolutely not enough information to guess at the >issue ;) > >I suggest you break at the return stmt of make_ssa_name_fn >looking for t->base.u.version == 101 to see where and with >which type _101 is created, from there watch *&t->typed.type >in case something adjusts the type. > >> Thanks, >> >> Gary Oblock >> >> >> >> >> >> CONFIDENTIALITY NOTICE: This e-mail message, including any >attachments, is for the sole use of the intended recipient(s) and >contains information that is confidential and proprietary to Ampere >Computing or its subsidiaries. It is to be used solely for the purpose >of furthering the parties' business relationship. Any unauthorized >review, copying, or distribution of this email (or any attachments >thereto) is strictly prohibited. If you are not the intended recipient, >please contact the sender immediately and permanently delete the >original and any copies of this email and any attachments thereto.
Re: #line directives in generated C files
On Thu, 27 Aug 2020, Pip Cet via Gcc wrote: > I may be missing an obvious workaround, but it seems we currently emit > a #line directive when including lines from machine description files > in C files, but never emit a second directive when switching back to > the generated C file. This makes stepping through the backend in gdb > somewhat painful, because gdb thinks it should display lines from the > md file even after leaving the included fragment. > > The attached patch is a proof of concept which unconditionally emits a > line containing "/* #unline */" after such fragments, and runs all > generated C files through a trivial filter which replaces those lines > by #line directives pointing back to the original file. It appears to > work. Thanks for taking on this! I hope you and/or Richard Sandiford get this wart fixed. I confess I usually hack read-md.c to not emit the #line directive whenever I actually need to step into the md-generated code, and though it's crossed my mind I never got around to try emitting a "closing" #line directive. :-/ IMHO stepping into the .md really isn't helpful. Even a pattern name in a comment in the generated code would be better. brgds, H-P
Re: #line directives in generated C files
On Thu, 3 Sep 2020, Hans-Peter Nilsson wrote: > IMHO stepping into the .md really isn't helpful. Even a pattern > name in a comment in the generated code would be better. ...and JFTR, yes I noticed there is, or rather line indicator for example /path/to/mmix.md:211 above gen_adddi3 in insn-emit.c. brgds, H-P
gcc-8-20200903 is now available
Snapshot gcc-8-20200903 is now available on https://gcc.gnu.org/pub/gcc/snapshots/8-20200903/ and on various mirrors, see http://gcc.gnu.org/mirrors.html for details. This snapshot has been generated from the GCC 8 git branch with the following options: git://gcc.gnu.org/git/gcc.git branch releases/gcc-8 revision eeb970e1ca1685f90b10f61566ad497d0c991837 You'll find: gcc-8-20200903.tar.xzComplete GCC SHA256=263e5a5a9dda7882d15790ed9b8753f085b909dddbd18ead2913ed9772d5112a SHA1=f6ecd62d1450bac3e9ea1c4359872a3a2c9e982b Diffs from 8-20200827 are available in the diffs/ subdirectory. When a particular snapshot is ready for public consumption the LATEST-8 link is updated and a message is sent to the gcc list. Please do not use a snapshot before it has been announced that way.
about souce code location
I am working a instrumention tool, and need get the location info for a gimple statement. I use the location structure to get the info, and it can work when i use -O1. When I use -O2, sometimes the info seems to be lost and I get line num is zero. anyone can tell me how to get the info?
A silly question regarding function types
Note, isn't a problem, rather, it's something that puzzles me. On walking a function types argument types this way for ( arg = TYPE_ARG_TYPES ( func_type); arg != NULL; arg = TREE_CHAIN ( arg)) { . . } I noticed an extra void argument that didn't exist tagged on the end. I then noticed other code doing this (which I copied:) for ( arg = TYPE_ARG_TYPES ( func_type); arg != NULL && arg != void_list_node; arg = TREE_CHAIN ( arg)) { . . } What is going on here??? Thanks, Gary CONFIDENTIALITY NOTICE: This e-mail message, including any attachments, is for the sole use of the intended recipient(s) and contains information that is confidential and proprietary to Ampere Computing or its subsidiaries. It is to be used solely for the purpose of furthering the parties' business relationship. Any unauthorized review, copying, or distribution of this email (or any attachments thereto) is strictly prohibited. If you are not the intended recipient, please contact the sender immediately and permanently delete the original and any copies of this email and any attachments thereto.