public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Mechanism to get at function information seems not to work
@ 2020-01-03 23:02 Gary Oblock
  2020-01-03 23:52 ` David Malcolm
  0 siblings, 1 reply; 3+ messages in thread
From: Gary Oblock @ 2020-01-03 23:02 UTC (permalink / raw)
  To: gcc

I'm having some grief attempting to get at the local definitions
in LTO (more about the options used later.)

Here's the sequence of code in my optimization (part of attempt
at structure reorganization optimizations.)

  cgraph_node* node;
  FOR_EACH_FUNCTION_WITH_GIMPLE_BODY ( node)
  {
    tree decl;
    unsigned i;
    struct function *fn = DECL_STRUCT_FUNCTION ( node->decl);

    // I'm assuming it's obvious what my debugging macros do...
    DEBUG( "fn %p\n", fn);
    DEBUG_F( print_generic_decl, stderr, node->decl, (dump_flags_t)-1);
    DEBUG( "\n");
    // I don't know why this is coming up null.... but I'll
    // skip it for now because causes a crash.
    if( fn == NULL )
    {
      continue;
    }

    FOR_EACH_LOCAL_DECL ( fn, i, decl)
    {
      :

What it returns is:

fn 0xffffb0fc9210
  static intD.xxxx max1.constprop.0D.xxxx (struct type_t *);
fn 0xffffb0fc9370
  static doubleD.xxxx max2.constprop.0D.xxxx (struct type_t *);
fn (nil)
  static intD.xxxx mainD.xxxx (void);
fn (nil)
  static struct type_t * setupD.xxxx (size_t);

Here's the test case:

aux.h
-----
#include "stdlib.h"
typedef struct type type_t;
struct type {
  int i;
  double x;
};

#define MAX(x,y) ((x)>(y) ? (x) : (y))

extern int max1( type_t *, size_t);
extern double max2( type_t *, size_t);
extern type_t *setup( size_t);

main.c
------
#include "aux.h"
#include "stdio.h"

int
main(void)
{
  type_t *data1 = setup(100);
  type_t *data2 = setup(200);

  printf("First %d\n" , max1(data1,100));
  printf("Second %e\n", max2(data2,200));
}

aux.c
-----
#include "aux.h"
#include "stdlib.h"

type_t *
setup( size_t size)
{
  type_t *data = (type_t *)malloc( size * sizeof(type_t));
  size_t i;
  for( i = 0; i < size; i++ ) {
    data[i].i = rand();
    data[i].x = drand48();
  }
  return data;
}

int
max1( type_t *array, size_t len)
{
  size_t i;
  int result = array[0].i;
  for( i = 1; i < len; i++  ) {
    result = MAX( array[i].i, result);
  }
  return result;
}

double
max2( type_t *array, size_t len)
{
  size_t i;
  double result = array[0].x;
  for( i = 1; i < len; i++  ) {
    result = MAX( array[i].x, result);
  }
  return result;
}

Here is how I compile them:

GCC=/home/goblock/str-reorg-gcc-build-dir/install/bin/gcc
OPTIONS="-O2 -flto -flto-partition=one -fipa-structure-reorg"

$GCC $OPTIONS -c main.c
$GCC $OPTIONS -c aux.c
$GCC $OPTIONS -o exe main.o aux.o

./exe

I'm wondering if this is a fundamental issue, if there's a bug
or perhaps I'm doing something dumb. I any advice is appreciated
here because my only real alternative here is insanely ugly.

Thanks,

Gary Oblock

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Mechanism to get at function information seems not to work
  2020-01-03 23:02 Mechanism to get at function information seems not to work Gary Oblock
@ 2020-01-03 23:52 ` David Malcolm
  2020-01-04  0:05   ` [EXT] " Gary Oblock
  0 siblings, 1 reply; 3+ messages in thread
From: David Malcolm @ 2020-01-03 23:52 UTC (permalink / raw)
  To: Gary Oblock, gcc

On Fri, 2020-01-03 at 23:02 +0000, Gary Oblock wrote:
> I'm having some grief attempting to get at the local definitions
> in LTO (more about the options used later.)
> 
> Here's the sequence of code in my optimization (part of attempt
> at structure reorganization optimizations.)
> 
>   cgraph_node* node;
>   FOR_EACH_FUNCTION_WITH_GIMPLE_BODY ( node)
>   {
>     tree decl;
>     unsigned i;
>     struct function *fn = DECL_STRUCT_FUNCTION ( node->decl);
> 
>     // I'm assuming it's obvious what my debugging macros do...
>     DEBUG( "fn %p\n", fn);
>     DEBUG_F( print_generic_decl, stderr, node->decl, (dump_flags_t)-
> 1);
>     DEBUG( "\n");
>     // I don't know why this is coming up null.... but I'll
>     // skip it for now because causes a crash.
>     if( fn == NULL )
>     {
>       continue;
>     }
> 
>     FOR_EACH_LOCAL_DECL ( fn, i, decl)
>     {
>       :
> 
> What it returns is:
> 
> fn 0xffffb0fc9210
>   static intD.xxxx max1.constprop.0D.xxxx (struct type_t *);
> fn 0xffffb0fc9370
>   static doubleD.xxxx max2.constprop.0D.xxxx (struct type_t *);
> fn (nil)
>   static intD.xxxx mainD.xxxx (void);
> fn (nil)
>   static struct type_t * setupD.xxxx (size_t);
> 

[...snip...]

> Here is how I compile them:
> 
> GCC=/home/goblock/str-reorg-gcc-build-dir/install/bin/gcc
> OPTIONS="-O2 -flto -flto-partition=one -fipa-structure-reorg"
> 
> $GCC $OPTIONS -c main.c
> $GCC $OPTIONS -c aux.c
> $GCC $OPTIONS -o exe main.o aux.o
> 
> ./exe
> 
> I'm wondering if this is a fundamental issue, if there's a bug
> or perhaps I'm doing something dumb. I any advice is appreciated
> here because my only real alternative here is insanely ugly.

This looks like the same issue as one I ran into when trying to add LTO
support to the static analyzer [1].

AIUI the LTO infrastructure partitions the functions in a kind of
sharding operation.  There's no guarantee for any given partition's
invocation of lto1 that it has a particular function body.

I fixed this in the analyzer by putting this loop at the top of the
pass:

  /* If using LTO, ensure that the cgraph nodes have function bodies.  */
  cgraph_node *node;
  FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
    node->get_untransformed_body ();

which seems to fix it for me (my pass then goes on to do a non-trivial
interprocedural traversal, so it needs to have all the function bodies
present first).

I'm not sure if this is the correct fix for your issue, but it worked
for my pass (I'm just using "-flto", FWIW).

Hope this is helpful
Dave

[1] https://gcc.gnu.org/wiki/DavidMalcolm/StaticAnalyzer


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [EXT] Re: Mechanism to get at function information seems not to work
  2020-01-03 23:52 ` David Malcolm
@ 2020-01-04  0:05   ` Gary Oblock
  0 siblings, 0 replies; 3+ messages in thread
From: Gary Oblock @ 2020-01-04  0:05 UTC (permalink / raw)
  To: David Malcolm, gcc

Thanks David,

I'll give it a try. By the way, I'm trying to force one partition
with "-flto-partition=one" I'm not sure if that makes a difference.

Gary


________________________________
From: David Malcolm <dmalcolm@redhat.com>
Sent: Friday, January 3, 2020 3:52 PM
To: Gary Oblock <goblock@marvell.com>; gcc@gcc.gnu.org <gcc@gcc.gnu.org>
Subject: [EXT] Re: Mechanism to get at function information seems not to work

External Email

----------------------------------------------------------------------
On Fri, 2020-01-03 at 23:02 +0000, Gary Oblock wrote:
> I'm having some grief attempting to get at the local definitions
> in LTO (more about the options used later.)
>
> Here's the sequence of code in my optimization (part of attempt
> at structure reorganization optimizations.)
>
>   cgraph_node* node;
>   FOR_EACH_FUNCTION_WITH_GIMPLE_BODY ( node)
>   {
>     tree decl;
>     unsigned i;
>     struct function *fn = DECL_STRUCT_FUNCTION ( node->decl);
>
>     // I'm assuming it's obvious what my debugging macros do...
>     DEBUG( "fn %p\n", fn);
>     DEBUG_F( print_generic_decl, stderr, node->decl, (dump_flags_t)-
> 1);
>     DEBUG( "\n");
>     // I don't know why this is coming up null.... but I'll
>     // skip it for now because causes a crash.
>     if( fn == NULL )
>     {
>       continue;
>     }
>
>     FOR_EACH_LOCAL_DECL ( fn, i, decl)
>     {
>       :
>
> What it returns is:
>
> fn 0xffffb0fc9210
>   static intD.xxxx max1.constprop.0D.xxxx (struct type_t *);
> fn 0xffffb0fc9370
>   static doubleD.xxxx max2.constprop.0D.xxxx (struct type_t *);
> fn (nil)
>   static intD.xxxx mainD.xxxx (void);
> fn (nil)
>   static struct type_t * setupD.xxxx (size_t);
>

[...snip...]

> Here is how I compile them:
>
> GCC=/home/goblock/str-reorg-gcc-build-dir/install/bin/gcc
> OPTIONS="-O2 -flto -flto-partition=one -fipa-structure-reorg"
>
> $GCC $OPTIONS -c main.c
> $GCC $OPTIONS -c aux.c
> $GCC $OPTIONS -o exe main.o aux.o
>
> ./exe
>
> I'm wondering if this is a fundamental issue, if there's a bug
> or perhaps I'm doing something dumb. I any advice is appreciated
> here because my only real alternative here is insanely ugly.

This looks like the same issue as one I ran into when trying to add LTO
support to the static analyzer [1].

AIUI the LTO infrastructure partitions the functions in a kind of
sharding operation.  There's no guarantee for any given partition's
invocation of lto1 that it has a particular function body.

I fixed this in the analyzer by putting this loop at the top of the
pass:

  /* If using LTO, ensure that the cgraph nodes have function bodies.  */
  cgraph_node *node;
  FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
    node->get_untransformed_body ();

which seems to fix it for me (my pass then goes on to do a non-trivial
interprocedural traversal, so it needs to have all the function bodies
present first).

I'm not sure if this is the correct fix for your issue, but it worked
for my pass (I'm just using "-flto", FWIW).

Hope this is helpful
Dave

[1] https://urldefense.proofpoint.com/v2/url?u=https-3A__gcc.gnu.org_wiki_DavidMalcolm_StaticAnalyzer&d=DwICaQ&c=nKjWec2b6R0mOyPaz7xtfQ&r=HVs3hYm_BnTtuG8V-km21WLujN2g6AKxQlP-LTQPUQI&m=PLNbIn26nObhyevJgxSrCwF8SwZVo7ILB5s5Uu2DmRk&s=quDOZbDeR-DxertzdPRUzHiBYIXOpQ6cRmjMsvC9EbE&e=


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2020-01-04  0:05 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-03 23:02 Mechanism to get at function information seems not to work Gary Oblock
2020-01-03 23:52 ` David Malcolm
2020-01-04  0:05   ` [EXT] " Gary Oblock

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).