Níveis de otimização do Clang

91

No gcc, o manual explica o que -O3, -Osetc. traduzir para em termos de argumentos de otimização específica ( -funswitch-loops, -fcompare-elim, etc.)

Estou procurando as mesmas informações para o clang .

Procurei online e no man clangqual só dá informações gerais ( -O2otimiza mais que -O1, -Osotimiza para velocidade, ...) e também procurei aqui no Stack Overflow e encontrei isso , mas não encontrei nada relevante nos arquivos de origem citados.

Edit: Eu encontrei uma resposta, mas ainda estou interessado se alguém tiver um link para um manual do usuário documentando todas as passagens de otimização e as passagens selecionadas por . Atualmente encontrei apenas esta lista de passes, mas nada sobre os níveis de otimização.-Ox

Antoine
fonte

Respostas:

156

Eu encontrei esta questão relacionada.

Resumindo, para saber mais sobre os passos de otimização do compilador:

llvm-as < /dev/null | opt -O3 -disable-output -debug-pass=Arguments

Conforme apontado na resposta de Geoff Nixon (+1), clangadicionalmente executa algumas otimizações de nível superior, que podemos recuperar com:

echo 'int;' | clang -xc -O3 - -o /dev/null -\#\#\#

A documentação de passes individuais está disponível aqui .



Com a versão 6.0, os passes são os seguintes:

  • linha de base ( -O0):

    • optconjuntos : -tti -verify -ee-instrument -targetlibinfo -assumption-cache-tracker -profile-summary-info -forceattrs -basiccg -sempre-inline -barrier
    • clangadiciona : -mdisable-fp-elim -mrelax-all
  • -O1 é baseado em -O0

    • opt adiciona:-targetlibinfo -tti -tbaa -scoped-noalias -assumption-cache-tracker -profile-summary-info -forceattrs -inferattrs -ipsccp -called-value-propagation -globalopt -domtree -mem2reg -deadargelim -basicaa -aa -loops -l -branch-prob -lazy-block-freq -opt-note-emitter -instcombine -simplifycfg -basiccg -globals-aa -prune-eh -sempre-inline -functionattrs -sroa -memoryssa -inicial-cse-memssa-execução especulativa -lazy-value-info -jump-threading -correlated-propagation -libcalls-shrinkwrap -branch-prob -block-freq -pgo-memop-opt -tailcallelim -reassociate -loop-simplify -lcssa-verification -lcssa -scalar-evolution -loop-rotate -licm -loop-unswitch -indvars -loop-idiom -loop-deletion -loop-unroll -memdep -memcpyopt -sccp-demanded-bits -bdce -dse -postdomtree -adce -barrier -rpo-functionattrs -globaldce -float2int -loop-accesses -loop-distrib-loop-vectorize -loop-load-elim -alignment-from-presuposições -strip-dead-prototypes -loop-sink -instsimplify -div-rem-pairs -verify -ee-instrument -early-cse -lower-expect
    • clangadiciona : -momit-leaf-frame-pointer
    • clangdrops : -mdisable-fp-elim -mrelax-all
  • -O2 é baseado em -O1

    • optadiciona : -inline -mldst-motion -gvn -elim-avail-extern -slp-vectorizer -constmerge
    • optgotas : -sempre-em linha
    • clangadiciona : -vectorize-loops -vectorize-slp
  • -O3 é baseado em -O2

    • optadiciona : -callsite-splitting -argpromotion
  • -Ofasté baseado em -O3, válido em, clangmas não emopt

    • clangadiciona : -fno-assinado-zeros -freciprocal-math -ffp-contract = rápido -menable-inseguro-fp-math -menable-no-nans -menable-no-infs -mreassociate -fno-trapping-math -ffast-math -finito-matemática apenas
  • -Os é similar a -O2

    • optdrops : -libcalls-shrinkwrap e -pgo-memopt-opt
  • -Oz é baseado em -Os

    • optdrops : -slp-vectorizer

Com a versão 3.8, os passes são os seguintes:

  • linha de base ( -O0):

    • optconjuntos : -targetlibinfo -tti -verify
    • clangadiciona : -mdisable-fp-elim -mrelax-all
  • -O1 é baseado em -O0

    • optadiciona : -globalopt -demanded-bits -branch-prob -inferattrs -ipsccp -dse -loop-simplify -scoped-noalias -barrier -adce -deadargelim -memdep -licm -globals-aa -rpo-functionattrs -basiccg -loop-idiom -forceattrs -mem2reg -simplifycfg -early-cse -instcombine -sccp -loop-unswitch -loop-vetorize -tailcallelim -functionattrs -loop-accesses -memcpyopt -loop-deletion -reassociate -strip-deadorrbasated-prototypes -copas -propagation -lcssa -domtree -always-inline -aa -block-freq -float2int -lower-expect -sroa -loop-unroll -alignment-from-presumindo -lazy-value-info -prune-eh -jump-threading -loop -rotate -indvars -bdce -scalar-evolution -tbaa -assumption-cache-tracker
    • clangadiciona : -momit-leaf-frame-pointer
    • clangdrops : -mdisable-fp-elim -mrelax-all
  • -O2 é baseado em -O1

    • optadiciona : -elim-avail-extern -mldst-motion -slp-vectorizer -gvn -inline -globaldce -constmerge
    • optgotas : -sempre-em linha
    • clangadiciona : -vectorize-loops -vectorize-slp
  • -O3 é baseado em -O2

    • optadiciona : -argpromotion
  • -Ofasté baseado em -O3, válido em, clangmas não emopt

    • clangadiciona : -fno-assinado-zeros -freciprocal-math -ffp-contract = rápido -menable-inseguro-fp-math -menable-no-nans -menable-no-infs
  • -Os é o mesmo que -O2

  • -Oz é baseado em -Os

    • optdrops : -slp-vectorizer
    • clangdrops : -vectorize-loops


Com a versão 3.7, os passos são os seguintes (resultado analisado do comando acima):

  • padrão (-O0): -targetlibinfo -verify -tti

  • -O1 é baseado em -O0

    • adiciona : -sccp -loop-simplify -float2int -lazy-value-info -correlated-propagation -bdce -lcssa -deadargelim -loop-unroll -loop-vectorize -barrier -memcpyopt -loop-accesses -assumption-cache-tracker -reassociate -loop-deletion -branch-prob -jump-threading -domtree -dse -loop-rotate -ipsccp -instcombine -scoped-noalias -licm -prune-eh -loop-unswitch -alinhamento-de-suposições -inicial-cse -inline -cost -simplifycfg -strip-dead-prototypes -tbaa -sroa -no-aa -adce -functionattrs -lower-expect -basiccg -loops -loop-idiom -tailcallelim -basicaa -indvars -globalopt -block-freq -scalar-evolution -memdep -sempre-em linha
  • -O2 é baseado em -01

    • adiciona : -elim-avail-extern -globaldce -inline -constmerge -mldst-motion -gvn -slp-vectorizer
    • remove : -sempre-inline
  • -O3 é baseado em -O2

    • adiciona : -argpromotion -verif
  • -Os é idêntico a -O2

  • -Oz é baseado em -Os

    • remove : -slp-vectorizer


Para a versão 3.6, os passes estão documentados na postagem de GYUNGMIN KIM.


Com a versão 3.5, os passos são os seguintes (resultado analisado do comando acima):

  • padrão (-O0): -targetlibinfo -verify -verify-di

  • -O1 é baseado em -O0

    • adiciona : -correlated-propagation -basiccg -simplifycfg -no-aa -jump-threading -sroa -loop-unswitch -ipsccp -instcombine -memdep -memcpyopt -barrier -block-freq -loop-simplify -loop-vectorize -inline-cost -branch-prob -early-cse -lazy-value-info -loop-rotate -strip-dead-prototypes -loop-deletion -tbaa -prune-eh -indvars -loop-unroll -reassociate -loops -sccp -sempre-inline -basicaa -dse -globalopt -tailcallelim -functionattrs -deadargelim -notti -scalar-evolution -lower-expect -licm -loop-idiom -adce -domtree -lcssa
  • -O2 é baseado em -01

    • adiciona : -gvn -constmerge -globaldce -slp-vectorizer -mldst-motion -inline
    • remove : -sempre-inline
  • -O3 é baseado em -O2

    • adiciona : -argpromotion
  • -Os é idêntico a -O2

  • -Oz é baseado em -Os

    • remove : -slp-vectorizer


Com a versão 3.4, os passos são os seguintes (resultado analisado do comando acima):

  • -O0: -targetlibinfo -preverify -domtree -verify

  • -O1 é baseado em -O0

    • adiciona : -adce -always-inline -basicaa -basiccg -correlated-propagation -deadargelim -dse -early-cse -functionattrs -globalopt -indvars -inline-cost -instcombine -ipsccp -jump-threading -lazy-value-info -lcssa -licm -loop-deletion -loop-idiom -loop-rotate -loop-simplify -loop-unroll -loop-unswitch -loops -lower-expect -memcpyopt -memdep -no-aa -notti -prune-eh -reassociate -scalar -evolution -sccp -simplifycfg -sroa -strip-dead-prototypes -tailcallelim -tbaa
  • -O2 é baseado em -01

    • adiciona : -barrier -constmerge -domtree -globaldce -gvn -inline -loop-vectorize -preverify -slp-vectorizer -targetlibinfo -verify
    • remove : -sempre-inline
  • -O3 é baseado em -O2

    • adiciona : -argpromotion
  • -Os é idêntico a -O2

  • -Oz é baseado em -O2

    • remove : -barrier -loop-vectorize -slp-vectorizer


Com a versão 3.2, os passos são os seguintes (resultado analisado do comando acima):

  • -O0: -targetlibinfo -preverify -domtree -verify

  • -O1 é baseado em -O0

    • adiciona : -sroa -early-cse -lower-expect -no-aa -tbaa -basicaa -globalopt -ipsccp -deadargelim -instcombine -simplifycfg -basiccg -prune-eh -sempre-inline -funçãoattrs -simplify-libcalls -lazy-value -info -jump-threading -correlated-propagation -tailcallelim -reassociate -loops -loop-simplify -lcssa -loop-rotate -licm -loop-unswitch -scalar-evolution -indvars -loop-idiom -loop-deletion -loop-unroll -memdep -memcpyopt -sccp -dse -adce -strip-dead-prototypes
  • -O2 é baseado em -01

    • adiciona : -inline -globaldce -constmerge
    • remove : -sempre-inline
  • -O3 é baseado em -O2

    • adiciona : -argpromotion
  • -Os é idêntico a -O2

  • -Oz é idêntico a -Os


Editar [março de 2014] removeu duplicatas das listas.

Editar [abril de 2014] adicionado link de documentação + opções para 3.4

Editar [setembro de 2014] opções adicionadas para 3.5

Editar [dezembro de 2015] adicionou opções para 3.7 e mencionar a resposta existente para 3.6

Editar [maio de 2016] opções adicionadas para 3.8, para opt e clang e mencionar a resposta existente para clang (versus opt)

Editar [nov 2018] adicionar opções para 6.0

Antoine
fonte
2
Existe uma maneira de fazer isso com a versão do clang que acompanha o XCode5? Tentei procurar o comando llvm-as, mas ele não existe em minha máquina em nenhum lugar que eu possa ver
Teknogrebo
@Antoine, por que algumas bandeiras, como -simplifycfgse repetem?
Paschalis
2
@Paschalis: Não tenho certeza, mas como alguns passes de otimização só funcionam se alguns outros passes foram executados e, por exemplo, simplifycfgsão necessários para vários passes. E debug-pass=Argumentsprovavelmente acontece antes da desduplicação. Removi as duplicatas em minha resposta, obrigado por seus comentários.
Antoine
5
Algumas otimizações criam coisas que podem ser otimizadas ainda mais (código morto, etc.), portanto, pode fazer sentido executar novamente alguns passos de otimização.
cyco130
1
@ZachB / @Antoine Por que não (também?) LLVM 7 (ou foi isso que você quis dizer?) Além disso: 1. Não tenho certeza há quanto tempo está lá, mas também há -Ogum GCC agora; 2. Todas as especificações para as versões anteriores ainda são necessárias? 3. Acho que, dadas as boas mudanças que foram feitas ao longo dos anos, e o status da comunidade, vou reduzir minha resposta para apenas mencionar coisas como clang -cc1 -mllvm -help-list-hidden(a menos que você prefira integrá-las).
Geoff Nixon
15

A resposta de @Antoine (e a outra pergunta vinculada) descreve com precisão as otimizações do LLVM que estão habilitadas, mas existem algumas outras opções específicas do Clang (ou seja, aquelas que afetam a redução para o AST) que são afetadas pelos -O[0|1|2|3|fast]sinalizadores.

Você pode dar uma olhada nisso com:

echo 'int;' | clang -xc -O0 - -o /dev/null -\#\#\#

echo 'int;' | clang -xc -O1 - -o /dev/null -\#\#\#

echo 'int;' | clang -xc -O2 - -o /dev/null -\#\#\#

echo 'int;' | clang -xc -O3 - -o /dev/null -\#\#\#

echo 'int;' | clang -xc -Ofast - -o /dev/null -\#\#\#

Por exemplo, -O0permite -mrelax-all, -O1permite -vectorize-loopse -vectorize-slp, e -Ofastpermite -menable-no-infs, -menable-no-nans, -menable-unsafe-fp-math, -ffp-contract=faste -ffast-math.


@Techogrebo:

Sim, não necessariamente não precisa das outras ferramentas LLVM. Experimentar:

echo 'int;' | clang -xc - -o /dev/null -mllvm -print-all-options

Além disso, existem opções muito mais detalhadas que você pode examinar / modificar apenas com o Clang ... você só precisa saber como acessá-las!

Experimente alguns dos seguintes:

clang -help

clang -cc1 -help

clang -cc1 -mllvm -help

clang -cc1 -mllvm -help-list-hidden

clang -cc1as -help

Geoff Nixon
fonte
3

LLVM 3.6 -O1

Argumentos de aprovação:-targetlibinfo -no-aa -tbaa -scoped-noalias -assumption-cache-tracker -basicaa -notti -verify-di -ipsccp -globalopt -deadargelim -domtree -instcombine -simplifycfg -basiccg -prune-eh -inline-cost -always -inline -functionattrs -sroa -domtree -early-cse -lazy-value-info -jump-threading -correlated-propagation -simplifycfg -domtree -instcombine -tailcallelim -simplifycfg -reassociate -domtree -loops -loopsa-simplify -lcs -rotate -licm -loop-unswitch -instcombine -scalar-evolution -loop-simplify -lcssa -indvars -loop-idiom -loop-deletion -function_tti -loop-unroll -memdep -memcpyopt -sccp -domtree -instcombine -lazy-value -info -jump-threading -correlated-propagation -domtree -memdep -dse -adce -simplifycfg -domtree -instcombine -barrier -domtree -loops -loop-simplify -lcssa -branch-prob -block-freq -scalar-evolution -loop -vectorize -instcombine-simplifycfg -domtree -instcombine -loops -loop-simplify -lcssa -scalar-evolution -function_tti -loop-unroll -alignment-from-presupostos -strip-dead-prototypes -verify -verify-di

-O2 com base em -O1

adicionar: -inline -mldst-motion -domtree -memdep -gvn -memdep -scalar-evolution -slp-vectorizer -globaldce -constmerge

e remove: -sempre-inline

-O3 baseado em -O2

adicionar: -argpromotion

GYUNGMIN KIM
fonte