https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128070

            Bug ID: 128070
           Summary: [compile-time-hog] -O3 cunrolli growth on many small
                    loops, super-linear compile time and memory
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: yuki.tanaka at defaultcase dot de
  Target Milestone: ---

Created attachment 65916
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=65916&action=edit
cunrolli-hog.c

The attached testcase (cunrolli-hog.c) contains N 13x13x13 loop nests (set with
-DN_COPIES=N). At -O3 cunrolli completely unrolls the innermost loops of every
nest; compile time and memory then grow super-linearly with N.
-fdisable-tree-cunrolli brings it back close to -O2.

$ xgcc -v
Using built-in specs.
COLLECT_GCC=./build/gcc/xgcc
Target: arm-none-eabi
Configured with: ../gcc/configure --target=arm-none-eabi
--with-multilib-list=rmprofile --enable-languages=c --without-headers
--with-newlib --enable-checking=release
Thread model: single
Supported LTO compression algorithms: zlib
gcc version 17.0.0 20261020 (experimental) (GCC)

Measured with:

CC="build/gcc/xgcc -B build/gcc -mcpu=cortex-m3 -mthumb"
for n in 25 50 75 100; do
  for v in "-O2" "-O3 -fdisable-tree-cunrolli" "-O3"; do
    /usr/bin/time -f "%e s / %M KB" -o t.txt timeout 600 $CC $v -DN_COPIES=$n
-S cunrolli-hog.c -o /dev/null 2>/dev/null; rc=$?
    echo "N=$n [$v]: rc=$rc $(tail -1 t.txt)"
  done
done

Output (wall time / max RSS):

N=25 [-O2]: rc=0 1.23 s / 135180 KB
N=25 [-O3 -fdisable-tree-cunrolli]: rc=0 2.10 s / 188380 KB
N=25 [-O3]: rc=0 12.48 s / 310208 KB
N=50 [-O2]: rc=0 3.74 s / 205956 KB
N=50 [-O3 -fdisable-tree-cunrolli]: rc=0 5.63 s / 292572 KB
N=50 [-O3]: rc=0 61.67 s / 753272 KB
N=75 [-O2]: rc=0 8.27 s / 312188 KB
N=75 [-O3 -fdisable-tree-cunrolli]: rc=0 11.24 s / 443548 KB
N=75 [-O3]: rc=0 152.02 s / 1554664 KB
N=100 [-O2]: rc=0 16.82 s / 442188 KB
N=100 [-O3 -fdisable-tree-cunrolli]: rc=0 21.68 s / 649592 KB
N=100 [-O3]: rc=0 276.78 s / 2586340 KB

At -O3 cunrolli completely unrolls the innermost loop of every nest (150 loops
for N=75, 13 iterations each, see -fdump-tree-cunrolli-details). Each of them
is below max-completely-peeled-insns, but the limit is checked per loop only;
nothing limits the total growth of the function. Most of the compile time is
then spent in "alias stmt walking" (see -ftime-report below), and compile time
and memory grow faster than linearly with N.

-ftime-report at -O3 (N=75, same compiler as above):
Time variable                                  wall           GGC
 phase setup                        :   0.01 (  0%)  3115k (  0%)
 phase parsing                      :   0.16 (  0%)    27M (  3%)
 phase opt and generate             : 156.81 (100%)   771M ( 96%)
 garbage collection                 :   0.05 (  0%)     0  (  0%)
 callgraph construction             :   0.01 (  0%)  8343k (  1%)
 callgraph functions expansion      : 156.49 (100%)   725M ( 90%)
 callgraph ipa passes               :   0.19 (  0%)  3473k (  0%)
 cfg cleanup                        :   0.04 (  0%)  3062k (  0%)
 trivially dead code                :   0.02 (  0%)     0  (  0%)
 df scan insns                      :   0.01 (  0%)    96  (  0%)
 df reaching defs                   :   0.09 (  0%)     0  (  0%)
 df live regs                       :   0.17 (  0%)     0  (  0%)
 df live&initialized regs           :   0.04 (  0%)     0  (  0%)
 df use-def / def-use chains        :   0.01 (  0%)     0  (  0%)
 df reg dead/unused notes           :   0.10 (  0%)   857k (  0%)
 register information               :   0.02 (  0%)     0  (  0%)
 alias analysis                     :   0.10 (  0%)  6694k (  1%)
 alias stmt walking                 : 133.90 ( 85%)    24M (  3%)
 register scan                      :   0.01 (  0%)    15k (  0%)
 rebuild jump labels                :   0.01 (  0%)     0  (  0%)
 preprocessing                      :   0.03 (  0%)  8021k (  1%)
 lexical analysis                   :   0.01 (  0%)     0  (  0%)
 parser function body               :   0.12 (  0%)    19M (  2%)
 tree gimplify                      :   0.06 (  0%)    10M (  1%)
 tree CFG construction              :   0.05 (  0%)    23M (  3%)
 tree CFG cleanup                   :   0.09 (  0%)   348k (  0%)
 tree VRP                           :   0.41 (  0%)  2401k (  0%)
 tree Early VRP                     :   0.04 (  0%)   387k (  0%)
 tree copy propagation              :   0.03 (  0%)     0  (  0%)
 tree PTA                           :   0.02 (  0%)   312  (  0%)
 tree SSA incremental               :   0.43 (  0%)  2748k (  0%)
 tree operand scan                  :   0.02 (  0%)  2742k (  0%)
 dominator optimization             :   0.39 (  0%)  2750k (  0%)
 backwards jump threading           :   0.38 (  0%)    54k (  0%)
 tree CCP                           :   0.09 (  0%)   243k (  0%)
 tree reassociation                 :   0.01 (  0%)   189k (  0%)
 tree PRE                           :  10.15 (  6%)   443M ( 55%)
 tree FRE                           :   0.28 (  0%)  2033k (  0%)
 tree RPO VN                        :   1.44 (  1%)  1565k (  0%)
 tree code sinking                  :   0.01 (  0%)    84k (  0%)
 tree linearize phis                :   0.01 (  0%)    39k (  0%)
 tree forward propagate             :   0.04 (  0%)   372k (  0%)
 tree conservative DCE              :   0.01 (  0%)  8024  (  0%)
 tree aggressive DCE                :   0.01 (  0%)   110k (  0%)
 tree DSE                           :   0.07 (  0%)    64M (  8%)
 tree loop invariant motion         :   0.03 (  0%)    45k (  0%)
 tree loop interchange              :   0.11 (  0%)  5137k (  1%)
 tree canonical iv                  :   0.01 (  0%)   116k (  0%)
 scev constant prop                 :   0.15 (  0%)  3600  (  0%)
 tree loop unswitching              :   0.27 (  0%)   115k (  0%)
 unroll and jam                     :   0.09 (  0%)  2538k (  0%)
 complete unrolling                 :   0.91 (  1%)  9239k (  1%)
 tree vectorization                 :   1.06 (  1%)    40M (  5%)
 tree slp vectorization             :   0.26 (  0%)    15M (  2%)
 tree loop distribution             :   0.33 (  0%)  9378k (  1%)
 tree iv optimization               :   0.64 (  0%)    29M (  4%)
 predictive commoning               :   0.18 (  0%)  4706k (  1%)
 tree copy headers                  :   0.17 (  0%)   301k (  0%)
 tree strlen optimization           :   0.13 (  0%)  1072  (  0%)
 dominance computation              :   0.02 (  0%)     0  (  0%)
 out of ssa                         :   0.09 (  0%)  6336  (  0%)
 expand vars                        :   0.00 (  0%)  1556k (  0%)
 expand                             :   0.14 (  0%)  6289k (  1%)
 lower subreg                       :   0.02 (  0%)   917k (  0%)
 forward prop                       :   0.04 (  0%)   241k (  0%)
 CSE                                :   0.19 (  0%)   623k (  0%)
 dead code elimination              :   0.02 (  0%)     0  (  0%)
 dead store elim1                   :   0.02 (  0%)  1119k (  0%)
 dead store elim2                   :   0.02 (  0%)  1080k (  0%)
 loop init                          :   0.02 (  0%)  3834k (  0%)
 loop versioning                    :   0.13 (  0%)     0  (  0%)
 loop invariant motion              :   0.02 (  0%)    39k (  0%)
 CPROP                              :   0.08 (  0%)  2645k (  0%)
 PRE                                :   0.39 (  0%)    40k (  0%)
 CSE 2                              :   0.09 (  0%)   222k (  0%)
 branch prediction                  :   0.01 (  0%)   201k (  0%)
 combiner                           :   0.31 (  0%)  7234k (  1%)
 late combiner                      :   0.04 (  0%)   683k (  0%)
 scheduling                         :   0.18 (  0%)  1183k (  0%)
 integrated RA                      :   0.41 (  0%)    13M (  2%)
 LRA non-specific                   :   0.08 (  0%)   104k (  0%)
 LRA virtuals elimination           :   0.01 (  0%)    28k (  0%)
 LRA reload inheritance             :   0.01 (  0%)  1078k (  0%)
 LRA create live ranges             :   0.03 (  0%)  9384  (  0%)
 LRA hard reg assignment            :   0.02 (  0%)     0  (  0%)
 LRA rematerialization              :   0.01 (  0%)     0  (  0%)
 reload CSE regs                    :   0.09 (  0%)  1883k (  0%)
 load CSE after reload              :   0.20 (  0%)    13k (  0%)
 peephole 2                         :   0.01 (  0%)    97k (  0%)
 hard reg cprop                     :   0.01 (  0%)     0  (  0%)
 scheduling 2                       :   0.08 (  0%)   115k (  0%)
 machine dep reorg                  :   0.01 (  0%)   115k (  0%)
 shorten branches                   :   0.01 (  0%)     0  (  0%)
 final                              :   0.02 (  0%)    48  (  0%)
 tree loop if-conversion            :   0.22 (  0%)  8838k (  1%)
 access analysis                    :   0.16 (  0%)    48  (  0%)
 ext dce                            :   0.06 (  0%)     0  (  0%)
 fold mem offsets                   :   0.01 (  0%)     0  (  0%)
 rest of compilation                :   0.49 (  0%)   244k (  0%)
 remove unused locals               :   0.01 (  0%)     0  (  0%)
 TOTAL                              : 156.98          802M

Reply via email to