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