有什么办法可以让GCC更快地编译一个switch语句吗?

有什么办法可以让GCC更快地编译一个switch语句吗?,c,gcc,optimization,compilation,switch-statement,C,Gcc,Optimization,Compilation,Switch Statement,我一直在研究产生C代码的程序。在一种模式下,它在一个开关语句中输出所有代码(打开程序计数器)。生成一个中等大小的输入文件,而GCC需要很长时间来编译它——在我的计算机上大约5分钟,在Github操作上大约10分钟。我用图表表示了GCC使用不同长度的switch语句编译文件所需的时间: 正如你所看到的,这是非线性的,每一千个案例比上一千个案例花费的时间更长 有什么方法可以加快GCC编译这个switch语句的速度吗?是否有任何可以插入到代码中的编译器提示,或者任何需要更改的设置(我已经在-O0中测

我一直在研究产生C代码的程序。在一种模式下,它在一个开关语句中输出所有代码(打开程序计数器)。生成一个中等大小的输入文件,而GCC需要很长时间来编译它——在我的计算机上大约5分钟,在Github操作上大约10分钟。我用图表表示了GCC使用不同长度的switch语句编译文件所需的时间:

正如你所看到的,这是非线性的,每一千个案例比上一千个案例花费的时间更长

有什么方法可以加快GCC编译这个switch语句的速度吗?是否有任何可以插入到代码中的编译器提示,或者任何需要更改的设置(我已经在-O0中测试并计时了)?这样一个具有许多稀疏情况的交换语句将被编译成一个二叉树,所以我考虑是否可以手动将其分割成100000到2000个的块,但这实际上并不能使编译更快;毕竟,我只是手工做编译器自己会做的事情。(我还没试过。)有什么想法吗

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

编辑:Nate Eldredge在评论中非常有帮助地指出,这是对GCC 8.4的回归。我现在有了


使用
-ftime报告-ftime报告详细信息编译的结果

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

你能发布一个反编译中典型代码的小例子吗?我想知道这是关于
开关本身,还是仅仅是函数中代码总量的问题。你可能想在gcc的bugzilla中提交一个报告。他们认为在-O0和-O1的过量编译时间是一个bug,并且对该问题的分析可以给出关于可能工作区的提示。GCC 84.0在大约3秒内编译,所以这看起来像是GCC 8和9之间的回归。我认为它值得一个bug报告。clang也很快(1.3秒),所以你可以把它作为一个临时的解决方法。