Как я могу реализовать тип данных String в LLVM?

Не допускается, чтобы персонал, не занимающийся вопросами развития, управлял персоналом, занимающимся вопросами развития.

Исправление: Персонал с нулевым опытом развития не должен иметь права управлять персоналом по развитию.

17
задан River 21 October 2017 в 21:47
поделиться

3 ответа

Что такое строка? Массив символов.

Что такое символ? Целое число.

Так что, хотя я ни в коем случае не эксперт по LLVM, я предполагаю, что если, например, вы хотите представить какой-то 8-битный набор символов, вы должны использовать массив i8 (8-битные целые числа ) или указатель на i8. И действительно, если у нас есть простая программа C hello world:

#include <stdio.h>

int main() {
        puts("Hello, world!");
        return 0;
}

И мы компилируем ее с помощью llvm-gcc и дамп сгенерированной сборки LLVM:

$ 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*)

Обратите внимание на ссылку на функцию put, объявленную в конце файла. В C put это

int puts(const char *s)

В LLVM это

i32 @puts(i8*)

Соответствие должно быть ясным.

Кстати, сгенерированный LLVM здесь очень подробный, потому что я скомпилировал без оптимизаций. Если вы их включите, ненужные инструкции исчезнут:

$ 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*)
20
ответ дан 30 November 2019 в 11:44
поделиться

Подумайте о том, как строка представлена ​​в обычных языках:

  • C: указатель на символ. Вам не нужно делать ничего особенного.
  • C ++: строка - это сложный объект с конструктором, деструктором и конструктором копирования. Внутри он обычно содержит строку C.
  • Java / C # / ...: строка - это сложный объект, содержащий массив символов.

Имя LLVM говорит само за себя. Это действительно «низкий уровень». Вы должны реализовать строки такими, какими вы хотите их видеть. Было бы глупо со стороны LLVM заставлять кого-либо использовать конкретную реализацию.

2
ответ дан 30 November 2019 в 11:44
поделиться

[Чтобы следовать вверх по другим ответам, которые объясняют, что такое строки, вот некоторая помощь по реализации]

Используя интерфейс C, вам понадобятся следующие вызовы:

LLVMValueRef llvmGenLocalStringVar(const char* data, int len)
{
  LLVMValueRef glob = LLVMAddGlobal(mod, LLVMArrayType(LLVMInt8Type(), len), "string");

  // set as internal linkage and constant
  LLVMSetLinkage(glob, LLVMInternalLinkage);
  LLVMSetGlobalConstant(glob, TRUE);

  // Initialize with string:
  LLVMSetInitializer(glob, LLVMConstString(data, len, TRUE));

  return glob;
}
12
ответ дан 30 November 2019 в 11:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: