ti-enxame.com

clang: como listar arquiteturas de destino suportadas?

Atualmente estou interessado em ARM em geral e especificamente em alvos iphone/Android. Mas eu só quero saber mais sobre o clang, já que parece desempenhar um papel importante nos próximos anos.

Eu tentei

clang -cc1 --help|grep -i list
clang -cc1 --help|grep Arch|grep -v search
clang -cc1 --help|grep target

 -triple <value>         Specify target triple (e.g. i686-Apple-darwin9)

Eu sei que o clang tem o parâmetro -triplet, mas como posso listar todos os valores possíveis para ele? Eu achei que o clang é muito diferente do gcc em relação à compilação cruzada, no mundo do GCC você deve ter um binário separado para tudo, como PLATFORM_make ou PLATFORM_ld (i * 86-pc-cygwin i * 86 - * - linux-gnu etc. - http://git.savannah.gnu.org/cgit/libtool.git/tree/doc/PLATFORMS )

no mundo clang, é apenas um binário (como eu li em alguns fóruns). Mas como obtenho a lista de alvos suportados? E se o meu destino não suportado na minha distro (linux/windows/macos/whatever) como posso obter aquele que suporta mais plataforma?

se eu SVN mais recente clang como este:

svn co http://llvm.org/svn/llvm-project/cfe/trunk clang

vou conseguir a maioria das plataformas? Parece que o Clang não foi construído com a compilação cruzada em mente de imediato, mas como é baseado no llvm, deveria ser muito amigável em teoria? obrigado!

75
exebook

Tanto quanto eu posso dizer, não há nenhuma opção de linha de comando para listar quais arquiteturas um dado binário clang suporta, e mesmo rodar strings nele realmente não ajuda. O Clang é essencialmente apenas um conversor de C para LLVM, e é o próprio LLVM que lida com o âmago da questão de como gerar o código de máquina real, portanto não é totalmente surpreendente que o Clang não esteja prestando muita atenção à arquitetura subjacente.

Como outros já observaram, você pode perguntar llc quais arquiteturas ele suporta. Isso não é tão útil não apenas porque esses componentes do LLVM podem não estar instalados, mas devido aos caprichos dos caminhos de busca e sistemas de empacotamento, seus binários llc e clang podem não corresponder à mesma versão do LLVM.

No entanto, para fins de argumentação, digamos que você tenha compilado o LLVM e o Clang ou que esteja feliz em aceitar seus binários do LLVM como bons o suficiente:

  • llc --version fornecerá uma lista de todas as arquiteturas que ele suporta. Por padrão, é compilado para suportar todas as arquiteturas. O que você pode pensar como uma arquitetura única como ARM pode ter várias arquiteturas de LLVM, como ARM normal, Thumb e AArch64. Isto é principalmente para conveniência de implementação porque os diferentes modos de execução têm codificações e semânticas de instrução muito diferentes.
  • Para cada uma das arquiteturas listadas, llc -march=Arch -mattr=help listará "CPUs disponíveis" e "recursos disponíveis". As CPUs geralmente são apenas uma forma conveniente de configurar uma coleção padrão de recursos.

Mas agora para as más notícias. Não existe uma tabela conveniente de triplas em Clang ou LLVM que possa ser descartada, porque os backends específicos da arquitetura têm a opção de analisar a tripla string em um objeto llvm::Triple (definido em include/llvm/ADT/Triple.h ). Em outras palavras, para descarregar todos os triplos disponíveis, é necessário resolver o problema da parada. Veja, por exemplo, llvm::ARM_MC::ParseARMTriple(...) quais casos especiais analisando a string "generic".

Em última análise, porém, o "triplo" é principalmente um recurso de compatibilidade com versões anteriores para tornar o Clang um substituto direto do GCC, portanto, você geralmente não precisa prestar muita atenção a ele, a menos que esteja portando o Clang ou o LLVM para uma nova plataforma ou arquitetura. Em vez disso, você provavelmente encontrará a saída llc -march=arm -mattr=help e incompreensível na enorme variedade de recursos ARM diferentes para ser mais útil em suas investigações.

Boa sorte com sua pesquisa!

38
pndc

Eu estou usando o Clang 3.3, acho que a melhor maneira de obter a resposta é ler o código-fonte. em llvm/ADT/Triple.h ( http://llvm.org/doxygen/Triple_8h_source.html ):

  enum ArchType {
    UnknownArch,

    arm,     // ARM: arm, armv.*, xscale
    aarch64, // AArch64: aarch64
    hexagon, // Hexagon: hexagon
    mips,    // MIPS: mips, mipsallegrex
    mipsel,  // MIPSEL: mipsel, mipsallegrexel
    mips64,  // MIPS64: mips64
    mips64el,// MIPS64EL: mips64el
    msp430,  // MSP430: msp430
    ppc,     // PPC: powerpc
    ppc64,   // PPC64: powerpc64, ppu
    r600,    // R600: AMD GPUs HD2XXX - HD6XXX
    sparc,   // Sparc: sparc
    sparcv9, // Sparcv9: Sparcv9
    systemz, // SystemZ: s390x
    tce,     // TCE (http://tce.cs.tut.fi/): tce
    thumb,   // Thumb: thumb, thumbv.*
    x86,     // X86: i[3-9]86
    x86_64,  // X86-64: AMD64, x86_64
    xcore,   // XCore: xcore
    mblaze,  // MBlaze: mblaze
    nvptx,   // NVPTX: 32-bit
    nvptx64, // NVPTX: 64-bit
    le32,    // le32: generic little-endian 32-bit CPU (PNaCl / Emscripten)
    amdil,   // amdil: AMD IL
    spir,    // SPIR: standard portable IR for OpenCL 32-bit version
    spir64   // SPIR: standard portable IR for OpenCL 64-bit version
  };

e em clang/lib/Driver/ToolChains.cpp, há sth sobre arm.

static const char *GetArmArchForMArch(StringRef Value) {
  return llvm::StringSwitch<const char*>(Value)
    .Case("armv6k", "armv6")
    .Case("armv6m", "armv6m")
    .Case("armv5tej", "armv5")
    .Case("xscale", "xscale")
    .Case("armv4t", "armv4t")
    .Case("armv7", "armv7")
    .Cases("armv7a", "armv7-a", "armv7")
    .Cases("armv7r", "armv7-r", "armv7")
    .Cases("armv7em", "armv7e-m", "armv7em")
    .Cases("armv7f", "armv7-f", "armv7f")
    .Cases("armv7k", "armv7-k", "armv7k")
    .Cases("armv7m", "armv7-m", "armv7m")
    .Cases("armv7s", "armv7-s", "armv7s")
    .Default(0);
}

static const char *GetArmArchForMCpu(StringRef Value) {
  return llvm::StringSwitch<const char *>(Value)
    .Cases("arm9e", "arm946e-s", "arm966e-s", "arm968e-s", "arm926ej-s","armv5")
    .Cases("arm10e", "arm10tdmi", "armv5")
    .Cases("arm1020t", "arm1020e", "arm1022e", "arm1026ej-s", "armv5")
    .Case("xscale", "xscale")
    .Cases("arm1136j-s", "arm1136jf-s", "arm1176jz-s", "arm1176jzf-s", "armv6")
    .Case("cortex-m0", "armv6m")
    .Cases("cortex-a8", "cortex-r4", "cortex-a9", "cortex-a15", "armv7")
    .Case("cortex-a9-mp", "armv7f")
    .Case("cortex-m3", "armv7m")
    .Case("cortex-m4", "armv7em")
    .Case("Swift", "armv7s")
    .Default(0);
}
30
a'Q

Uma dica que você pode fazer: se você está tentando encontrar um alvo em particular triplo, é instalar o llvm nesse sistema então faça um

$ llc --version | grep Default
  Default target: x86_64-Apple-darwin16.1.0

ou alternativamente:

$ llvm-config --Host-target
x86_64-Apple-darwin16.0.0
or
$ clang -v 2>&1 | grep Target
Target: x86_64-Apple-darwin16.1.0

Então você sabe como direcioná-lo ao fazer a compilação cruzada de qualquer maneira.

Aparentemente existem "lotes" de alvos por aí, eis uma lista, sinta-se à vontade para adicioná-la ao estilo wiki da comunidade:

arm-none-eabi
armv7a-none-eabi
arm-linux-gnueabihf 
arm-none-linux-gnueabi
i386-pc-linux-gnu 
x86_64-Apple-darwin10
i686-w64-windows-gnu # same as i686-w64-mingw32
x86_64-pc-linux-gnu # from ubuntu 64 bit
x86_64-unknown-windows-cygnus # cygwin 64-bit
x86_64-w64-windows-gnu # same as x86_64-w64-mingw32
i686-pc-windows-gnu # MSVC
x86_64-pc-windows-gnu # MSVC 64-BIT

Aqui está o que o docs lista de qualquer maneira (aparentemente é um quádruplo [ou quíntuplo?] Em vez de um triplo estes dias):

The triple has the general format <Arch><sub>-<vendor>-<sys>-<abi>, where:
Arch = x86, arm, thumb, mips, etc.
sub = for ex. on ARM: v5, v6m, v7a, v7m, etc.
vendor = pc, Apple, nvidia, ibm, etc.
sys = none, linux, win32, darwin, cuda, etc.
abi = eabi, gnu, Android, macho, elf, etc.

e você pode até mesmo ajustar especificar um cpu alvo além disso, embora ele use um padrão sensível para o cpu alvo baseado no triplo.

Às vezes, os alvos "resolvem" a mesma coisa, para ver o que um alvo é realmente tratado como:

 $ clang -target x86_64-w64-mingw32 -v 2>&1 | grep Target
 Target: x86_64-w64-windows-gnu
14
rogerdpack

De acordo com Jonathan Roelofs nesta palestra “Quais alvos o Clang suporta?” :

$ llc --version
LLVM (http://llvm.org/):
  LLVM version 3.6.0
  Optimized build with assertions.
  Built Apr  2 2015 (01:25:22).
  Default target: x86_64-Apple-darwin12.6.0
  Host CPU: corei7-avx

  Registered Targets:
    aarch64    - AArch64 (little endian)
    aarch64_be - AArch64 (big endian)
    amdgcn     - AMD GCN GPUs
    arm        - ARM
    arm64      - ARM64 (little endian)
    armeb      - ARM (big endian)
    cpp        - C++ backend
    hexagon    - Hexagon
    mips       - Mips
    mips64     - Mips64 [experimental]
    mips64el   - Mips64el [experimental]
    mipsel     - Mipsel
    msp430     - MSP430 [experimental]
    nvptx      - NVIDIA PTX 32-bit
    nvptx64    - NVIDIA PTX 64-bit
    ppc32      - PowerPC 32
    ppc64      - PowerPC 64
    ppc64le    - PowerPC 64 LE
    r600       - AMD GPUs HD2XXX-HD6XXX
    sparc      - Sparc
    sparcv9    - Sparc V9
    systemz    - SystemZ
    thumb      - Thumb
    thumbeb    - Thumb (big endian)
    x86        - 32-bit X86: Pentium-Pro and above
    x86-64     - 64-bit X86: EM64T and AMD64
    xcore      - XCore

Versões futuras do Clang podem fornecer o seguinte. Eles são listados como "propostos", embora ainda não estejam disponíveis pelo menos a partir da versão 3.9.0:

$ clang -target <target_from_list_above> --print-multi-libs
$ clang -print-supported-archs
$ clang -march x86 -print-supported-systems 
$ clang -march x86 -print-available-systems 
10
jww

Tente também

> llc -mattr=help

Available CPUs for this target:

  amdfam10      - Select the amdfam10 processor.
  athlon        - Select the athlon processor.
  athlon-4      - Select the athlon-4 processor.
  athlon-fx     - Select the athlon-fx processor.
  athlon-mp     - Select the athlon-mp processor.
  athlon-tbird  - Select the athlon-tbird processor.
  athlon-xp     - Select the athlon-xp processor.
  athlon64      - Select the athlon64 processor.
  athlon64-sse3 - Select the athlon64-sse3 processor.
  atom          - Select the atom processor.
  ...
Available features for this target:

  16bit-mode           - 16-bit mode (i8086).
  32bit-mode           - 32-bit mode (80386).
  3dnow                - Enable 3DNow! instructions.
  3dnowa               - Enable 3DNow! Athlon instructions.
  64bit                - Support 64-bit instructions.
  64bit-mode           - 64-bit mode (x86_64).
  adx                  - Support ADX instructions.
  ...
5
Zinovy Nis

Não vai listar todos os triplos, mas

llvm-as < /dev/null | llc -mcpu=help

pelo menos listará todas as CPUs.

1
bcmills