Re: Passing the complex args in the GPR's

2023-06-07 Thread Michael Matz via Gcc
Hey,

On Tue, 6 Jun 2023, Umesh Kalappa via Gcc wrote:

> Question is : Why does GCC choose to use GPR's here and have any
> reference to support this decision  ?

You explicitely used -m32 ppc, so 
https://www.polyomino.org.uk/publications/2011/Power-Arch-32-bit-ABI-supp-1.0-Unified.pdf
 
applies.  It explicitely states in "B.1 ATR-Linux Inclusion and 
Conformance" that it is "ATR-PASS-COMPLEX-IN-GPRS", and other sections 
detail what that means (namely passing complex args in r3 .. r10, whatever 
fits).  GCC adheres to that, and has to.

The history how that came to be was explained in the thread.


Ciao,
Michael.

 > 
> Thank you
> ~Umesh
> 
> 
> 
> On Tue, Jun 6, 2023 at 10:16 PM Segher Boessenkool
>  wrote:
> >
> > Hi!
> >
> > On Tue, Jun 06, 2023 at 08:35:22PM +0530, Umesh Kalappa wrote:
> > > Hi Adnrew,
> > > Thank you for the quick response and for PPC64 too ,we do have
> > > mismatches in ABI b/w complex operations like
> > > https://godbolt.org/z/bjsYovx4c .
> > >
> > > Any reason why GCC chose to use GPR 's here ?
> >
> > What did you expect, what happened instead?  Why did you expect that,
> > and why then is it an error what did happen?
> >
> > You used -O0.  As long as the code works, all is fine.  But unoptimised
> > code frequently is hard to read, please use -O2 instead?
> >
> > As Andrew says, why did you use -m32 for GCC but -m64 for LLVM?  It is
> > hard to compare those at all!  32-bit PowerPC Linux ABI (based on 32-bit
> > PowerPC ELF ABI from 1995, BE version) vs. 64-bit ELFv2 ABI from 2015
> > (LE version).
> >
> >
> > Segher
> 


[OpenACC] cheking the status of AMD GPU offloading performance

2023-06-07 Thread Chang Liu via Gcc

Hi everyone,

I have a general question regarding the GPU offloading support on AMD 
GPUs using OpenACC or OpenMP. I am doing some tests by compiling the new 
version of GCC (13 and 14), following the instructions online 
(https://gcc.gnu.org/wiki/Offloading#How_to_try_offloading_enabled_GCC).


I finally got the GPU offloading to work, but a simple test Fortran 
program doing matrix multiplication shows that the performance on a 
gfx90a device is 10 times slower than that of AMD AOMP LLVM compiled 
version.


I wonder if this is normal? and the performance on AMD GPU is still 
lagging behind other compilers?


I also want to try the og13 development branch, but got a lot of 
compilation error when building gcc. Do I need to use a newer version of 
gcc to compile it (I am using gcc 7.5 now)?


Thanks.

Chang


About addition of .symtab and .strtab sections in simple-object-elf.c

2023-06-07 Thread Rishi Raj via Gcc
Hi Everyone,
I am working on the GSOC project "Bypass Assembler when generating LTO
object files." My mentors and I have decided to work on the ELF files
first, so I will add .symtab along with the symbol __gnu_lto_slim to
the ELF file as a first step.
When I was going through the simple-object-elf.c:
simple_object_elf_write_to_file() I found out that it writes the
following:
/* Write out a complete ELF file.
   Ehdr
   initial dummy Shdr
   user-created Shdrs
   .shstrtab Shdr
   user-created section data
   .shstrtab data  */
and .symtab is missing here. To add the missing symtab I have thought
of these two possible implementations.
1) Add it in simple-object-elf.c (based on -fbypass-asm flag).
2) We can add .symtab section in lto-object.cc along with other LTO sections.
I am a bit skeptical about the second one as .symtab with other lto
sections might be confusing. Any comments regarding which one should I
proceed with will be helpful.
--
Thanks & Regards
Rishi Raj


When do I need -fnon-call-exceptions?

2023-06-07 Thread Helmut Zeisel via Gcc
I wrote some simple program that set a signal handler for SIGFPE, throws a C++ 
exception in the signal handler
and catches the exception.
I compiled with and without -fnon-call-exceptions (on x64 Linux).
In both cases, the result was the same: the exception was caught and the 
destructors were called as expected.
I also tried "-fno-non-call-exceptions -fexceptions" and got the same result.

My question: when do I really need -fnon-call-exceptions?
Is there some simple program where I can see the difference whether it is on or 
off??

Helmut



An overview of the analyzer support of the operator new

2023-06-07 Thread Benjamin Priour via Gcc
Hi,

I've been mapping where the analyzer is lacking support of the operator new
different variants.
I've written a bunch of test cases already to demonstrate it, you can find
them below.
They are not yet formatted for a patch submission, and as some of them may
require new warnings, I didn't use dg-* directives either.
You will notice I included true positives and negatives as well, as I think
they might spur ideas on some edge cases that may fail.
All that to say I would greatly appreciate your comments if any test is
wrong, or if you have pointers on additional test cases.
You can also find a godbolt  here.

The most annoying one is the recurrent noisy false positive
-Wanalyzer-possible-null-argument on usage of a new expression.
Although a placement new on a static buffer too short is flagged by the
middle-end, the analyzer stay quiet.
A placement on a dynamic buffer too short to contain the placement is never
reported however. See PR105948


Thanks,
Benjamin

#include 

struct A
{
int x = 4;
int y = 6;
};

void test1()
{
int *x = ::new int; // true negative on -Wanalyzer-possible-null-argument
int *arr = ::new int[3]; // true negative on
-Wanalyzer-possible-null-argument
A *a = ::new A(); // false positive -Wanalyzer-possible-null-argument (a
throwing new cannot returns null)
::delete a;
::delete x;
::delete[] arr;
}

void test_allocators_mismatch()
{
int *a = ::new int;
int *b = ::new int[3];

::delete[] a; /* true positive -Wanalyzer-mismatching-deallocation flagged
*/
::delete b; /* true positive -Wanalyzer-mismatching-deallocation flagged */
}

// From clang core.uninitialized.NewArraySize
void test_garbage_new_array()
{
int n;
int *arr = ::new int[n]; /* true positive
-Wanalyzer-use-of-uninitialized-value reported for 'n' */
/* however nothing is reported for 'arr', even with
'-fno-analyzer-suppress-followups', one could expect a specific warning */
::delete[] arr; /* no warnings here either */
}

void test_placement()
{
void *chunk = ::operator new(20); // true negative
-Wanalyzer-possible-null-dereference
A *a = ::new (chunk) A();
a->~A();
::operator delete(chunk);
}

void test_delete_placement()
{
A *a = ::new A; // false positive -Wanalyzer-possible-null-argument
(throwing new)
int *z = ::new (&a->y) int;
a->~A(); // deconstruct properly
::operator delete(a);
::operator delete(z); // nothing from analyzer but got
-Wfree-nonheap-object, even though analyzer also has
Wanalyzer-free-of-non-heap
}

void test_write_placement_after_delete()
{
short *s = ::new short;
long *lp = ::new (s) long;
::delete s;
*lp = 12; // true positive -Wanalyzer-use-after-free flagged, as well as a
wrong -Wanalyzer-null-dereference of lp
}

void test_read_placement_after_delete()
{
short *s = ::new short;
long *lp = ::new (s) long;
::delete s;
long m = *lp; // true positive -Wanalyzer-use-after-free flagged, as well
as a wrong -Wanalyzer-null-dereference of lp
}

void test_use_placement_after_destruction()
{
A a;
int *lp = ::new (&a.y) int;
a.~A();
int m = *lp; /* true positive -Wanalyzer-use-of-uninitialized-value,
nothing about use-after-delete though */
}

// From clang cplusplus.PlacementNewChecker
void test_placement_size_static()
{
short s;
long *lp = ::new (&s) long; /* nothing from analyzer, but still got
-Wplacement-new= */
}

void test_placement_size_dynamic()
{
short *s = ::new short;
long *lp = ::new (s) long; // Nothing reported here at all, would expect a
-Wanalyzer-placement-new=
::delete s;
}

void test_placement_null()
{
int *x = nullptr;
int *p = ::new (x) int; // Placement new on NULL is undefined, yet nothing
is reported.
::operator delete(x);
}

void test_initialization_through_placement()
{
int x;
int *p = ::new (&x) int;
*p = 10;
int z = x + 2; // Everything is fine, no warning emitted
}


Re: When do I need -fnon-call-exceptions?

2023-06-07 Thread Ian Lance Taylor via Gcc
On Wed, Jun 7, 2023 at 10:09 AM Helmut Zeisel via Gcc  wrote:
>
> I wrote some simple program that set a signal handler for SIGFPE, throws a 
> C++ exception in the signal handler
> and catches the exception.
> I compiled with and without -fnon-call-exceptions (on x64 Linux).
> In both cases, the result was the same: the exception was caught and the 
> destructors were called as expected.
> I also tried "-fno-non-call-exceptions -fexceptions" and got the same result.
>
> My question: when do I really need -fnon-call-exceptions?
> Is there some simple program where I can see the difference whether it is on 
> or off??

On x864 Linux -fasynchronous-unwind-tables is the default.  That is
probably sufficient to make your test case work.

Ian


Re: When do I need -fnon-call-exceptions?

2023-06-07 Thread Eric Botcazou via Gcc
> On x864 Linux -fasynchronous-unwind-tables is the default.  That is
> probably sufficient to make your test case work.

The testcase g++.dg/torture/except-1.C you recently added to the testsuite 
does not pass at all if -fnon-call-exceptions is not specified (and does not 
pass with optimization if -fno-delete-dead-exceptions is not specified).

-- 
Eric Botcazou




On inform diagnostics in plugins, support scripts for gdb and modeling creation of PyObjects for static analysis

2023-06-07 Thread Eric Feng via Gcc
Hi everyone,

I am one of the GSoC participants this year — in particular, I am
working on a static analyzer plugin for CPython extension module code.
I'm encountering a few challenges and would appreciate any guidance on
the following issues:

1) Issue with "inform" diagnostics in the plugin:
I am currently unable to see any "inform" messages from my plugin when
compiling test programs with the plugin enabled. As per the structure
of existing analyzer plugins, I have included the following code in
the plugin_init function:

#if ENABLE_ANALYZER
const char *plugin_name = plugin_info->base_name;
if (0)
inform(input_location, "got here; %qs", plugin_name);
register_callback(plugin_info->base_name,
  PLUGIN_ANALYZER_INIT,
  ana::cpython_analyzer_init_cb,
  NULL);
#else
sorry_no_analyzer();
#endif
return 0;

I expected to see the "got here" message (among others in other areas
of the plugin) when compiling test programs but haven't observed any
output. I also did not observe the "sorry" diagnostic. I am compiling
a simple CPython extension module with the plugin loaded like so:

gcc-dev -S -fanalyzer -fplugin=/path/to/cpython_plugin.so
-I/usr/include/python3.9 -lpython3.9 -x c refcount6.c

Additionally, I compiled the plugin following the steps outlined in
the GCC documentation for plugin building
(https://gcc.gnu.org/onlinedocs/gccint/Plugins-building.html):

g++-dev -shared -I/home/flappy/gcc_/gcc/gcc
-I/usr/local/lib/gcc/aarch64-unknown-linux-gnu/14.0.0/plugin/include
-fPIC -fno-rtti -O2 analyzer_cpython_plugin.c -o cpython_plugin.so

Please let me know if I missed any steps or if there is something else
I should consider. I have no trouble seeing inform calls when they are
added to the core GCC.

2) gdb not detecting .gdbinit in build/gcc:
Following Dave's GCC newbies guide, I ran gcc/configure within the gcc
subdirectory of the build directory to generate a .gdbinit file.
Dave's guide suggested that this file would be automatically detected
and run by gdb. However, it appears that GDB is not detecting this
.gdbinit file, even after I added the following line to my ~/.gdbinit
file:

add-auto-load-safe-path /absolute/path/to/build/gcc

3) Modeling creation of a new PyObject:
Many CPython API calls involve the creation of a new PyObject. To
model the creation of a simple PyObject, we can allocate a new heap
region using get_or_create_region_for_heap_alloc. We can then create
field_regions using get_field_region to associate the newly allocated
region to represent fields such as ob_refcnt and ob_type in the
PyObject struct. However, one of the parameters to get _field_region
is a tree representing the field (e.g ob_refcnt). I'm currently
wondering how we may retrieve this information. My intuition is that
it would be fairly easy if we can first get a tree representation of
the PyObject struct. Since we include the relevant headers when
compiling CPython extension modules (e.g., -I/usr/include/python3.9),
I wonder if there is a way to "look up" the tree representation of
PyObject from the included headers. This information may also be
important for obtaining a svalue representing the size of the PyObject
in get_or_create_region_for_heap_alloc. If there is no way to "look
up" a tree representation of PyObject as described in the included
Python header files, does it make sense for us to just create a tree
representation manually for this task? Please let me know if this
approach makes sense and if so where I could look into to get the
required information.

Thanks all.

Best,
Eric


Re: On inform diagnostics in plugins, support scripts for gdb and modeling creation of PyObjects for static analysis

2023-06-07 Thread David Malcolm via Gcc
On Wed, 2023-06-07 at 16:21 -0400, Eric Feng wrote:
> Hi everyone,
> 
> I am one of the GSoC participants this year — in particular, I am
> working on a static analyzer plugin for CPython extension module
> code.
> I'm encountering a few challenges and would appreciate any guidance
> on
> the following issues:
> 
> 1) Issue with "inform" diagnostics in the plugin:
> I am currently unable to see any "inform" messages from my plugin
> when
> compiling test programs with the plugin enabled. As per the structure
> of existing analyzer plugins, I have included the following code in
> the plugin_init function:
> 
> #if ENABLE_ANALYZER
>     const char *plugin_name = plugin_info->base_name;
>     if (0)
>     inform(input_location, "got here; %qs", plugin_name);

If that's the code, does it work if you get rid of the "if (0)"
conditional, or change it to "if (1)"?  As written, that guard is
false, so that call to "inform" will never be executed.

>     register_callback(plugin_info->base_name,
>   PLUGIN_ANALYZER_INIT,
>   ana::cpython_analyzer_init_cb,
>   NULL);
> #else
>     sorry_no_analyzer();
> #endif
>     return 0;
> 
> I expected to see the "got here" message (among others in other areas
> of the plugin) when compiling test programs but haven't observed any
> output. I also did not observe the "sorry" diagnostic. I am compiling
> a simple CPython extension module with the plugin loaded like so:
> 
> gcc-dev -S -fanalyzer -fplugin=/path/to/cpython_plugin.so
> -I/usr/include/python3.9 -lpython3.9 -x c refcount6.c

Looks reasonable.

> 
> Additionally, I compiled the plugin following the steps outlined in
> the GCC documentation for plugin building
> (https://gcc.gnu.org/onlinedocs/gccint/Plugins-building.html):
> 
> g++-dev -shared -I/home/flappy/gcc_/gcc/gcc
> -I/usr/local/lib/gcc/aarch64-unknown-linux-gnu/14.0.0/plugin/include
> -fPIC -fno-rtti -O2 analyzer_cpython_plugin.c -o cpython_plugin.so
> 
> Please let me know if I missed any steps or if there is something
> else
> I should consider. I have no trouble seeing inform calls when they
> are
> added to the core GCC.
> 
> 2) gdb not detecting .gdbinit in build/gcc:
> Following Dave's GCC newbies guide, I ran gcc/configure within the
> gcc
> subdirectory of the build directory to generate a .gdbinit file.
> Dave's guide suggested that this file would be automatically detected
> and run by gdb. However, it appears that GDB is not detecting this
> .gdbinit file, even after I added the following line to my ~/.gdbinit
> file:
> 
> add-auto-load-safe-path /absolute/path/to/build/gcc

Are you invoking gcc from an installed copy, or from the build
directory?  I think my instructions assume the latter.

> 
> 3) Modeling creation of a new PyObject:
> Many CPython API calls involve the creation of a new PyObject. To
> model the creation of a simple PyObject, we can allocate a new heap
> region using get_or_create_region_for_heap_alloc. We can then create
> field_regions using get_field_region to associate the newly allocated
> region to represent fields such as ob_refcnt and ob_type in the
> PyObject struct. However, one of the parameters to get _field_region
> is a tree representing the field (e.g ob_refcnt). I'm currently
> wondering how we may retrieve this information. My intuition is that
> it would be fairly easy if we can first get a tree representation of
> the PyObject struct. Since we include the relevant headers when
> compiling CPython extension modules (e.g., -I/usr/include/python3.9),
> I wonder if there is a way to "look up" the tree representation of
> PyObject from the included headers. This information may also be
> important for obtaining a svalue representing the size of the
> PyObject
> in get_or_create_region_for_heap_alloc. If there is no way to "look
> up" a tree representation of PyObject as described in the included
> Python header files, does it make sense for us to just create a tree
> representation manually for this task? Please let me know if this
> approach makes sense and if so where I could look into to get the
> required information.

Don't attempt to build the struct by hand; we want to look up the
struct from the user's headers.  There are at least two ABIs for
PyObject, so we want to be sure we're using the correct one.

IIRC, to look things up by name, that's generally a frontend thing,
since every language has its own concept of scopes/namespaces/etc.

It sounds like you want to look for a type in the global scope of the
C/C++ FE with the name "PyObject".

We currently have some hooks in the analyzer for getting constants from
the frontends; see analyzer-language.cc, where the frontend calls
on_finish_translation_unit, where the analyzer queries the FE for the
named constants that will be of interest during analysis.  Maybe we can
extend this so that we have a way to look up named types there, and
stash the tree for later use, and thus your plugin could ask the

Re: An overview of the analyzer support of the operator new

2023-06-07 Thread David Malcolm via Gcc
On Wed, 2023-06-07 at 19:19 +0200, Benjamin Priour wrote:
> Hi,
> 
> I've been mapping where the analyzer is lacking support of the
> operator new
> different variants.
> I've written a bunch of test cases already to demonstrate it, you can
> find
> them below.
> They are not yet formatted for a patch submission, and as some of
> them may
> require new warnings, I didn't use dg-* directives either.

You can always mark the dg-directives with "xfail" and a comment if the
warning isn't implemented yet.

> You will notice I included true positives and negatives as well, as I
> think
> they might spur ideas on some edge cases that may fail.
> All that to say I would greatly appreciate your comments if any test
> is
> wrong, or if you have pointers on additional test cases.

Looks great.

Note that the results might be affected by exceptions; do any results
change for -fexceptions versus -fno-exceptions?

> You can also find a godbolt  here.
> 
> The most annoying one is the recurrent noisy false positive
> -Wanalyzer-possible-null-argument on usage of a new expression.
> Although a placement new on a static buffer too short is flagged by
> the
> middle-end, the analyzer stay quiet.
> A placement on a dynamic buffer too short to contain the placement is
> never
> reported however. See PR105948
> 

Yeah; looks like that will need some extra code in the analyzer to
implement; you can ask the region_model what the capacity of the region
is; do you have access to the required size of the region at the
placement new call?  If so then the implementation should be very
similar as -Wanalyzer-out-of-bounds (or reuse it?)

Dave

> 
> Thanks,
> Benjamin
> 
> #include 
> 
> struct A
> {
> int x = 4;
> int y = 6;
> };
> 
> void test1()
> {
> int *x = ::new int; // true negative on -Wanalyzer-possible-null-
> argument
> int *arr = ::new int[3]; // true negative on
> -Wanalyzer-possible-null-argument
> A *a = ::new A(); // false positive -Wanalyzer-possible-null-argument
> (a
> throwing new cannot returns null)
> ::delete a;
> ::delete x;
> ::delete[] arr;
> }
> 
> void test_allocators_mismatch()
> {
> int *a = ::new int;
> int *b = ::new int[3];
> 
> ::delete[] a; /* true positive -Wanalyzer-mismatching-deallocation
> flagged
> */
> ::delete b; /* true positive -Wanalyzer-mismatching-deallocation
> flagged */
> }
> 
> // From clang core.uninitialized.NewArraySize
> void test_garbage_new_array()
> {
> int n;
> int *arr = ::new int[n]; /* true positive
> -Wanalyzer-use-of-uninitialized-value reported for 'n' */
> /* however nothing is reported for 'arr', even with
> '-fno-analyzer-suppress-followups', one could expect a specific
> warning */
> ::delete[] arr; /* no warnings here either */
> }
> 
> void test_placement()
> {
> void *chunk = ::operator new(20); // true negative
> -Wanalyzer-possible-null-dereference
> A *a = ::new (chunk) A();
> a->~A();
> ::operator delete(chunk);
> }
> 
> void test_delete_placement()
> {
> A *a = ::new A; // false positive -Wanalyzer-possible-null-argument
> (throwing new)
> int *z = ::new (&a->y) int;
> a->~A(); // deconstruct properly
> ::operator delete(a);
> ::operator delete(z); // nothing from analyzer but got
> -Wfree-nonheap-object, even though analyzer also has
> Wanalyzer-free-of-non-heap
> }
> 
> void test_write_placement_after_delete()
> {
> short *s = ::new short;
> long *lp = ::new (s) long;
> ::delete s;
> *lp = 12; // true positive -Wanalyzer-use-after-free flagged, as well
> as a
> wrong -Wanalyzer-null-dereference of lp
> }
> 
> void test_read_placement_after_delete()
> {
> short *s = ::new short;
> long *lp = ::new (s) long;
> ::delete s;
> long m = *lp; // true positive -Wanalyzer-use-after-free flagged, as
> well
> as a wrong -Wanalyzer-null-dereference of lp
> }
> 
> void test_use_placement_after_destruction()
> {
> A a;
> int *lp = ::new (&a.y) int;
> a.~A();
> int m = *lp; /* true positive -Wanalyzer-use-of-uninitialized-value,
> nothing about use-after-delete though */
> }
> 
> // From clang cplusplus.PlacementNewChecker
> void test_placement_size_static()
> {
> short s;
> long *lp = ::new (&s) long; /* nothing from analyzer, but still got
> -Wplacement-new= */
> }
> 
> void test_placement_size_dynamic()
> {
> short *s = ::new short;
> long *lp = ::new (s) long; // Nothing reported here at all, would
> expect a
> -Wanalyzer-placement-new=
> ::delete s;
> }
> 
> void test_placement_null()
> {
> int *x = nullptr;
> int *p = ::new (x) int; // Placement new on NULL is undefined, yet
> nothing
> is reported.
> ::operator delete(x);
> }
> 
> void test_initialization_through_placement()
> {
> int x;
> int *p = ::new (&x) int;
> *p = 10;
> int z = x + 2; // Everything is fine, no warning emitted
> }



gcc-10-20230607 is now available

2023-06-07 Thread GCC Administrator via Gcc
Snapshot gcc-10-20230607 is now available on
  https://gcc.gnu.org/pub/gcc/snapshots/10-20230607/
and on various mirrors, see http://gcc.gnu.org/mirrors.html for details.

This snapshot has been generated from the GCC 10 git branch
with the following options: git://gcc.gnu.org/git/gcc.git branch 
releases/gcc-10 revision 27d409610fa67b6c296ef29c4585e699a4e32414

You'll find:

 gcc-10-20230607.tar.xz   Complete GCC

  SHA256=06103cc3251daff66de5df74a31f41bca3ceccc7548a9bedaeddd00b86d209d7
  SHA1=69792cbf3a6daaa3d805f32d22308ca23cd654cd

Diffs from 10-20230531 are available in the diffs/ subdirectory.

When a particular snapshot is ready for public consumption the LATEST-10
link is updated and a message is sent to the gcc list.  Please do not use
a snapshot before it has been announced that way.


Re: Followup on PR/109279: large constants on RISCV

2023-06-07 Thread Jeff Law via Gcc




On 6/1/23 20:38, Vineet Gupta wrote:

Hi Jeff,

I finally got around to collecting various observations on PR/109279 - 
more importantly the state of large constants in RV backend, apologies 
in advance for the long email.


It seems the various commits in area have improved the original test 
case of 0x1010101_01010101


   Before 2e886eef7f2b  |   With 2e886eef7f2b   | With 
0530254413f8 | With c104ef4b5eb1
Right.  The handling of that constant shows a nice progression.  On our 
architecture the latter two versions are probably equivalent from a 
latency standpoint, but the last is obviously best as it's smaller and 
probably better on in-order architectures as well.





But same commits seem to have regressed Andrew's test from same PR 
(which is the theme of this email).

The seemingly contrived test turned out to be much more than I'd hoped for.

    long long f(void)
    {
  unsigned t = 0x101_0101;
  long long t1 = t;
  long long t2 = ((unsigned long long )t) << 32;
  asm("":"+r"(t1));
  return t1 | t2;
    }

[ ... ]
It may be more instructions, but I suspect they end up being the same 
performance for us across all three varaints.  Fusion and out-of-order 
execution save the day.  But I realize there may be targets where the 
first is going to be preferred.






   Before 2e886eef7f2b  |   With 2e886eef7f2b    | With 0530254413f8
     (ideal code)   | define_insn_and_split  | "splitter relaxed new
    |    |  pseudos"
    li   a0,0x101   |    li   a5,0x101   |    li a0,0x101_
    addi a0,a0,0x101    |    addi a5,a5,0x101    |    addi a0,a0,0x101
    slli a5,a0,32   |    mv   a0,a5  |    li a5,0x101_
    or   a0,a0,a5   |    slli a5,a5,32   |    slli a0,a0,32
    ret |    or   a0,a0,a5   |    addi a5,a5,0x101
    |    ret |    or   a0,a5,a0
     |    ret

As a baseline, RTL just before cse1 (in 260r.dfinit) in all of above is:

[ ... ]
Right. Standard looking synthesis.





Prior to 2e886eef7f2b, cse1 could do its job: finding oldest equivalent 
registers for the fragments of const and reusing the reg.

Right.  That's what I would expect.

[ ... ]




With 2e886eef7f2b, define_insn_and_split "*mvconst_internal" recog() 
kicks in during cse1, eliding insns for a const_int.


    (insn 7 6 8 2 (set (reg:DI 137)
     (const_int [0x1010101])) {*mvconst_internal}
     (expr_list:REG_EQUAL (const_int [0x1010101])))
    [...]

    (insn 11 10 12 2 (set (reg:DI 140)
     (const_int [0x1010101_])) {*mvconst_internal}
     (expr_list:REG_EQUAL (const_int  [0x1010101_]) ))
Understood.  Not ideal, but we generally don't have good ways to limit 
patterns to being available at different times during the optimization 
phase.  One thing you might want to try (which I thought we used at one 
point) was make the pattern conditional on cse_not_expected.  The goal 
would be to avoid exposing the pattern until a later point in the 
optimizer pipeline.  It may have been the case that we dropped that over 
time during development.  It's all getting fuzzy at this point.




Eventually split1 breaks it up using same mvconst_internal splitter, but 
the cse opportunity has been lost.
Right.  I'd have to look at the pass definitions, but I suspect the 
splitting pass where this happens is after the last standard CSE pass. 
So we don't get a chance to CSE the constant synthesis.



*This is a now a baseline for large consts handling for RV backend which 
we all need to be aware of*.
Understood.  Though it's not as bad as you might think :-)  You can 
spend an inordinate amount of time improving constant synthesis, 
generate code that looks really good, but in the end it may not make a 
bit of different in real performance.  Been there, done that.  I'm not 
saying we give up, but we need to keep in mind that we're often better 
off trading a bit on the constant synthesis if doing so helps code where 
those constants get used.






(2) Now on to the nuances as to why things get progressively worse after 
commit 0530254413f8.


It all seems to get down to register allocation passes:

sched1 before 0530254413f8

    ;; 0--> b  0: i  22 r140=0x101    :alu
    ;; 1--> b  0: i  20 r137=0x101    :alu
    ;; 2--> b  0: i  23 r140=r140+0x101   :alu
    ;; 3--> b  0: i  21 r137=r137+0x101   :alu
    ;; 4--> b  0: i  24 r140=r140<<0x20   :alu
    ;; 5--> b  0: i  25 r136=r137 :alu
    ;; 6--> b  0: i   8 r136=asm_operands :nothing
    ;; 7--> b  0: i  17 a0=r136|r140  :alu
    ;; 8--> b  0: i  18 use a0    :nothing

sched1 with 0530254413f8

    ;; 0--> b  0: i  22 r144=0x101    :alu
    ;; 1--> b  0: i  20 r143=0x101    :alu
    ;; 2--> b  0: i  23 r145=r144+0x101   :alu
    ;; 3--> b  0: i  21 r137=r143+0x1

Re: On inform diagnostics in plugins, support scripts for gdb and modeling creation of PyObjects for static analysis

2023-06-07 Thread Eric Feng via Gcc
Hi Dave,

> If that's the code, does it work if you get rid of the "if (0)"
> conditional, or change it to "if (1)"?  As written, that guard is
> false, so that call to "inform" will never be executed.

Woops! Somehow I missed that but yes, it works now. Thanks!

>  Are you invoking gcc from an installed copy, or from the build
> directory?  I think my instructions assume the latter.

Ah gotcha, thanks! It loads as expected when invoking gcc from the
build directory.

> Don't attempt to build the struct by hand; we want to look up the
> struct from the user's headers.  There are at least two ABIs for
> PyObject, so we want to be sure we're using the correct one.
>
> IIRC, to look things up by name, that's generally a frontend thing,
> since every language has its own concept of scopes/namespaces/etc.
>
> It sounds like you want to look for a type in the global scope of the
> C/C++ FE with the name "PyObject".
>
> We currently have some hooks in the analyzer for getting constants from
> the frontends; see analyzer-language.cc, where the frontend calls
> on_finish_translation_unit, where the analyzer queries the FE for the
> named constants that will be of interest during analysis.  Maybe we can
> extend this so that we have a way to look up named types there, and
> stash the tree for later use, and thus your plugin could ask the
> frontend which tree is the PyObject RECORD_TYPE before the frontend is
> cleaned up (in on_finish_translation_unit).

Sounds good, I will look into that. Thanks for the suggestion!

Best,
Eric


On Wed, Jun 7, 2023 at 5:55 PM David Malcolm  wrote:
>
> On Wed, 2023-06-07 at 16:21 -0400, Eric Feng wrote:
> > Hi everyone,
> >
> > I am one of the GSoC participants this year — in particular, I am
> > working on a static analyzer plugin for CPython extension module
> > code.
> > I'm encountering a few challenges and would appreciate any guidance
> > on
> > the following issues:
> >
> > 1) Issue with "inform" diagnostics in the plugin:
> > I am currently unable to see any "inform" messages from my plugin
> > when
> > compiling test programs with the plugin enabled. As per the structure
> > of existing analyzer plugins, I have included the following code in
> > the plugin_init function:
> >
> > #if ENABLE_ANALYZER
> > const char *plugin_name = plugin_info->base_name;
> > if (0)
> > inform(input_location, "got here; %qs", plugin_name);
>
> If that's the code, does it work if you get rid of the "if (0)"
> conditional, or change it to "if (1)"?  As written, that guard is
> false, so that call to "inform" will never be executed.
>
> > register_callback(plugin_info->base_name,
> >   PLUGIN_ANALYZER_INIT,
> >   ana::cpython_analyzer_init_cb,
> >   NULL);
> > #else
> > sorry_no_analyzer();
> > #endif
> > return 0;
> >
> > I expected to see the "got here" message (among others in other areas
> > of the plugin) when compiling test programs but haven't observed any
> > output. I also did not observe the "sorry" diagnostic. I am compiling
> > a simple CPython extension module with the plugin loaded like so:
> >
> > gcc-dev -S -fanalyzer -fplugin=/path/to/cpython_plugin.so
> > -I/usr/include/python3.9 -lpython3.9 -x c refcount6.c
>
> Looks reasonable.
>
> >
> > Additionally, I compiled the plugin following the steps outlined in
> > the GCC documentation for plugin building
> > (https://gcc.gnu.org/onlinedocs/gccint/Plugins-building.html):
> >
> > g++-dev -shared -I/home/flappy/gcc_/gcc/gcc
> > -I/usr/local/lib/gcc/aarch64-unknown-linux-gnu/14.0.0/plugin/include
> > -fPIC -fno-rtti -O2 analyzer_cpython_plugin.c -o cpython_plugin.so
> >
> > Please let me know if I missed any steps or if there is something
> > else
> > I should consider. I have no trouble seeing inform calls when they
> > are
> > added to the core GCC.
> >
> > 2) gdb not detecting .gdbinit in build/gcc:
> > Following Dave's GCC newbies guide, I ran gcc/configure within the
> > gcc
> > subdirectory of the build directory to generate a .gdbinit file.
> > Dave's guide suggested that this file would be automatically detected
> > and run by gdb. However, it appears that GDB is not detecting this
> > .gdbinit file, even after I added the following line to my ~/.gdbinit
> > file:
> >
> > add-auto-load-safe-path /absolute/path/to/build/gcc
>
> Are you invoking gcc from an installed copy, or from the build
> directory?  I think my instructions assume the latter.
>
> >
> > 3) Modeling creation of a new PyObject:
> > Many CPython API calls involve the creation of a new PyObject. To
> > model the creation of a simple PyObject, we can allocate a new heap
> > region using get_or_create_region_for_heap_alloc. We can then create
> > field_regions using get_field_region to associate the newly allocated
> > region to represent fields such as ob_refcnt and ob_type in the
> > PyObject struct. However, one of the parameters to get _field_region
> > is a tree representing

Targetting p0847 for GCC14 (explicit object parameter)

2023-06-07 Thread waffl3x via Gcc
I would like to boldly suggest implementing P0847 should be targeted at
GCC14. In my anecdotal experiences, this feature is very important to
people, and very important to myself, I believe it should be a priority.

I am not suggesting this without offering to contribute, however
because of my inexperience with compiler hacking I am concerned I would
hinder efforts. With that said, if no one is interested in starting
work on it, but there is consensus that the feature is important
enough, then I will do my best to take up that job.

If this was already the understood plan for GCC14, I apologize for my
ignorance on the matter. I searched around and couldn't find any
information regarding it, the mail list didn't seem to have any results
either. If it's there and I missed it, please do point it out. I am
also wondering if there is a public document with information about the
feature roadmap? I can understand why there isn't one if that isn't the
case, I imagine it would just cause a nuisance for the developers. I
had read the GCC Development Plan document a few months ago and given
the information in it I decided to wait for development to move on to
GCC14 before getting in touch. In hindsight that might have been a
mistake, oops!

I apologize if I overlooked something obvious, please don't hesitate to
correct any misconceptions I'm having here as it's not my intention to
step on any toes here, I just really really value this feature and want
to see it sooner rather than later.

I look forward to hearing everyone's input,
-Alex