2013-02-06 12 views
12

La lingua LLVM specifica tipi interi come in, dove N è il bit-larghezza del numero intero e varia da 1 a 2^23-1 (Secondo: http://llvm.org/docs/LangRef.html#integer-type)tipi interi di llvm

Ho 2 domande :

  1. Quando si compila un programma C fino al livello LLVM IR, quali tipi può essere abbassata a i1, i2, i3, ecc? Sembra che i tipi i8, i16, i32, i64 debbano essere sufficienti, quindi mi stavo chiedendo cosa fossero per tutti gli altri quasi 8 milioni di tipi interi.

  2. È vero che entrambi i tipi di interi con segno e senza segno sono ridotti a i32? Qual è la ragione per questo, e perché non si applica a qualcosa come 32-bit float (che è rappresentato come f32 in LLVM)?

risposta

15

Prima di tutto, essere consapevoli entrambi interi arbitrari di dimensioni standard e senza distinzione tra numeri interi con e senza segno sono modifiche aggiunti a LLVM 2.0. Le versioni precedenti avevano solo pochi tipi interi, con una distinzione firmata/non firmata.

Ora, alle tue domande:

  1. LLVM, anche se progettato con C/C++ in mente, non è specifico per queste lingue. Avere più tipi interi possibili ti dà più flessibilità. Non è necessario utilizzare questi tipi, ovviamente - e suppongo che, come hai detto, qualsiasi frontend C/C++ a LLVM (cioè Clang) probabilmente genererebbe solo i1, i8, i16, i32 e i64 .

    Modifica: apparentemente mi sbaglio e Clang utilizza anche altri tipi di interi, vedi il commento di Jens sotto.

  2. Sì, LLVM non distingue tra il tipo di intero con segno e senza segno, quindi entrambi verranno abbassati su i32. Le operazioni sul numero intero senza segno, tuttavia, saranno tradotte in base al tipo originale; per esempio. una divisione tra interi senza segno sarà udiv mentre tra firmata sarà sdiv. Poiché gli interi sono rappresentati come two's complement, tuttavia, molte operazioni (ad esempio add) non si preoccupano di firmate/non firmate e quindi hanno una sola versione.

    Per quanto riguarda perché nessuna distinzione è stata fatta in LLVM tra firmato e non firmato, leggere the details on this enhancement request - in breve, avendo entrambi firmati e versioni unsigned ha portato ad un grande gonfiare IR ed era dannoso per alcune ottimizzazioni, così è stata abbandonata.

    Infine, chiedete perché no f32 - la risposta è che non lo so, forse è stato ritenuto meno utile di numeri interi di dimensioni arbitrarie. Tuttavia, notare che f32 in realtà non è descrittivo - se si desidera che i tipi in virgola mobile arbitrario è necessario specificare almeno la dimensione del numero di base e la dimensione dell'esponente, qualcosa come f23e8 invece di float e f52e11 invece di double. È un po 'ingombrante se me lo chiedi, anche se credo che lo float e lo double avrebbero potuto essere resi sinonimi di quelli.

+0

In realtà 'f32' esiste per i numeri in virgola mobile. La ragione per cui l'ho chiesto è che ho pensato che se entrambi gli interi firmati e non firmati possono essere rappresentati da i32, allora forse anche un float a 32 bit può essere rappresentato in questo modo. Immagino che questa sia stata una decisione di progettazione dettagliata come hai detto. –

+0

@AliJ Non vedo 'f32' elencato su [la sezione ref lang sui tipi a virgola mobile] (http://llvm.org/docs/LangRef.html#floating-point-types) ... a meno che tu significava che c'era un'implementazione comune associata a quel nome? – Oak

+3

Grazie per questo! Come è successo, ho appena trovato due istruzioni generate da Clang: 'store i576% bla, i576 * bitcast (% class.Foo * @_Global in i576 *), align 8' e'% 11 = load i384 *% 10, allineare 8'. Suppongo che questi siano ridotti a una chiamata 'memcpy' oa una sequenza smartish di istruzioni store/load usando i tipi SIMD. – Jens

Problemi correlati