irange best practices document

2020-09-03 Thread Aldy Hernandez via Gcc
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?

2020-09-03 Thread Erick Ochoa

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?

2020-09-03 Thread Jakub Jelinek via Gcc
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?

2020-09-03 Thread Richard Biener via Gcc
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

2020-09-03 Thread Gary Oblock via Gcc
>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

2020-09-03 Thread Richard Biener via Gcc
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

2020-09-03 Thread Hans-Peter Nilsson
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

2020-09-03 Thread Hans-Peter Nilsson
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

2020-09-03 Thread GCC Administrator via Gcc
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

2020-09-03 Thread 易会战 via Gcc
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

2020-09-03 Thread Gary Oblock via Gcc
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.