RE: COBOL: Hoping for insight with middle-end computation time.

Robert Dubner <[email protected]>
Newsgroups gmane.comp.gcc.devel
Message-ID <[email protected]>

> -----Original Message-----
> From: Richard Biener <[email protected]>
> Sent: Saturday, March 21, 2026 03:33
> To: Robert Dubner <[email protected]>
> Cc: David Malcolm <[email protected]>; H. J. Lu <[email protected]>;
> [email protected]; James K. Lowden <[email protected]>
> Subject: Re: COBOL: Hoping for insight with middle-end computation time.
>
>
>
> > Am 21.03.2026 um 04:17 schrieb Robert Dubner <[email protected]>:
> >
> > Let's try another line of query.
> >
> > Maybe here are things I should be doing that I am not, or things that I 
> > am
> > doing that I shouldn't.
> >
> > As described earlier, I created a version of the gcobol/cobol1 compiler 
> > that
> > produced a stripped-down GENERIC that resulted in this repeated pattern 
> > in
> > the -fdump-tree-original output.
> >
> >      _intermediate__stack1_3.0.0.data = &_stack1_data_17.0;
> >      _intermediate__stack1_3.0.0.capacity = 16;
> >      _intermediate__stack1_3.0.0.allocated = 16;
> >      _intermediate__stack1_3.0.0.offset = 0;
> >      _intermediate__stack1_3.0.0.name = &"_stack1"[0];
> >      _intermediate__stack1_3.0.0.picture = &""[0];
> >      _intermediate__stack1_3.0.0.initial = 0B;
> >      _intermediate__stack1_3.0.0.parent = 0B;
> >      _intermediate__stack1_3.0.0.occurs_lower = 0;
> >      _intermediate__stack1_3.0.0.occurs_upper = 0;
> >      _intermediate__stack1_3.0.0.attr = 4160;
> >      _intermediate__stack1_3.0.0.type = 6;
> >      _intermediate__stack1_3.0.0.level = 0;
> >      _intermediate__stack1_3.0.0.digits = 37;
> >      _intermediate__stack1_3.0.0.rdigits = 0;
> >      _intermediate__stack1_3.0.0.encoding = 1;
> >      _intermediate__stack1_3.0.0.alphabet = 0;
> >      D.311 = 0;
> >      D.312 = 0;
> >      _13 = D.311 & 18;
> >      if (_13 != 0) goto <D.369>; else goto <D.370>;
> >      <D.369>:
> >      goto <D.371>;
> >      <D.370>:
> >      D.314 = 0;
> >      ..pa_erf.19_14 = ..pa_erf;
> >      D.312 = D.312 | ..pa_erf.19_14;
> >      if (D.312 != 0) goto <D.373>; else goto <D.374>;
> >      <D.373>:
> >      goto <D.375>;
> >      <D.374>:
> >      <D.375>:
> >      <D.371>:
> >
> > I have experimented with a C program until I came up with the same 
> > .gimple:
> >
> > typedef struct strct
> >  {
> >  int a0; int a1; int a2; int a3; int a4; int a5; int a6; int a7; int a8;
> > int a9;
> >  }strct;
> >
> > int
> > main(int argc, char **argv)
> >  {
> >  strct strc0{0,1,2,3,4,5,6,7,8,9};
> >  int x0=0;
> >  int y0=0;
> >  int z0;
> >  y0=x0&18;
> >  if(y0!=0)
> >    {}
> >  else
> >    {
> >    z0=z0|pa_erf;
> >    if(z0!=0)
> >      {}
> >    }
> >  }
> >
> > Here is a side-by-side comparison of the repetitive .gimple generated by 
> > the
> > two compilations:
> >
> > From the gcobol compilation                      From the xg++ 
> > compilation
> 
> > --------                      -------------------------
> > D.322 = 0;                                       x3 = 0;
> > D.323 = 0;                                       y3 = 0;
> > _17 = D.322 & 18;                                y3 = x3 & 18;
> > if (_17 != 0) goto <D.385>; else goto <D.386>;   if (y3 != 0) goto 
> > <D.3063>;
> > else goto <D.3064>;
> > <D.385>:                                         <D.3063>:
> > goto <D.387>;                                    goto <D.3065>;
> > <D.386>:                                         <D.3064>:
> > D.324 = 0;
> > ..pa_erf.25_18 = ..pa_erf;                       pa_erf.3_4 = pa_erf;
> > D.323 = D.323 | ..pa_erf.25_18;                  z3 = z3 | pa_erf.3_4;
> > if (D.323 != 0) goto <D.389>; else goto <D.390>; if (z3 != 0) goto 
> > <D.3066>;
> > else goto <D.3067>;
> > <D.389>:                                         <D.3066>:
> > goto <D.391>;                                    goto <D.3068>;
> > <D.390>:                                         <D.3067>:
> > <D.391>:                                         <D.3068>:
> > <D.387>:                                         <D.3065>:
> > You can see they are essentially identical.
>
> Could it be your D.324 is global?  Comparing the GIMPLE would tell. 
> Possibly
> also BIND_EXPRs matter.  -blocks dumps (some) also dump the scope tree.
>
> > However!
> >
> > 10,000 repeats of that code in the C++ program compiles in 1.36 seconds.
> > 20,000 repeats                                             3.18 seconds.
> > 40,000 repeats                                             7.92 seconds.
> >
> > 10,000 repeats in the COBOL program                       16.76 seconds.
> > 20,000 repeats in the COBOL program                       97.40 seconds.
> > 10,000 repeats in the COBOL program                      551.56 seconds.
> >
> > Those times are -O0 compilations from the same build of gcc, invoked in 
> > the
> > same ways.
> >
> > So.  I am obviously doing something different in gcobol than whatever is
> > happening in xg++.
> >
> > The GENERIC I am creating is apparently about right.  So, now I have to 
> > ask
> > a question that I probably should have asked years ago:
> >
> > What do I need to do before creating the GENERIC for a function?
> >
> > What do I need to do afterward?
> >
> > Right now I don't think I am doing anything special before generating 
> > any
> > GENERIC.
> >
> > At the end of a source code module, I call
> >
> >    cgraph_node::finalize_function(function_decl, true);
> >
> > for each function I created in that module.
> >
> > What am I missing?  What could I be doing, or not doing, that's causing 
> > that
> > N-squared behavior?
>
> I don’t think you are doing anything obviously wrong.  With cobol you are 
> going
> to have a single large function which is somewhat special and more prone 
> to run
> into such bugs where people were lazy and never imagined there’s so large 
> data.
> We’ll have to fix those algorithms eventually.
>
> > I am feeling like somebody who has found a car, and figured out how to 
> > get
> > it started and get it moving in first gear, but hasn't figured out how 
> > to
> > get to any of the higher gears.
>
> There might be things you can do in the frontend to avoid running into 
> such
> issues, but at least from the above it’s not obvious what that should be.
>

You folks have been giving me additional lines of investigation to follow, 
and I will.

I have a C program and a COBOL program that produce essentially identical 
output from -fdump-tree-gimple.  I see that the outputs 
from -fdump-tree-original are not very much alike:

From C:

  <<cleanup_point   struct strctD.2994 strc1D.3033 = {.a0D.2984=0, 
.a1D.2985=1, .a2D.2986=2, .a3D.2987=3, .a4D.2988=4, .a5D.2989=5, 
.a6D.2990=6, .a7D.2991=7, .a8D.2992=8, .a9D.2993=9};>>;
  <<cleanup_point   intD.9 x1D.3034 = 0;>>;
  <<cleanup_point   intD.9 y1D.3035 = 0;>>;
    intD.9 z1D.3036;
  <<cleanup_point <<< Unknown tree: expr_stmt
    (voidD.54) (y1D.3035 = x1D.3034 & 18) >>>>>;
  if (y1D.3035 != 0)
    {

    }
  else
    {
      <<cleanup_point <<< Unknown tree: expr_stmt
        (voidD.54) (z1D.3036 = z1D.3036 | pa_erfD.2981) >>>>>;
      if (z1D.3036 != 0)
        {

        }
    }

And from GCOBOL

    struct  _intermediate__stack1_3.0.0 = {.data=&_stack1_data_17.0, 
.capacity=16, .allocated=16, .offset=0, .name=&"_stack1"[0], 
.picture=&""[0], .initial=0B, .parent=0B, .occurs_lower=0, .occurs_upper=0, 
.attr=4160, .type=6, .level=0, .digits=37, .rdigits=0, .encoding=1, 
.alphabet=0};
    unsigned char _stack1_data_17.0[16];
    signed int D.311 = 0;
    signed int D.312 = 0;
  (D.311 & 18) != 0 ?  :   unsigned long D.314;
  D.314 = 0;
  D.312 = D.312 | ..pa_erf;
  D.312 != 0 ?  : ;;

What I don't yet know is what's significant.

I'll keep looking.  I'll try not to ask too many questions.



> Richard
>
> >
> >
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.