Время генерации кода - PullRequest
       1

Время генерации кода

3 голосов
/ 20 октября 2011

Для относительно простого (алгоритмического) языка, такого как C, сколько времени тратится на этапе генерации кода по сравнению с анализом / лексированием / семантическим анализом?Я заинтересован в более общем ответе или даже в том, что он довольно специфичен для реализации.

Ответы [ 4 ]

3 голосов
/ 20 октября 2011

Вы можете использовать GCC для выдачи статистики, используя -fstats. Вот пример резюме, созданного gcc4.5:

Execution times (seconds)
 callgraph construction:   0.05 ( 1%) usr   0.06 ( 2%) sys   0.14 ( 1%) wall    2885 kB ( 1%) ggc
 callgraph optimization:   0.14 ( 2%) usr   0.05 ( 2%) sys   0.26 ( 2%) wall    4433 kB ( 1%) ggc
 ipa cp                :   0.02 ( 0%) usr   0.00 ( 0%) sys   0.02 ( 0%) wall     430 kB ( 0%) ggc
 ipa reference         :   0.01 ( 0%) usr   0.00 ( 0%) sys   0.02 ( 0%) wall      11 kB ( 0%) ggc
 ipa pure const        :   0.03 ( 0%) usr   0.01 ( 0%) sys   0.04 ( 0%) wall      31 kB ( 0%) ggc
 ipa SRA               :   0.02 ( 0%) usr   0.00 ( 0%) sys   0.08 ( 1%) wall    5280 kB ( 2%) ggc
 cfg cleanup           :   0.08 ( 1%) usr   0.02 ( 1%) sys   0.12 ( 1%) wall     102 kB ( 0%) ggc
 trivially dead code   :   0.03 ( 0%) usr   0.00 ( 0%) sys   0.05 ( 0%) wall       0 kB ( 0%) ggc
 df multiple defs      :   0.03 ( 0%) usr   0.00 ( 0%) sys   0.01 ( 0%) wall       0 kB ( 0%) ggc
 df reaching defs      :   0.04 ( 0%) usr   0.00 ( 0%) sys   0.00 ( 0%) wall       0 kB ( 0%) ggc
 df live regs          :   0.06 ( 1%) usr   0.01 ( 0%) sys   0.17 ( 1%) wall       0 kB ( 0%) ggc
 df live&initialized regs:   0.05 ( 1%) usr   0.00 ( 0%) sys   0.08 ( 1%) wall       0 kB ( 0%) ggc
 df use-def / def-use chains:   0.01 ( 0%) usr   0.00 ( 0%) sys   0.02 ( 0%) wall       0 kB ( 0%) ggc
 df reg dead/unused notes:   0.08 ( 1%) usr   0.01 ( 0%) sys   0.08 ( 1%) wall    1165 kB ( 0%) ggc
 register information  :   0.02 ( 0%) usr   0.01 ( 0%) sys   0.03 ( 0%) wall       0 kB ( 0%) ggc
 alias analysis        :   0.07 ( 1%) usr   0.01 ( 0%) sys   0.06 ( 0%) wall    2993 kB ( 1%) ggc
 alias stmt walking    :   0.05 ( 1%) usr   0.02 ( 1%) sys   0.10 ( 1%) wall       5 kB ( 0%) ggc
 register scan         :   0.01 ( 0%) usr   0.00 ( 0%) sys   0.00 ( 0%) wall      10 kB ( 0%) ggc
 rebuild jump labels   :   0.02 ( 0%) usr   0.01 ( 0%) sys   0.05 ( 0%) wall       0 kB ( 0%) ggc
 preprocessing         :   0.16 ( 2%) usr   0.15 ( 6%) sys   0.34 ( 3%) wall    1508 kB ( 0%) ggc
 parser                :   0.99 (12%) usr   0.36 (14%) sys   1.24 (10%) wall  102915 kB (33%) ggc
 name lookup           :   0.50 ( 6%) usr   0.68 (26%) sys   1.25 (10%) wall   19025 kB ( 6%) ggc
 inline heuristics     :   0.10 ( 1%) usr   0.02 ( 1%) sys   0.13 ( 1%) wall    2310 kB ( 1%) ggc
 integration           :   0.24 ( 3%) usr   0.08 ( 3%) sys   0.29 ( 2%) wall   32982 kB (10%) ggc
 tree gimplify         :   0.12 ( 1%) usr   0.00 ( 0%) sys   0.06 ( 0%) wall   10967 kB ( 3%) ggc
 tree eh               :   0.02 ( 0%) usr   0.00 ( 0%) sys   0.02 ( 0%) wall    2932 kB ( 1%) ggc
 tree CFG construction :   0.01 ( 0%) usr   0.00 ( 0%) sys   0.04 ( 0%) wall    6725 kB ( 2%) ggc
 tree CFG cleanup      :   0.15 ( 2%) usr   0.03 ( 1%) sys   0.15 ( 1%) wall     531 kB ( 0%) ggc
 tree VRP              :   0.11 ( 1%) usr   0.00 ( 0%) sys   0.12 ( 1%) wall    9477 kB ( 3%) ggc
 tree copy propagation :   0.09 ( 1%) usr   0.01 ( 0%) sys   0.09 ( 1%) wall    2850 kB ( 1%) ggc
 tree find ref. vars   :   0.02 ( 0%) usr   0.00 ( 0%) sys   0.03 ( 0%) wall     422 kB ( 0%) ggc
 tree PTA              :   0.27 ( 3%) usr   0.00 ( 0%) sys   0.33 ( 3%) wall    2279 kB ( 1%) ggc
 tree PHI insertion    :   0.02 ( 0%) usr   0.00 ( 0%) sys   0.00 ( 0%) wall     325 kB ( 0%) ggc
 tree SSA rewrite      :   0.04 ( 0%) usr   0.00 ( 0%) sys   0.06 ( 0%) wall    5069 kB ( 2%) ggc
 tree SSA other        :   0.02 ( 0%) usr   0.03 ( 1%) sys   0.06 ( 0%) wall     547 kB ( 0%) ggc
 tree SSA incremental  :   0.15 ( 2%) usr   0.03 ( 1%) sys   0.17 ( 1%) wall     819 kB ( 0%) ggc
 tree operand scan     :   0.12 ( 1%) usr   0.08 ( 3%) sys   0.25 ( 2%) wall   16876 kB ( 5%) ggc
 dominator optimization:   0.07 ( 1%) usr   0.02 ( 1%) sys   0.04 ( 0%) wall    2663 kB ( 1%) ggc
 tree SRA              :   0.04 ( 0%) usr   0.01 ( 0%) sys   0.02 ( 0%) wall      94 kB ( 0%) ggc
 tree CCP              :   0.07 ( 1%) usr   0.00 ( 0%) sys   0.06 ( 0%) wall    2507 kB ( 1%) ggc
 tree PHI const/copy prop:   0.01 ( 0%) usr   0.00 ( 0%) sys   0.00 ( 0%) wall       7 kB ( 0%) ggc
 tree split crit edges :   0.00 ( 0%) usr   0.00 ( 0%) sys   0.02 ( 0%) wall     991 kB ( 0%) ggc
 tree reassociation    :   0.02 ( 0%) usr   0.00 ( 0%) sys   0.02 ( 0%) wall     888 kB ( 0%) ggc
 tree PRE              :   0.15 ( 2%) usr   0.02 ( 1%) sys   0.15 ( 1%) wall    3586 kB ( 1%) ggc
 tree FRE              :   0.07 ( 1%) usr   0.01 ( 0%) sys   0.14 ( 1%) wall    2627 kB ( 1%) ggc
 tree code sinking     :   0.00 ( 0%) usr   0.00 ( 0%) sys   0.03 ( 0%) wall     470 kB ( 0%) ggc
 tree linearize phis   :   0.02 ( 0%) usr   0.00 ( 0%) sys   0.02 ( 0%) wall      17 kB ( 0%) ggc
 tree forward propagate:   0.02 ( 0%) usr   0.00 ( 0%) sys   0.03 ( 0%) wall     878 kB ( 0%) ggc
 tree phiprop          :   0.01 ( 0%) usr   0.00 ( 0%) sys   0.00 ( 0%) wall      24 kB ( 0%) ggc
 tree conservative DCE :   0.03 ( 0%) usr   0.04 ( 2%) sys   0.04 ( 0%) wall      27 kB ( 0%) ggc
 tree aggressive DCE   :   0.12 ( 1%) usr   0.01 ( 0%) sys   0.15 ( 1%) wall    7686 kB ( 2%) ggc
 tree DSE              :   0.08 ( 1%) usr   0.00 ( 0%) sys   0.03 ( 0%) wall     285 kB ( 0%) ggc
 PHI merge             :   0.00 ( 0%) usr   0.01 ( 0%) sys   0.01 ( 0%) wall      44 kB ( 0%) ggc
 tree loop bounds      :   0.00 ( 0%) usr   0.01 ( 0%) sys   0.01 ( 0%) wall      33 kB ( 0%) ggc
 tree loop invariant motion:   0.01 ( 0%) usr   0.00 ( 0%) sys   0.00 ( 0%) wall       0 kB ( 0%) ggc
 complete unrolling    :   0.00 ( 0%) usr   0.00 ( 0%) sys   0.01 ( 0%) wall    1000 kB ( 0%) ggc
 tree vectorization    :   0.02 ( 0%) usr   0.00 ( 0%) sys   0.02 ( 0%) wall     686 kB ( 0%) ggc
 tree slp vectorization:   0.06 ( 1%) usr   0.00 ( 0%) sys   0.07 ( 1%) wall    4623 kB ( 1%) ggc
 tree iv optimization  :   0.02 ( 0%) usr   0.00 ( 0%) sys   0.00 ( 0%) wall     671 kB ( 0%) ggc
 predictive commoning  :   0.01 ( 0%) usr   0.00 ( 0%) sys   0.01 ( 0%) wall      58 kB ( 0%) ggc
 tree loop init        :   0.00 ( 0%) usr   0.00 ( 0%) sys   0.01 ( 0%) wall     824 kB ( 0%) ggc
 tree NRV optimization :   0.01 ( 0%) usr   0.00 ( 0%) sys   0.02 ( 0%) wall      18 kB ( 0%) ggc
 tree rename SSA copies:   0.03 ( 0%) usr   0.00 ( 0%) sys   0.02 ( 0%) wall       0 kB ( 0%) ggc
 dominance frontiers   :   0.01 ( 0%) usr   0.01 ( 0%) sys   0.01 ( 0%) wall       0 kB ( 0%) ggc
 dominance computation :   0.27 ( 3%) usr   0.04 ( 2%) sys   0.23 ( 2%) wall       0 kB ( 0%) ggc
 control dependences   :   0.00 ( 0%) usr   0.01 ( 0%) sys   0.01 ( 0%) wall       0 kB ( 0%) ggc
 expand                :   0.93 (11%) usr   0.34 (13%) sys   1.18 (10%) wall   22542 kB ( 7%) ggc
 varconst              :   0.02 ( 0%) usr   0.00 ( 0%) sys   0.03 ( 0%) wall     456 kB ( 0%) ggc
 jump                  :   0.00 ( 0%) usr   0.01 ( 0%) sys   0.00 ( 0%) wall     351 kB ( 0%) ggc
 forward prop          :   0.08 ( 1%) usr   0.01 ( 0%) sys   0.10 ( 1%) wall    1368 kB ( 0%) ggc
 CSE                   :   0.13 ( 2%) usr   0.00 ( 0%) sys   0.12 ( 1%) wall     162 kB ( 0%) ggc
 dead code elimination :   0.03 ( 0%) usr   0.00 ( 0%) sys   0.05 ( 0%) wall       0 kB ( 0%) ggc
 dead store elim1      :   0.11 ( 1%) usr   0.00 ( 0%) sys   0.05 ( 0%) wall     612 kB ( 0%) ggc
 dead store elim2      :   0.13 ( 2%) usr   0.00 ( 0%) sys   0.09 ( 1%) wall     932 kB ( 0%) ggc
 loop analysis         :   0.02 ( 0%) usr   0.00 ( 0%) sys   0.01 ( 0%) wall     503 kB ( 0%) ggc
 loop invariant motion :   0.01 ( 0%) usr   0.01 ( 0%) sys   0.01 ( 0%) wall      67 kB ( 0%) ggc
 CPROP                 :   0.13 ( 2%) usr   0.00 ( 0%) sys   0.10 ( 1%) wall    1024 kB ( 0%) ggc
 PRE                   :   0.01 ( 0%) usr   0.00 ( 0%) sys   0.02 ( 0%) wall     118 kB ( 0%) ggc
 CSE 2                 :   0.09 ( 1%) usr   0.02 ( 1%) sys   0.05 ( 0%) wall     221 kB ( 0%) ggc
 branch prediction     :   0.03 ( 0%) usr   0.02 ( 1%) sys   0.06 ( 0%) wall    1578 kB ( 1%) ggc
 combiner              :   0.10 ( 1%) usr   0.00 ( 0%) sys   0.08 ( 1%) wall     679 kB ( 0%) ggc
 if-conversion         :   0.01 ( 0%) usr   0.00 ( 0%) sys   0.06 ( 0%) wall     953 kB ( 0%) ggc
 regmove               :   0.02 ( 0%) usr   0.00 ( 0%) sys   0.02 ( 0%) wall       1 kB ( 0%) ggc
 integrated RA         :   0.35 ( 4%) usr   0.00 ( 0%) sys   0.34 ( 3%) wall    4128 kB ( 1%) ggc
 reload                :   0.20 ( 2%) usr   0.01 ( 0%) sys   0.31 ( 3%) wall    2554 kB ( 1%) ggc
 reload CSE regs       :   0.11 ( 1%) usr   0.00 ( 0%) sys   0.13 ( 1%) wall    1551 kB ( 0%) ggc
 load CSE after reload :   0.01 ( 0%) usr   0.00 ( 0%) sys   0.01 ( 0%) wall       1 kB ( 0%) ggc
 thread pro- & epilogue:   0.03 ( 0%) usr   0.00 ( 0%) sys   0.08 ( 1%) wall    3980 kB ( 1%) ggc
 if-conversion 2       :   0.01 ( 0%) usr   0.00 ( 0%) sys   0.01 ( 0%) wall     456 kB ( 0%) ggc
 combine stack adjustments:   0.00 ( 0%) usr   0.00 ( 0%) sys   0.01 ( 0%) wall       0 kB ( 0%) ggc
 peephole 2            :   0.01 ( 0%) usr   0.00 ( 0%) sys   0.05 ( 0%) wall     124 kB ( 0%) ggc
 hard reg cprop        :   0.06 ( 1%) usr   0.00 ( 0%) sys   0.05 ( 0%) wall      31 kB ( 0%) ggc
 scheduling 2          :   0.42 ( 5%) usr   0.02 ( 1%) sys   0.36 ( 3%) wall     630 kB ( 0%) ggc
 machine dep reorg     :   0.04 ( 0%) usr   0.00 ( 0%) sys   0.04 ( 0%) wall       6 kB ( 0%) ggc
 reorder blocks        :   0.04 ( 0%) usr   0.00 ( 0%) sys   0.06 ( 0%) wall     919 kB ( 0%) ggc
 final                 :   0.05 ( 1%) usr   0.00 ( 0%) sys   0.10 ( 1%) wall    1187 kB ( 0%) ggc
 symout                :   0.02 ( 0%) usr   0.01 ( 0%) sys   0.04 ( 0%) wall     148 kB ( 0%) ggc
 plugin execution      :   0.18 ( 2%) usr   0.32 (12%) sys   0.43 ( 4%) wall       0 kB ( 0%) ggc
 TOTAL                 :   8.48             2.64            12.15             315665 kB
1 голос
/ 21 октября 2011

C компиляторы тратят большую часть своего времени на чтение заголовочных файлов по моему опыту.Раньше я использовал компилятор C, который печатал статистику об этом, и даже довольно простые 100-строчные файлы содержали бы 10 000 строк заголовков, если бы они выполняли достаточно системных вызовов.

1 голос
/ 20 октября 2011

Ответ на этот вопрос действительно зависит от компилятора и алгоритмов, выбранных для каждой фазы.В целом, лексирование / разбор будет очень дешевым, анализ и оптимизация будут дорогостоящими, а генерация кода будет где-то посередине.

Генерация кода обычно включает в себя выбор команд, планирование и распределение регистров.В зависимости от вашего компилятора могут быть другие этапы.

  • Выбор инструкций - это процесс перевода вашего промежуточного представления в специфичные для архитектуры инструкции.Самый простой способ сделать это - просто иметь фиксированную последовательность для каждой инструкции IR;это даст плохой код, но очень быстро, так что вы можете увидеть это в JIT-компиляторе.В заранее скомпилированных языках, таких как C, у вас будет алгоритм «тайлинга», который покрывает ваш IR тайлами, представляющими машинные инструкции.Существуют различные алгоритмы, такие как maximal много, жадный алгоритм, используемый LLVM.Все известные мне алгоритмы O (n), но некоторые принимают несколько проходов.В общем, чем более оптимальным является мозаичное построение, тем дольше это занимает.
  • Планирование инструкций позволяет упорядочить инструкции так, чтобы они выполнялись с минимальным количеством остановок на конкретном ЦП.Этот этап сильно зависит от процессора (а не только от архитектуры).Эта фаза является необязательной.
  • Распределение регистров - это присвоение переменных регистрам или слотам стека.Опять же, есть несколько алгоритмов.Раскраска графа хороша, но она должна быть аппроксимирована, так как истинная раскраска графа является NP-полной.Линейное сканирование (используется LLVM) намного быстрее, но не так хорошо.Оба алгоритма O (n).
0 голосов
/ 20 октября 2011

По генерации кода, я полагаю, вы имеете в виду генерацию объектного кода? Если так, то это относительно быстрый процесс. Большинство компиляторов используют одно или несколько промежуточных представлений (IR) для упрощения анализа / оптимизации. К тому времени, когда этот IR должен быть сгенерирован в объектный код, он находится на относительно низком уровне и, таким образом, очень похож на целевой код объекта. Это делает его чрезвычайно простым для вывода объектного кода. Должна быть возможность генерировать этот окончательный объектный код за один проход.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...