[clang] clang : 지원되는 대상 아키텍처를 나열하는 방법은 무엇입니까?

현재 저는 ARM, 특히 아이폰 / 안드로이드 타겟에 관심이 있습니다. 그러나 나는 clang에 대해 더 많이 알고 싶습니다. 앞으로 몇 년 동안 중요한 역할을 할 것 같기 때문입니다.

나는 시도했다

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)

clang에 -triplet 매개 변수가 있다는 것을 알고 있지만 가능한 모든 값을 나열하려면 어떻게해야합니까? 나는 clang이 크로스 컴파일과 관련하여 gcc와 매우 다르다는 것을 발견했습니다. GCC 세계에서는 PLATFORM_make 또는 PLATFORM_ld (i * 86-pc-cygwin i * 86-*-linux-gnu 등)와 같은 모든 것에 대해 별도의 바이너리가 있어야합니다. http : //git.savannah.gnu.org/cgit/libtool.git/tree/doc/PLATFORMS )

clang 세계에서는 (일부 포럼에서 읽은 것처럼) 단 하나의 바이너리입니다. 하지만 지원되는 대상 목록은 어떻게 얻습니까? 그리고 내 대상이 내 배포판 (linux / windows / macos / whatever)에서 지원되지 않는 경우 더 많은 플랫폼을 지원하는 대상을 어떻게 얻을 수 있습니까?

다음과 같이 최신 clang을 SVN하면

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

대부분의 플랫폼을 얻을 수 있습니까? Clang이 바로 크로스 컴파일을 염두에두고 빌드되지 않은 것처럼 보이지만 llvm 기반이기 때문에 이론상 매우 크로스 친화적이어야합니까? 감사합니다!



답변

내가 말할 수있는 한, 주어진 clang바이너리가 지원 하는 아키텍처를 나열하는 명령 줄 옵션이 없으며 심지어 실행 strings하는 것도 실제로 도움이되지 않습니다. Clang은 본질적으로 C to LLVM 번역기이며 실제 기계 코드 생성의 핵심을 다루는 것은 LLVM 자체이므로 Clang이 기본 아키텍처에 많은 관심을 기울이지 않는다는 것이 전혀 놀라운 일이 아닙니다.

다른 사람들이 이미 언급했듯이 llc지원하는 아키텍처를 물어볼 수 있습니다 . 이것은 이러한 LLVM 구성 요소가 설치되지 않았기 때문이 아니라 검색 경로 및 패키징 시스템의 변동으로 인해 사용자 llcclang바이너리가 동일한 버전의 LLVM에 해당하지 않을 수 있습니다.

그러나 논쟁을 위해 LLVM과 Clang을 모두 직접 컴파일했거나 LLVM 바이너리를 충분히 만족스럽게 받아 들였다고 가정 해 보겠습니다.

  • llc --version지원하는 모든 아키텍처 목록을 제공합니다. 기본적으로 모든 아키텍처를 지원하도록 컴파일됩니다. ARM과 같은 단일 아키텍처로 생각할 수있는 것은 일반 ARM, Thumb 및 AArch64와 같은 여러 LLVM 아키텍처가있을 수 있습니다. 다른 실행 모드는 명령어 인코딩과 의미가 매우 다르기 때문에 이는 주로 구현 편의를위한 것입니다.
  • 나열된 각 아키텍처에 대해 llc -march=ARCH -mattr=help“사용 가능한 CPU”및 “사용 가능한 기능”이 나열 됩니다. CPU는 일반적으로 기본 기능 모음을 설정하는 편리한 방법입니다.

하지만 지금은 나쁜 소식입니다. Clang 또는 LLVM에는 덤프 할 수있는 편리한 트리플 테이블이 없습니다. 아키텍처 별 백엔드에는 트리플 문자열을 llvm::Triple객체 로 구문 분석하는 옵션이 있기 때문입니다 ( include / llvm / ADT / Triple.h에 정의 ). 즉, 사용 가능한 모든 트리플을 덤프하려면 중지 문제를 해결해야합니다. 예를 들어 llvm::ARM_MC::ParseARMTriple(...)문자열을 구문 분석하는 특수 사례 를 참조하십시오 "generic".

하지만 궁극적으로 “트리플”은 대부분 Clang을 GCC의 드롭 인 대체품으로 만드는 이전 버전과의 호환성 기능이므로 Clang 또는 LLVM을 새 플랫폼으로 이식하지 않는 한 일반적으로 많은주의를 기울일 필요가 없습니다. 또는 건축. 대신, llc -march=arm -mattr=help조사에 더 유용 할 수있는 다양한 ARM 기능의 방대한 배열에서 출력을 찾을 수있을 것입니다 .

연구에 행운을 빕니다!


답변

저는 Clang 3.3을 사용하고 있습니다. 답을 얻는 가장 좋은 방법은 소스 코드를 읽는 것입니다. 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
  };

clang / lib / Driver / ToolChains.cpp에는 arm에 대한 sth가 있습니다.

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);
}


답변

할 수있는 한 가지 힌트 : 특정 타겟 트리플을 찾으려고하는 경우 해당 시스템에 llvm을 설치 한 다음

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

또는 대안으로 :

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

그러면 어쨌든 크로스 컴파일 할 때 대상을 지정하는 방법을 알고 있습니다.

분명히 거기에는 “많은”대상이 있습니다. 여기에 목록이 있습니다. 자유롭게 추가 할 수 있습니다. 커뮤니티 위키 스타일 :

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

어쨌든 문서 목록 은 다음과 같습니다 (요즘에는 3 배가 아닌 4 배 [또는 5 배?]).

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.

트리플을 기반으로 대상 CPU에 대해 합리적인 기본값을 사용하지만이 이상의 대상 CPU를 미세 조정할 수도 있습니다.

때때로 대상은 동일한 대상으로 “해결”하여 대상이 실제로 무엇으로 취급되는지 확인합니다.

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


답변

이 강연에서 Jonathan Roelofs에 따르면 “Clang은 어떤 타겟을 지원하나요?” :

$ 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

향후 버전의 Clang은 다음을 제공 할 수 있습니다. 적어도 v 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


답변

또한 시도

> 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.
  ...


답변

Clang 11 (트렁크)을 시작하면 새로 추가 된 -print-targets플래그를 사용하여 지원되는 대상 아키텍처 목록을 간편하게 인쇄 할 수 있습니다 .

$ clang-11 -print-targets
  Registered Targets:
    aarch64    - AArch64 (little endian)
    aarch64_32 - AArch64 (little endian ILP32)
    aarch64_be - AArch64 (big endian)
    amdgcn     - AMD GCN GPUs
    arm        - ARM
    arm64      - ARM64 (little endian)
    arm64_32   - ARM64 (little endian ILP32)
    armeb      - ARM (big endian)
    avr        - Atmel AVR Microcontroller
    bpf        - BPF (host endian)
    bpfeb      - BPF (big endian)
    bpfel      - BPF (little endian)
    hexagon    - Hexagon
    lanai      - Lanai
    mips       - MIPS (32-bit big endian)
    mips64     - MIPS (64-bit big endian)
    mips64el   - MIPS (64-bit little endian)
    mipsel     - MIPS (32-bit little endian)
    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
    riscv32    - 32-bit RISC-V
    riscv64    - 64-bit RISC-V
    sparc      - Sparc
    sparcel    - Sparc LE
    sparcv9    - Sparc V9
    systemz    - SystemZ
    thumb      - Thumb
    thumbeb    - Thumb (big endian)
    wasm32     - WebAssembly 32-bit
    wasm64     - WebAssembly 64-bit
    x86        - 32-bit X86: Pentium-Pro and above
    x86-64     - 64-bit X86: EM64T and AMD64
    xcore      - XCore

참조 : LLVM PR , LLVM commit , Clang 11 documentation .


답변

모든 트리플을 나열하지는 않지만

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

최소한 모든 CPU를 나열합니다.