¿Qué es un hilo? Una variedad de personajes.
¿Qué es un personaje? Un entero.
Entonces, aunque no soy experto en LLVM de ninguna manera, supongo que si, por ejemplo, quisieras representar un conjunto de caracteres de 8 bits, utilizarías una matriz de i8 (enteros de 8 bits), o un puntero a i8. Y de hecho, si tenemos un sencillo programa hola mundo C:
#include <stdio.h>
int main() {
puts("Hello, world!");
return 0;
}
y compilamos usando llvm-gcc y volcar el ensamblaje LLVM generada:
$ llvm-gcc -S -emit-llvm hello.c
$ cat hello.s
; ModuleID = 'hello.c'
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
target triple = "x86_64-linux-gnu"
@.str = internal constant [14 x i8] c"Hello, world!\00" ; <[14 x i8]*> [#uses=1]
define i32 @main() {
entry:
%retval = alloca i32 ; <i32*> [#uses=2]
%tmp = alloca i32 ; <i32*> [#uses=2]
%"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
%tmp1 = getelementptr [14 x i8]* @.str, i32 0, i64 0 ; <i8*> [#uses=1]
%tmp2 = call i32 @puts(i8* %tmp1) nounwind ; <i32> [#uses=0]
store i32 0, i32* %tmp, align 4
%tmp3 = load i32* %tmp, align 4 ; <i32> [#uses=1]
store i32 %tmp3, i32* %retval, align 4
br label %return
return: ; preds = %entry
%retval4 = load i32* %retval ; <i32> [#uses=1]
ret i32 %retval4
}
declare i32 @puts(i8*)
Aviso la referencia a la función pone declaró al final del archivo. En C, pone es
int puts(const char *s)
en LLVM, es
i32 @puts(i8*)
La correspondencia debe ser clara.
Como un lado, el LLVM generado es muy detallado aquí porque compilé sin optimizaciones. Si a su vez las de, las instrucciones innecesarias desaparecen:
$ llvm-gcc -O2 -S -emit-llvm hello.c
$ cat hello.s
; ModuleID = 'hello.c'
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
target triple = "x86_64-linux-gnu"
@.str = internal constant [14 x i8] c"Hello, world!\00" ; <[14 x i8]*> [#uses=1]
define i32 @main() nounwind {
entry:
%tmp2 = tail call i32 @puts(i8* getelementptr ([14 x i8]* @.str, i32 0, i64 0)) nounwind ; <i32> [#uses=0]
ret i32 0
}
declare i32 @puts(i8*)
Hmm, está bien, así que si quiero usar cadenas como muchos de los idiomas interpretados hoy en día (no solo una matriz, sino también la longitud, etc.) tendría que declarar que como una especie de estructura que lleva el equipaje extra con ella, ¿tendría? ser un tipo completamente nuevo en el back-end? –
Sí, eso es básicamente correcto, pero no tiene que ser un nuevo tipo en el back-end. Puede usar una estructura LLVM para almacenar los datos que necesita y luego definir algunas funciones que actúan en su contenedor de cadenas. Como dice Zifre, realmente es una máquina virtual de bajo nivel. –
Bien, he descubierto que puedes crear pequeñas y agradables matrices en llvm, pero no he encontrado en ninguna parte que muestre cómo reasignar estas matrices a un tamaño diferente (lo que tendré que hacer si quiero hacer una string longer) –