> -----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
>
> >
> >

Reply via email to