有什么办法可以让 GCC 更快地编译包含数千个案例的 switch 语句吗?

问题描述 投票:0回答:1

我一直在开发一个反编译器(用于Glulx),它可以生成C代码。在一种模式下,它在一个 switch 语句中输出所有代码(打开程序计数器)。一个中等大小的输入文件会产生近 11,000 个案例,GCC 需要很长时间来编译它 - 在我的计算机上几乎需要 5 分钟,在 Github Actions 上几乎需要 10 分钟。我绘制了 GCC 编译具有不同长度的 switch 语句的文件需要多长时间:

A graph of number of cases vs time

如您所见,它是非线性的,每增加 1000 个案例所花费的时间就会比最后 1000 个案例花费的时间更长。

有什么办法可以加快 GCC 编译这个 switch 语句的速度吗?是否有任何我可以插入到代码中的编译器提示,或任何要更改的设置(我一直在 -O0 中对此进行测试和计时)?像这样的 switch 语句,有很多稀疏的情况,会被编译成二叉树,所以我确实考虑过是否可以手动将其分成 1000-2000 个情况的块,但这实际上可能不会使编译更快;毕竟我只是手动执行编译器本身会执行的操作。 (我还没试过。)有什么想法吗?

如果相关的话,大多数案例都会失败:在 10898 个案例中,只有 637 个案例最终无条件中断。

编辑:Nate Eldredge 在评论中非常有帮助地指出这是 GCC 8.4 的回归。我现在已经在 GCC bug 跟踪器报告了这个问题。


使用

-ftime-report -ftime-report-details
编译的结果:

Time variable                                   usr           sys          wall               GGC
 phase setup                        :   0.00 (  0%)   0.00 (  0%)   0.01 (  0%)    1240 kB (  1%)
 phase parsing                      :   1.26 (  0%)   0.87 ( 71%)   2.13 (  1%)   31503 kB ( 14%)
 phase opt and generate             : 277.02 (100%)   0.35 ( 29%) 277.48 ( 99%)  197271 kB ( 86%)
 callgraph construction             :   0.08 (  0%)   0.01 (  1%)   0.09 (  0%)   27116 kB ( 12%)
 `- tree eh                         :   0.02 (  0%)   0.00 (  0%)   0.02 (  0%)      76 kB (  0%)
 `- tree gimplify                   :   0.25 (  0%)   0.01 (  1%)   0.26 (  0%)   35760 kB ( 16%)
 callgraph optimization             :   0.01 (  0%)   0.00 (  0%)   0.02 (  0%)       0 kB (  0%)
 `- inline parameters               :   0.06 (  0%)   0.00 (  0%)   0.06 (  0%)    2047 kB (  1%)
 `- callgraph construction          :   0.03 (  0%)   0.00 (  0%)   0.02 (  0%)   14151 kB (  6%)
 `- ipa dead code removal           :   0.01 (  0%)   0.00 (  0%)   0.00 (  0%)       0 kB (  0%)
 callgraph ipa passes               :   0.33 (  0%)   0.10 (  8%)   0.43 (  0%)   27623 kB ( 12%)
 ipa dead code removal              :   0.01 (  0%)   0.00 (  0%)   0.00 (  0%)       0 kB (  0%)
 ipa inlining heuristics            :   0.01 (  0%)   0.00 (  0%)   0.01 (  0%)       0 kB (  0%)
 cfg construction                   :   0.59 (  0%)   0.01 (  1%)   0.61 (  0%)    6684 kB (  3%)
 `- rebuild jump labels             :   0.03 (  0%)   0.00 (  0%)   0.03 (  0%)       0 kB (  0%)
 cfg cleanup                        :   0.12 (  0%)   0.00 (  0%)   0.12 (  0%)     417 kB (  0%)
 trivially dead code                :   0.13 (  0%)   0.00 (  0%)   0.12 (  0%)       0 kB (  0%)
 df scan insns                      :   0.30 (  0%)   0.03 (  2%)   0.34 (  0%)       0 kB (  0%)
 df live regs                       :   0.10 (  0%)   0.01 (  1%)   0.11 (  0%)       0 kB (  0%)
 df reg dead/unused notes           :   0.11 (  0%)   0.00 (  0%)   0.11 (  0%)    5115 kB (  2%)
 register information               :   0.03 (  0%)   0.00 (  0%)   0.03 (  0%)       0 kB (  0%)
 alias analysis                     :   0.03 (  0%)   0.00 (  0%)   0.03 (  0%)    2048 kB (  1%)
 alias stmt walking                 :   0.01 (  0%)   0.01 (  1%)   0.07 (  0%)       0 kB (  0%)
 rebuild jump labels                :   0.05 (  0%)   0.00 (  0%)   0.05 (  0%)      27 kB (  0%)
 preprocessing                      :   0.23 (  0%)   0.27 ( 22%)   0.69 (  0%)    8646 kB (  4%)
 lexical analysis                   :   0.45 (  0%)   0.28 ( 23%)   0.76 (  0%)       0 kB (  0%)
 `- preprocessing                   :   0.23 (  0%)   0.27 ( 22%)   0.69 (  0%)    8646 kB (  4%)
 parser (global)                    :   0.03 (  0%)   0.00 (  0%)   0.00 (  0%)     949 kB (  0%)
 `- lexical analysis                :   0.00 (  0%)   0.01 (  1%)   0.00 (  0%)       0 kB (  0%)
 parser function body               :   0.55 (  0%)   0.32 ( 26%)   0.68 (  0%)   21899 kB ( 10%)
 `- lexical analysis                :   0.20 (  0%)   0.13 ( 11%)   0.45 (  0%)       0 kB (  0%)
 inline parameters                  :   0.06 (  0%)   0.00 (  0%)   0.06 (  0%)    2047 kB (  1%)
 tree gimplify                      :   0.25 (  0%)   0.01 (  1%)   0.26 (  0%)   35760 kB ( 16%)
 tree eh                            :   0.02 (  0%)   0.00 (  0%)   0.02 (  0%)      76 kB (  0%)
 tree CFG construction              :   0.03 (  0%)   0.01 (  1%)   0.03 (  0%)    8036 kB (  3%)
 `- tree CFG cleanup                :   0.00 (  0%)   0.00 (  0%)   0.01 (  0%)       0 kB (  0%)
 tree CFG cleanup                   :   0.10 (  0%)   0.00 (  0%)   0.11 (  0%)      14 kB (  0%)
 `- tree CFG cleanup                :   0.02 (  0%)   0.00 (  0%)   0.02 (  0%)       0 kB (  0%)
 tree PHI insertion                 :   0.02 (  0%)   0.00 (  0%)   0.01 (  0%)    3820 kB (  2%)
 tree SSA rewrite                   :   0.03 (  0%)   0.00 (  0%)   0.04 (  0%)    1948 kB (  1%)
 tree SSA other                     :   0.05 (  0%)   0.02 (  2%)   0.10 (  0%)       0 kB (  0%)
 `- tree SSA rewrite                :   0.01 (  0%)   0.00 (  0%)   0.02 (  0%)    1948 kB (  1%)
 `- tree PHI insertion              :   0.02 (  0%)   0.00 (  0%)   0.01 (  0%)    3820 kB (  2%)
 `- tree operand scan               :   0.06 (  0%)   0.06 (  5%)   0.11 (  0%)    5653 kB (  2%)
 `- dominance computation           :   0.01 (  0%)   0.00 (  0%)   0.00 (  0%)       0 kB (  0%)
 tree SSA incremental               :   0.01 (  0%)   0.00 (  0%)   0.02 (  0%)       0 kB (  0%)
 `- tree SSA rewrite                :   0.02 (  0%)   0.00 (  0%)   0.02 (  0%)       0 kB (  0%)
 `- dominance frontiers             :   0.01 (  0%)   0.00 (  0%)   0.01 (  0%)       0 kB (  0%)
 `- dominance computation           :   0.01 (  0%)   0.00 (  0%)   0.00 (  0%)       0 kB (  0%)
 tree operand scan                  :   0.06 (  0%)   0.06 (  5%)   0.12 (  0%)    5989 kB (  3%)
 tree switch lowering               : 271.78 ( 98%)   0.08 (  7%) 271.97 ( 97%)   10454 kB (  5%)
 `- tree CFG cleanup                :   0.01 (  0%)   0.00 (  0%)   0.01 (  0%)       0 kB (  0%)
 `- tree operand scan               :   0.00 (  0%)   0.00 (  0%)   0.01 (  0%)     336 kB (  0%)
 dominance frontiers                :   0.01 (  0%)   0.00 (  0%)   0.01 (  0%)       0 kB (  0%)
 dominance computation              :   0.06 (  0%)   0.00 (  0%)   0.03 (  0%)       0 kB (  0%)
 out of ssa                         :   0.04 (  0%)   0.00 (  0%)   0.04 (  0%)     510 kB (  0%)
 expand vars                        :   0.06 (  0%)   0.00 (  0%)   0.06 (  0%)    7694 kB (  3%)
 expand                             :   0.29 (  0%)   0.02 (  2%)   0.31 (  0%)   46170 kB ( 20%)
 `- out of ssa                      :   0.04 (  0%)   0.00 (  0%)   0.04 (  0%)     510 kB (  0%)
 `- expand vars                     :   0.06 (  0%)   0.00 (  0%)   0.06 (  0%)    7694 kB (  3%)
 `- post expand cleanups            :   0.03 (  0%)   0.00 (  0%)   0.03 (  0%)       0 kB (  0%)
 post expand cleanups               :   0.05 (  0%)   0.00 (  0%)   0.05 (  0%)     246 kB (  0%)
 `- rebuild jump labels             :   0.02 (  0%)   0.00 (  0%)   0.02 (  0%)      27 kB (  0%)
 jump                               :   0.00 (  0%)   0.00 (  0%)   0.00 (  0%)       0 kB (  0%)
 `- cfg cleanup                     :   0.01 (  0%)   0.00 (  0%)   0.02 (  0%)       0 kB (  0%)
 `- trivially dead code             :   0.06 (  0%)   0.00 (  0%)   0.06 (  0%)       0 kB (  0%)
 loop init                          :   0.02 (  0%)   0.00 (  0%)   0.03 (  0%)       1 kB (  0%)
 `- dominance computation           :   0.02 (  0%)   0.00 (  0%)   0.02 (  0%)       0 kB (  0%)
 loop fini                          :   0.01 (  0%)   0.00 (  0%)   0.00 (  0%)       0 kB (  0%)
 integrated RA                      :   1.04 (  0%)   0.05 (  4%)   1.09 (  0%)   24640 kB ( 11%)
 `- df live regs                    :   0.05 (  0%)   0.01 (  1%)   0.06 (  0%)       0 kB (  0%)
 `- register information            :   0.03 (  0%)   0.00 (  0%)   0.03 (  0%)       0 kB (  0%)
 `- df reg dead/unused notes        :   0.11 (  0%)   0.00 (  0%)   0.11 (  0%)    5115 kB (  2%)
 `- trivially dead code             :   0.07 (  0%)   0.00 (  0%)   0.06 (  0%)       0 kB (  0%)
 `- alias analysis                  :   0.03 (  0%)   0.00 (  0%)   0.03 (  0%)    2048 kB (  1%)
 LRA non-specific                   :   0.38 (  0%)   0.00 (  0%)   0.40 (  0%)      65 kB (  0%)
 `- LRA virtuals elimination        :   0.06 (  0%)   0.00 (  0%)   0.05 (  0%)     143 kB (  0%)
 `- LRA create live ranges          :   0.07 (  0%)   0.01 (  1%)   0.08 (  0%)      11 kB (  0%)
 `- LRA hard reg assignment         :   0.03 (  0%)   0.00 (  0%)   0.03 (  0%)       0 kB (  0%)
 LRA virtuals elimination           :   0.06 (  0%)   0.00 (  0%)   0.05 (  0%)     143 kB (  0%)
 LRA create live ranges             :   0.07 (  0%)   0.01 (  1%)   0.08 (  0%)      11 kB (  0%)
 LRA hard reg assignment            :   0.03 (  0%)   0.00 (  0%)   0.03 (  0%)       0 kB (  0%)
 reload                             :   0.01 (  0%)   0.00 (  0%)   0.01 (  0%)       0 kB (  0%)
 `- integrated RA                   :   0.23 (  0%)   0.00 (  0%)   0.23 (  0%)       0 kB (  0%)
 `- LRA non-specific                :   0.11 (  0%)   0.00 (  0%)   0.11 (  0%)       0 kB (  0%)
 thread pro- & epilogue             :   0.16 (  0%)   0.00 (  0%)   0.16 (  0%)       2 kB (  0%)
 `- cfg cleanup                     :   0.05 (  0%)   0.00 (  0%)   0.04 (  0%)     401 kB (  0%)
 `- df live regs                    :   0.05 (  0%)   0.00 (  0%)   0.05 (  0%)       0 kB (  0%)
 machine dep reorg                  :   0.01 (  0%)   0.00 (  0%)   0.01 (  0%)       0 kB (  0%)
 shorten branches                   :   0.14 (  0%)   0.00 (  0%)   0.14 (  0%)       0 kB (  0%)
 final                              :   0.34 (  0%)   0.01 (  1%)   0.34 (  0%)    8094 kB (  4%)
 uninit var analysis                :   0.04 (  0%)   0.01 (  1%)   0.01 (  0%)       0 kB (  0%)
 `- alias stmt walking              :   0.01 (  0%)   0.01 (  1%)   0.07 (  0%)       0 kB (  0%)
 `- dominance computation           :   0.01 (  0%)   0.00 (  0%)   0.00 (  0%)       0 kB (  0%)
 initialize rtl                     :   0.01 (  0%)   0.00 (  0%)   0.01 (  0%)      12 kB (  0%)
 rest of compilation                :   0.20 (  0%)   0.00 (  0%)   0.17 (  0%)     116 kB (  0%)
 `- machine dep reorg               :   0.01 (  0%)   0.00 (  0%)   0.01 (  0%)       0 kB (  0%)
 `- final                           :   0.05 (  0%)   0.00 (  0%)   0.05 (  0%)    8016 kB (  3%)
 `- cfg construction                :   0.00 (  0%)   0.00 (  0%)   0.01 (  0%)       0 kB (  0%)
 `- integrated RA                   :   0.67 (  0%)   0.04 (  3%)   0.70 (  0%)   16448 kB (  7%)
 `- loop fini                       :   0.01 (  0%)   0.00 (  0%)   0.00 (  0%)       0 kB (  0%)
 `- shorten branches                :   0.14 (  0%)   0.00 (  0%)   0.14 (  0%)       0 kB (  0%)
 `- initialize rtl                  :   0.01 (  0%)   0.00 (  0%)   0.01 (  0%)      12 kB (  0%)
 `- df scan insns                   :   0.30 (  0%)   0.03 (  2%)   0.34 (  0%)       0 kB (  0%)
 `- tree CFG cleanup                :   0.01 (  0%)   0.00 (  0%)   0.01 (  0%)       0 kB (  0%)
 repair loop structures             :   0.00 (  0%)   0.00 (  0%)   0.00 (  0%)       0 kB (  0%)
 `- loop init                       :   0.02 (  0%)   0.00 (  0%)   0.03 (  0%)       0 kB (  0%)
 `- dominance computation           :   0.01 (  0%)   0.00 (  0%)   0.01 (  0%)       0 kB (  0%)
 TOTAL                              : 278.28          1.22        279.62         230025 kB
c gcc optimization compilation switch-statement
1个回答
0
投票

这是GCC 中的一个错误。它已在 GCC 11 中修复。

© www.soinside.com 2019 - 2024. All rights reserved.